diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..d2f3c30b --- /dev/null +++ b/.clang-format @@ -0,0 +1,6 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +ColumnLimit: 100 +UseTab: Never +PointerAlignment: Left +SortIncludes: false diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000..45e4526a --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# clang-format entire tree +b056da581f6bb381a113d3223786714f1bcd0d86 diff --git a/db/dbHandle.h b/db/dbHandle.h index 389c8274..9849d025 100644 --- a/db/dbHandle.h +++ b/db/dbHandle.h @@ -5,47 +5,38 @@ #ifndef __DBHANDLE_H #define __DBHANDLE_H "$Id: dbHandle.h,v 1.1 2007/08/28 16:09:58 dan_karrels Exp $" -#include -#include +#include +#include -#include "defs.h" +#include "defs.h" #ifdef HAVE_PGSQL -#include "pgsqlDB.h" +#include "pgsqlDB.h" #endif -namespace gnuworld -{ +namespace gnuworld { class dbHandle #ifdef HAVE_PGSQL - : public pgsqlDB + : public pgsqlDB #endif { -public: - dbHandle( xClient* bot, - const std::string& dbHost, - const unsigned short int dbPort, - const std::string& dbName, - const std::string& userName, - const std::string& password ) + public: + dbHandle(xClient* bot, const std::string& dbHost, const unsigned short int dbPort, + const std::string& dbName, const std::string& userName, const std::string& password) #ifdef HAVE_PGSQL - : pgsqlDB( bot, - dbHost, - dbPort, - dbName, - userName, - password ) + : pgsqlDB(bot, dbHost, dbPort, dbName, userName, password) #endif - {} - dbHandle( xClient* bot, const std::string& connectInfo ) + { + } + dbHandle(xClient* bot, const std::string& connectInfo) #ifdef HAVE_PGSQL - : pgsqlDB( bot, connectInfo ) + : pgsqlDB(bot, connectInfo) #endif - {} - virtual ~dbHandle() {} - -} ; + { + } + virtual ~dbHandle() {} +}; } // namespace gnuworld diff --git a/db/gnuworldDB.cc b/db/gnuworldDB.cc index e5154f12..79bdc683 100644 --- a/db/gnuworldDB.cc +++ b/db/gnuworldDB.cc @@ -21,36 +21,22 @@ * $Id: gnuworldDB.cc,v 1.5 2008/01/02 23:32:17 kewlio Exp $ */ -#include -#include "gnuworldDB.h" +#include +#include "gnuworldDB.h" -namespace gnuworld -{ -using std::string ; +namespace gnuworld { +using std::string; -gnuworldDB::gnuworldDB( ) -{ - /* dummy to prevent issues with pedantic compilers */ -} +gnuworldDB::gnuworldDB() { /* dummy to prevent issues with pedantic compilers */ } -gnuworldDB::gnuworldDB( const string& _dbHost, - const unsigned short int _dbPort, - const string& _dbName, - const string& _userName, - const string& _password ) - : dbHost( _dbHost ), - dbPort( _dbPort ), - dbName( _dbName ), - userName( _userName ), - password( _password ) -{} +gnuworldDB::gnuworldDB(const string& _dbHost, const unsigned short int _dbPort, + const string& _dbName, const string& _userName, const string& _password) + : dbHost(_dbHost), dbPort(_dbPort), dbName(_dbName), userName(_userName), password(_password) {} -gnuworldDB::gnuworldDB( const string& /* connectInfo */ ) -{ -// TODO +gnuworldDB::gnuworldDB(const string& /* connectInfo */) { + // TODO } -gnuworldDB::~gnuworldDB() -{} +gnuworldDB::~gnuworldDB() {} } // namespace gnuworld diff --git a/db/gnuworldDB.h b/db/gnuworldDB.h index 01e90ab4..23472b5c 100644 --- a/db/gnuworldDB.h +++ b/db/gnuworldDB.h @@ -23,92 +23,74 @@ #ifndef __GNUWORLDDB_H #define __GNUWORLDDB_H "$Id: gnuworldDB.h,v 1.5 2009/07/26 18:30:37 mrbean_ Exp $" -#include -#include +#include +#include -#include +#include -namespace gnuworld -{ +namespace gnuworld { -class gnuworldDB -{ -protected: - std::string dbHost ; - unsigned short int dbPort ; - std::string dbName ; - std::string userName ; - std::string password ; +class gnuworldDB { + protected: + std::string dbHost; + unsigned short int dbPort; + std::string dbName; + std::string userName; + std::string password; -public: - gnuworldDB() ; - gnuworldDB( const std::string& dbHost, - const unsigned short int dbPort, - const std::string& dbName, - const std::string& userName, - const std::string& password ) ; - gnuworldDB( const std::string& connectInfo ) ; - virtual ~gnuworldDB() ; + public: + gnuworldDB(); + gnuworldDB(const std::string& dbHost, const unsigned short int dbPort, + const std::string& dbName, const std::string& userName, const std::string& password); + gnuworldDB(const std::string& connectInfo); + virtual ~gnuworldDB(); - /** - * The Exec method will execute an SQL command with the database. - * The "returnData" argument is false by default, and indicated - * whether or not data is expected back. - * If data is expected back, pass true to this method, - * and the return value will indicate if data was successfully - * returned. - * Otherwise, no data is expected back, and the method will - * return true if the command was successfully executed - * (with no data returned). - */ - virtual bool Exec( const std::stringstream&, - bool returnData = false ) = 0 ; + /** + * The Exec method will execute an SQL command with the database. + * The "returnData" argument is false by default, and indicated + * whether or not data is expected back. + * If data is expected back, pass true to this method, + * and the return value will indicate if data was successfully + * returned. + * Otherwise, no data is expected back, and the method will + * return true if the command was successfully executed + * (with no data returned). + */ + virtual bool Exec(const std::stringstream&, bool returnData = false) = 0; - /** - * The Exec method will execute an SQL command with the database. - * The "returnData" argument is false by default, and indicated - * whether or not data is expected back. - * If data is expected back, pass true to this method, - * and the return value will indicate if data was successfully - * returned. - * Otherwise, no data is expected back, and the method will - * return true if the command was successfully executed - * (with no data returned). - */ - virtual bool Exec( const std::string&, - bool returnData = false ) = 0 ; - virtual bool isConnected() const = 0 ; - virtual bool ConnectionBad() const - { return !isConnected() ; } + /** + * The Exec method will execute an SQL command with the database. + * The "returnData" argument is false by default, and indicated + * whether or not data is expected back. + * If data is expected back, pass true to this method, + * and the return value will indicate if data was successfully + * returned. + * Otherwise, no data is expected back, and the method will + * return true if the command was successfully executed + * (with no data returned). + */ + virtual bool Exec(const std::string&, bool returnData = false) = 0; + virtual bool isConnected() const = 0; + virtual bool ConnectionBad() const { return !isConnected(); } - virtual unsigned int countTuples() const = 0 ; - virtual unsigned int affectedRows() const = 0 ; - virtual unsigned int Tuples() const - { return countTuples() ; } + virtual unsigned int countTuples() const = 0; + virtual unsigned int affectedRows() const = 0; + virtual unsigned int Tuples() const { return countTuples(); } - virtual const std::string ErrorMessage() const = 0 ; - virtual const std::string GetValue( unsigned int row, - unsigned int column ) const = 0 ; - virtual const std::string GetValue( unsigned int row, - const std::string& colName ) - const = 0 ; + virtual const std::string ErrorMessage() const = 0; + virtual const std::string GetValue(unsigned int row, unsigned int column) const = 0; + virtual const std::string GetValue(unsigned int row, const std::string& colName) const = 0; - virtual bool PutLine( const std::string& ) = 0 ; - virtual bool StartCopyIn( const std::string& ) = 0 ; - virtual bool StopCopyIn() = 0 ; + virtual bool PutLine(const std::string&) = 0; + virtual bool StartCopyIn(const std::string&) = 0; + virtual bool StopCopyIn() = 0; - inline const std::string& getDBHost() const - { return dbHost ; } - inline const unsigned short int& getDBPort() const - { return dbPort ; } - inline const std::string& getDBName() const - { return dbName ; } - inline const std::string& getUserName() const - { return userName ; } - inline const std::string& getPassword() const - { return password ; } - -} ; + inline const std::string& getDBHost() const { return dbHost; } + inline const unsigned short int& getDBPort() const { return dbPort; } + inline const std::string& getDBName() const { return dbName; } + inline const std::string& getUserName() const { return userName; } + inline const std::string& getPassword() const { return password; } +}; } // namespace gnuworld diff --git a/db/pgsqlDB.cc b/db/pgsqlDB.cc index f2ec3f02..e509ff3f 100644 --- a/db/pgsqlDB.cc +++ b/db/pgsqlDB.cc @@ -21,210 +21,159 @@ * $Id: pgsqlDB.cc,v 1.5 2009/07/25 16:59:48 mrbean_ Exp $ */ -#include - -#include -#include -#include -#include -#include - -#include "libpq-fe.h" -#include "gnuworldDB.h" -#include "pgsqlDB.h" -#include "client.h" -#include "logger.h" - -namespace gnuworld -{ -using std::cout ; -using std::endl ; -using std::ends ; -using std::string ; -using std::stringstream ; - -pgsqlDB::pgsqlDB( xClient* _bot, - const string& dbHost, - const unsigned short int dbPort, - const string& dbName, - const string& userName, - const string& password ) -: gnuworldDB( dbHost, dbPort, dbName, userName, password ), - bot( _bot ), - theDB( 0 ), - lastResult( 0 ) -{ -stringstream s ; -s << "host=" << dbHost - << " dbname=" << dbName - << " port=" << dbPort ; - -if( !userName.empty() ) - { - s << " user=" << userName ; - } -if( !password.empty() ) - { - s << " password=" << password ; - } -s << ends ; - -// Allow exception to be thrown -theDB = PQconnectdb( s.str().c_str() ) ; -if( 0 == theDB ) - { - cout << "pgsqlDB> Failed to allocate memory for db handle" - << endl ; - throw std::exception() ; - } -if( !isConnected() ) - { - cout << "pgsqlDB> Failed to connect to db: " - << ErrorMessage() - << endl ; -// throw std::exception() ; - } +#include + +#include +#include +#include +#include +#include + +#include "libpq-fe.h" +#include "gnuworldDB.h" +#include "pgsqlDB.h" +#include "client.h" +#include "logger.h" + +namespace gnuworld { +using std::cout; +using std::endl; +using std::ends; +using std::string; +using std::stringstream; + +pgsqlDB::pgsqlDB(xClient* _bot, const string& dbHost, const unsigned short int dbPort, + const string& dbName, const string& userName, const string& password) + : gnuworldDB(dbHost, dbPort, dbName, userName, password), bot(_bot), theDB(0), lastResult(0) { + stringstream s; + s << "host=" << dbHost << " dbname=" << dbName << " port=" << dbPort; + + if (!userName.empty()) { + s << " user=" << userName; + } + if (!password.empty()) { + s << " password=" << password; + } + s << ends; + + // Allow exception to be thrown + theDB = PQconnectdb(s.str().c_str()); + if (0 == theDB) { + cout << "pgsqlDB> Failed to allocate memory for db handle" << endl; + throw std::exception(); + } + if (!isConnected()) { + cout << "pgsqlDB> Failed to connect to db: " << ErrorMessage() << endl; + // throw std::exception() ; + } } -pgsqlDB::pgsqlDB( xClient* _bot, const string& connectInfo ) -: bot( _bot ) -{ -// TODO -// Allow exception to be thrown -lastResult = 0; -theDB = PQconnectdb( connectInfo.c_str() ) ; -if( 0 == theDB ) - { - cout << "pgsqlDB> Failed to allocate memory for db handle" - << endl ; - throw std::exception() ; - } -if( !isConnected() ) - { - cout << "pgsqlDB> Failed to connect to db: " - << ErrorMessage() - << endl ; - throw std::exception() ; - } +pgsqlDB::pgsqlDB(xClient* _bot, const string& connectInfo) : bot(_bot) { + // TODO + // Allow exception to be thrown + lastResult = 0; + theDB = PQconnectdb(connectInfo.c_str()); + if (0 == theDB) { + cout << "pgsqlDB> Failed to allocate memory for db handle" << endl; + throw std::exception(); + } + if (!isConnected()) { + cout << "pgsqlDB> Failed to connect to db: " << ErrorMessage() << endl; + throw std::exception(); + } } -pgsqlDB::~pgsqlDB() -{ -if( theDB != 0 ) - { - PQfinish( theDB ) ; - theDB = 0 ; - } -if( lastResult != 0 ) - { - PQclear( lastResult ) ; - lastResult = 0 ; - } +pgsqlDB::~pgsqlDB() { + if (theDB != 0) { + PQfinish(theDB); + theDB = 0; + } + if (lastResult != 0) { + PQclear(lastResult); + lastResult = 0; + } } -bool pgsqlDB::Exec( const string& theQuery, bool log ) -{ -/* Log query. */ -if (log) - bot->getLogger()->write( SQL, theQuery ) ; - -// It is necessary to manually deallocate the last result -// to prevent memory leaks. -if( lastResult != 0 ) - { - PQclear( lastResult ) ; - lastResult = 0 ; - } -lastResult = PQexec( theDB, theQuery.c_str() ) ; - -ExecStatusType status = PQresultStatus( lastResult ) ; -if (PGRES_COPY_IN == status) return true; -if (PGRES_TUPLES_OK == status) return true; -if (PGRES_COMMAND_OK == status) return true; -return false; +bool pgsqlDB::Exec(const string& theQuery, bool log) { + /* Log query. */ + if (log) + bot->getLogger()->write(SQL, theQuery); + + // It is necessary to manually deallocate the last result + // to prevent memory leaks. + if (lastResult != 0) { + PQclear(lastResult); + lastResult = 0; + } + lastResult = PQexec(theDB, theQuery.c_str()); + + ExecStatusType status = PQresultStatus(lastResult); + if (PGRES_COPY_IN == status) + return true; + if (PGRES_TUPLES_OK == status) + return true; + if (PGRES_COMMAND_OK == status) + return true; + return false; } -bool pgsqlDB::Exec( const stringstream& theQuery, bool retData ) -{ -return Exec( theQuery.str(), retData ) ; +bool pgsqlDB::Exec(const stringstream& theQuery, bool retData) { + return Exec(theQuery.str(), retData); } -bool pgsqlDB::StartCopyIn( const string& writeMe ) -{ -return Exec( writeMe ) ; -} +bool pgsqlDB::StartCopyIn(const string& writeMe) { return Exec(writeMe); } -bool pgsqlDB::StopCopyIn() -{ -if( 0 == lastResult ) - { - return false ; - } -return (PQputCopyEnd( theDB, 0 ) != -1) ; +bool pgsqlDB::StopCopyIn() { + if (0 == lastResult) { + return false; + } + return (PQputCopyEnd(theDB, 0) != -1); } -bool pgsqlDB::PutLine( const string& writeMe ) -{ -if( 0 == lastResult ) - { - return false ; - } -return (PQputline( theDB, writeMe.c_str() ) != -1) ; +bool pgsqlDB::PutLine(const string& writeMe) { + if (0 == lastResult) { + return false; + } + return (PQputline(theDB, writeMe.c_str()) != -1); } -unsigned int pgsqlDB::countTuples() const -{ -if( 0 == lastResult ) - { - return 0 ; - } -return PQntuples( lastResult ) ; +unsigned int pgsqlDB::countTuples() const { + if (0 == lastResult) { + return 0; + } + return PQntuples(lastResult); } -unsigned int pgsqlDB::affectedRows() const -{ -if( 0 == lastResult ) - return 0 ; +unsigned int pgsqlDB::affectedRows() const { + if (0 == lastResult) + return 0; -return std::atoi( PQcmdTuples( lastResult ) ) ; + return std::atoi(PQcmdTuples(lastResult)); } -const string pgsqlDB::ErrorMessage() const -{ -return string( PQerrorMessage( theDB ) ) ; -} +const string pgsqlDB::ErrorMessage() const { return string(PQerrorMessage(theDB)); } -const string pgsqlDB::GetValue( unsigned int rowNumber, - unsigned int columnNumber ) const -{ -if( 0 == lastResult ) - { - return string() ; - } -return PQgetvalue( lastResult, rowNumber, columnNumber ) ; +const string pgsqlDB::GetValue(unsigned int rowNumber, unsigned int columnNumber) const { + if (0 == lastResult) { + return string(); + } + return PQgetvalue(lastResult, rowNumber, columnNumber); } -const string pgsqlDB::GetValue( unsigned int rowNumber, - const string& columnName ) const -{ -if( 0 == lastResult ) - { - return string( "No result stored" ) ; - } - -// Retrieve the column number for this name. -const int columnNumber = PQfnumber( lastResult, columnName.c_str() ) ; -if( -1 == columnNumber ) - { - return (string( "No such column: " ) + columnName) ; - } - -return PQgetvalue( lastResult, rowNumber, columnNumber ) ; -} +const string pgsqlDB::GetValue(unsigned int rowNumber, const string& columnName) const { + if (0 == lastResult) { + return string("No result stored"); + } -bool pgsqlDB::isConnected() const -{ -return (CONNECTION_OK == PQstatus( theDB )) ; + // Retrieve the column number for this name. + const int columnNumber = PQfnumber(lastResult, columnName.c_str()); + if (-1 == columnNumber) { + return (string("No such column: ") + columnName); + } + + return PQgetvalue(lastResult, rowNumber, columnNumber); } +bool pgsqlDB::isConnected() const { return (CONNECTION_OK == PQstatus(theDB)); } + } // namespace gnuworld diff --git a/db/pgsqlDB.h b/db/pgsqlDB.h index df65a596..86d903f2 100644 --- a/db/pgsqlDB.h +++ b/db/pgsqlDB.h @@ -23,55 +23,45 @@ #ifndef __PGSQLDB_H #define __PGSQLDB_H "$Id: pgsqlDB.h,v 1.3 2007/08/28 16:09:59 dan_karrels Exp $" -#include +#include -#include -#include +#include +#include -#include "libpq-fe.h" -#include "gnuworldDB.h" -#include "client.h" +#include "libpq-fe.h" +#include "gnuworldDB.h" +#include "client.h" -namespace gnuworld -{ +namespace gnuworld { -class pgsqlDB : public gnuworldDB -{ -protected: - xClient *bot ; - PGconn *theDB ; - PGresult *lastResult ; +class pgsqlDB : public gnuworldDB { + protected: + xClient* bot; + PGconn* theDB; + PGresult* lastResult; -public: - pgsqlDB( xClient* bot, - const std::string& dbHost, - const unsigned short int dbPort, - const std::string& dbName, - const std::string& userName, - const std::string& password ); - pgsqlDB( xClient* bot, const std::string& connectInfo ); - virtual ~pgsqlDB() ; + public: + pgsqlDB(xClient* bot, const std::string& dbHost, const unsigned short int dbPort, + const std::string& dbName, const std::string& userName, const std::string& password); + pgsqlDB(xClient* bot, const std::string& connectInfo); + virtual ~pgsqlDB(); - virtual bool Exec( const std::string&, bool = true ) ; - virtual bool Exec( const std::stringstream&, bool = true ) ; - virtual bool isConnected() const ; + virtual bool Exec(const std::string&, bool = true); + virtual bool Exec(const std::stringstream&, bool = true); + virtual bool isConnected() const; - virtual bool PutLine( const std::string& ) ; - virtual bool StartCopyIn( const std::string& ) ; - virtual bool StopCopyIn() ; + virtual bool PutLine(const std::string&); + virtual bool StartCopyIn(const std::string&); + virtual bool StopCopyIn(); - virtual unsigned int countTuples() const ; - virtual unsigned int affectedRows() const ; - virtual const std::string ErrorMessage() const ; + virtual unsigned int countTuples() const; + virtual unsigned int affectedRows() const; + virtual const std::string ErrorMessage() const; - // tuple number, field number (row,col) - virtual const std::string GetValue( unsigned int, - unsigned int ) const ; - virtual const std::string GetValue( unsigned int row, - const std::string& colName ) - const ; - -} ; + // tuple number, field number (row,col) + virtual const std::string GetValue(unsigned int, unsigned int) const; + virtual const std::string GetValue(unsigned int row, const std::string& colName) const; +}; } // namespace gnuworld diff --git a/include/Channel.h b/include/Channel.h index 4e7d4a94..88971b97 100644 --- a/include/Channel.h +++ b/include/Channel.h @@ -24,636 +24,584 @@ #ifndef __CHANNEL_H #define __CHANNEL_H "$Id: Channel.h,v 1.37 2008/04/16 20:29:36 danielaustin Exp $" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -#include +#include -#include "ChannelUser.h" -#include "xparameters.h" -#include "ELog.h" -#include "gnuworld_config.h" +#include "ChannelUser.h" +#include "xparameters.h" +#include "ELog.h" +#include "gnuworld_config.h" #ifdef USE_THREAD -#include -#include +#include +#include #endif -namespace gnuworld -{ +namespace gnuworld { /// Forward declaration of class iClient. -class iClient ; +class iClient; /** * This class represents a single network channel. * Channel users are also maintained in this structure. */ -class Channel -{ +class Channel { -protected: + protected: + /** + * The type used to hold this channel's users. + */ + typedef std::map userListType; - /** - * The type used to hold this channel's users. - */ - typedef std::map< unsigned int, ChannelUser* > userListType ; + /** + * The type to be used to store channel bans. + */ + typedef std::list banListType; - /** - * The type to be used to store channel bans. - */ - typedef std::list< std::string > banListType ; + /// Make class xServer a friend of this class. + friend class xServer; - /// Make class xServer a friend of this class. - friend class xServer ; + public: + /** + * The type used to store this channel's current channel + * modes. + */ + typedef unsigned int modeType; -public: + /// Bit representing channel mode +t + static const modeType MODE_T; - /** - * The type used to store this channel's current channel - * modes. - */ - typedef unsigned int modeType ; + /// Bit representing channel mode +n + static const modeType MODE_N; - /// Bit representing channel mode +t - static const modeType MODE_T ; + /// Bit representing channel mode +s + static const modeType MODE_S; - /// Bit representing channel mode +n - static const modeType MODE_N ; + /// Bit representing channel mode +p + static const modeType MODE_P; - /// Bit representing channel mode +s - static const modeType MODE_S ; + /// Bit representing channel mode +k + static const modeType MODE_K; - /// Bit representing channel mode +p - static const modeType MODE_P ; + /// Bit representing channel mode +l + static const modeType MODE_L; + + /// Bit representing channel mode +m + static const modeType MODE_M; + + /// Bit representing channel mode +i + static const modeType MODE_I; + + /// Bit representing channel mode +r + static const modeType MODE_R; + + /// Bit representing channel mode +R + static const modeType MODE_REG; + + /// Bit representing channel mode +D + static const modeType MODE_D; + + /// Bit representing channel mode +c + static const modeType MODE_C; + + /// Bit representing channel mode +C + static const modeType MODE_CTCP; + + /// Bit representing channel mode +P + static const modeType MODE_PART; + + /// Bit representing channel mode +M + static const modeType MODE_MNOREG; + + /// Bit representing channel mode +A + static const modeType MODE_A; + + /// Bit representing channel mode +U + static const modeType MODE_U; + + /// Bit representing channel mode +Z + static const modeType MODE_Z; + + /// Type used to store number of clients in channel + typedef userListType::size_type size_type; + + /** + * The type used for mutable iteration through this + * channel's user structure. + */ + typedef userListType::iterator userIterator; + + /** + * The type used for immutable iteration through this + * channel's user structure. + */ + typedef userListType::const_iterator const_userIterator; + + /** + * The type used for immutable iteration through this + * channel's ban structure. + */ + typedef banListType::const_iterator const_banIterator; + + /** + * The type used for mutable iteration through this + * channel's ban structure. + */ + typedef banListType::iterator banIterator; + + /** + * Construct a channel of the given name, constructed at the + * given creation time. + */ + Channel(const std::string& _name, const time_t& _creationTime); + + /** + * Destroy this channel. + */ + virtual ~Channel(); + + /** + * Test if a given channel mode is set. + */ + inline bool getMode(const modeType& whichMode) const { + return (whichMode == (modes & whichMode)); + } + + /** + * Set the given channel mode. + */ + inline void setMode(const modeType& whichMode) { modes |= whichMode; } + + /** + * Remove the given channel mode. + */ + inline void removeMode(const modeType& whichMode) { modes &= ~whichMode; } + + /** + * Return true if the given mode is set for the the ChannelUser + * corresponding to the given iClient. + */ + bool getUserMode(const ChannelUser::modeType& whichMode, iClient*) const; + + /** + * Remove the given mode from the ChannelUser associated with + * the given iClient. + */ + bool removeUserMode(const ChannelUser::modeType& whichMode, iClient*); + + /** + * Set the given mode for the ChannelUser associated with the + * given iClient. + */ + bool setUserMode(const ChannelUser::modeType& whichMode, iClient*); + + /** + * Set a limit on the channel. This method will set the + * channel mode and set the limit. + */ + inline void setLimit(const unsigned int& newLimit) { limit = newLimit; } + + /** + * Set a key on the channel. This method will set the + * channel mode and the key as well. + */ + inline void setKey(const std::string& newKey) { key = newKey; } + + /** + * Set an Apass on the channel. This method will set the + * channel mode and the Apass as well. + */ + inline void setApass(const std::string& newApass) { Apass = newApass; } + + /** + * Set an Upass on the channel. This method will set the + * channel mode and the Upass as well. + */ + inline void setUpass(const std::string& newUpass) { Upass = newUpass; } + + /** + * Add a ban to this Channel's ban list. + */ + void setBan(const std::string& banMask); + + /** + * Remove a ban from this channel's ban list. This does a lexical + * comparison, not a wildcard match. + * Returns true if ban found (and removed), false if not + * found. + */ + bool removeBan(const std::string& banMask); + + /** + * Remove all the bans in the channels ban list. + */ + inline void removeAllBans() { banList.clear(); } + + /** + * Remove all channel modes on users and the channel itself. + * Use with caution. + */ + void removeAllModes(); + + /** + * Find a ban in the channel's ban list which lexically matches + * the given banMask. + */ + bool findBan(const std::string& banMask) const; + + /** + * Find a ban in the channel's ban list which wildcard matches + * the given banMask. + */ + bool matchBan(const std::string& banMask) const; + + /** + * Search for a ban that matches the mask in (banMask). + * If a matching ban is found, it is stored in (matchingBan), + * and true is returned. + * Otherwise, (matchingBan) is unmodified, and false is + * returned. + */ + inline bool getMatchingBan(const std::string& banMask, std::string& matchingBan) const; + + /** + * Retrieve the current channel modes. + */ + inline const modeType& getModes() const { return modes; } + + /** + * Retrieve a string of the current channel modes. + */ + const std::string getModeString() const; + + /** + * Type used to store the size of the banlist. + */ + typedef banListType::size_type banListSizeType; + + /** + * Retrieve the number of elements in the ban list. + */ + inline banListSizeType banList_size() const { return banList.size(); } + + /** + * Retrieve the name of this channel. + */ + inline const std::string& getName() const { return name; } + + /** + * Retrieve the creation time of this channel. + */ + inline const time_t& getCreationTime() const { return creationTime; } + + /** + * Set the creation time of this channel. This is protected + * so that only class xServer may access it externally. + */ + inline virtual void setCreationTime(const time_t& newCT) { creationTime = newCT; } + + /** + * Retrieve this channel's key. Note that the + * existence of a key does not mean that channel + * mode +k is set. + */ + inline const std::string& getKey() const { return key; } + + /** + * Retrieve this channel's Apass. Note that the + * existence of an Apass does not mean that channel + * mode +A is set. + */ + inline const std::string& getApass() const { return Apass; } + + /** + * Retrieve this channel's Upass. Note that the + * existence of an Upass does not mean that channel + * mode +U is set. + */ + inline const std::string& getUpass() const { return Upass; } + + /** + * Retrieve this channel's limit. Note that the + * existence of a limit here does not mean that + * channel mode +l is set. + */ + inline const unsigned int& getLimit() const { return limit; } - /// Bit representing channel mode +k - static const modeType MODE_K ; +#ifdef USE_THREAD + /** + * Returns the mutex for this channel object. + */ + inline std::shared_mutex& getMutex() const { return chanMutex; } +#endif + + /** + * Return true if no clients remain in this channel, + * false otherwise. + */ + inline bool empty() const { return userList.empty(); } + + /** + * Return the number of clients in this channel. + */ + inline size_type size() const { return userList.size(); } + + /** + * Retrieve a const_iterator to the beginning of the ban list. + */ + inline const_banIterator banList_begin() const { return banList.begin(); } + + /** + * Retrieve a const_iterator to the end of the channel ban list. + */ + inline const_banIterator banList_end() const { return banList.end(); } + + /** + * Retrieve an iterator to the beginning of the ban list. + */ + inline banIterator banList_begin() { return banList.begin(); } + + /** + * Retrieve an iterator to the end of the channel ban list. + */ + inline banIterator banList_end() { return banList.end(); } + + /** + * Retrieve an iterator to the beginning of + * this channel's user structure. + */ + inline userIterator userList_begin() { return userList.begin(); } + + /** + * Retrieve an iterator to the end of + * this channel's user structure. + */ + inline userIterator userList_end() { return userList.end(); } + + inline size_type userList_size() { return userList.size(); } + + /** + * Return the Channel's userlist. + */ + inline const userListType& users() const { return userList; } + + /** + * Retrieve a const iterator to the beginning of + * this channel's user structure. + */ + inline const_userIterator userList_begin() const { return userList.begin(); } + + /** + * Retrieve a const iterator to the end of this + * channel's user structure. + */ + inline const_userIterator userList_end() const { return userList.end(); } + + /** + * Add a ChannelUser to this channel's internal user + * structure. + */ + bool addUser(ChannelUser* newUser); + + /** + * Add an iClient to this chanenl's internal user + * structure. + */ + bool addUser(iClient* theClient); + + /** + * Remove a ChannelUser from this channel's internal + * user structure. Note that the memory associated + * with the ChannelUser is NOT deallocated, it is + * returned to the caller. + */ + ChannelUser* removeUser(iClient* theClient); + + /** + * Remove the given ChannelUser from this Channel. + */ + ChannelUser* removeUser(ChannelUser* theUser); + + /** + * Remove a ChannelUser from this channel's internal + * user structure. Note that the memory associated + * with the ChannelUser is NOT deallocated, it is + * returned to the caller. + */ + ChannelUser* removeUser(const unsigned int& intYYXXX); + + /** + * Return the ChannelUser associated with the given iClient, + * NULL if not found. + */ + ChannelUser* findUser(const iClient* theClient) const; - /// Bit representing channel mode +l - static const modeType MODE_L ; +#ifdef TOPIC_TRACK - /// Bit representing channel mode +m - static const modeType MODE_M ; + /** + * Returns the channel topic (if TOPIC_TRACK is defined) + */ + const std::string& getTopic() const { return topic; } - /// Bit representing channel mode +i - static const modeType MODE_I ; - - /// Bit representing channel mode +r - static const modeType MODE_R ; - - /// Bit representing channel mode +R - static const modeType MODE_REG ; - - /// Bit representing channel mode +D - static const modeType MODE_D ; - - /// Bit representing channel mode +c - static const modeType MODE_C ; - - /// Bit representing channel mode +C - static const modeType MODE_CTCP ; - - /// Bit representing channel mode +P - static const modeType MODE_PART ; - - /// Bit representing channel mode +M - static const modeType MODE_MNOREG ; - - /// Bit representing channel mode +A - static const modeType MODE_A ; - - /// Bit representing channel mode +U - static const modeType MODE_U ; - - /// Bit representing channel mode +Z - static const modeType MODE_Z ; - - /// Type used to store number of clients in channel - typedef userListType::size_type size_type ; - - /** - * The type used for mutable iteration through this - * channel's user structure. - */ - typedef userListType::iterator userIterator ; - - /** - * The type used for immutable iteration through this - * channel's user structure. - */ - typedef userListType::const_iterator const_userIterator ; - - /** - * The type used for immutable iteration through this - * channel's ban structure. - */ - typedef banListType::const_iterator const_banIterator ; - - /** - * The type used for mutable iteration through this - * channel's ban structure. - */ - typedef banListType::iterator banIterator ; - - /** - * Construct a channel of the given name, constructed at the - * given creation time. - */ - Channel( const std::string& _name, - const time_t& _creationTime ) ; - - /** - * Destroy this channel. - */ - virtual ~Channel() ; - - /** - * Test if a given channel mode is set. - */ - inline bool getMode( const modeType& whichMode ) const - { return (whichMode == (modes & whichMode)) ; } - - /** - * Set the given channel mode. - */ - inline void setMode( const modeType& whichMode ) - { modes |= whichMode ; } - - /** - * Remove the given channel mode. - */ - inline void removeMode( const modeType& whichMode ) - { modes &= ~whichMode ; } - - /** - * Return true if the given mode is set for the the ChannelUser - * corresponding to the given iClient. - */ - bool getUserMode( const ChannelUser::modeType& whichMode, - iClient* ) const ; - - /** - * Remove the given mode from the ChannelUser associated with - * the given iClient. - */ - bool removeUserMode( const ChannelUser::modeType& whichMode, - iClient* ) ; - - /** - * Set the given mode for the ChannelUser associated with the - * given iClient. - */ - bool setUserMode( const ChannelUser::modeType& whichMode, - iClient* ) ; - - /** - * Set a limit on the channel. This method will set the - * channel mode and set the limit. - */ - inline void setLimit( const unsigned int& newLimit ) - { limit = newLimit ; } - - /** - * Set a key on the channel. This method will set the - * channel mode and the key as well. - */ - inline void setKey( const std::string& newKey ) - { key = newKey ; } - - /** - * Set an Apass on the channel. This method will set the - * channel mode and the Apass as well. - */ - inline void setApass( const std::string& newApass ) - { Apass = newApass ; } - - /** - * Set an Upass on the channel. This method will set the - * channel mode and the Upass as well. - */ - inline void setUpass( const std::string& newUpass ) - { Upass = newUpass ; } - - /** - * Add a ban to this Channel's ban list. - */ - void setBan( const std::string& banMask ) ; - - /** - * Remove a ban from this channel's ban list. This does a lexical - * comparison, not a wildcard match. - * Returns true if ban found (and removed), false if not - * found. - */ - bool removeBan( const std::string& banMask ) ; - - /** - * Remove all the bans in the channels ban list. - */ - inline void removeAllBans() - { banList.clear(); } - - /** - * Remove all channel modes on users and the channel itself. - * Use with caution. - */ - void removeAllModes() ; - - /** - * Find a ban in the channel's ban list which lexically matches - * the given banMask. - */ - bool findBan( const std::string& banMask ) const ; - - /** - * Find a ban in the channel's ban list which wildcard matches - * the given banMask. - */ - bool matchBan( const std::string& banMask ) const ; - - /** - * Search for a ban that matches the mask in (banMask). - * If a matching ban is found, it is stored in (matchingBan), - * and true is returned. - * Otherwise, (matchingBan) is unmodified, and false is - * returned. - */ - inline bool getMatchingBan( const std::string& banMask, - std::string& matchingBan ) const ; - - /** - * Retrieve the current channel modes. - */ - inline const modeType& getModes() const - { return modes ; } - - /** - * Retrieve a string of the current channel modes. - */ - const std::string getModeString() const ; - - /** - * Type used to store the size of the banlist. - */ - typedef banListType::size_type banListSizeType ; - - /** - * Retrieve the number of elements in the ban list. - */ - inline banListSizeType banList_size() const - { return banList.size() ; } - - /** - * Retrieve the name of this channel. - */ - inline const std::string& getName() const - { return name ; } - - /** - * Retrieve the creation time of this channel. - */ - inline const time_t& getCreationTime() const - { return creationTime ; } - - /** - * Set the creation time of this channel. This is protected - * so that only class xServer may access it externally. - */ - inline virtual void setCreationTime( const time_t& newCT ) - { creationTime = newCT ; } - - /** - * Retrieve this channel's key. Note that the - * existence of a key does not mean that channel - * mode +k is set. - */ - inline const std::string& getKey() const - { return key ; } - - /** - * Retrieve this channel's Apass. Note that the - * existence of an Apass does not mean that channel - * mode +A is set. - */ - inline const std::string& getApass() const - { return Apass ; } - - /** - * Retrieve this channel's Upass. Note that the - * existence of an Upass does not mean that channel - * mode +U is set. - */ - inline const std::string& getUpass() const - { return Upass ; } - - /** - * Retrieve this channel's limit. Note that the - * existence of a limit here does not mean that - * channel mode +l is set. - */ - inline const unsigned int& getLimit() const - { return limit ; } + const std::string& getTopicWhoSet() const { return topic_whoset; } + + const long& getTopicTS() const { return topic_ts; } + + /** + * Sets this channel's topic value to the value passed in. + * This method exists only if TOPIC_TRACK is defined. + */ + void setTopic(const std::string& _Topic) { topic = _Topic; } + + void setTopicWhoSet(const std::string& _TopicWhoSet) { topic_whoset = _TopicWhoSet; } + + void setTopicTS(const time_t& _TopicTS) { topic_ts = _TopicTS; } -#ifdef USE_THREAD - /** - * Returns the mutex for this channel object. - */ - inline std::shared_mutex& getMutex() const - { return chanMutex ; } #endif - /** - * Return true if no clients remain in this channel, - * false otherwise. - */ - inline bool empty() const - { return userList.empty() ; } - - /** - * Return the number of clients in this channel. - */ - inline size_type size() const - { return userList.size() ; } - - /** - * Retrieve a const_iterator to the beginning of the ban list. - */ - inline const_banIterator banList_begin() const - { return banList.begin() ; } - - /** - * Retrieve a const_iterator to the end of the channel ban list. - */ - inline const_banIterator banList_end() const - { return banList.end() ; } - - /** - * Retrieve an iterator to the beginning of the ban list. - */ - inline banIterator banList_begin() - { return banList.begin() ; } - - /** - * Retrieve an iterator to the end of the channel ban list. - */ - inline banIterator banList_end() - { return banList.end() ; } - - /** - * Retrieve an iterator to the beginning of - * this channel's user structure. - */ - inline userIterator userList_begin() - { return userList.begin() ; } - - /** - * Retrieve an iterator to the end of - * this channel's user structure. - */ - inline userIterator userList_end() - { return userList.end() ; } - - - inline size_type userList_size() - { return userList.size() ; } - - /** - * Return the Channel's userlist. - */ - inline const userListType& users() const - { return userList ; } - - /** - * Retrieve a const iterator to the beginning of - * this channel's user structure. - */ - inline const_userIterator userList_begin() const - { return userList.begin() ; } - - /** - * Retrieve a const iterator to the end of this - * channel's user structure. - */ - inline const_userIterator userList_end() const - { return userList.end() ; } - - /** - * Add a ChannelUser to this channel's internal user - * structure. - */ - bool addUser( ChannelUser* newUser ) ; - - /** - * Add an iClient to this chanenl's internal user - * structure. - */ - bool addUser( iClient* theClient ) ; - - /** - * Remove a ChannelUser from this channel's internal - * user structure. Note that the memory associated - * with the ChannelUser is NOT deallocated, it is - * returned to the caller. - */ - ChannelUser* removeUser( iClient* theClient ) ; - - /** - * Remove the given ChannelUser from this Channel. - */ - ChannelUser* removeUser( ChannelUser* theUser ) ; - - /** - * Remove a ChannelUser from this channel's internal - * user structure. Note that the memory associated - * with the ChannelUser is NOT deallocated, it is - * returned to the caller. - */ - ChannelUser* removeUser( const unsigned int& intYYXXX ) ; - - /** - * Return the ChannelUser associated with the given iClient, - * NULL if not found. - */ - ChannelUser* findUser( const iClient* theClient ) const ; - -#ifdef TOPIC_TRACK - - /** - * Returns the channel topic (if TOPIC_TRACK is defined) - */ - const std::string& getTopic() const - { return topic; } - - const std::string& getTopicWhoSet() const - { return topic_whoset; } - - const long& getTopicTS() const - { return topic_ts; } - - /** - * Sets this channel's topic value to the value passed in. - * This method exists only if TOPIC_TRACK is defined. - */ - void setTopic( const std::string& _Topic ) - { topic = _Topic; } - - void setTopicWhoSet( const std::string& _TopicWhoSet ) - { topic_whoset = _TopicWhoSet; } - - void setTopicTS( const time_t& _TopicTS ) - { topic_ts = _TopicTS; } - -#endif - - /** - * Convenience operator for outputting Channel information - * to a C++ output stream. - */ - friend ELog& operator<<( ELog& out, const Channel& rhs ) - { - out << "Name: " << rhs.name - << ", creation time: " << rhs.creationTime ; - return out ; - } - - /** - * Return a level 2 ban for the given user. - */ - static std::string createBan( const iClient* ) ; - -protected: - - /** - * Handle one or more "simple" mode changes. - */ - virtual void onMode( const std::vector< - std::pair< bool, modeType > >& ) ; - - /** - * This method is called when channel mode 'l' is set - * or unset. - */ - virtual void onModeL( bool, const unsigned int& ) ; - - /** - * This method is called when channel mode 'k' is set - * or unset. - */ - virtual void onModeK( bool, const std::string& ) ; - - /** - * This method is called when channel mode 'A' is set - * or unset. - */ - virtual void onModeA( bool, const std::string& ) ; - - /** - * This method is called when channel mode 'U' is set - * or unset. - */ - virtual void onModeU( bool, const std::string& ) ; - - /** - * This method is called when one or more channel - * mode (t)'s is/are set or unset. - */ - virtual void onModeO( const std::vector< - std::pair< bool, ChannelUser* > >& ) ; - - /** - * This method is called when one or more channel - * mode (v)'s is/are set or unset. - */ - virtual void onModeV( const std::vector< - std::pair< bool, ChannelUser* > >& ) ; - - /** - * This method is called when one or more channel - * mode (b)'s is/are set or unset. - * This method will add to the vector passed to it any - * bans that have been removed as a result of newly added - * overlapping bans. - */ - virtual void onModeB( std::vector< - std::pair< bool, std::string > >& ) ; - - /** - * The name of this channel. - */ - std::string name ; - - /** - * The time at which this channel was created. - */ - time_t creationTime ; - - /** - * This channel's current modes. - */ - modeType modes ; - - /** - * The limit associated with this channel. - * Note that this variable may hold values - * even when channel mode +l is NOT set. - */ - unsigned int limit ; - - /** - * The key associated with this channel. - * Note that this variable may hold values - * even when channel mode +k is NOT set. - */ - std::string key ; - - /** - * The Apass associated with this channel. - * Note that this variable may hold values - * even when channel mode +A is NOT set. - */ - std::string Apass ; - - /** - * The Upass associated with this channel. - * Note that this variable may hold values - * even when channel mode +U is NOT set. - */ - std::string Upass ; - - /** - * The structure used to hold the ChannelUser - * instances. - */ - userListType userList ; - - /** - * The structure used to store the channel bans. - */ - banListType banList ; + /** + * Convenience operator for outputting Channel information + * to a C++ output stream. + */ + friend ELog& operator<<(ELog& out, const Channel& rhs) { + out << "Name: " << rhs.name << ", creation time: " << rhs.creationTime; + return out; + } + + /** + * Return a level 2 ban for the given user. + */ + static std::string createBan(const iClient*); + + protected: + /** + * Handle one or more "simple" mode changes. + */ + virtual void onMode(const std::vector>&); + + /** + * This method is called when channel mode 'l' is set + * or unset. + */ + virtual void onModeL(bool, const unsigned int&); + + /** + * This method is called when channel mode 'k' is set + * or unset. + */ + virtual void onModeK(bool, const std::string&); + + /** + * This method is called when channel mode 'A' is set + * or unset. + */ + virtual void onModeA(bool, const std::string&); + + /** + * This method is called when channel mode 'U' is set + * or unset. + */ + virtual void onModeU(bool, const std::string&); + + /** + * This method is called when one or more channel + * mode (t)'s is/are set or unset. + */ + virtual void onModeO(const std::vector>&); + + /** + * This method is called when one or more channel + * mode (v)'s is/are set or unset. + */ + virtual void onModeV(const std::vector>&); + + /** + * This method is called when one or more channel + * mode (b)'s is/are set or unset. + * This method will add to the vector passed to it any + * bans that have been removed as a result of newly added + * overlapping bans. + */ + virtual void onModeB(std::vector>&); + + /** + * The name of this channel. + */ + std::string name; + + /** + * The time at which this channel was created. + */ + time_t creationTime; + + /** + * This channel's current modes. + */ + modeType modes; + + /** + * The limit associated with this channel. + * Note that this variable may hold values + * even when channel mode +l is NOT set. + */ + unsigned int limit; + + /** + * The key associated with this channel. + * Note that this variable may hold values + * even when channel mode +k is NOT set. + */ + std::string key; + + /** + * The Apass associated with this channel. + * Note that this variable may hold values + * even when channel mode +A is NOT set. + */ + std::string Apass; + + /** + * The Upass associated with this channel. + * Note that this variable may hold values + * even when channel mode +U is NOT set. + */ + std::string Upass; + + /** + * The structure used to hold the ChannelUser + * instances. + */ + userListType userList; + + /** + * The structure used to store the channel bans. + */ + banListType banList; #ifdef USE_THREAD - /** - * A mutex to lock the channel object. - */ - mutable std::shared_mutex chanMutex ; + /** + * A mutex to lock the channel object. + */ + mutable std::shared_mutex chanMutex; #endif - + #ifdef TOPIC_TRACK - /** - * This channel's topic, only if TOPIC_TRACK is defined. - */ - std::string topic; + /** + * This channel's topic, only if TOPIC_TRACK is defined. + */ + std::string topic; - std::string topic_whoset; + std::string topic_whoset; - time_t topic_ts; + time_t topic_ts; #endif - -} ; +}; } // namespace gnuworld diff --git a/include/ChannelUser.h b/include/ChannelUser.h index 55227436..6ab310ce 100644 --- a/include/ChannelUser.h +++ b/include/ChannelUser.h @@ -23,217 +23,199 @@ #ifndef __CHANNELUSER_H #define __CHANNELUSER_H "$Id: ChannelUser.h,v 1.16 2009/07/26 18:30:37 mrbean_ Exp $" -#include +#include -#include "Numeric.h" +#include "Numeric.h" -#include "ELog.h" +#include "ELog.h" -namespace gnuworld -{ +namespace gnuworld { /// Forward declaration of class iClient. -class iClient ; +class iClient; /** * This class represents an individual channel patron, one * instance for each user in each channel. */ -class ChannelUser -{ - -public: - /** - * The type to be used for this ChannelUser's channel - * modes. - */ - typedef unsigned char modeType ; - - /// Bit representing channel user mode +o - static const modeType MODE_O ; - - /// Bit representing channel user mode +v - static const modeType MODE_V ; - - /** - * Construct a ChannelUser given an iClient - * pointer. - */ - ChannelUser( iClient* ) ; - - /** - * Destroy this ChannelUser. - * No heap space allocated. - */ - virtual ~ChannelUser() ; - - /** - * Retrieve a given channel user mode. - */ - inline bool getMode( const modeType& whichMode ) const - { return (whichMode == (modes & whichMode)) ; } - - /** - * Return true if this user has mode +o on this channel, - * false otherwise. - */ - inline bool isModeO() const - { return getMode( MODE_O ) ; } - - /** - * Return true if this user has mode +v on this channel, - * false otherwise. - */ - inline bool isModeV() const - { return getMode( MODE_V ) ; } - - /** - * Retrieve this ChannelUser's current modes in - * its channel. - */ - inline const modeType& getModes() const - { return modes ; } - - /** - * Set a given channel user mode. - */ - inline void setMode( const modeType& whichMode ) - { modes |= whichMode ; } - - /** - * Set the user's mode +o state in this channel. - */ - inline void setModeO() - { setMode( MODE_O ) ; } - - /** - * Set the user's mode +v state in this channel. - */ - inline void setModeV() - { return setMode( MODE_V ) ; } - - /** - * Remove a given channel user mode. - */ - inline void removeMode( const modeType& whichMode ) - { modes &= ~whichMode ; } - - /** - * Remove the user's mode +o state in this channel. - */ - inline void removeModeO() - { removeMode( MODE_O ) ; } - - /** - * Remove the user's mode +v state in this channel. - */ - inline void removeModeV() - { removeMode( MODE_V ) ; } - - /* - * These are not defined in the header file to avoid - * recursive includes. - */ - - /** - * Retrieve this user's nick name. - * Note that this method will simply query this - * instance's iClient object for the nick name. - * Thus, if the user changes its nickname, this - * will be reflected automatically. - */ - const std::string& getNickName() const ; - - /** - * Retrieve this user's user name. - */ - const std::string& getUserName() const ; - - /** - * Retrieve this channel user's host name. - */ - const std::string& getHostName() const ; - - /** - * Retrieve this channel user's network numeric. - */ - const std::string getCharYYXXX() const ; - - /** - * Retrieve this channel user's IP. - */ - const irc_in_addr& getIP() const ; - - /** - * Retrieve this channel user's integer representation - * of its server numeric. - */ - unsigned int getIntYY() const ; - - /** - * Retrieve this channel user's integer representation - * of its client numeric. - */ - unsigned int getIntXXX() const ; - - /** - * Retrieve this channel user's integer representation - * of its network numeric. - */ - unsigned int getIntYYXXX() const ; - - /** - * Return true if this client is an oper. - */ - bool isOper() const ; - - /** - * Return a pointer to the iClient to which this ChannelUser - * is associated. - * Use of this method is strongly discouraged. - */ - inline iClient* getClient() const - { return theClient ; } - - /** - * Return a human readable string of modes this user has - * in the channel. - * Valid modes are: - * - "op" - * - "voice" - * - "oper" - */ - std::string getModeString() const ; - - /** - * Convenience operator method for outputting this - * ChannelUser's information to a C++ standard - * output stream. - */ - friend ELog& operator<<( ELog& out, const ChannelUser& rhs ) - { - out << rhs.getNickName() << '!' - << rhs.getUserName() << '@' - << rhs.getHostName() << ' ' - << rhs.getCharYYXXX() - << " user modes: " - << rhs.getModeString() ; - return out ; - } - -protected: - - /** - * The iClient to which this ChannelUser instance is associated. - */ - iClient* theClient ; - - /** - * This channel user's modes in the current channel. - */ - modeType modes ; - -} ; +class ChannelUser { + + public: + /** + * The type to be used for this ChannelUser's channel + * modes. + */ + typedef unsigned char modeType; + + /// Bit representing channel user mode +o + static const modeType MODE_O; + + /// Bit representing channel user mode +v + static const modeType MODE_V; + + /** + * Construct a ChannelUser given an iClient + * pointer. + */ + ChannelUser(iClient*); + + /** + * Destroy this ChannelUser. + * No heap space allocated. + */ + virtual ~ChannelUser(); + + /** + * Retrieve a given channel user mode. + */ + inline bool getMode(const modeType& whichMode) const { + return (whichMode == (modes & whichMode)); + } + + /** + * Return true if this user has mode +o on this channel, + * false otherwise. + */ + inline bool isModeO() const { return getMode(MODE_O); } + + /** + * Return true if this user has mode +v on this channel, + * false otherwise. + */ + inline bool isModeV() const { return getMode(MODE_V); } + + /** + * Retrieve this ChannelUser's current modes in + * its channel. + */ + inline const modeType& getModes() const { return modes; } + + /** + * Set a given channel user mode. + */ + inline void setMode(const modeType& whichMode) { modes |= whichMode; } + + /** + * Set the user's mode +o state in this channel. + */ + inline void setModeO() { setMode(MODE_O); } + + /** + * Set the user's mode +v state in this channel. + */ + inline void setModeV() { return setMode(MODE_V); } + + /** + * Remove a given channel user mode. + */ + inline void removeMode(const modeType& whichMode) { modes &= ~whichMode; } + + /** + * Remove the user's mode +o state in this channel. + */ + inline void removeModeO() { removeMode(MODE_O); } + + /** + * Remove the user's mode +v state in this channel. + */ + inline void removeModeV() { removeMode(MODE_V); } + + /* + * These are not defined in the header file to avoid + * recursive includes. + */ + + /** + * Retrieve this user's nick name. + * Note that this method will simply query this + * instance's iClient object for the nick name. + * Thus, if the user changes its nickname, this + * will be reflected automatically. + */ + const std::string& getNickName() const; + + /** + * Retrieve this user's user name. + */ + const std::string& getUserName() const; + + /** + * Retrieve this channel user's host name. + */ + const std::string& getHostName() const; + + /** + * Retrieve this channel user's network numeric. + */ + const std::string getCharYYXXX() const; + + /** + * Retrieve this channel user's IP. + */ + const irc_in_addr& getIP() const; + + /** + * Retrieve this channel user's integer representation + * of its server numeric. + */ + unsigned int getIntYY() const; + + /** + * Retrieve this channel user's integer representation + * of its client numeric. + */ + unsigned int getIntXXX() const; + + /** + * Retrieve this channel user's integer representation + * of its network numeric. + */ + unsigned int getIntYYXXX() const; + + /** + * Return true if this client is an oper. + */ + bool isOper() const; + + /** + * Return a pointer to the iClient to which this ChannelUser + * is associated. + * Use of this method is strongly discouraged. + */ + inline iClient* getClient() const { return theClient; } + + /** + * Return a human readable string of modes this user has + * in the channel. + * Valid modes are: + * - "op" + * - "voice" + * - "oper" + */ + std::string getModeString() const; + + /** + * Convenience operator method for outputting this + * ChannelUser's information to a C++ standard + * output stream. + */ + friend ELog& operator<<(ELog& out, const ChannelUser& rhs) { + out << rhs.getNickName() << '!' << rhs.getUserName() << '@' << rhs.getHostName() << ' ' + << rhs.getCharYYXXX() << " user modes: " << rhs.getModeString(); + return out; + } + + protected: + /** + * The iClient to which this ChannelUser instance is associated. + */ + iClient* theClient; + + /** + * This channel user's modes in the current channel. + */ + modeType modes; +}; } // namespace gnuworld diff --git a/include/Gline.h b/include/Gline.h index ed7a03db..22c9c497 100644 --- a/include/Gline.h +++ b/include/Gline.h @@ -23,169 +23,140 @@ #ifndef __GLINE_H #define __GLINE_H "$Id: Gline.h,v 1.7 2003/12/29 23:59:36 dan_karrels Exp $" -#include +#include -#include +#include -#include "misc.h" +#include "misc.h" -namespace gnuworld -{ +namespace gnuworld { /** * A simple data storage class which represents a network G-Line. */ -class Gline -{ - -public: - - /** - * Construct a Gline instance given the nick!user@host of the - * user requesting it, the userHost being glined, th reason - * for the gline, and the duration (in seconds) of the - * gline. - */ - Gline( const std::string& _setBy, - const std::string& _userHost, - const std::string& _reason, - const time_t& _duration , - const time_t& _lastmod = ::time( 0 )) - : setBy( _setBy ), - userHost( _userHost ), - reason( _reason ), - expiration( _duration + ::time( 0 ) ), - lastmod( _lastmod ) - {} - - /** - * Copy constructor. - * Construct a Gline given another Gline. - */ - Gline( const Gline& rhs ) - : setBy( rhs.setBy ), - userHost( rhs.userHost ), - reason( rhs.reason ), - expiration( rhs.expiration ), - lastmod (rhs.lastmod) - {} - - /** - * Destroy this gline. No heap space allocated. - */ - virtual ~Gline() - {} - - /** - * Return true if this Gline is equivalent (case insensitive) - * to the given userHost mask. - * This does NOT perform a wildcard match. - */ - inline bool operator==( const std::string& _userHost ) const - { return (0 == strcasecmp( userHost, _userHost )) ; } - - /** - * Retrieve the nick!user@host of the user who set this gline. - */ - inline const std::string& getSetBy() const - { return setBy ; } - - /** - * Retrieve the user@host which has been glined. - */ - inline const std::string& getUserHost() const - { return userHost ; } - - /** - * Retrieve the reason for this gline. - */ - inline const std::string& getReason() const - { return reason ; } - - /** - * Retrieve the time at which this gline will expire. - */ - inline const time_t& getExpiration() const - { return expiration ; } - - /** - * Retrieve the time at which the gline was last modified - */ - inline const time_t& getLastmod() const - { return lastmod ; } - - /** - * Retrieve the user/server who set this gline. - */ - inline void setSetBy( const std::string& _setBy ) - { setBy = _setBy; } - - /** - * Set the hostmask affected by this gline. - */ - inline void setHost( const std::string& _host ) - { userHost = _host; } - - /** - * Set the reason for this gline. - */ - inline void setReason( const std::string& _reason ) - { reason = _reason; } - - /** - * Set the expiration time on this gline. - */ - inline void setExpiration( const time_t _expiration ) - { expiration = _expiration; } - - /** - * Set the lastmod time - */ - inline void setLastmod( const time_t _lastmod ) - { lastmod = _lastmod; } - - /** - * Convenience operator method which allows the output - * of a Gline instance to a C++ standard output stream. - */ - friend ELog& operator<<( ELog& out, const Gline& rhs ) - { - out << "Mask: " << rhs.userHost << ' ' - << "Reason: " << rhs.reason << ' ' - << "Set by: " << rhs.setBy << ' ' - << "Expires: " << rhs.expiration << ' ' - << "Last modified: " << rhs.lastmod ; - return out ; - } - -protected: - - /** - * The nick!user@host of the user who set this gline. - */ - std::string setBy ; - - /** - * The banned user@host. - */ - std::string userHost ; - - /** - * The reason this gline was set. - */ - std::string reason ; - - /** - * The time at which this gline expires. - */ - time_t expiration ; - - /** - * The time at which this gline was last modified - */ - time_t lastmod ; - -} ; +class Gline { + + public: + /** + * Construct a Gline instance given the nick!user@host of the + * user requesting it, the userHost being glined, th reason + * for the gline, and the duration (in seconds) of the + * gline. + */ + Gline(const std::string& _setBy, const std::string& _userHost, const std::string& _reason, + const time_t& _duration, const time_t& _lastmod = ::time(0)) + : setBy(_setBy), userHost(_userHost), reason(_reason), expiration(_duration + ::time(0)), + lastmod(_lastmod) {} + + /** + * Copy constructor. + * Construct a Gline given another Gline. + */ + Gline(const Gline& rhs) + : setBy(rhs.setBy), userHost(rhs.userHost), reason(rhs.reason), expiration(rhs.expiration), + lastmod(rhs.lastmod) {} + + /** + * Destroy this gline. No heap space allocated. + */ + virtual ~Gline() {} + + /** + * Return true if this Gline is equivalent (case insensitive) + * to the given userHost mask. + * This does NOT perform a wildcard match. + */ + inline bool operator==(const std::string& _userHost) const { + return (0 == strcasecmp(userHost, _userHost)); + } + + /** + * Retrieve the nick!user@host of the user who set this gline. + */ + inline const std::string& getSetBy() const { return setBy; } + + /** + * Retrieve the user@host which has been glined. + */ + inline const std::string& getUserHost() const { return userHost; } + + /** + * Retrieve the reason for this gline. + */ + inline const std::string& getReason() const { return reason; } + + /** + * Retrieve the time at which this gline will expire. + */ + inline const time_t& getExpiration() const { return expiration; } + + /** + * Retrieve the time at which the gline was last modified + */ + inline const time_t& getLastmod() const { return lastmod; } + + /** + * Retrieve the user/server who set this gline. + */ + inline void setSetBy(const std::string& _setBy) { setBy = _setBy; } + + /** + * Set the hostmask affected by this gline. + */ + inline void setHost(const std::string& _host) { userHost = _host; } + + /** + * Set the reason for this gline. + */ + inline void setReason(const std::string& _reason) { reason = _reason; } + + /** + * Set the expiration time on this gline. + */ + inline void setExpiration(const time_t _expiration) { expiration = _expiration; } + + /** + * Set the lastmod time + */ + inline void setLastmod(const time_t _lastmod) { lastmod = _lastmod; } + + /** + * Convenience operator method which allows the output + * of a Gline instance to a C++ standard output stream. + */ + friend ELog& operator<<(ELog& out, const Gline& rhs) { + out << "Mask: " << rhs.userHost << ' ' << "Reason: " << rhs.reason << ' ' + << "Set by: " << rhs.setBy << ' ' << "Expires: " << rhs.expiration << ' ' + << "Last modified: " << rhs.lastmod; + return out; + } + + protected: + /** + * The nick!user@host of the user who set this gline. + */ + std::string setBy; + + /** + * The banned user@host. + */ + std::string userHost; + + /** + * The reason this gline was set. + */ + std::string reason; + + /** + * The time at which this gline expires. + */ + time_t expiration; + + /** + * The time at which this gline was last modified + */ + time_t lastmod; +}; } // namespace gnuworld diff --git a/include/LoadClientTimerHandler.h b/include/LoadClientTimerHandler.h index 31ab5aa8..4c494668 100644 --- a/include/LoadClientTimerHandler.h +++ b/include/LoadClientTimerHandler.h @@ -21,16 +21,16 @@ */ #ifndef __LOADCLIENTTIMERHANDLER_H -#define __LOADCLIENTTIMERHANDLER_H "$Id: LoadClientTimerHandler.h,v 1.6 2004/05/19 19:46:33 jeekay Exp $" +#define __LOADCLIENTTIMERHANDLER_H \ + "$Id: LoadClientTimerHandler.h,v 1.6 2004/05/19 19:46:33 jeekay Exp $" -#include +#include -#include "ServerTimerHandlers.h" +#include "ServerTimerHandlers.h" -namespace gnuworld -{ +namespace gnuworld { -class xServer ; +class xServer; /** * The purpose of this class is to load xClient's at a particular time, @@ -38,46 +38,38 @@ class xServer ; * event system to give the xClient time to unload before reloading a * new instance. */ -class LoadClientTimerHandler : public ServerTimerHandler -{ - -protected: - - /// The name of the module to be loaded - std::string moduleName ; - - /// The configuration file name to pass to the client constructor - std::string configFileName ; - -public: - - /** - * Constructor receives: - * - The xServer instance for the system - * - The xClient's module name - * - The configuration file name for the xClient. - */ - LoadClientTimerHandler( xServer* theServer, - const std::string& _moduleName, - const std::string& _configFileName ) - : ServerTimerHandler( theServer, 0), - moduleName( _moduleName ), - configFileName( _configFileName ) - {} - - /** - * Default destructor, nothing to do here atm. - */ - virtual ~LoadClientTimerHandler() - {} - - /** - * The method that is called by the server when this handler's - * time to perform has arrived. - */ - virtual void OnTimer( const timerID& , void* ) ; - -} ; +class LoadClientTimerHandler : public ServerTimerHandler { + + protected: + /// The name of the module to be loaded + std::string moduleName; + + /// The configuration file name to pass to the client constructor + std::string configFileName; + + public: + /** + * Constructor receives: + * - The xServer instance for the system + * - The xClient's module name + * - The configuration file name for the xClient. + */ + LoadClientTimerHandler(xServer* theServer, const std::string& _moduleName, + const std::string& _configFileName) + : ServerTimerHandler(theServer, 0), moduleName(_moduleName), + configFileName(_configFileName) {} + + /** + * Default destructor, nothing to do here atm. + */ + virtual ~LoadClientTimerHandler() {} + + /** + * The method that is called by the server when this handler's + * time to perform has arrived. + */ + virtual void OnTimer(const timerID&, void*); +}; } // namespace gnuworld diff --git a/include/Network.h b/include/Network.h index 4108d5e4..a7503fe8 100644 --- a/include/Network.h +++ b/include/Network.h @@ -24,26 +24,25 @@ #ifndef __NETWORK_H #define __NETWORK_H "$Id: Network.h,v 1.48 2007/04/27 19:30:43 mrbean_ Exp $" -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include -#include +#include -#include "iServer.h" -#include "iClient.h" -#include "Channel.h" -#include "client.h" -#include "misc.h" // struct noCaseCompare -#include "gnuworld_config.h" +#include "iServer.h" +#include "iClient.h" +#include "Channel.h" +#include "client.h" +#include "misc.h" // struct noCaseCompare +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -class xServer ; +class xServer; /** * This class is responsible for storing the network's iClient's, @@ -65,7 +64,7 @@ class xServer ; * * removeFake{client,server} * - Removes fake element of {client,server} - * + * * remove{Client,Server} * - Removes normal element of {client,server} * - Removes fake element of {client,server} @@ -74,958 +73,883 @@ class xServer ; * This also means that OnSplit() will properly clean up even * fake servers and clients. */ -class xNetwork -{ - /// Allow xServer to access this class's private - /// members/methods. - friend class xServer ; - -private: - - /** - * Type used to store all reserved intYY and intYYXXX's - * for the local server and juped iClient/xClient/iServer's. - * Keyed top level by the server's intYY, then each - * set is keyed by intXXX for that particular server. - */ - typedef std::map< unsigned int, std::set< unsigned int > > - reservedNumericMapType ; - - /** - * This is an iterator type definition for the - * reservedNumericMapType. - */ - typedef reservedNumericMapType::iterator - reservedNumeric_iterator ; - - /** - * This type maps fake iClient's to their owning - * xClient's, keyed by the iClient's intYYXXX numeric. - */ - typedef std::map< unsigned int, std::pair< iClient*, xClient* > > - fakeClientMapType ; - - /** - * This type stores fake (juped) servers. - */ - typedef std::map< unsigned int, std::pair< iServer*, xClient* > > - fakeServerMapType ; - - /** - * This is the type of vector for storing - * local (services) clients. - */ - typedef std::map< unsigned int, xClient* > xClientMapType ; - - /** - * This is the type used to store the network Channel - * instances. - */ - typedef std::map< std::string, Channel*, noCaseCompare > - channelMapType ; - - /** - * This is the type used to store the nick name/iClient* pairs. - */ - typedef std::map< std::string, iClient*, noCaseCompare > - nickMapType ; - - /** - * The type used to store information about iClient's, - * keyed by integer numeric. - */ - typedef std::map< unsigned int, iClient* > numericMapType ; - - /** - * The type used to store information about iServer's, - * keyed by integer numeric. - */ - typedef std::map< unsigned int, iServer* > serverMapType ; - - /** - * The type used to store Network configuration pairs (CF), - * keyed by the configuration key. - */ - typedef std::map< std::string, std::pair< std::string, time_t > > netConfMapType ; - -public: - - /** - * The default constructor handles all of the default - * allocation and initialization. - */ - xNetwork() ; - - /** - * The default destructor will deallocate all objects - * that are not explicitly removed from this structure. - * Therefore, it is highly recommend that the application - * programmer iterate through this structure and remove - * all items before destroying this structure. - */ - virtual ~xNetwork() ; - - /* Addition methods - * These methods return true if addition is successful, - * false otherwise. - */ - - /** - * Add a new iClient to the network. This will also handle - * any additions into the nickname table, if required. - * Returns false if the addition fails. - */ - virtual bool addClient( iClient* ) ; - - /** - * Add a fake client to this (or a juped) server. The - * xClient is the "owner" of the iClient. - * This method will fill in the iClient's intXXX/charXXX, - * but the intYY/charYY must be valid. - */ - virtual bool addFakeClient( iClient* theClient, - xClient* ownerClient ) ; - - /** - * Add a services client to the network table. - * This is stored in the table of local clients. - * Returns false if the addition fails. - */ - virtual bool addClient( xClient* ) ; - - /** - * Add a new server to the network table. - * Returns false if the addition fails. - */ - virtual bool addServer( iServer* ) ; - - /** - * Add a new fake (juped) server to the structure - * of fake servers. - * Returns true on success, false on failure. - */ - virtual bool addFakeServer( iServer*, xClient* ) ; - - /** - * Add a new channel to the network table. - * Returns false if the addition fails. - */ - virtual bool addChannel( Channel* ) ; - - /** - * Add a new netconf variable to the network table. - */ - virtual void addNetConf( const std::string& key, - const std::string& value, - time_t timestamp ) - { netConfMap[ key ] = std::make_pair( value, timestamp ) ; } - - /** - * Find a netconf variable by key. - * Returns std::nullopt if not found. - */ - virtual std::optional< std::pair< std::string, time_t > > findNetConf( const std::string& key ) const ; - - /* - * All nickname based searches are case insensitive. - */ - - /** - * Find a remote client given the client's integer numeric. - * Returns NULL if not found. - */ - virtual iClient* findClient( const unsigned int& YY, - const unsigned int& XXX ) const ; - - /** - * Find a remote client given the client's integer numeric. - * Returns NULL if not found. - */ - virtual iClient* findClient( const unsigned int& intYYXXX ) - const ; - - /** - * Find a fake client given the client's integer numeric. - * Returns NULL if not found. - */ - virtual iClient* findFakeClient( const unsigned int& YY, - const unsigned int& XXX ) const ; - - /** - * Find a remote client given the client's character numeric. - * Returns NULL if not found. - */ - virtual iClient* findClient( const std::string& yyxxx ) - const ; - - /** - * Find a fake client by numeric. - * Returns NULL if not found. - */ - virtual iClient* findFakeClient( const std::string& yyxxx ) - const ; - - /** - * Lookup a fake (juped) iClient. - */ - virtual iClient* findFakeClient( iClient* ) const ; - - /** - * Lookup the xClient owner of a particular iClient. - */ - virtual xClient* findFakeClientOwner( iClient* ) const ; - - /** - * Lookup all fake iClients belonging to an xClient. - * If the xClient is NULL, return all fake clients. - */ - virtual std::list< iClient* > findFakeClients( xClient* ) const ; - - /** - * Retrieve a pointer to an iClient given its nick name. - * Returns NULL if not found. - */ - virtual iClient* findNick( const std::string& nickName ) - const ; - - /** - * Find a local (services) client by its character numeric. - * Returns NULL if not found. - */ - virtual xClient* findLocalClient( const std::string& yyxxx ) - const ; - - /** - * Find a local (services) client by its integer numeric. - * Returns NULL if not found. - */ - virtual xClient* findLocalClient( const unsigned int& intYYXXX ) - const ; - - /** - * Find a local (services) client by its case-insensitive nickname. - * Returns NULL if not found. - */ - virtual xClient* findLocalNick( const std::string& nickName ) - const ; - - /** - * Lookup a fake (juped) iClient by nickname. - */ - virtual iClient* findFakeNick( const std::string& nickName ) - const ; - - /** - * Find a remote server by its integer numeric. - * Returns NULL if not found. - */ - virtual iServer* findServer( const unsigned int& YY ) const ; - - /** - * Find a fake server, return that server if it is fake (juped), - * or NULL otherwise. - */ - virtual iServer* findFakeServer( const iServer* ) const ; - - /** - * Find a fake server described by the given intYY numeric. - * Return 0 on failure. - */ - virtual iServer* findFakeServer( unsigned int intYY ) const ; - - /** - * Find a remote server by its character numeric. - * Returns NULL if not found. - */ - virtual iServer* findServer( const std::string& YY ) const ; - - /** - * Find a remote server by its case-insensitive name. - * Returns NULL if not found. - */ - virtual iServer* findServerName( const std::string& name ) - const ; - - /** - * Find a fake server by (case insensitive) name. - */ - virtual iServer* findFakeServerName( const std::string& ) - const ; - - /** - * Find a remote server by a wildmask name. - * Returns NULL if not found. - */ - virtual iServer* findExpandedServerName( - const std::string& name ) const ; - /** - * Returns all the servers which are currently in bursting state - */ - virtual std::list< iServer* > getAllBurstingServers(); - - /** - * Find a global channel by case insensitive name. - * Returns NULL if not found. - */ - virtual Channel* findChannel( const std::string& name ) - const ; - - /* Removal methods. */ - - /** - * Remove a remote client by integer numeric and return a - * pointer to the iClient. - * Return NULL if not found. - */ - virtual iClient* removeClient( - const unsigned int& intYYXXX ) ; - - /** - * Remove a remote client by integer server and client numerics, - * and return a pointer to the iClient. - * Returns NULL if not found. - */ - virtual iClient* removeClient( const unsigned int& YY, - const unsigned int& XXX ) ; - - /** - * Remove a remote client by character numeric, and return a - * pointer to it. - * Returns NULL if not found. - */ - virtual iClient* removeClient( const std::string& yyxxx ) ; - - /** - * Remove a remote client by its pointer. - * This will NOT deallocate the iClient instance. - */ - virtual iClient* removeClient( iClient* ) ; - - /** - * Remove a local client from the network data tables. - */ - virtual xClient* removeLocalClient( xClient* ) ; - - /** - * Remove a fake client from the network data structures - * and deallocate its reserved numeric. - */ - virtual iClient* removeFakeClient( iClient* ) ; - - /** - * Remove a fake server from the network data structures - * and deallocate its reserved numeric. - */ - virtual iServer* removeFakeServer( iServer* ) ; - - /** - * Remove a fake iServer from the network data structures - * by (case-insensitive) name, and remove its reserved - * numeric. - */ - virtual iServer* removeFakeServerName( const std::string& ) ; - - /** - * Remove a nick name from the internal nick name table. - * Note that this returns void. This is because nick names - * are cross referenced in the nick name table. That is, - * no heap space is allocated for elements in the nick name - * table, they simply point to iClient instances. - */ - virtual void removeNick( const std::string& nickName ) ; - - /** - * Remove a remote server by its integer numeric, and - * return a pointer to it. - * When a server is removed, all its clients are also - * removed. Each client is deleted, so make sure that - * the clients added to the network table (this) are - * allocated on the heap, and that there are no - * other stale pointers to any clients. - * If postEvent is true, then an EVT_QUIT will be generated - * for each client removal. - * Returns NULL if not found. - */ - virtual iServer* removeServer( const unsigned int& YY, - bool postEvent = false ) ; - - /** - * Remove a remote server by its character numeric, and - * return a pointer to it. - * When a server is removed, all its clients are also - * removed. Each client is deleted, so make sure that - * the clients added to the network table (this) are - * allocated on the heap, and that there are no - * other stale pointers to any clients. - * Returns NULL if not found. - */ - virtual iServer* removeServer( const std::string& YY ) ; - - /** - * Remove a remote server by its case-insensitive name, and - * return a pointer to it. - * When a server is removed, all its clients are also - * removed. Each client is deleted, so make sure that - * the clients added to the network table (this) are - * allocated on the heap, and that there are no - * other stale pointers to any clients. - * Returns NULL if not found. - */ - virtual iServer* removeServerName( const std::string& name ) ; - - /** - * Remove a channel from the network table, keyed by its - * case insensitive name. - * Returns NULL if not found. - */ - virtual Channel* removeChannel( const std::string& name ) ; - - /** - * Remove a channel from the network table. - * Returns the Channel which has been removed, or NULL if the - * channel was not found. - */ - virtual Channel* removeChannel( const Channel* theChan ) ; - - /* Utility methods */ - - /** - * Change a remote client's nickname, given its character - * numeric and new nickname. - * This method does NOT work for local clients. - */ - virtual void rehashNick( const std::string& yyxxx, - const std::string& newNick, const time_t& newTS ) ; - - /** - * This method performs a recursive removal of all servers - * which are uplinked by intYY. - * The server referenced by intYY is deallocated in this - * method. - */ - virtual void OnSplit( const unsigned int& intYY ) ; - - /** - * An iterator to a network (iClient), which allows mutation. - * This iterator is a pair< const string (nickname), iClient* >. - */ - typedef nickMapType::iterator clientIterator ; - - /** - * Return the network iClient list. - */ - inline const nickMapType clients() const - { return nickMap ; } - - /** - * Return a mutator to the beginning of the network client - * data structure. The client referenced is mutable. - */ - inline clientIterator clients_begin() - { return nickMap.begin() ; } - - /** - * Return a mutator to the end of the network client - * data structure. The client referenced is mutable. - */ - inline clientIterator clients_end() - { return nickMap.end() ; } - - /** - * An iterator to a network (iClient), which disallows mutation. - * This iterator is a pair< const string (nickname), iClient* >. - */ - typedef nickMapType::const_iterator const_clientIterator ; - - /** - * Return a mutator to the beginning of the network client - * data structure. The client referenced is immutable. - */ - inline const_clientIterator clients_begin() const - { return nickMap.begin() ; } - - /** - * Return a mutator to the end of the network client - * data structure. The client referenced is immutable. - */ - inline const_clientIterator clients_end() const - { return nickMap.end() ; } - - /** - * Define a non-const iterator for walking through the - * structure of remote servers. - */ - typedef serverMapType::iterator serverIterator ; - - /** - * Define a const iterator for walking through the structure - * of remote servers. - */ - typedef serverMapType::const_iterator const_serverIterator ; - - /** - * Return the servers table - */ - inline const serverMapType servers() const - { return serverMap ; } - - /** - * Return a non-const iterator to the beginning of the - * remote servers table. - */ - inline serverIterator servers_begin() - { return serverMap.begin() ; } - - /** - * Return a non-const iterator to the end of the - * remote servers table. - */ - inline serverIterator servers_end() - { return serverMap.end() ; } - - /** - * Return a const iterator to the beginning of the - * remote servers table. - */ - inline const_serverIterator servers_begin() const - { return serverMap.begin() ; } - - /** - * Return a const iterator to the end of the remote - * servers table. - */ - inline const_serverIterator servers_end() const - { return serverMap.end() ; } - - /** - * Define a non-const iterator for walking through the - * structure of local clients (xClients). - */ - typedef xClientMapType::iterator localClientIterator ; - - /** - * Define a const iterator for walking through the - * structure of local clients (xClients). - */ - typedef xClientMapType::const_iterator const_localClientIterator ; - - /** - * Return a non-const iterator to the beginning of the - * local clients table. - */ - inline localClientIterator localClient_begin() - { return localClients.begin() ; } - - /** - * Return a non-const iterator to the end of the local - * clients table. - */ - inline localClientIterator localClient_end() - { return localClients.end() ; } - - /** - * Return a const iterator the beginning of the - * local clients table. - */ - inline const_localClientIterator localClient_begin() const - { return localClients.begin() ; } - - /** - * Return a const iterator to the end of the local - * clients table. - */ - inline const_localClientIterator localClient_end() const - { return localClients.end() ; } - - /** - * Define a const iterator for walking through the - * channels structure - */ - typedef channelMapType::const_iterator const_channelIterator; - - /** - * Returns an iterator to the begining of the channels structure - */ - inline const_channelIterator channels_begin() const - { return channelMap.begin(); } - - /** - * Returns an iterator to the end of the channels structure - */ - inline const_channelIterator channels_end() const - { return channelMap.end(); } - - /** - * Define a mutating iterator for walking through the - * channels structure - */ - typedef channelMapType::iterator channelIterator; - - /** - * Returns an iterator to the begining of the channels structure - */ - inline channelIterator channels_begin() - { return channelMap.begin(); } - - /** - * Returns an iterator to the end of the channels structure - */ - inline channelIterator channels_end() - { return channelMap.end(); } - - /** - * const_iterator to a fake client. - */ - typedef fakeClientMapType::const_iterator const_fakeClientIterator ; - - /** - * Return a const iterator the beginning of the fake - * client structure. - */ - inline const_fakeClientIterator fakeClient_begin() const - { return fakeClientMap.begin() ; } - - /** - * Return a const iterator the end of the fake - * client structure. - */ - inline const_fakeClientIterator fakeClient_end() const - { return fakeClientMap.end() ; } - - /** - * Mutable iterator to a fake client. - */ - typedef fakeClientMapType::iterator fakeClientIterator ; - - /** - * Return a mutable iterator the beginning of the fake - * client structure. - */ - inline fakeClientIterator fakeClient_begin() - { return fakeClientMap.begin() ; } - - /** - * Return a mutable iterator the end of the fake - * client structure. - */ - inline fakeClientIterator fakeClient_end() - { return fakeClientMap.end() ; } - - /** - * const_iterator to the fakeServerMap. - */ - typedef fakeServerMapType::const_iterator - const_fakeServerIterator ; - - /** - * Return a const_iterator to the beginning of the fake - * server structure. - */ - inline const_fakeServerIterator fakeServers_begin() const - { return fakeServerMap.begin() ; } - - /** - * Return a const_iterator to the end of the fake - * server structure. - */ - inline const_fakeServerIterator fakeServers_end() const - { return fakeServerMap.end() ; } - - /** - * iterator to the fakeServerMap. - */ - typedef fakeServerMapType::iterator fakeServerIterator ; - - /** - * Return a mutable iterator to the beginning of the fake - * server structure. - */ - inline fakeServerIterator fakeServers_begin() - { return fakeServerMap.begin() ; } - - /** - * Return a mutable iterator to the end of the fake - * server structure. - */ - inline fakeServerIterator fakeServers_end() - { return fakeServerMap.end() ; } - - /** - * Return the number of channels currently stored in the - * the channel table. - */ - inline size_t channelList_size() const - { return channelMap.size() ; } - - /** - * Return the number of servers currently stored in the - * the server table. - */ - size_t serverList_size() const ; - - /** - * Return the number of network clients currently stored - * in the client table. - */ - size_t clientList_size() const ; - - /** - * Retrieve the number of clients on the given server. - */ - size_t countClients( const iServer* theServer ) const ; - - /** - * This method is used to set the xServer used for - * backwards communication. This is bad, and I would like - * very much to get rid of it. - */ - virtual void setServer( xServer* _theServer ) ; - - /** - * Attempt to match the hostname, which may include wildcard - * characters, with any clients on the network. Return a - * list of pointers to const iClient's which match. - */ - virtual std::list< const iClient* > matchHost( - const std::string& wildHost ) const ; - - /** - * Match the given user@host string, which may include - * wildcards, to each client on the network. Return a - * list of pointers to const iClient's which match. - */ - virtual std::list< const iClient* > matchUserHost( - const std::string& ) const ; - - /** - * Match the given channel key, which may include wildcards, - * to each channel on the network. Return a list of pointers - * to const Channel's which match. - */ - virtual std::list getChannelsWithKey( - const std::string& key) const; - - /** - * Match the given channel modes, which may NOT include wildcards, - * to each channel on the network. Return a list of pointers - * to const Channel's which match. - */ - virtual std::list getChannelsWithModes( - const std::string& modes) const; +class xNetwork { + /// Allow xServer to access this class's private + /// members/methods. + friend class xServer; + + private: + /** + * Type used to store all reserved intYY and intYYXXX's + * for the local server and juped iClient/xClient/iServer's. + * Keyed top level by the server's intYY, then each + * set is keyed by intXXX for that particular server. + */ + typedef std::map> reservedNumericMapType; + + /** + * This is an iterator type definition for the + * reservedNumericMapType. + */ + typedef reservedNumericMapType::iterator reservedNumeric_iterator; + + /** + * This type maps fake iClient's to their owning + * xClient's, keyed by the iClient's intYYXXX numeric. + */ + typedef std::map> fakeClientMapType; + + /** + * This type stores fake (juped) servers. + */ + typedef std::map> fakeServerMapType; + + /** + * This is the type of vector for storing + * local (services) clients. + */ + typedef std::map xClientMapType; + + /** + * This is the type used to store the network Channel + * instances. + */ + typedef std::map channelMapType; + + /** + * This is the type used to store the nick name/iClient* pairs. + */ + typedef std::map nickMapType; + + /** + * The type used to store information about iClient's, + * keyed by integer numeric. + */ + typedef std::map numericMapType; + + /** + * The type used to store information about iServer's, + * keyed by integer numeric. + */ + typedef std::map serverMapType; + + /** + * The type used to store Network configuration pairs (CF), + * keyed by the configuration key. + */ + typedef std::map> netConfMapType; + + public: + /** + * The default constructor handles all of the default + * allocation and initialization. + */ + xNetwork(); + + /** + * The default destructor will deallocate all objects + * that are not explicitly removed from this structure. + * Therefore, it is highly recommend that the application + * programmer iterate through this structure and remove + * all items before destroying this structure. + */ + virtual ~xNetwork(); + + /* Addition methods + * These methods return true if addition is successful, + * false otherwise. + */ + + /** + * Add a new iClient to the network. This will also handle + * any additions into the nickname table, if required. + * Returns false if the addition fails. + */ + virtual bool addClient(iClient*); + + /** + * Add a fake client to this (or a juped) server. The + * xClient is the "owner" of the iClient. + * This method will fill in the iClient's intXXX/charXXX, + * but the intYY/charYY must be valid. + */ + virtual bool addFakeClient(iClient* theClient, xClient* ownerClient); + + /** + * Add a services client to the network table. + * This is stored in the table of local clients. + * Returns false if the addition fails. + */ + virtual bool addClient(xClient*); + + /** + * Add a new server to the network table. + * Returns false if the addition fails. + */ + virtual bool addServer(iServer*); + + /** + * Add a new fake (juped) server to the structure + * of fake servers. + * Returns true on success, false on failure. + */ + virtual bool addFakeServer(iServer*, xClient*); + + /** + * Add a new channel to the network table. + * Returns false if the addition fails. + */ + virtual bool addChannel(Channel*); + + /** + * Add a new netconf variable to the network table. + */ + virtual void addNetConf(const std::string& key, const std::string& value, time_t timestamp) { + netConfMap[key] = std::make_pair(value, timestamp); + } + + /** + * Find a netconf variable by key. + * Returns std::nullopt if not found. + */ + virtual std::optional> findNetConf(const std::string& key) const; + + /* + * All nickname based searches are case insensitive. + */ + + /** + * Find a remote client given the client's integer numeric. + * Returns NULL if not found. + */ + virtual iClient* findClient(const unsigned int& YY, const unsigned int& XXX) const; + + /** + * Find a remote client given the client's integer numeric. + * Returns NULL if not found. + */ + virtual iClient* findClient(const unsigned int& intYYXXX) const; + + /** + * Find a fake client given the client's integer numeric. + * Returns NULL if not found. + */ + virtual iClient* findFakeClient(const unsigned int& YY, const unsigned int& XXX) const; + + /** + * Find a remote client given the client's character numeric. + * Returns NULL if not found. + */ + virtual iClient* findClient(const std::string& yyxxx) const; + + /** + * Find a fake client by numeric. + * Returns NULL if not found. + */ + virtual iClient* findFakeClient(const std::string& yyxxx) const; + + /** + * Lookup a fake (juped) iClient. + */ + virtual iClient* findFakeClient(iClient*) const; + + /** + * Lookup the xClient owner of a particular iClient. + */ + virtual xClient* findFakeClientOwner(iClient*) const; + + /** + * Lookup all fake iClients belonging to an xClient. + * If the xClient is NULL, return all fake clients. + */ + virtual std::list findFakeClients(xClient*) const; + + /** + * Retrieve a pointer to an iClient given its nick name. + * Returns NULL if not found. + */ + virtual iClient* findNick(const std::string& nickName) const; + + /** + * Find a local (services) client by its character numeric. + * Returns NULL if not found. + */ + virtual xClient* findLocalClient(const std::string& yyxxx) const; + + /** + * Find a local (services) client by its integer numeric. + * Returns NULL if not found. + */ + virtual xClient* findLocalClient(const unsigned int& intYYXXX) const; + + /** + * Find a local (services) client by its case-insensitive nickname. + * Returns NULL if not found. + */ + virtual xClient* findLocalNick(const std::string& nickName) const; + + /** + * Lookup a fake (juped) iClient by nickname. + */ + virtual iClient* findFakeNick(const std::string& nickName) const; + + /** + * Find a remote server by its integer numeric. + * Returns NULL if not found. + */ + virtual iServer* findServer(const unsigned int& YY) const; + + /** + * Find a fake server, return that server if it is fake (juped), + * or NULL otherwise. + */ + virtual iServer* findFakeServer(const iServer*) const; + + /** + * Find a fake server described by the given intYY numeric. + * Return 0 on failure. + */ + virtual iServer* findFakeServer(unsigned int intYY) const; + + /** + * Find a remote server by its character numeric. + * Returns NULL if not found. + */ + virtual iServer* findServer(const std::string& YY) const; + + /** + * Find a remote server by its case-insensitive name. + * Returns NULL if not found. + */ + virtual iServer* findServerName(const std::string& name) const; + + /** + * Find a fake server by (case insensitive) name. + */ + virtual iServer* findFakeServerName(const std::string&) const; + + /** + * Find a remote server by a wildmask name. + * Returns NULL if not found. + */ + virtual iServer* findExpandedServerName(const std::string& name) const; + /** + * Returns all the servers which are currently in bursting state + */ + virtual std::list getAllBurstingServers(); + + /** + * Find a global channel by case insensitive name. + * Returns NULL if not found. + */ + virtual Channel* findChannel(const std::string& name) const; + + /* Removal methods. */ + + /** + * Remove a remote client by integer numeric and return a + * pointer to the iClient. + * Return NULL if not found. + */ + virtual iClient* removeClient(const unsigned int& intYYXXX); + + /** + * Remove a remote client by integer server and client numerics, + * and return a pointer to the iClient. + * Returns NULL if not found. + */ + virtual iClient* removeClient(const unsigned int& YY, const unsigned int& XXX); + + /** + * Remove a remote client by character numeric, and return a + * pointer to it. + * Returns NULL if not found. + */ + virtual iClient* removeClient(const std::string& yyxxx); + + /** + * Remove a remote client by its pointer. + * This will NOT deallocate the iClient instance. + */ + virtual iClient* removeClient(iClient*); + + /** + * Remove a local client from the network data tables. + */ + virtual xClient* removeLocalClient(xClient*); + + /** + * Remove a fake client from the network data structures + * and deallocate its reserved numeric. + */ + virtual iClient* removeFakeClient(iClient*); + + /** + * Remove a fake server from the network data structures + * and deallocate its reserved numeric. + */ + virtual iServer* removeFakeServer(iServer*); + + /** + * Remove a fake iServer from the network data structures + * by (case-insensitive) name, and remove its reserved + * numeric. + */ + virtual iServer* removeFakeServerName(const std::string&); + + /** + * Remove a nick name from the internal nick name table. + * Note that this returns void. This is because nick names + * are cross referenced in the nick name table. That is, + * no heap space is allocated for elements in the nick name + * table, they simply point to iClient instances. + */ + virtual void removeNick(const std::string& nickName); + + /** + * Remove a remote server by its integer numeric, and + * return a pointer to it. + * When a server is removed, all its clients are also + * removed. Each client is deleted, so make sure that + * the clients added to the network table (this) are + * allocated on the heap, and that there are no + * other stale pointers to any clients. + * If postEvent is true, then an EVT_QUIT will be generated + * for each client removal. + * Returns NULL if not found. + */ + virtual iServer* removeServer(const unsigned int& YY, bool postEvent = false); + + /** + * Remove a remote server by its character numeric, and + * return a pointer to it. + * When a server is removed, all its clients are also + * removed. Each client is deleted, so make sure that + * the clients added to the network table (this) are + * allocated on the heap, and that there are no + * other stale pointers to any clients. + * Returns NULL if not found. + */ + virtual iServer* removeServer(const std::string& YY); + + /** + * Remove a remote server by its case-insensitive name, and + * return a pointer to it. + * When a server is removed, all its clients are also + * removed. Each client is deleted, so make sure that + * the clients added to the network table (this) are + * allocated on the heap, and that there are no + * other stale pointers to any clients. + * Returns NULL if not found. + */ + virtual iServer* removeServerName(const std::string& name); + + /** + * Remove a channel from the network table, keyed by its + * case insensitive name. + * Returns NULL if not found. + */ + virtual Channel* removeChannel(const std::string& name); + + /** + * Remove a channel from the network table. + * Returns the Channel which has been removed, or NULL if the + * channel was not found. + */ + virtual Channel* removeChannel(const Channel* theChan); + + /* Utility methods */ + + /** + * Change a remote client's nickname, given its character + * numeric and new nickname. + * This method does NOT work for local clients. + */ + virtual void rehashNick(const std::string& yyxxx, const std::string& newNick, + const time_t& newTS); + + /** + * This method performs a recursive removal of all servers + * which are uplinked by intYY. + * The server referenced by intYY is deallocated in this + * method. + */ + virtual void OnSplit(const unsigned int& intYY); + + /** + * An iterator to a network (iClient), which allows mutation. + * This iterator is a pair< const string (nickname), iClient* >. + */ + typedef nickMapType::iterator clientIterator; + + /** + * Return the network iClient list. + */ + inline const nickMapType clients() const { return nickMap; } + + /** + * Return a mutator to the beginning of the network client + * data structure. The client referenced is mutable. + */ + inline clientIterator clients_begin() { return nickMap.begin(); } + + /** + * Return a mutator to the end of the network client + * data structure. The client referenced is mutable. + */ + inline clientIterator clients_end() { return nickMap.end(); } + + /** + * An iterator to a network (iClient), which disallows mutation. + * This iterator is a pair< const string (nickname), iClient* >. + */ + typedef nickMapType::const_iterator const_clientIterator; + + /** + * Return a mutator to the beginning of the network client + * data structure. The client referenced is immutable. + */ + inline const_clientIterator clients_begin() const { return nickMap.begin(); } + + /** + * Return a mutator to the end of the network client + * data structure. The client referenced is immutable. + */ + inline const_clientIterator clients_end() const { return nickMap.end(); } + + /** + * Define a non-const iterator for walking through the + * structure of remote servers. + */ + typedef serverMapType::iterator serverIterator; + + /** + * Define a const iterator for walking through the structure + * of remote servers. + */ + typedef serverMapType::const_iterator const_serverIterator; + + /** + * Return the servers table + */ + inline const serverMapType servers() const { return serverMap; } + + /** + * Return a non-const iterator to the beginning of the + * remote servers table. + */ + inline serverIterator servers_begin() { return serverMap.begin(); } + + /** + * Return a non-const iterator to the end of the + * remote servers table. + */ + inline serverIterator servers_end() { return serverMap.end(); } + + /** + * Return a const iterator to the beginning of the + * remote servers table. + */ + inline const_serverIterator servers_begin() const { return serverMap.begin(); } + + /** + * Return a const iterator to the end of the remote + * servers table. + */ + inline const_serverIterator servers_end() const { return serverMap.end(); } + + /** + * Define a non-const iterator for walking through the + * structure of local clients (xClients). + */ + typedef xClientMapType::iterator localClientIterator; + + /** + * Define a const iterator for walking through the + * structure of local clients (xClients). + */ + typedef xClientMapType::const_iterator const_localClientIterator; + + /** + * Return a non-const iterator to the beginning of the + * local clients table. + */ + inline localClientIterator localClient_begin() { return localClients.begin(); } + + /** + * Return a non-const iterator to the end of the local + * clients table. + */ + inline localClientIterator localClient_end() { return localClients.end(); } + + /** + * Return a const iterator the beginning of the + * local clients table. + */ + inline const_localClientIterator localClient_begin() const { return localClients.begin(); } + + /** + * Return a const iterator to the end of the local + * clients table. + */ + inline const_localClientIterator localClient_end() const { return localClients.end(); } + + /** + * Define a const iterator for walking through the + * channels structure + */ + typedef channelMapType::const_iterator const_channelIterator; + + /** + * Returns an iterator to the begining of the channels structure + */ + inline const_channelIterator channels_begin() const { return channelMap.begin(); } + + /** + * Returns an iterator to the end of the channels structure + */ + inline const_channelIterator channels_end() const { return channelMap.end(); } + + /** + * Define a mutating iterator for walking through the + * channels structure + */ + typedef channelMapType::iterator channelIterator; + + /** + * Returns an iterator to the begining of the channels structure + */ + inline channelIterator channels_begin() { return channelMap.begin(); } + + /** + * Returns an iterator to the end of the channels structure + */ + inline channelIterator channels_end() { return channelMap.end(); } + + /** + * const_iterator to a fake client. + */ + typedef fakeClientMapType::const_iterator const_fakeClientIterator; + + /** + * Return a const iterator the beginning of the fake + * client structure. + */ + inline const_fakeClientIterator fakeClient_begin() const { return fakeClientMap.begin(); } + + /** + * Return a const iterator the end of the fake + * client structure. + */ + inline const_fakeClientIterator fakeClient_end() const { return fakeClientMap.end(); } + + /** + * Mutable iterator to a fake client. + */ + typedef fakeClientMapType::iterator fakeClientIterator; + + /** + * Return a mutable iterator the beginning of the fake + * client structure. + */ + inline fakeClientIterator fakeClient_begin() { return fakeClientMap.begin(); } + + /** + * Return a mutable iterator the end of the fake + * client structure. + */ + inline fakeClientIterator fakeClient_end() { return fakeClientMap.end(); } + + /** + * const_iterator to the fakeServerMap. + */ + typedef fakeServerMapType::const_iterator const_fakeServerIterator; + + /** + * Return a const_iterator to the beginning of the fake + * server structure. + */ + inline const_fakeServerIterator fakeServers_begin() const { return fakeServerMap.begin(); } + + /** + * Return a const_iterator to the end of the fake + * server structure. + */ + inline const_fakeServerIterator fakeServers_end() const { return fakeServerMap.end(); } + + /** + * iterator to the fakeServerMap. + */ + typedef fakeServerMapType::iterator fakeServerIterator; + + /** + * Return a mutable iterator to the beginning of the fake + * server structure. + */ + inline fakeServerIterator fakeServers_begin() { return fakeServerMap.begin(); } + + /** + * Return a mutable iterator to the end of the fake + * server structure. + */ + inline fakeServerIterator fakeServers_end() { return fakeServerMap.end(); } + + /** + * Return the number of channels currently stored in the + * the channel table. + */ + inline size_t channelList_size() const { return channelMap.size(); } + + /** + * Return the number of servers currently stored in the + * the server table. + */ + size_t serverList_size() const; + + /** + * Return the number of network clients currently stored + * in the client table. + */ + size_t clientList_size() const; + + /** + * Retrieve the number of clients on the given server. + */ + size_t countClients(const iServer* theServer) const; + + /** + * This method is used to set the xServer used for + * backwards communication. This is bad, and I would like + * very much to get rid of it. + */ + virtual void setServer(xServer* _theServer); + + /** + * Attempt to match the hostname, which may include wildcard + * characters, with any clients on the network. Return a + * list of pointers to const iClient's which match. + */ + virtual std::list matchHost(const std::string& wildHost) const; + + /** + * Match the given user@host string, which may include + * wildcards, to each client on the network. Return a + * list of pointers to const iClient's which match. + */ + virtual std::list matchUserHost(const std::string&) const; + + /** + * Match the given channel key, which may include wildcards, + * to each channel on the network. Return a list of pointers + * to const Channel's which match. + */ + virtual std::list getChannelsWithKey(const std::string& key) const; + + /** + * Match the given channel modes, which may NOT include wildcards, + * to each channel on the network. Return a list of pointers + * to const Channel's which match. + */ + virtual std::list getChannelsWithModes(const std::string& modes) const; #ifdef TOPIC_TRACK - /** - * Match the given channel topic, which may include wildcards, - * to each channel on the network. Return a list of pointers - * to const Channel's which match. - */ - virtual std::list getChannelsWithTopic( - const std::string& topic) const; - - /** - * Match the given channel topic setter, which may include wildcards, - * to each channel on the network. Return a list of pointers - * to const Channel's which match. - */ - virtual std::list getChannelsWithTopicBy( - const std::string& topicby) const; + /** + * Match the given channel topic, which may include wildcards, + * to each channel on the network. Return a list of pointers + * to const Channel's which match. + */ + virtual std::list getChannelsWithTopic(const std::string& topic) const; + + /** + * Match the given channel topic setter, which may include wildcards, + * to each channel on the network. Return a list of pointers + * to const Channel's which match. + */ + virtual std::list getChannelsWithTopicBy(const std::string& topicby) const; #endif - /** - * Attempt to find hostnames which are equivalent to the given - * hostname, found using a case insensitive search. - * Return a list of pointers to const iClient's which are - * found. - */ - virtual std::list< const iClient* > findHost( - const std::string& hostName ) const ; - - /** - * Perform a similar match as to matchHost(), except return - * only the number of matches found. - */ - virtual size_t countMatchingHost( const std::string& wildHost ) - const ; - - /** - * Perform a similar match as to matchUserHost(), except return - * only the number of matches found. - */ - virtual size_t countMatchingUserHost( const std::string& wildUserHost ) - const ; - /** - * Perform a similar operation as to findHost(), except return - * only the number of hosts found. - */ - virtual size_t countHost( const std::string& hostName ) const ; - - /** - * Attempt to match the real hostname, which may include wildcard - * characters, with any clients on the network. Return a - * list of pointers to const iClient's which match. - */ - virtual std::list< const iClient* > matchRealHost( - const std::string& wildHost ) const ; - - /** - * Match the given user@host string, which may include - * wildcards, to each client on the network. Return a - * list of pointers to const iClient's which match. - */ - virtual std::list< const iClient* > matchRealUserHost( - const std::string& ) const ; - - /** - * Attempt to find real hostnames which are equivalent to the given - * hostname, found using a case insensitive search. - * Return a list of pointers to const iClient's which are - * found. - */ - virtual std::list< const iClient* > findRealHost( - const std::string& hostName ) const ; - - /** - * Perform a similar match as to matchRealHost(), except return - * only the number of matches found. - */ - virtual size_t countMatchingRealHost( const std::string& wildHost ) - const ; - - /** - * Perform a similar match as to matchRealUserHost(), except return - * only the number of matches found. - */ - virtual size_t countMatchingRealUserHost( const std::string& wildUserHost ) - const ; - /** - * Perform a similar operation as to findRealHost(), except return - * only the number of hosts found. - */ - virtual size_t countRealHost( const std::string& hostName ) const ; - - /** - * Match the given client real name string, which may include - * wildcards, to each client on the network. Return a - * list of pointers to const iClient's which match. - */ - virtual std::list< const iClient* > matchRealName( - const std::string& ) const ; - - /** - * Find a new server (iServer) numeric. - * The new numeric is assigned to intYY. - * On success, true is returned, false otherwise. - */ - virtual bool allocateServerNumeric( unsigned int& intYY ) ; - -protected: - - /** - * Disable copy constructing, this method is declared - * but NOT defined. - */ - xNetwork( const xNetwork& ) ; - - /** - * Disable copy assignment, this method is declared but - * NOT defined. - */ - xNetwork operator=( const xNetwork& ) ; - - /** - * Find a new client (iClient or xClient) numeric. - * The new numeric is assigned to newIntYYXXX. - * On success, true is returned, false otherwise. - */ - virtual bool allocateClientNumeric( unsigned int intYY, - unsigned int& newIntXXX ) ; - - /** - * Free a reserved client (iClient or xClient) numeric. - */ - virtual bool freeClientNumeric( unsigned int intYYXXX ) ; - - - /** - * Free a reserved server (iServer) numeric. - */ - virtual bool freeServerNumeric( unsigned int intYYXXX ) ; - - /** - * This method is used internally when a client is added to - * the structure. - */ - virtual void addNick( iClient* ) ; - - /** - * Perform a simple recursive search for all leaves of - * the server whose numeric is the second arguments, and - * place each of those servers' numerics into the vector. - */ - virtual void findLeaves( std::vector< unsigned int >& yyVector, - const unsigned int intYY ) const ; - - /** - * The vector of local clients. - */ - xClientMapType localClients ; - - /** - * The structure used to store the network channel - * information. - */ - channelMapType channelMap ; - - /** - * The structure used to store the nick name->iClient - * cross references. - */ - nickMapType nickMap ; - - /** - * The container used to store the network iClient's, - * keyed by iClient numeric. - */ - numericMapType numericMap ; - - /** - * The container used to store the network iServer's, - * keyed by iServer numeric. - */ - serverMapType serverMap ; - - /** - * This structure holds all network configuration pairs - * bursted on the network (CF). - */ - netConfMapType netConfMap ; - - /** - * This variable is used backwards calls to the main server. - */ - xServer *theServer ; - - /** - * This structure maps fake iClient's to their owning - * xClient's. - */ - fakeClientMapType fakeClientMap ; - - /** - * This structure stores fake (juped) servers. - */ - fakeServerMapType fakeServerMap ; - - /** - * Structure used to store all reserved intYY and intYYXXX's - * for the local server and juped iClient/xClient/iServer's. - */ - reservedNumericMapType reservedNumericMap ; -} ; + /** + * Attempt to find hostnames which are equivalent to the given + * hostname, found using a case insensitive search. + * Return a list of pointers to const iClient's which are + * found. + */ + virtual std::list findHost(const std::string& hostName) const; + + /** + * Perform a similar match as to matchHost(), except return + * only the number of matches found. + */ + virtual size_t countMatchingHost(const std::string& wildHost) const; + + /** + * Perform a similar match as to matchUserHost(), except return + * only the number of matches found. + */ + virtual size_t countMatchingUserHost(const std::string& wildUserHost) const; + /** + * Perform a similar operation as to findHost(), except return + * only the number of hosts found. + */ + virtual size_t countHost(const std::string& hostName) const; + + /** + * Attempt to match the real hostname, which may include wildcard + * characters, with any clients on the network. Return a + * list of pointers to const iClient's which match. + */ + virtual std::list matchRealHost(const std::string& wildHost) const; + + /** + * Match the given user@host string, which may include + * wildcards, to each client on the network. Return a + * list of pointers to const iClient's which match. + */ + virtual std::list matchRealUserHost(const std::string&) const; + + /** + * Attempt to find real hostnames which are equivalent to the given + * hostname, found using a case insensitive search. + * Return a list of pointers to const iClient's which are + * found. + */ + virtual std::list findRealHost(const std::string& hostName) const; + + /** + * Perform a similar match as to matchRealHost(), except return + * only the number of matches found. + */ + virtual size_t countMatchingRealHost(const std::string& wildHost) const; + + /** + * Perform a similar match as to matchRealUserHost(), except return + * only the number of matches found. + */ + virtual size_t countMatchingRealUserHost(const std::string& wildUserHost) const; + /** + * Perform a similar operation as to findRealHost(), except return + * only the number of hosts found. + */ + virtual size_t countRealHost(const std::string& hostName) const; + + /** + * Match the given client real name string, which may include + * wildcards, to each client on the network. Return a + * list of pointers to const iClient's which match. + */ + virtual std::list matchRealName(const std::string&) const; + + /** + * Find a new server (iServer) numeric. + * The new numeric is assigned to intYY. + * On success, true is returned, false otherwise. + */ + virtual bool allocateServerNumeric(unsigned int& intYY); + + protected: + /** + * Disable copy constructing, this method is declared + * but NOT defined. + */ + xNetwork(const xNetwork&); + + /** + * Disable copy assignment, this method is declared but + * NOT defined. + */ + xNetwork operator=(const xNetwork&); + + /** + * Find a new client (iClient or xClient) numeric. + * The new numeric is assigned to newIntYYXXX. + * On success, true is returned, false otherwise. + */ + virtual bool allocateClientNumeric(unsigned int intYY, unsigned int& newIntXXX); + + /** + * Free a reserved client (iClient or xClient) numeric. + */ + virtual bool freeClientNumeric(unsigned int intYYXXX); + + /** + * Free a reserved server (iServer) numeric. + */ + virtual bool freeServerNumeric(unsigned int intYYXXX); + + /** + * This method is used internally when a client is added to + * the structure. + */ + virtual void addNick(iClient*); + + /** + * Perform a simple recursive search for all leaves of + * the server whose numeric is the second arguments, and + * place each of those servers' numerics into the vector. + */ + virtual void findLeaves(std::vector& yyVector, const unsigned int intYY) const; + + /** + * The vector of local clients. + */ + xClientMapType localClients; + + /** + * The structure used to store the network channel + * information. + */ + channelMapType channelMap; + + /** + * The structure used to store the nick name->iClient + * cross references. + */ + nickMapType nickMap; + + /** + * The container used to store the network iClient's, + * keyed by iClient numeric. + */ + numericMapType numericMap; + + /** + * The container used to store the network iServer's, + * keyed by iServer numeric. + */ + serverMapType serverMap; + + /** + * This structure holds all network configuration pairs + * bursted on the network (CF). + */ + netConfMapType netConfMap; + + /** + * This variable is used backwards calls to the main server. + */ + xServer* theServer; + + /** + * This structure maps fake iClient's to their owning + * xClient's. + */ + fakeClientMapType fakeClientMap; + + /** + * This structure stores fake (juped) servers. + */ + fakeServerMapType fakeServerMap; + + /** + * Structure used to store all reserved intYY and intYYXXX's + * for the local server and juped iClient/xClient/iServer's. + */ + reservedNumericMapType reservedNumericMap; +}; /** * Declare the single xNetwork instance as global, for now. */ -extern xNetwork* Network ; +extern xNetwork* Network; } // namespace gnuworld diff --git a/include/NetworkTarget.h b/include/NetworkTarget.h index 4c494aaf..60b1da3a 100644 --- a/include/NetworkTarget.h +++ b/include/NetworkTarget.h @@ -25,183 +25,161 @@ #ifndef __NETWORKTARGET_H #define __NETWORKTARGET_H -#include +#include -#include "Numeric.h" +#include "Numeric.h" -namespace gnuworld -{ +namespace gnuworld { -class xNetwork ; +class xNetwork; /** * This class is basically a convenience class for addressing * targets according to the ircu network protocol. That is, * this class supports integer and string numerics. */ -class NetworkTarget -{ - /// Allow xNetwork to call the protected mutator methods - friend class xNetwork ; - -private: - - /** - * The integer base 64 representation of this target's - * server. - */ - unsigned int intYY ; - - /** - * The integer base 64 representation of this target's - * client ID (relative to its server). - */ - unsigned int intXXX ; - - /** - * The char array base 64 representation of this target's - * server. - */ - char charYY[ 3 ] ; - - /** - * The char array base 64 representation of this target's - * client ID (relative to its server). - */ - char charXXX[ 4 ] ; - -public: - /** - * Instantiate a NetworkTarget with no arguments. - * All variables will be set to 0. - */ - NetworkTarget() - : intYY( 0 ), - intXXX( 0 ) - { - charYY[ 0 ] = charYY[ 1 ] = charYY[ 2 ] = 0 ; - charXXX[ 0 ] = charXXX[ 1 ] = charXXX[ 2 ] = charXXX[ 3 ] = 0 ; - } - - /** - * Instantiate a NetworkTarget given its base 64 integer - * numerics. - */ - NetworkTarget( const unsigned int& intYY, - const unsigned int& intXXX ) - { - setIntYY( intYY ) ; - setIntXXX( intXXX ) ; - } - - /** - * Instantiate a NetworkTarget given its base 64 char array - * numerics. - */ - NetworkTarget( const std::string& stringYYXXX ) - { - setCharYY( stringYYXXX.substr( 0, 2 ) ) ; - setCharXXX( stringYYXXX.substr( 2, 3 ) ) ; - } - - /** - * Destroy this NetworkTarget object. - */ - virtual ~NetworkTarget() - {} - - /** - * Return the integer base 64 representation of this - * target's server. - */ - inline unsigned int getIntYY() const - { return intYY ; } - - /** - * Return the integer base 64 representation of this - * target's client identifier (relative to its server). - */ - inline unsigned int getIntXXX() const - { return intXXX ; } - - /** - * Return the integer base 64 representation of this - * target's full client/server numeric. - */ - inline unsigned int getIntYYXXX() const - { return combinebase64int( intYY, intXXX ) ; } - - /** - * Return the char array base 64 representation of this - * target's server. - */ - inline const std::string getCharYY() const - { return std::string( charYY ) ; } - - /** - * Return the char array base 64 representation of this - * target's client identifier (relative to its server). - */ - inline const std::string getCharXXX() const - { return std::string( charXXX ) ; } - - /** - * Return the char array base 64 representation of this - * target's full client/server numeric. - */ - inline const std::string getCharYYXXX() const - { return (getCharYY() + getCharXXX()) ; } - -protected: - - /** - * Set the integer base 64 representation of this - * target's server. - */ - inline void setIntYY( unsigned int newIntYY ) - { - intYY = newIntYY ; - inttobase64( charYY, intYY, 2 ) ; - charYY[ 2 ] = 0 ; - } - - /** - * Set the integer base 64 representation of this - * target's client identifier (relative to its server). - */ - inline void setIntXXX( unsigned int newIntXXX ) - { - intXXX = newIntXXX ; - inttobase64( charXXX, intXXX, 3 ) ; - charXXX[ 3 ] = 0 ; - } - - /** - * Set the char array base 64 representation of this - * target's server. - */ - inline void setCharYY( const std::string& stringYY ) - { - charYY[ 0 ] = stringYY[ 0 ] ; - charYY[ 1 ] = stringYY[ 1 ] ; - charYY[ 2 ] = 0 ; - intYY = base64toint( stringYY.c_str(), 2 ) ; - } - - /** - * Set the char array base 64 representation of this - * target's client identifier (relative to its server). - */ - inline void setCharXXX( const std::string& stringXXX ) - { - charXXX[ 0 ] = stringXXX[ 0 ] ; - charXXX[ 1 ] = stringXXX[ 1 ] ; - charXXX[ 2 ] = stringXXX[ 2 ] ; - charXXX[ 3 ] = 0 ; - intXXX = base64toint( stringXXX.c_str(), 3 ) ; - } - -} ; +class NetworkTarget { + /// Allow xNetwork to call the protected mutator methods + friend class xNetwork; + + private: + /** + * The integer base 64 representation of this target's + * server. + */ + unsigned int intYY; + + /** + * The integer base 64 representation of this target's + * client ID (relative to its server). + */ + unsigned int intXXX; + + /** + * The char array base 64 representation of this target's + * server. + */ + char charYY[3]; + + /** + * The char array base 64 representation of this target's + * client ID (relative to its server). + */ + char charXXX[4]; + + public: + /** + * Instantiate a NetworkTarget with no arguments. + * All variables will be set to 0. + */ + NetworkTarget() : intYY(0), intXXX(0) { + charYY[0] = charYY[1] = charYY[2] = 0; + charXXX[0] = charXXX[1] = charXXX[2] = charXXX[3] = 0; + } + + /** + * Instantiate a NetworkTarget given its base 64 integer + * numerics. + */ + NetworkTarget(const unsigned int& intYY, const unsigned int& intXXX) { + setIntYY(intYY); + setIntXXX(intXXX); + } + + /** + * Instantiate a NetworkTarget given its base 64 char array + * numerics. + */ + NetworkTarget(const std::string& stringYYXXX) { + setCharYY(stringYYXXX.substr(0, 2)); + setCharXXX(stringYYXXX.substr(2, 3)); + } + + /** + * Destroy this NetworkTarget object. + */ + virtual ~NetworkTarget() {} + + /** + * Return the integer base 64 representation of this + * target's server. + */ + inline unsigned int getIntYY() const { return intYY; } + + /** + * Return the integer base 64 representation of this + * target's client identifier (relative to its server). + */ + inline unsigned int getIntXXX() const { return intXXX; } + + /** + * Return the integer base 64 representation of this + * target's full client/server numeric. + */ + inline unsigned int getIntYYXXX() const { return combinebase64int(intYY, intXXX); } + + /** + * Return the char array base 64 representation of this + * target's server. + */ + inline const std::string getCharYY() const { return std::string(charYY); } + + /** + * Return the char array base 64 representation of this + * target's client identifier (relative to its server). + */ + inline const std::string getCharXXX() const { return std::string(charXXX); } + + /** + * Return the char array base 64 representation of this + * target's full client/server numeric. + */ + inline const std::string getCharYYXXX() const { return (getCharYY() + getCharXXX()); } + + protected: + /** + * Set the integer base 64 representation of this + * target's server. + */ + inline void setIntYY(unsigned int newIntYY) { + intYY = newIntYY; + inttobase64(charYY, intYY, 2); + charYY[2] = 0; + } + + /** + * Set the integer base 64 representation of this + * target's client identifier (relative to its server). + */ + inline void setIntXXX(unsigned int newIntXXX) { + intXXX = newIntXXX; + inttobase64(charXXX, intXXX, 3); + charXXX[3] = 0; + } + + /** + * Set the char array base 64 representation of this + * target's server. + */ + inline void setCharYY(const std::string& stringYY) { + charYY[0] = stringYY[0]; + charYY[1] = stringYY[1]; + charYY[2] = 0; + intYY = base64toint(stringYY.c_str(), 2); + } + + /** + * Set the char array base 64 representation of this + * target's client identifier (relative to its server). + */ + inline void setCharXXX(const std::string& stringXXX) { + charXXX[0] = stringXXX[0]; + charXXX[1] = stringXXX[1]; + charXXX[2] = stringXXX[2]; + charXXX[3] = 0; + intXXX = base64toint(stringXXX.c_str(), 3); + } +}; } // namespace gnuworld diff --git a/include/Numeric.h b/include/Numeric.h index c5b7db9d..b2220b32 100644 --- a/include/Numeric.h +++ b/include/Numeric.h @@ -45,36 +45,35 @@ * just-disconnected-client aren't confused with just-connected ones. */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -#include /* for DupString()'s strcpy, strlen */ -#include //for sscanf +#include /* for DupString()'s strcpy, strlen */ +#include //for sscanf -///For Test functions -#include // std::reverse -///For Test functions +/// For Test functions +#include // std::reverse +/// For Test functions #ifndef INCLUDED_ircd_chattr_h #include "ircd_chattr.h" #endif /* These must be the same on ALL servers ! Do not change ! */ -#include +#include -namespace gnuworld -{ +namespace gnuworld { /// The length of the character numerics, 5 for n2k #define P10_NUMNICKLEN 5 #define NUMNICKLOG 6 -#define NUMNICKMAXCHAR 'z' /* See convert2n[] */ -#define NUMNICKBASE 64 /* (2 << NUMNICKLOG) */ -#define NUMNICKMASK 63 /* (NUMNICKBASE-1) */ -#define NN_MAX_SERVER 4096 /* (NUMNICKBASE * NUMNICKBASE) */ +#define NUMNICKMAXCHAR 'z' /* See convert2n[] */ +#define NUMNICKBASE 64 /* (2 << NUMNICKLOG) */ +#define NUMNICKMASK 63 /* (NUMNICKBASE-1) */ +#define NN_MAX_SERVER 4096 /* (NUMNICKBASE * NUMNICKBASE) */ /** Maximum length of a numeric IP (v4 or v6) address. * "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255" @@ -99,102 +98,84 @@ namespace gnuworld * '&', '#', '+', '$', '@' and '%' : * Because m_message() matches these characters to detect special cases. */ -static const char convert2y[] = { - 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', - 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', - 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', - 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','[',']' -}; +static const char convert2y[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '[', ']'}; /** * convert2n[] ocnverts a character to the corresponding integer. */ static const unsigned int convert2n[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 52,53,54,55,56,57,58,59,60,61, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, - 15,16,17,18,19,20,21,22,23,24,25,62, 0,63, 0, 0, - 0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, - 41,42,43,44,45,46,47,48,49,50,51, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 62, 0, 63, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* * this new faster inet_ntoa was ripped from: * From: Thomas Helvey */ /** Array of text strings for dotted quads. */ -static const char* IpQuadTab[] = -{ - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", - "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", - "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", - "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", - "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", - "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", - "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", - "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", - "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", - "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", - "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", - "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", - "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", - "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", - "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", - "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", - "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", - "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", - "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", - "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", - "200", "201", "202", "203", "204", "205", "206", "207", "208", "209", - "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", - "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", - "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", - "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", - "250", "251", "252", "253", "254", "255" -}; +static const char* IpQuadTab[] = { + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", + "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", + "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", + "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", + "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", + "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", + "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", + "91", "92", "93", "94", "95", "96", "97", "98", "99", "100", "101", "102", "103", + "104", "105", "106", "107", "108", "109", "110", "111", "112", "113", "114", "115", "116", + "117", "118", "119", "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", + "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142", + "143", "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", + "156", "157", "158", "159", "160", "161", "162", "163", "164", "165", "166", "167", "168", + "169", "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", "180", "181", + "182", "183", "184", "185", "186", "187", "188", "189", "190", "191", "192", "193", "194", + "195", "196", "197", "198", "199", "200", "201", "202", "203", "204", "205", "206", "207", + "208", "209", "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", "220", + "221", "222", "223", "224", "225", "226", "227", "228", "229", "230", "231", "232", "233", + "234", "235", "236", "237", "238", "239", "240", "241", "242", "243", "244", "245", "246", + "247", "248", "249", "250", "251", "252", "253", "254", "255"}; /** * This method converts a base64 character array to * an unsigned integer. */ -inline unsigned int base64toint( const char* s ) -{ -unsigned int i = convert2n[ static_cast< unsigned char >( *s++ ) ] ; -while( *s ) - { - i <<= NUMNICKLOG; - i += convert2n[ static_cast< unsigned char >( *s++ ) ] ; - } -return i ; +inline unsigned int base64toint(const char* s) { + unsigned int i = convert2n[static_cast(*s++)]; + while (*s) { + i <<= NUMNICKLOG; + i += convert2n[static_cast(*s++)]; + } + return i; } /** * This method converts only the first (count) characters * of the string (s) to unsigned integer format. */ -inline unsigned int base64toint( const char* s, size_t count ) -{ -assert( s != 0 ) ; - -unsigned int i = convert2n[ static_cast< unsigned char >( *s++ ) ] ; -while (*s && --count > 0) - { - i <<= NUMNICKLOG; - i += convert2n[ static_cast< unsigned char >( *s++ ) ] ; - } - -return i; +inline unsigned int base64toint(const char* s, size_t count) { + assert(s != 0); + + unsigned int i = convert2n[static_cast(*s++)]; + while (*s && --count > 0) { + i <<= NUMNICKLOG; + i += convert2n[static_cast(*s++)]; + } + + return i; } /** @@ -204,67 +185,58 @@ return i; * (count) characters (excluding null terminator). * This method returns a pointer to the base 64 buffer. */ -inline const char* inttobase64( char* buf, unsigned int v, size_t count ) -{ -assert( buf != 0 ) ; - -buf[count] = '\0'; -while (count > 0) - { - buf[ --count ] = convert2y[(v & NUMNICKMASK)]; - v >>= NUMNICKLOG; - } - -return buf; +inline const char* inttobase64(char* buf, unsigned int v, size_t count) { + assert(buf != 0); + + buf[count] = '\0'; + while (count > 0) { + buf[--count] = convert2y[(v & NUMNICKMASK)]; + v >>= NUMNICKLOG; + } + + return buf; } -inline void splitbase64int( unsigned int intYYXXX, - unsigned int& intYY, - unsigned int& intXXX ) -{ -// Decompose to charYYXXX -char charYYXXX[ 6 ] ; -inttobase64( charYYXXX, intYYXXX, 5 ) ; - -// Now split the charYYXXX into two ints -intYY = base64toint( charYYXXX, 2 ) ; -intXXX = base64toint( &charYYXXX[ 2 ], 3 ) ; +inline void splitbase64int(unsigned int intYYXXX, unsigned int& intYY, unsigned int& intXXX) { + // Decompose to charYYXXX + char charYYXXX[6]; + inttobase64(charYYXXX, intYYXXX, 5); + + // Now split the charYYXXX into two ints + intYY = base64toint(charYYXXX, 2); + intXXX = base64toint(&charYYXXX[2], 3); } -inline unsigned int combinebase64int( const unsigned int& intYY, - const unsigned int& intXXX ) -{ -char charYYXXX[ 6 ] ; +inline unsigned int combinebase64int(const unsigned int& intYY, const unsigned int& intXXX) { + char charYYXXX[6]; -inttobase64( charYYXXX, intYY, 2 ) ; -inttobase64( &charYYXXX[ 2 ], intXXX, 3 ) ; + inttobase64(charYYXXX, intYY, 2); + inttobase64(&charYYXXX[2], intXXX, 3); -return base64toint( charYYXXX, 5 ) ; + return base64toint(charYYXXX, 5); } /** Evaluate to non-zero if \a ADDR is a valid address (not all 0s and not all 1s). */ -#define irc_in_addr_valid(ADDR) (((ADDR)->in6_16[0] && ((ADDR)->in6_16[0]) != 65535) \ - || (ADDR)->in6_16[1] != (ADDR)->in6_16[0] \ - || (ADDR)->in6_16[2] != (ADDR)->in6_16[0] \ - || (ADDR)->in6_16[3] != (ADDR)->in6_16[0] \ - || (ADDR)->in6_16[4] != (ADDR)->in6_16[0] \ - || (ADDR)->in6_16[5] != (ADDR)->in6_16[0] \ - || (ADDR)->in6_16[6] != (ADDR)->in6_16[0] \ - || (ADDR)->in6_16[7] != (ADDR)->in6_16[0]) +#define irc_in_addr_valid(ADDR) \ + (((ADDR)->in6_16[0] && ((ADDR)->in6_16[0]) != 65535) || \ + (ADDR)->in6_16[1] != (ADDR)->in6_16[0] || (ADDR)->in6_16[2] != (ADDR)->in6_16[0] || \ + (ADDR)->in6_16[3] != (ADDR)->in6_16[0] || (ADDR)->in6_16[4] != (ADDR)->in6_16[0] || \ + (ADDR)->in6_16[5] != (ADDR)->in6_16[0] || (ADDR)->in6_16[6] != (ADDR)->in6_16[0] || \ + (ADDR)->in6_16[7] != (ADDR)->in6_16[0]) /** Evaluate to non-zero if \a ADDR (of type struct irc_in_addr) is an IPv4 address. */ -#define irc_in_addr_is_ipv4(ADDR) (!(ADDR)->in6_16[0] && !(ADDR)->in6_16[1] && !(ADDR)->in6_16[2] \ - && !(ADDR)->in6_16[3] && !(ADDR)->in6_16[4] \ - && ((!(ADDR)->in6_16[5] && (ADDR)->in6_16[6]) \ - || (ADDR)->in6_16[5] == 65535)) +#define irc_in_addr_is_ipv4(ADDR) \ + (!(ADDR)->in6_16[0] && !(ADDR)->in6_16[1] && !(ADDR)->in6_16[2] && !(ADDR)->in6_16[3] && \ + !(ADDR)->in6_16[4] && \ + ((!(ADDR)->in6_16[5] && (ADDR)->in6_16[6]) || (ADDR)->in6_16[5] == 65535)) /** Evaluate to non-zero if \a A is a different IP than \a B. */ -#define irc_in_addr_cmp(A,B) (irc_in_addr_is_ipv4(A) ? ((A)->in6_16[6] != (B)->in6_16[6] \ - || (A)->in6_16[7] != (B)->in6_16[7] || !irc_in_addr_is_ipv4(B)) \ - : memcmp((A), (B), sizeof(struct irc_in_addr))) +#define irc_in_addr_cmp(A, B) \ + (irc_in_addr_is_ipv4(A) ? ((A)->in6_16[6] != (B)->in6_16[6] || \ + (A)->in6_16[7] != (B)->in6_16[7] || !irc_in_addr_is_ipv4(B)) \ + : memcmp((A), (B), sizeof(struct irc_in_addr))) /** Structure to store an IP address. */ -struct irc_in_addr -{ - unsigned short in6_16[8]; /**< IPv6 encoded parts, little-endian. */ +struct irc_in_addr { + unsigned short in6_16[8]; /**< IPv6 encoded parts, little-endian. */ }; /** Encode an IP address in the base64 used by numnicks. @@ -280,89 +252,88 @@ struct irc_in_addr * @param[in] count Number of bytes writable to \a buf. * @param[in] v6_ok If non-zero, peer understands base-64 encoded IPv6 addresses. */ -inline const char* iptobase64(char* buf, const struct irc_in_addr* addr, unsigned int count, int v6_ok) -{ - if (irc_in_addr_is_ipv4(addr)) { - assert(count >= 6); - inttobase64(buf, (ntohs(addr->in6_16[6]) << 16) | ntohs(addr->in6_16[7]), 6); - } else if (!v6_ok) { - assert(count >= 6); - if (addr->in6_16[0] == htons(0x2002)) - inttobase64(buf, (ntohs(addr->in6_16[1]) << 16) | ntohs(addr->in6_16[2]), 6); - else - strcpy(buf, "AAAAAA"); - } else { - unsigned int max_start, max_zeros, curr_zeros, zero, ii; - char *output = buf; - - assert(count >= 25); - /* Can start by printing out the leading non-zero parts. */ - for (ii = 0; (ii < 8) && (addr->in6_16[ii]); ++ii) { - inttobase64(output, ntohs(addr->in6_16[ii]), 3); - output += 3; - } - /* Find the longest run of zeros. */ - for (max_start = zero = ii, max_zeros = curr_zeros = 0; ii < 8; ++ii) { - if (!addr->in6_16[ii]) - curr_zeros++; - else if (curr_zeros > max_zeros) { - max_start = ii - curr_zeros; - max_zeros = curr_zeros; - curr_zeros = 0; - } - } - if (curr_zeros > max_zeros) { - max_start = ii - curr_zeros; - max_zeros = curr_zeros; - curr_zeros = 0; - } - /* Print the rest of the address */ - for (ii = zero; ii < 8; ) { - if ((ii == max_start) && max_zeros) { - *output++ = '_'; - ii += max_zeros; - } else { - inttobase64(output, ntohs(addr->in6_16[ii]), 3); - output += 3; - ii++; - } +inline const char* iptobase64(char* buf, const struct irc_in_addr* addr, unsigned int count, + int v6_ok) { + if (irc_in_addr_is_ipv4(addr)) { + assert(count >= 6); + inttobase64(buf, (ntohs(addr->in6_16[6]) << 16) | ntohs(addr->in6_16[7]), 6); + } else if (!v6_ok) { + assert(count >= 6); + if (addr->in6_16[0] == htons(0x2002)) + inttobase64(buf, (ntohs(addr->in6_16[1]) << 16) | ntohs(addr->in6_16[2]), 6); + else + strcpy(buf, "AAAAAA"); + } else { + unsigned int max_start, max_zeros, curr_zeros, zero, ii; + char* output = buf; + + assert(count >= 25); + /* Can start by printing out the leading non-zero parts. */ + for (ii = 0; (ii < 8) && (addr->in6_16[ii]); ++ii) { + inttobase64(output, ntohs(addr->in6_16[ii]), 3); + output += 3; + } + /* Find the longest run of zeros. */ + for (max_start = zero = ii, max_zeros = curr_zeros = 0; ii < 8; ++ii) { + if (!addr->in6_16[ii]) + curr_zeros++; + else if (curr_zeros > max_zeros) { + max_start = ii - curr_zeros; + max_zeros = curr_zeros; + curr_zeros = 0; + } + } + if (curr_zeros > max_zeros) { + max_start = ii - curr_zeros; + max_zeros = curr_zeros; + curr_zeros = 0; + } + /* Print the rest of the address */ + for (ii = zero; ii < 8;) { + if ((ii == max_start) && max_zeros) { + *output++ = '_'; + ii += max_zeros; + } else { + inttobase64(output, ntohs(addr->in6_16[ii]), 3); + output += 3; + ii++; + } + } + *output = '\0'; } - *output = '\0'; - } - return buf; + return buf; } /** Decode an IP address from base64. * @param[in] input Input buffer to decode. * @param[out] addr IP address structure to populate. */ -inline void base64toip(const char* input, struct irc_in_addr* addr) -{ - memset(addr, 0, sizeof(*addr)); - if (strlen(input) == 6) { - unsigned int in = base64toint(input); - /* An all-zero address should stay that way. */ - if (in) { - addr->in6_16[5] = htons(65535); - addr->in6_16[6] = htons(in >> 16); - addr->in6_16[7] = htons(in & 65535); +inline void base64toip(const char* input, struct irc_in_addr* addr) { + memset(addr, 0, sizeof(*addr)); + if (strlen(input) == 6) { + unsigned int in = base64toint(input); + /* An all-zero address should stay that way. */ + if (in) { + addr->in6_16[5] = htons(65535); + addr->in6_16[6] = htons(in >> 16); + addr->in6_16[7] = htons(in & 65535); + } + } else { + unsigned int pos = 0; + do { + if (*input == '_') { + unsigned int left; + for (left = (25 - strlen(input)) / 3 - pos; left; left--) + addr->in6_16[pos++] = 0; + input++; + } else { + unsigned short accum = convert2n[(unsigned char)*input++]; + accum = (accum << NUMNICKLOG) | convert2n[(unsigned char)*input++]; + accum = (accum << NUMNICKLOG) | convert2n[(unsigned char)*input++]; + addr->in6_16[pos++] = ntohs(accum); + } + } while (pos < 8); } - } else { - unsigned int pos = 0; - do { - if (*input == '_') { - unsigned int left; - for (left = (25 - strlen(input)) / 3 - pos; left; left--) - addr->in6_16[pos++] = 0; - input++; - } else { - unsigned short accum = convert2n[(unsigned char)*input++]; - accum = (accum << NUMNICKLOG) | convert2n[(unsigned char)*input++]; - accum = (accum << NUMNICKLOG) | convert2n[(unsigned char)*input++]; - addr->in6_16[pos++] = ntohs(accum); - } - } while (pos < 8); - } } /**ircu's ip_registry_canonicalize function: @@ -370,10 +341,9 @@ inline void base64toip(const char* input, struct irc_in_addr* addr) * addresses are translated into 6to4 form; IPv6 addresses are left * alone. */ -inline irc_in_addr convert_ipv4_to_ipv6_form (const struct irc_in_addr in) -{ +inline irc_in_addr convert_ipv4_to_ipv6_form(const struct irc_in_addr in) { if (irc_in_addr_is_ipv4(&in)) { - irc_in_addr out; + irc_in_addr out; out.in6_16[0] = htons(0x2002); out.in6_16[1] = in.in6_16[6]; out.in6_16[2] = in.in6_16[7]; @@ -381,7 +351,7 @@ inline irc_in_addr convert_ipv4_to_ipv6_form (const struct irc_in_addr in) out.in6_16[6] = out.in6_16[7] = 0; return out; } else - return in; + return in; } /** Attempt to parse an IPv4 address into a network-endian form. @@ -390,62 +360,71 @@ inline irc_in_addr convert_ipv4_to_ipv6_form (const struct irc_in_addr in) * @param[out] pbits Number of bits found in pbits. * @return Number of characters used from \a input, or 0 if the parse failed. */ -inline static unsigned int -ircd_aton_ip4(const char *input, unsigned int *output, unsigned char *pbits) -{ - unsigned int dots = 0, pos = 0, part = 0, ip = 0, bits; - - /* Intentionally no support for bizarre IPv4 formats (plain - * integers, octal or hex components) -- only vanilla dotted - * decimal quads. - */ - if (input[0] == '.') - return 0; - bits = 32; - while (1) switch (input[pos]) { - case '\0': - if (dots < 3) - return 0; - out: - ip |= part << (24 - 8 * dots); - *output = htonl(ip); - if (pbits) - *pbits = bits; - return pos; - case '.': - if (++dots > 3) - return 0; - if (input[++pos] == '.') - return 0; - ip |= part << (32 - 8 * dots); - part = 0; - if (input[pos] == '*') { - while (input[++pos] == '*' || input[pos] == '.') ; - if (input[pos] != '\0') +inline static unsigned int ircd_aton_ip4(const char* input, unsigned int* output, + unsigned char* pbits) { + unsigned int dots = 0, pos = 0, part = 0, ip = 0, bits; + + /* Intentionally no support for bizarre IPv4 formats (plain + * integers, octal or hex components) -- only vanilla dotted + * decimal quads. + */ + if (input[0] == '.') return 0; - if (pbits) - *pbits = dots * 8; - *output = htonl(ip); - return pos; - } - break; - case '/': - if (!pbits || !IsDigit(input[pos + 1])) - return 0; - for (bits = 0; IsDigit(input[++pos]); ) - bits = bits * 10 + input[pos] - '0'; - if (bits > 32) - return 0; - goto out; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - part = part * 10 + input[pos++] - '0'; - if (part > 255) - return 0; - break; - default: - return 0; - } + bits = 32; + while (1) + switch (input[pos]) { + case '\0': + if (dots < 3) + return 0; + out: + ip |= part << (24 - 8 * dots); + *output = htonl(ip); + if (pbits) + *pbits = bits; + return pos; + case '.': + if (++dots > 3) + return 0; + if (input[++pos] == '.') + return 0; + ip |= part << (32 - 8 * dots); + part = 0; + if (input[pos] == '*') { + while (input[++pos] == '*' || input[pos] == '.') + ; + if (input[pos] != '\0') + return 0; + if (pbits) + *pbits = dots * 8; + *output = htonl(ip); + return pos; + } + break; + case '/': + if (!pbits || !IsDigit(input[pos + 1])) + return 0; + for (bits = 0; IsDigit(input[++pos]);) + bits = bits * 10 + input[pos] - '0'; + if (bits > 32) + return 0; + goto out; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + part = part * 10 + input[pos++] - '0'; + if (part > 255) + return 0; + break; + default: + return 0; + } } /** Parse a numeric IPv4 or IPv6 address into an irc_in_addr. @@ -455,142 +434,163 @@ ircd_aton_ip4(const char *input, unsigned int *output, unsigned char *pbits) * @return Number of characters used from \a input, or 0 if the * address was unparseable or malformed. */ -inline int ipmask_parse(const char *input, struct irc_in_addr *ip, unsigned char *pbits) -{ - char *colon; - char *dot; - - assert(ip); - assert(input); - memset(ip, 0, sizeof(*ip)); - colon = (char*)strchr(input, ':'); - dot = (char*)strchr(input, '.'); - - if (colon && (!dot || (dot > colon))) { - unsigned int part = 0, pos = 0, ii = 0, colon = 8; - const char *part_start = NULL; - - /* Parse IPv6, possibly like ::127.0.0.1. - * This is pretty straightforward; the only trick is borrowed - * from Paul Vixie (BIND): when it sees a "::" continue as if - * it were a single ":", but note where it happened, and fill - * with zeros afterward. - */ - if (input[pos] == ':') { - if ((input[pos+1] != ':') || (input[pos+2] == ':')) - return 0; - colon = 0; - pos += 2; - part_start = input + pos; - } - while (ii < 8) switch (input[pos]) { - unsigned char chval; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - chval = input[pos] - '0'; - use_chval: - part = (part << 4) | chval; - if (part > 0xffff) - return 0; - pos++; - break; - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - chval = input[pos] - 'A' + 10; - goto use_chval; - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - chval = input[pos] - 'a' + 10; - goto use_chval; - case ':': - part_start = input + ++pos; - if (input[pos] == '.') - return 0; - if (input[pos] == '\0') - return 0; - ip->in6_16[ii++] = htons(part); - part = 0; - if (input[pos] == ':') { - if (colon < 8) - return 0; - if (ii == 8) - return 0; - colon = ii; - pos++; - } - break; - case '.': { - uint32_t ip4; - unsigned int len; - len = ircd_aton_ip4(part_start, &ip4, pbits); - if (!len || (ii > 6)) - return 0; - ip->in6_16[ii++] = htons(ntohl(ip4) >> 16); - ip->in6_16[ii++] = htons(ntohl(ip4) & 65535); - if (pbits) - *pbits += 96; - pos = part_start + len - input; - goto finish; - } - case '/': - if (!pbits || !IsDigit(input[pos + 1])) - return 0; - ip->in6_16[ii++] = htons(part); - for (part = 0; IsDigit(input[++pos]); ) - part = part * 10 + input[pos] - '0'; - if (part > 128) - return 0; - *pbits = part; - goto finish; - case '*': - while (input[++pos] == '*' || input[pos] == ':') ; - if (input[pos] != '\0' || colon < 8) - return 0; - if (part && ii < 8) - ip->in6_16[ii++] = htons(part); - if (pbits) - *pbits = ii * 16; - return pos; - case '\0': - ip->in6_16[ii++] = htons(part); - if (colon == 8 && ii < 8) - return 0; - if (pbits) - *pbits = 128; - goto finish; - default: - return 0; - } - if (input[pos] != '\0') - return 0; - finish: - if (colon < 8) { - unsigned int jj; - /* Shift stuff after "::" up and fill middle with zeros. */ - for (jj = 0; jj < ii - colon; jj++) - ip->in6_16[7 - jj] = ip->in6_16[ii - jj - 1]; - for (jj = 0; jj < 8 - ii; jj++) - ip->in6_16[colon + jj] = 0; - } - return pos; - } else if (dot || strchr(input, '/')) { - unsigned int addr; - int len = ircd_aton_ip4(input, &addr, pbits); - if (len) { - ip->in6_16[5] = htons(65535); - ip->in6_16[6] = htons(ntohl(addr) >> 16); - ip->in6_16[7] = htons(ntohl(addr) & 65535); - if (pbits) - *pbits += 96; - } - return len; - } else if (input[0] == '*') { - unsigned int pos = 0; - while (input[++pos] == '*') ; - if (input[pos] != '\0') - return 0; - if (pbits) - *pbits = 0; - return pos; - } else return 0; /* parse failed */ +inline int ipmask_parse(const char* input, struct irc_in_addr* ip, unsigned char* pbits) { + char* colon; + char* dot; + + assert(ip); + assert(input); + memset(ip, 0, sizeof(*ip)); + colon = (char*)strchr(input, ':'); + dot = (char*)strchr(input, '.'); + + if (colon && (!dot || (dot > colon))) { + unsigned int part = 0, pos = 0, ii = 0, colon = 8; + const char* part_start = NULL; + + /* Parse IPv6, possibly like ::127.0.0.1. + * This is pretty straightforward; the only trick is borrowed + * from Paul Vixie (BIND): when it sees a "::" continue as if + * it were a single ":", but note where it happened, and fill + * with zeros afterward. + */ + if (input[pos] == ':') { + if ((input[pos + 1] != ':') || (input[pos + 2] == ':')) + return 0; + colon = 0; + pos += 2; + part_start = input + pos; + } + while (ii < 8) + switch (input[pos]) { + unsigned char chval; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + chval = input[pos] - '0'; + use_chval: + part = (part << 4) | chval; + if (part > 0xffff) + return 0; + pos++; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + chval = input[pos] - 'A' + 10; + goto use_chval; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + chval = input[pos] - 'a' + 10; + goto use_chval; + case ':': + part_start = input + ++pos; + if (input[pos] == '.') + return 0; + if (input[pos] == '\0') + return 0; + ip->in6_16[ii++] = htons(part); + part = 0; + if (input[pos] == ':') { + if (colon < 8) + return 0; + if (ii == 8) + return 0; + colon = ii; + pos++; + } + break; + case '.': { + uint32_t ip4; + unsigned int len; + len = ircd_aton_ip4(part_start, &ip4, pbits); + if (!len || (ii > 6)) + return 0; + ip->in6_16[ii++] = htons(ntohl(ip4) >> 16); + ip->in6_16[ii++] = htons(ntohl(ip4) & 65535); + if (pbits) + *pbits += 96; + pos = part_start + len - input; + goto finish; + } + case '/': + if (!pbits || !IsDigit(input[pos + 1])) + return 0; + ip->in6_16[ii++] = htons(part); + for (part = 0; IsDigit(input[++pos]);) + part = part * 10 + input[pos] - '0'; + if (part > 128) + return 0; + *pbits = part; + goto finish; + case '*': + while (input[++pos] == '*' || input[pos] == ':') + ; + if (input[pos] != '\0' || colon < 8) + return 0; + if (part && ii < 8) + ip->in6_16[ii++] = htons(part); + if (pbits) + *pbits = ii * 16; + return pos; + case '\0': + ip->in6_16[ii++] = htons(part); + if (colon == 8 && ii < 8) + return 0; + if (pbits) + *pbits = 128; + goto finish; + default: + return 0; + } + if (input[pos] != '\0') + return 0; + finish: + if (colon < 8) { + unsigned int jj; + /* Shift stuff after "::" up and fill middle with zeros. */ + for (jj = 0; jj < ii - colon; jj++) + ip->in6_16[7 - jj] = ip->in6_16[ii - jj - 1]; + for (jj = 0; jj < 8 - ii; jj++) + ip->in6_16[colon + jj] = 0; + } + return pos; + } else if (dot || strchr(input, '/')) { + unsigned int addr; + int len = ircd_aton_ip4(input, &addr, pbits); + if (len) { + ip->in6_16[5] = htons(65535); + ip->in6_16[6] = htons(ntohl(addr) >> 16); + ip->in6_16[7] = htons(ntohl(addr) & 65535); + if (pbits) + *pbits += 96; + } + return len; + } else if (input[0] == '*') { + unsigned int pos = 0; + while (input[++pos] == '*') + ; + if (input[pos] != '\0') + return 0; + if (pbits) + *pbits = 0; + return pos; + } else + return 0; /* parse failed */ } /** Convert an IP address to printable ASCII form. @@ -598,77 +598,79 @@ inline int ipmask_parse(const char *input, struct irc_in_addr *ip, unsigned char * @param[in] in Address to format. * @return Pointer to the output buffer \a buf. */ -inline const char* ircd_ntoa_r(char* buf, const struct irc_in_addr* in, bool unfolded = false) -{ +inline const char* ircd_ntoa_r(char* buf, const struct irc_in_addr* in, bool unfolded = false) { assert(buf != NULL); assert(in != NULL); if (irc_in_addr_is_ipv4(in)) { - unsigned int pos, len; - unsigned char *pch; - - pch = (unsigned char*)&in->in6_16[6]; - len = strlen(IpQuadTab[*pch]); - memcpy(buf, IpQuadTab[*pch++], len); - pos = len; - buf[pos++] = '.'; - len = strlen(IpQuadTab[*pch]); - memcpy(buf+pos, IpQuadTab[*pch++], len); - pos += len; - buf[pos++] = '.'; - len = strlen(IpQuadTab[*pch]); - memcpy(buf+pos, IpQuadTab[*pch++], len); - pos += len; - buf[pos++] = '.'; - len = strlen(IpQuadTab[*pch]); - memcpy(buf+pos, IpQuadTab[*pch++], len); - buf[pos + len] = '\0'; - return buf; + unsigned int pos, len; + unsigned char* pch; + + pch = (unsigned char*)&in->in6_16[6]; + len = strlen(IpQuadTab[*pch]); + memcpy(buf, IpQuadTab[*pch++], len); + pos = len; + buf[pos++] = '.'; + len = strlen(IpQuadTab[*pch]); + memcpy(buf + pos, IpQuadTab[*pch++], len); + pos += len; + buf[pos++] = '.'; + len = strlen(IpQuadTab[*pch]); + memcpy(buf + pos, IpQuadTab[*pch++], len); + pos += len; + buf[pos++] = '.'; + len = strlen(IpQuadTab[*pch]); + memcpy(buf + pos, IpQuadTab[*pch++], len); + buf[pos + len] = '\0'; + return buf; } else { - static const char hexdigits[] = "0123456789abcdef"; - unsigned int pos, part, max_start, max_zeros, curr_zeros, ii; - - /* Find longest run of zeros. */ - for (max_start = ii = 1, max_zeros = curr_zeros = 0; ii < 8; ++ii) { - if (!in->in6_16[ii]) - curr_zeros++; - else if (curr_zeros > max_zeros) { - max_start = ii - curr_zeros; - max_zeros = curr_zeros; - curr_zeros = 0; + static const char hexdigits[] = "0123456789abcdef"; + unsigned int pos, part, max_start, max_zeros, curr_zeros, ii; + + /* Find longest run of zeros. */ + for (max_start = ii = 1, max_zeros = curr_zeros = 0; ii < 8; ++ii) { + if (!in->in6_16[ii]) + curr_zeros++; + else if (curr_zeros > max_zeros) { + max_start = ii - curr_zeros; + max_zeros = curr_zeros; + curr_zeros = 0; + } + } + if (curr_zeros > max_zeros) { + max_start = ii - curr_zeros; + max_zeros = curr_zeros; } - } - if (curr_zeros > max_zeros) { - max_start = ii - curr_zeros; - max_zeros = curr_zeros; - } - /* Print out address. */ + /* Print out address. */ /** Append \a CH to the output buffer. */ -#define APPEND(CH) do { buf[pos++] = (CH); } while (0) - for (pos = ii = 0; (ii < 8); ++ii) { - if (!unfolded) - if ((max_zeros > 0) && (ii == max_start)) { - APPEND(':'); - ii += max_zeros - 1; - continue; +#define APPEND(CH) \ + do { \ + buf[pos++] = (CH); \ + } while (0) + for (pos = ii = 0; (ii < 8); ++ii) { + if (!unfolded) + if ((max_zeros > 0) && (ii == max_start)) { + APPEND(':'); + ii += max_zeros - 1; + continue; + } + part = ntohs(in->in6_16[ii]); + if ((part >= 0x1000) || (unfolded)) + APPEND(hexdigits[part >> 12]); + if ((part >= 0x100) || (unfolded)) + APPEND(hexdigits[(part >> 8) & 15]); + if ((part >= 0x10) || (unfolded)) + APPEND(hexdigits[(part >> 4) & 15]); + APPEND(hexdigits[part & 15]); + if (ii < 7) + APPEND(':'); } - part = ntohs(in->in6_16[ii]); - if ((part >= 0x1000) || (unfolded)) - APPEND(hexdigits[part >> 12]); - if ((part >= 0x100) || (unfolded)) - APPEND(hexdigits[(part >> 8) & 15]); - if ((part >= 0x10) || (unfolded)) - APPEND(hexdigits[(part >> 4) & 15]); - APPEND(hexdigits[part & 15]); - if (ii < 7) - APPEND(':'); - } #undef APPEND - /* Nul terminate and return number of characters used. */ - buf[pos++] = '\0'; - return buf; + /* Nul terminate and return number of characters used. */ + buf[pos++] = '\0'; + return buf; } } @@ -677,33 +679,29 @@ inline const char* ircd_ntoa_r(char* buf, const struct irc_in_addr* in, bool unf * @param[in] in Address to convert. * @return Pointer to a static buffer containing the readable form. */ -inline const char* ircd_ntoa(const struct irc_in_addr* in, bool unfolded = false) -{ - static char buf[SOCKIPLEN]; - return ircd_ntoa_r(buf, in, unfolded); +inline const char* ircd_ntoa(const struct irc_in_addr* in, bool unfolded = false) { + static char buf[SOCKIPLEN]; + return ircd_ntoa_r(buf, in, unfolded); } -///Temporary (removable) functions -inline irc_in_addr NullIPv6() -{ - irc_in_addr res; - for (unsigned short i = 0; i < 8; i ++) - res.in6_16[i] = 0; - return res; +/// Temporary (removable) functions +inline irc_in_addr NullIPv6() { + irc_in_addr res; + for (unsigned short i = 0; i < 8; i++) + res.in6_16[i] = 0; + return res; } ///////////end///////////////// /////// Test functions //////// -inline std::string DecToBin(unsigned short number) -{ +inline std::string DecToBin(unsigned short number) { std::string result = ""; unsigned short count = 0; short space = 0; const size_t size = sizeof(number) * 8; - do - { - if ((number & 1) == 0 ) + do { + if ((number & 1) == 0) result += "0"; else result += "1"; @@ -711,41 +709,38 @@ inline std::string DecToBin(unsigned short number) space++; count++; - if ((space == 4) && (count < size)) - { - result += ' '; - space = 0; + if ((space == 4) && (count < size)) { + result += ' '; + space = 0; } number >>= 1; - } while ( number ); + } while (number); - for ( ; count < size; count++) - { - if (space == 4) - { - result += ' '; - space = 0; + for (; count < size; count++) { + if (space == 4) { + result += ' '; + space = 0; } - space++; + space++; result += '0'; - } + } std::reverse(result.begin(), result.end()); return result; } -//Legacy function -inline unsigned int convertStrIPtoInt(std::string IP) -{ - int client_addr[4] = { 0 }; - sscanf(IP.c_str(), "%d.%d.%d.%d", &client_addr[0], &client_addr[1], &client_addr[2], &client_addr[3]); - return ntohl((client_addr[0]) | (client_addr[1] << 8) | (client_addr[2] << 16) | (client_addr[3] << 24)); +// Legacy function +inline unsigned int convertStrIPtoInt(std::string IP) { + int client_addr[4] = {0}; + sscanf(IP.c_str(), "%d.%d.%d.%d", &client_addr[0], &client_addr[1], &client_addr[2], + &client_addr[3]); + return ntohl((client_addr[0]) | (client_addr[1] << 8) | (client_addr[2] << 16) | + (client_addr[3] << 24)); } -//Legacy function -inline std::string convertIntToStrIP(unsigned IP) -{ +// Legacy function +inline std::string convertIntToStrIP(unsigned IP) { unsigned mask_ip = htonl(IP); struct in_addr tmp_ip; tmp_ip.s_addr = mask_ip; @@ -754,16 +749,15 @@ inline std::string convertIntToStrIP(unsigned IP) return (std::string)client_ip; } -inline std::string print_irc_in_addr(const irc_in_addr& IP) -{ - std::string res = DecToBin(ntohs(IP.in6_16[0])); - for (unsigned short i = 1; i < 8; i++) - res += "|" + DecToBin(ntohs(IP.in6_16[i])); - return res; +inline std::string print_irc_in_addr(const irc_in_addr& IP) { + std::string res = DecToBin(ntohs(IP.in6_16[0])); + for (unsigned short i = 1; i < 8; i++) + res += "|" + DecToBin(ntohs(IP.in6_16[i])); + return res; } /////// Test functions end //////// -//inline irc_in_addr irc_IPCIDRMinIP(const std::string& IP, unsigned CClonesCIDR = 120) +// inline irc_in_addr irc_IPCIDRMinIP(const std::string& IP, unsigned CClonesCIDR = 120) //{ // unsigned char maskbits; // irc_in_addr ircip; @@ -780,38 +774,35 @@ inline std::string print_irc_in_addr(const irc_in_addr& IP) // ip16 <<= rem; // ircip.in6_16[7-i] = htons(ip16); // return ircip; -//} - -inline irc_in_addr irc_in6_CIDRMinIP(irc_in_addr ircip, unsigned CClonesCIDR = 120) -{ - unsigned int quot = (128 - CClonesCIDR)/16; - unsigned int rem = (128 - CClonesCIDR) % 16; - unsigned int i; - for (i = 0; i < quot; i++) - ircip.in6_16[7-i] = 0; - if (CClonesCIDR == 0) /* We have i=8 here. Not something we want, do we? */ - i--; - unsigned short ip16 = ntohs(ircip.in6_16[7-i]); - ip16 >>= rem; - ip16 <<= rem; - ircip.in6_16[7-i] = htons(ip16); - return ircip; +// } + +inline irc_in_addr irc_in6_CIDRMinIP(irc_in_addr ircip, unsigned CClonesCIDR = 120) { + unsigned int quot = (128 - CClonesCIDR) / 16; + unsigned int rem = (128 - CClonesCIDR) % 16; + unsigned int i; + for (i = 0; i < quot; i++) + ircip.in6_16[7 - i] = 0; + if (CClonesCIDR == 0) /* We have i=8 here. Not something we want, do we? */ + i--; + unsigned short ip16 = ntohs(ircip.in6_16[7 - i]); + ip16 >>= rem; + ip16 <<= rem; + ircip.in6_16[7 - i] = htons(ip16); + return ircip; } -inline std::string IPCIDRMinIP(irc_in_addr ircip, unsigned CClonesCIDR = 120) -{ - irc_in_addr ip6 = irc_in6_CIDRMinIP(ircip, CClonesCIDR); - return (std::string)ircd_ntoa(&ip6); +inline std::string IPCIDRMinIP(irc_in_addr ircip, unsigned CClonesCIDR = 120) { + irc_in_addr ip6 = irc_in6_CIDRMinIP(ircip, CClonesCIDR); + return (std::string)ircd_ntoa(&ip6); } -inline std::string IPCIDRMinIP(const std::string& IP, unsigned CClonesCIDR = 120) -{ - irc_in_addr ircip; - unsigned char ipmask_len; - if (!ipmask_parse(IP.c_str(), &ircip, &ipmask_len)) - return std::string(); +inline std::string IPCIDRMinIP(const std::string& IP, unsigned CClonesCIDR = 120) { + irc_in_addr ircip; + unsigned char ipmask_len; + if (!ipmask_parse(IP.c_str(), &ircip, &ipmask_len)) + return std::string(); - return IPCIDRMinIP(ircip,CClonesCIDR); + return IPCIDRMinIP(ircip, CClonesCIDR); } } // namespace gnuworld diff --git a/include/ServerCommandHandler.h b/include/ServerCommandHandler.h index 348b7271..ff7b4fc0 100644 --- a/include/ServerCommandHandler.h +++ b/include/ServerCommandHandler.h @@ -20,61 +20,44 @@ */ #ifndef __SERVERCOMMANDHANDLER_H -#define __SERVERCOMMANDHANDLER_H "$Id: ServerCommandHandler.h,v 1.3 2003/06/28 01:21:18 dan_karrels Exp $" +#define __SERVERCOMMANDHANDLER_H \ + "$Id: ServerCommandHandler.h,v 1.3 2003/06/28 01:21:18 dan_karrels Exp $" -#include "xparameters.h" -#include "ELog.h" +#include "xparameters.h" +#include "ELog.h" -namespace gnuworld -{ +namespace gnuworld { -class xServer ; +class xServer; -class ServerCommandHandler -{ -protected: - xServer *theServer ; +class ServerCommandHandler { + protected: + xServer* theServer; -public: + public: + ServerCommandHandler(xServer* _theServer) : theServer(_theServer) {} + virtual ~ServerCommandHandler() {} - ServerCommandHandler( xServer* _theServer ) - : theServer( _theServer ) - {} - virtual ~ServerCommandHandler() - {} + virtual bool Execute(const xParameters&) = 0; +}; - virtual bool Execute( const xParameters& ) = 0 ; -} ; +#define CREATE_HANDLER(name) \ + class name : public ServerCommandHandler { \ + public: \ + name(xServer* theServer) : ServerCommandHandler(theServer) {} \ + virtual ~name() {} \ + \ + virtual bool Execute(const xParameters&); \ + }; \ + \ + extern "C" { \ + name* _gnuwinit_##name(xServer* theServer) { return new name(theServer); } \ + } -#define CREATE_HANDLER(name) \ -class name : public ServerCommandHandler \ -{ \ -public: \ - name( xServer* theServer ) \ - : ServerCommandHandler( theServer ) \ - {} \ - virtual ~name() \ - {} \ -\ - virtual bool Execute( const xParameters& ) ; \ -} ; \ -\ -extern "C" \ -{ \ - name* _gnuwinit_##name( xServer* theServer ) \ - { \ - return new name( theServer ) ; \ - } \ -} - -#define CREATE_LOADER(name) \ -extern "C" \ -{ \ - name* _gnuwinit_##name( xServer* theServer ) \ - { \ - return new name( theServer ) ; \ - } \ -} +#define CREATE_LOADER(name) \ + extern "C" { \ + name* _gnuwinit_##name(xServer* theServer) { return new name(theServer); } \ + } } // namespace gnuworld diff --git a/include/ServerTimerHandlers.h b/include/ServerTimerHandlers.h index 3f266b59..a854b364 100644 --- a/include/ServerTimerHandlers.h +++ b/include/ServerTimerHandlers.h @@ -23,15 +23,14 @@ #ifndef __SERVERTIMERHANDLERS_H #define __SERVERTIMERHANDLERS_H "$Id: ServerTimerHandlers.h,v 1.6 2004/05/19 19:46:33 jeekay Exp $" -#include "TimerHandler.h" +#include "TimerHandler.h" -#include +#include -namespace gnuworld -{ +namespace gnuworld { /// Forward declaration of the xServer class -class xServer ; +class xServer; /** * This is the abstract base class from which each timer to be used @@ -40,67 +39,60 @@ class xServer ; * OnTimer(). The OnTimer() method will be called by the timer * system when the timer expires. */ -class ServerTimerHandler : public TimerHandler -{ -public: - /** - * The constructor receives a pointer to the server core, - * and the interval at which to reschedule the timer, - * if the timer handler chooses to do so. - */ - ServerTimerHandler( xServer* _theServer, time_t _updateInterval ) - : theServer( _theServer ), - updateInterval( _updateInterval ) - {} +class ServerTimerHandler : public TimerHandler { + public: + /** + * The constructor receives a pointer to the server core, + * and the interval at which to reschedule the timer, + * if the timer handler chooses to do so. + */ + ServerTimerHandler(xServer* _theServer, time_t _updateInterval) + : theServer(_theServer), updateInterval(_updateInterval) {} - /** - * This is the virtual destructor, which currently does - * nothing, but must be present in a class hierarchy. - */ - virtual ~ServerTimerHandler() - {} + /** + * This is the virtual destructor, which currently does + * nothing, but must be present in a class hierarchy. + */ + virtual ~ServerTimerHandler() {} - /** - * This method is called when the timer expires. The timerID - * argument is registration ID of the timer. The void* - * argument is a pointer to whatever data was given during - * timer registration. Make sure that this data is placed - * into persistent memory, otherwise a segmentation fault - * may occur when running OnTimer(). - */ - virtual void OnTimer( const timerID& , void* ) = 0 ; + /** + * This method is called when the timer expires. The timerID + * argument is registration ID of the timer. The void* + * argument is a pointer to whatever data was given during + * timer registration. Make sure that this data is placed + * into persistent memory, otherwise a segmentation fault + * may occur when running OnTimer(). + */ + virtual void OnTimer(const timerID&, void*) = 0; -protected: + protected: + /** + * This is a pointer to the server core. + */ + xServer* theServer; - /** - * This is a pointer to the server core. - */ - xServer* theServer ; - - /** - * This is the timer rescheduling interval. - */ - time_t updateInterval ; -} ; + /** + * This is the timer rescheduling interval. + */ + time_t updateInterval; +}; /** * This macro is used to create a generic subclass of class * ServerTimerHandler, and to declare the OnTimer() method as * concrete. */ -#define SUBCLASS_SERVERTIMERHANDLER(className)\ -class className##Timer : public ServerTimerHandler \ -{ \ -public: \ - className##Timer( xServer* theServer, time_t updateInterval ) \ - : ServerTimerHandler( theServer, updateInterval ) \ - {} \ - virtual ~className##Timer() {} \ - virtual void OnTimer( const timerID& , void* ) ; \ -} ; +#define SUBCLASS_SERVERTIMERHANDLER(className) \ + class className##Timer : public ServerTimerHandler { \ + public: \ + className##Timer(xServer* theServer, time_t updateInterval) \ + : ServerTimerHandler(theServer, updateInterval) {} \ + virtual ~className##Timer() {} \ + virtual void OnTimer(const timerID&, void*); \ + }; -SUBCLASS_SERVERTIMERHANDLER( GlineUpdate ) -SUBCLASS_SERVERTIMERHANDLER( PING ) +SUBCLASS_SERVERTIMERHANDLER(GlineUpdate) +SUBCLASS_SERVERTIMERHANDLER(PING) } // namespace gnuworld diff --git a/include/Timer.h b/include/Timer.h index 96051a72..06816d09 100644 --- a/include/Timer.h +++ b/include/Timer.h @@ -26,26 +26,34 @@ namespace gnuworld { class Timer { -public: - inline Timer(bool autostart = true) - { if(autostart) { Start(); } } - - inline void Start() - { gettimeofday(&startTime, 0); } - inline void Stop() - { gettimeofday(&stopTime, 0); } - inline unsigned int getTimeMS() - { return (stopTime.tv_sec - startTime.tv_sec) * 1000 + - (stopTime.tv_usec - startTime.tv_usec) / 1000; } - inline unsigned long getTimeUS() - { return (stopTime.tv_sec - startTime.tv_sec) * 1000000 + - (stopTime.tv_usec - startTime.tv_usec); } - inline unsigned int stopTimeMS() - { Stop(); return getTimeMS(); } - inline unsigned long stopTimeUS() - { Stop(); return getTimeUS(); } -protected: - struct timeval startTime, stopTime; + public: + inline Timer(bool autostart = true) { + if (autostart) { + Start(); + } + } + + inline void Start() { gettimeofday(&startTime, 0); } + inline void Stop() { gettimeofday(&stopTime, 0); } + inline unsigned int getTimeMS() { + return (stopTime.tv_sec - startTime.tv_sec) * 1000 + + (stopTime.tv_usec - startTime.tv_usec) / 1000; + } + inline unsigned long getTimeUS() { + return (stopTime.tv_sec - startTime.tv_sec) * 1000000 + + (stopTime.tv_usec - startTime.tv_usec); + } + inline unsigned int stopTimeMS() { + Stop(); + return getTimeMS(); + } + inline unsigned long stopTimeUS() { + Stop(); + return getTimeUS(); + } + + protected: + struct timeval startTime, stopTime; }; // class Timer } // namespace gnuworld diff --git a/include/TimerHandler.h b/include/TimerHandler.h index c6e6f27e..ed3d3a38 100644 --- a/include/TimerHandler.h +++ b/include/TimerHandler.h @@ -23,8 +23,7 @@ #ifndef __TIMERHANDLER_H #define __TIMERHANDLER_H "$Id: TimerHandler.h,v 1.6 2004/05/19 19:46:33 jeekay Exp $" -namespace gnuworld -{ +namespace gnuworld { /** * This is the abstract base class used in the GNUWorld timer system. @@ -32,56 +31,52 @@ namespace gnuworld * abstract method OnTimer(). The OnTimer() method will be called * by the timer system when the timer has expired. */ -class TimerHandler -{ +class TimerHandler { -public: + public: + /** + * The constructor does nothing. + */ + TimerHandler() {} - /** - * The constructor does nothing. - */ - TimerHandler() {} + /** + * The destructor does nothing. + */ + virtual ~TimerHandler() {} - /** - * The destructor does nothing. - */ - virtual ~TimerHandler() {} + /** + * The type used to represent timer events. + */ + typedef unsigned int timerID; - /** - * The type used to represent timer events. - */ - typedef unsigned int timerID ; + /** + * Handle a timer event. The first argument is the + * handle for the timer registration, and the second + * is the argument that was passed when registering the + * timer. + */ + virtual void OnTimer(const timerID&, void*) = 0; - /** - * Handle a timer event. The first argument is the - * handle for the timer registration, and the second - * is the argument that was passed when registering the - * timer. - */ - virtual void OnTimer( const timerID& , void* ) = 0 ; - - /** - * This method is invoked when the server removes a - * timed event without being requested by the TimerHandler. - * This can happen when the TimerHandler is being destroyed, - * but has not removed all of its timers yet. - */ - virtual void OnTimerDestroy( timerID, void * ) {} - -} ; + /** + * This method is invoked when the server removes a + * timed event without being requested by the TimerHandler. + * This can happen when the TimerHandler is being destroyed, + * but has not removed all of its timers yet. + */ + virtual void OnTimerDestroy(timerID, void*) {} +}; /** * This macro is meant to assist in creating new subclasses of * the TimerHandler class. */ -#define SUBCLASS_TIMERHANDLER(className) \ -class className##Timer : public TimerHandler \ -{ \ -public: \ -className##Timer() {} \ -virtual ~className##Timer() {} \ -virtual void OnTimer( timerID, void* ) ; \ -} ; +#define SUBCLASS_TIMERHANDLER(className) \ + class className##Timer : public TimerHandler { \ + public: \ + className##Timer() {} \ + virtual ~className##Timer() {} \ + virtual void OnTimer(timerID, void*); \ + }; } // namespace gnuworld diff --git a/include/UnloadClientTimerHandler.h b/include/UnloadClientTimerHandler.h index bd92ac0d..09fa3dbd 100644 --- a/include/UnloadClientTimerHandler.h +++ b/include/UnloadClientTimerHandler.h @@ -21,61 +21,52 @@ */ #ifndef __UNLOADCLIENTTIMERHANDLER_H -#define __UNLOADCLIENTTIMERHANDLER_H "$Id: UnloadClientTimerHandler.h,v 1.7 2004/05/19 19:46:33 jeekay Exp $" +#define __UNLOADCLIENTTIMERHANDLER_H \ + "$Id: UnloadClientTimerHandler.h,v 1.7 2004/05/19 19:46:33 jeekay Exp $" -#include +#include -#include "ServerTimerHandlers.h" +#include "ServerTimerHandlers.h" -namespace gnuworld -{ +namespace gnuworld { -class xServer ; +class xServer; /** * This class is responsible for unloading an xClient at a particular time. * This delayed unload allows the xClient to finish cleanup work as * requested by the server event system. */ -class UnloadClientTimerHandler : public ServerTimerHandler -{ - -protected: - - /// The xClient module name - std::string moduleName ; - - /// The reason for the unload, will be delivered to the xClient - std::string reason ; - -public: - - /** - * The constructor receives the follow arguments: - * - A pointer to the global xServer instance - * - The xClient module name - * - The reason for unloading the client. - */ - UnloadClientTimerHandler( xServer* theServer, - const std::string& _moduleName, - const std::string& _reason ) - : ServerTimerHandler( theServer, 0), - moduleName( _moduleName ), - reason( _reason ) - {} - - /** - * Destructor, not much to talk about here. - */ - virtual ~UnloadClientTimerHandler() - {} - - /** - * The method that is called when it's time to unload the client. - */ - virtual void OnTimer( const timerID& , void* ) ; - -} ; +class UnloadClientTimerHandler : public ServerTimerHandler { + + protected: + /// The xClient module name + std::string moduleName; + + /// The reason for the unload, will be delivered to the xClient + std::string reason; + + public: + /** + * The constructor receives the follow arguments: + * - A pointer to the global xServer instance + * - The xClient module name + * - The reason for unloading the client. + */ + UnloadClientTimerHandler(xServer* theServer, const std::string& _moduleName, + const std::string& _reason) + : ServerTimerHandler(theServer, 0), moduleName(_moduleName), reason(_reason) {} + + /** + * Destructor, not much to talk about here. + */ + virtual ~UnloadClientTimerHandler() {} + + /** + * The method that is called when it's time to unload the client. + */ + virtual void OnTimer(const timerID&, void*); +}; } // namespace gnuworld diff --git a/include/client.h b/include/client.h index 37f2729b..9e81ad34 100644 --- a/include/client.h +++ b/include/client.h @@ -7,9 +7,9 @@ * 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 + * 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. * @@ -24,19 +24,18 @@ #ifndef __CLIENT_H #define __CLIENT_H "$Id: client.h,v 1.59 2005/09/29 17:40:06 kewlio Exp $" -#include -#include -#include +#include +#include +#include -#include "NetworkTarget.h" -#include "server.h" -#include "iClient.h" -#include "events.h" -#include "TimerHandler.h" -#include "logger.h" +#include "NetworkTarget.h" +#include "server.h" +#include "iClient.h" +#include "events.h" +#include "TimerHandler.h" +#include "logger.h" -namespace gnuworld -{ +namespace gnuworld { /** * This is the public concrete base class that represents @@ -47,985 +46,885 @@ namespace gnuworld * This has proven to be extremely easy: I built a functioning * services client in 11 minutes, though it didn't do much :) */ -class xClient : public TimerHandler, public NetworkTarget -{ - /// Let xServer access our protected members. - friend class xServer ; - - /// Let xNetwork access our protected members. - friend class xNetwork ; - -public: - - /** - * Declare the type for the xClient's internal - * mode representation. Note that this typedef - * is deliberately public. - */ - typedef iClient::modeType modeType ; - - /** - * Construct a new xClient from a config file. - */ - xClient( const std::string& ) ; - - /** - * The primary purpose of this method is do call the - * deallocation methods of any xClient's which are storing - * data in the customDataMap. - * Client responsibilities: - * Removing all timers registered with the xServer - * Removing all custom data members held in the iClient's - */ - virtual ~xClient() ; - - /** - * This method must call xServer::BurstChannel() with appropriate - * channel modes for any channel it wishes to own. - */ - virtual void BurstChannels() ; - - /** - * BurstGlines is called before eob, for the client to burst - * all of its glines - */ - virtual bool BurstGlines() ; - - /** - * Kill will issue a KILL command to the network for - * the given iClient (network generic client). - */ - virtual bool Kill( iClient*, const std::string& ) ; - virtual bool Kill( iClient*, const std::string&, bool ) ; - - /** - * QuoteAsServer will send data to the network as the - * server itself. Try to avoid using this method. - */ - virtual bool QuoteAsServer( const std::string& Command ); - - /** - * Write a string of data to the network. - */ - virtual bool Write( const std::string& s ) - { return QuoteAsServer( s ) ; } - - /** - * Write a string of data to the network. - */ - virtual bool Write( const std::stringstream& s ) - { return QuoteAsServer( s.str() ) ; } - - /** - * Write a variable length argument list to the network. - */ - virtual bool Write( const char*, ... ) ; - - /** - * This method will change modes in a channel. - * If the fourth argument is true, then the modes will be - * changed as the server, otherwise the client will set - * the modes (joining and parting the channel if necessary). - * Removing mode 'k' expects an argument, but it doesn't matter - * what the argument is. - * Removing mode 'l' requires NO argument to be issued. - */ - virtual bool Mode( const std::string& chanName, - const std::string& modes, - const std::string& args, - bool modeAsServer = false ) ; - - /** - * This method will change modes in a channel. - * If the fourth argument is true, then the modes will be - * changed as the server, otherwise the client will set - * the modes (joining and parting the channel if necessary). - * Removing mode 'k' expects an argument, but it doesn't matter - * what the argument is. - * Removing mode 'l' requires NO argument to be issued. - */ - virtual bool Mode( Channel*, - const std::string& modes, - const std::string& args, - bool modeAsServer = false ) ; - - /** - * Mode is used to set the bot's modes. If connected to the - * network already, these new modes will be written to the - * network. - */ - virtual bool Mode( const std::string& Mode ) ; - - /** - * Issue a clearmode (CM) for the given channel and update - * all internal structures. - * This method will also post a channel event for each - * mode. - */ - virtual bool ClearMode( Channel* theChan, - const std::string& modes, - bool modeAsServer = false ) ; - - /** - * OnConnect is called when the server connects to the - * network, during burst time. The client's NICK - * information has already been sent to the network. - */ - virtual void OnConnect() ; - - /** - * Invoked when the uplink has been terminated. - */ - virtual void OnDisconnect() ; - - /** - * This method is invoked when the server has been requested - * to shutdown. If currently connected to the network, this - * method gives xClient's a chance to gracefully QUIT from - * the network, or whatever other processing is useful. - * To force data to be written before final shutdown (again, - * if connected), set xServer::FlushData(). - * Timers will be executed after this method is invoked, once, - * depending upon target time of course :) - */ - virtual void OnShutdown( const std::string& reason ) ; - - /** - * Invoked after the client has been loaded, perform - * initialization stuff here. - */ - virtual void OnAttach() ; - - /** - * This method will be invoked when the server is unloading - * the client for whatever reason. - */ - virtual void OnDetach( const std::string& = - std::string( "Server Shutdown") ) ; - - /** - * OnKill() is called when the client has been KILL'd. - */ - virtual void OnKill() ; - - /** - * This method is called when a network client performs - * a whois on this xClient. - */ - virtual void OnWhois( iClient* sourceClient, - iClient* targetClient ) ; - - /** - * This method is called when a network client invites - * a services client to a channel. - */ - virtual void OnInvite( iClient* sourceClient, - Channel* theChan ); - - /** - * OnEvent is called when a network event occurs. - * To receive a particular event, the client must - * first register for that event with the xServer. - */ - virtual void OnEvent( const eventType& theEvent, - void* Data1 = NULL, void* Data2 = NULL, - void* Data3 = NULL, void* Data4 = NULL ) ; - - /** - * OnChannelEvent is called when a requested channel - * event occurs. - */ - virtual void OnChannelEvent( const channelEventType&, - Channel*, - void* Data1 = NULL, void* Data2 = NULL, - void* Data3 = NULL, void* Data4 = NULL ) ; - - /** - * 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 OnNetworkKick( Channel* theChan, - iClient* srcClient, // may be NULL - iClient* destClient, - const std::string& kickMessage, - bool authoritative ) ; - - /** - * This method is invoked when one or more "simple" (no argument) - * channel modes are set or unset. - * The ChannelUser* (source) user may be NULL if the modes - * are being changed by a server. - */ - virtual void OnChannelMode( Channel*, ChannelUser*, - const xServer::modeVectorType& ) ; - - /** - * This method is invoked when a user sets or removes - * channel mode l (limit). Keep in mind that the - * source ChannelUser may be NULL if a server is - * setting the mode. - * If the mode is being removed, the limit argument - * will be 0. - */ - virtual void OnChannelModeL( Channel*, bool polarity, - ChannelUser*, const unsigned int& ) ; - - /** - * This method is invoked when a user sets or removes - * channel mode k (key). Keep in mind that the - * source ChannelUser may be NULL if a server is - * setting the mode. - * If the mode is being removed, the key argument will - * be empty. - */ - virtual void OnChannelModeK( Channel*, bool polarity, - ChannelUser*, const std::string& ) ; - - /** - * This method is invoked when a user sets or removes - * channel mode A (Apass). Keep in mind that the - * source ChannelUser may be NULL if a server is - * setting the mode. - * If the mode is being removed, the Apass argument will - * be empty. - */ - virtual void OnChannelModeA( Channel*, bool polarity, - ChannelUser*, const std::string& ) ; - - /** - * This method is invoked when a user sets or removes - * channel mode U (Upass). Keep in mind that the - * source ChannelUser may be NULL if a server is - * setting the mode. - * If the mode is being removed, the Upass argument will - * be empty. - */ - virtual void OnChannelModeU( Channel*, bool polarity, - ChannelUser*, const std::string& ) ; - - /** - * This method is invoked when a user sets or removes - * one or more channel mode (o). Keep in mind that the - * source ChannelUser may be NULL if a server is - * setting the mode. - */ - virtual void OnChannelModeO( Channel*, ChannelUser*, - const xServer::opVectorType& ) ; - - /** - * This method is invoked when a user sets or removes - * one or more channel mode (v). Keep in mind that the - * source ChannelUser may be NULL if a server is - * setting the mode. - */ - virtual void OnChannelModeV( Channel*, ChannelUser*, - const xServer::voiceVectorType& ) ; - - /** - * This method is invoked when a user sets or removes - * one or more channel mode (b). Keep in mind that the - * source ChannelUser may be NULL if a server is - * setting the mode. - */ - virtual void OnChannelModeB( Channel*, ChannelUser*, - const xServer::banVectorType& ) ; - - /** - * This method is called for each signal that occurs - * in the system. There is no registration needed to - * receive signals, just overload this method. Be - * sure to end the method with a call to the base - * class OnSignal (or the closest base class). - */ - virtual void OnSignal( int ) ; - - /** - * OnCTCP is called when a CTCP command is issued to - * the client. - */ - virtual void OnCTCP( iClient* Sender, - const std::string& CTCP, - const std::string& Message, - bool Secure = false ) ; - - /** - * OnFakeCTCP is called when a CTCP command is issued to - * one of this xClient's fake clients. - */ - virtual void OnFakeCTCP( iClient* Sender, - iClient* fakeClient, - const std::string& CTCP, - const std::string& Message, - bool Secure = false ) ; - - /** - * This method is called when a channel CTCP occurs - * in a channel in which an xClient resides, and the - * xClient is user mode -d. - */ - virtual void OnChannelCTCP( iClient* Sender, - Channel* theChan, - const std::string& CTCPCommand, - const std::string& Message ) ; - - /** - * This method is called when a channel CTCP occurs - * in a channel in which an xClient resides, and the - * xClient is user mode -d. - */ - virtual void OnFakeChannelCTCP( iClient* Sender, - iClient* fakeClient, - Channel* theChan, - const std::string& CTCPCommand, - const std::string& Message ) ; - - /** - * OnPrivateMessage is called when a PRIVMSG command - * is issued to the client. - */ - virtual void OnPrivateMessage( iClient* Sender, - const std::string& Message, - bool secure = false ) ; - - /** - * Invoked when a private message arives for a fake client - * owned by this xClient. - */ - virtual void OnFakePrivateMessage( iClient* Sender, - iClient* Target, - const std::string& Message, - bool secure = false ) ; - - /** - * This method is called when a channel message occurs - * in a channel in which an xClient resides, and the - * xClient is user mode -d. - */ - virtual void OnChannelMessage( iClient* Sender, - Channel* theChan, - const std::string& Message ) ; - - /** - * Invoked when a fake client in a channel receives - * a channel message. - */ - virtual void OnFakeChannelMessage( iClient* Sender, - iClient* Target, - Channel* theChan, - const std::string& Message ) ; - - /** - * OnPrivateNotice is called when a NOTICE command - * is issued to the client. - */ - virtual void OnPrivateNotice( iClient* Sender, - const std::string& Message, - bool secure = false ) ; - - /** - * Invoked when a private notice arives for a fake client - * owned by this xClient. - */ - virtual void OnFakePrivateNotice( iClient* Sender, - iClient* Target, - const std::string& Message, - bool secure = false ) ; - - /** - * OnChannelNotice is called when a module receives - * channel notice, and is mode -d. - */ - virtual void OnChannelNotice( iClient* Sender, - Channel* theChan, - const std::string& Message ) ; - - /** - * Invoked when a fake client in a channel receives - * a channel notice. - */ - virtual void OnFakeChannelNotice( iClient* Sender, - iClient* Target, - Channel* theChan, - const std::string& Message ) ; - - /** - * OnServerMessage is called when a server messages - * a client. - */ - virtual void OnServerMessage( iServer* Sender, - const std::string& Message, bool secure = false ) ; - - /** - * Handle a timer event. The first argument is the - * handle for the timer registration, and the second is - * the arguments that were passed when registering the - * timer. - * This method overloads the pure virtual TimerHandler - * base class method declaration. - */ - virtual void OnTimer( const xServer::timerID& , void* ) ; - - /** - * A timer has been destroyed by the server (such as during - * a shutdown). Perform cleanup for the timer here. - */ - virtual void OnTimerDestroy( xServer::timerID, void* ) ; - - /* Utility methods */ - - /** - * Op a user on a channel, join/part the channel if necessary. - */ - virtual bool Op( Channel*, iClient* ) ; - - /** - * Op one or more users on a channel, join/part the channel - * if necessary. - */ - virtual bool Op( Channel*, const std::vector< iClient* >& ) ; - - /** - * Voice a user on a channel, join/part the channel if necessary. - */ - virtual bool Voice( Channel*, iClient* ) ; - - /** - * Voice one or more users on a channel, join/part the channel - * if necessary. - */ - virtual bool Voice( Channel*, const std::vector< iClient* >& ) ; - - /** - * Deop a user on a channel, join/part the channel if necessary. - */ - virtual bool DeOp( Channel*, iClient* ) ; - - /** - * Deop a user on a channel, join/part the channel if necessary. - */ - virtual bool DeOp( Channel*, const std::vector< iClient* >& ) ; - - /** - * Devoice a user on a channel, join/part the channel if necessary. - */ - virtual bool DeVoice( Channel*, iClient* ) ; - - /** - * Devoice one or more users on a channel, join/part the channel - * if necessary. - */ - virtual bool DeVoice( Channel*, const std::vector< iClient* >& ) ; - - /** - * Set a ban on a channel, join/part the channel if necessary. - */ - virtual bool Ban( Channel*, iClient* ) ; - - /** - * Set a ban on a channel, join/part the channel if necessary. - */ - virtual bool Ban( Channel*, const std::vector< iClient* >& ) ; - - /** - * Set bans on a channel from a banVector, join/part the channel if necessary. - * The banVector must not include duplicates. - */ - virtual bool Ban( Channel*, const xServer::banVectorType& ) ; - - /** - * Ban kick a client from a channel for the given reason. - */ - virtual bool BanKick( Channel*, iClient*, const std::string& ) ; - - /** - * Remove a channel ban. - */ - virtual bool UnBan( Channel*, const std::string& ) ; - - /** - * Removes channel bans from a banVector, join/part the channel if necessary. - * The banVector must not include duplicates, and only include exact existing - * bans on the channel. - */ - virtual bool UnBan( Channel*, const xServer::banVectorType& ) ; - - /** - * Kick a user from a channel, join/part if necessary. - */ - virtual bool Kick( Channel*, iClient*, const std::string&, bool modeAsServer = false); - - /** - * Kick several users from a channel, join/part if necessary. - */ - virtual bool Kick( Channel*, const std::vector< iClient* >&, const std::string&, bool modeAsServer = false); - - /** - * Kick all users from a channel that matches the specified IP, join/part if necessary. - */ - virtual bool Kick( Channel*, const string&, - const std::string&, bool modeAsServer = false ) ; - - /** - * Set the topic in a channel, joining, opping, and parting - * the client if necessary. - */ - virtual bool Topic( Channel*, const std::string& ) ; - - /** - * Join will cause the client to join a channel. - */ - virtual bool Join( const std::string& chanName, - const std::string& modes = std::string(), - const time_t& joinTime = 0, - bool getOps = false ) ; - - /** - * Join the given channel. - */ - virtual bool Join( Channel* theChan, - const std::string& modes = std::string(), - const time_t& joinTime = 0, - bool getOps = false ) ; - - /** - * This method is called when the bot joins a channel. - */ - virtual void OnJoin( Channel* ) ; - - /** - * This method is called when the bot joins a channel. - */ - virtual void OnJoin( const std::string& ) ; - - /** - * Part will cause the client to part a channel. - */ - virtual bool Part( const std::string&, - const std::string& = std::string() ) ; - - /** - * Part the given channel. - */ - virtual bool Part( Channel* ) ; - - /** - * This method is called when the bot parts a channel. - */ - virtual void OnPart( Channel* ) ; - - /** - * This method is called when the bot parts a channel. - */ - virtual void OnPart( const std::string& ) ; - - /** - * Invite a user to a channel. Join the channel if necessary - * (and then part). - */ - virtual bool Invite( iClient*, const std::string& ) ; - - /** - * Invite a user to a channel. Join the channel if necessary - * (and then part). - */ - virtual bool Invite( iClient*, Channel* ) ; - - /** - * Return true if the bot is on the given channel. - */ - virtual bool isOnChannel( const std::string& chanName ) const ; - - /** - * Return true if the bot is on the given channel. - */ - virtual bool isOnChannel( const Channel* theChan ) const ; - - /** - * DoCTCP will issue a CTCP (reply) to the given iClient. - */ - virtual bool DoCTCP( iClient* Target, - const std::string& CTCP, - const std::string& Message ) ; - - /** - * DoFakeCTCP will issue a CTCP (reply) to the given - * iClient with a fake client interface. - */ - virtual bool DoFakeCTCP( const iClient* Target, - const iClient* srcClient, - const std::string& CTCP, - const std::string& Message ) ; - - /** - * Message will PRIVMSG a string of data to the given iClient. - */ - virtual bool Message( const iClient* Target, - const char* Message, ... ) ; - - /** - * Message an iClient with a fake client interface. - */ - virtual bool FakeMessage( const iClient* Target, - const iClient* srcClient, - const std::string& Message ) ; - - /** - * Message a channel with a fake client interface. - */ - virtual bool FakeMessage( const Channel* theChan, - const iClient* srcClient, - const std::string& Message ) ; - - /** - * Notice an iClient with a fake client interface. - */ - virtual bool FakeNotice( const iClient* Target, - const iClient* srcClient, - const std::string& Message ) ; - - /** - * Notice a channel with a fake client interface. - */ - virtual bool FakeNotice( const Channel* theChan, - const iClient* srcClient, - const std::string& Message ) ; - - /** - * Message will PRIVMSG a string of data to the given iClient. - */ - virtual bool Message( const iClient* Target, - const std::string& Message ) ; - - /** - * This format of Message will write a string of data - * to a channel. - */ - virtual bool Message( const std::string& Channel, - const char* Message, ... ) ; - - /** - * This format of Message will write a string of data - * to a channel. - */ - virtual bool Message( const std::string& Channel, - const std::string& Message ) ; - - /** - * This format of Message will write a string of data - * to a channel. - */ - virtual bool Message( const Channel* theChan, - const std::string& Message ) ; - - /** - * Have this module message a channel. - */ - virtual bool Message( const Channel* theChan, - const char* Format, ... ) ; - - /** - * Notice will send a NOTICE command to the given iClient. - */ - virtual bool Notice( const iClient* Target, - const char* Message, ... ) ; - - /** - * Notice will send a NOTICE command to the given iClient. - */ - virtual bool Notice( const iClient* Target, const std::string& ) ; - - /** - * This Notice() signature will send a channel NOTICE. - */ - virtual bool Notice( const std::string& Channel, - const char* Message, ... ) ; - - /** - * This Notice() signature will send a channel NOTICE. - */ - virtual bool Notice( const Channel* theChan, - const char* Message, ... ) ; - - /** - * Notice channel operators with given message. - */ - virtual bool NoticeChannelOps( const Channel* theChan, - const char* Message, ... ) ; - - /** - * Notice channel operators with given message. - */ - virtual bool NoticeChannelOps( const string& chanName, - const char* Message, ... ) ; - - /** - * This Notice() signature will send a channel NOTICE. - */ - virtual bool Notice( const Channel*, const std::string& ) ; - - /** - * Have this bot send a global wallops message. - */ - virtual bool Wallops( const std::string& ) ; - - /** - * Have this bot send a global wallops message. - */ - virtual bool Wallops( const char* Format, ... ) ; - - /** - * Have the server send a wallops. - */ - virtual bool WallopsAsServer( const std::string& ) ; - - /** - * Have the server send a wallops. - */ - virtual bool WallopsAsServer( const char* Format, ... ) ; - - /** - * Return this xClient's network instance (iClient*). - */ - inline iClient* getInstance() const - { return me ; } - - /** - * Return this bot's nick name. - */ - inline const std::string& getNickName() const - { return nickName ; } - - /** - * Retrieve this bot's user name. - */ - inline const std::string& getUserName() const - { return userName ; } - - /** - * Retrieve this bot's host name. - */ - inline const std::string& getHostName() const - { return hostName ; } - - /** - * Retrieve this bot's description. - */ - inline const std::string& getDescription() const - { return userDescription ; } - - /** - * Retrieve this bot's uplink's numeric, integer format. - */ - unsigned int getUplinkIntYY() const - { return MyUplink->getIntYY() ; } - - /** - * Retrieve this bot's uplink's highest client count - * numeric, integer format. - */ - inline unsigned int getUplinkIntXXX() const - { return MyUplink->getIntXXX() ; } - - /** - * Retrieve this bot's uplink's numeric, character - * array format. - */ - inline const std::string getUplinkCharYY() const - { return MyUplink->getCharYY() ; } - - /** - * Retrieve this bot's uplink's client count numeric, - * character array format. - */ - inline const std::string getUplinkCharXXX() const - { return MyUplink->getCharXXX() ; } - - /** - * Retrieve this bot's uplink's network numeric, - * std::string format. - */ - inline const std::string getUplinkCharYYXXX() const - { return MyUplink->getCharYYXXX() ; } - - /** - * Retrieve this bot's uplink's server name. - */ - inline const std::string& getUplinkName() const - { return MyUplink->getName() ; } - - /** - * Retrieve this bot's uplink's description. - */ - inline const std::string& getUplinkDescription() const - { return MyUplink->getDescription() ; } - - /** - * Accessor method for the bot's user modes. - */ - virtual std::string getModes() const ; - - /** - * Return true if an arbitrary mode is set, false otherwise. - */ - inline bool getMode( const modeType& whichMode ) const - { return ((mode & whichMode) == whichMode) ; } - - /** - * Obtain a pointer to the single xServer instance, which - * is the uplink of every services bot. - * Use of this method is discouraged. - */ - inline xServer* getUplink() const - { return MyUplink ; } - - /** - * Return the name of the configuration file from which this - * client derived its configuration information. - */ - inline const std::string& getConfigFileName() const - { return configFileName ; } - - /** - * Returns a pointer to the logger object of this client. - */ - inline Logger* getLogger() - { return logger.get() ; } - - /** - * Return true if the server is connected to a network. - */ - inline bool isConnected() const - { return (MyUplink && MyUplink->isConnected()) ; } - - /** - * Utility method for outputting client information to - * a gnuworld logging stream. - */ - friend ELog& operator<<( ELog& out, - const xClient& theClient ) - { - out << theClient.nickName << '!' - << theClient.userName << '@' - << theClient.hostName - << " Numeric: " << theClient.getCharYYXXX() - << ", int YY/XXX/YYXXX: " - << theClient.getIntYY() << '/' - << theClient.getIntXXX() << '/' - << theClient.getIntYYXXX() ; - return out ; - } - -protected: - - /** - * Allow sub classes to call default constructor - * This method is defined in the source file. - */ - xClient() ; - - /** - * Disallow copying. - * This method is declared, but NOT defined. - */ - xClient( const xClient& ) ; - - /** - * Disallow default assignment. - * This method is declared, but NOT defined. - */ - xClient operator=( const xClient& ) ; - - /** - * This method is called by the xServer, and its purpose is - * to reset its iClient instance. - */ - inline void resetInstance() - { me = 0 ; } - - /** - * This method is called to add a channel to the bot's - * internal channel database; typically called from - * OnJoin(). This is used to maintain the integrity - * of isOnChannel() calls. - */ - virtual bool addChan( Channel* ) ; - - /** - * This method is called to remove a channel from the - * bot's internal database; typically called from OnPart(). - * This is used to maintain the integrity of isOnChannel() - * calls. - */ - virtual bool removeChan( Channel* ) ; - - /** - * This method sets the iClient instance of this xClient. - */ - virtual void setInstance( iClient* me ) - { this->me = me ; } - - /** - * The iClient representation of this xClient. - * This variable will be set by xNetwork once the - * xClient links to the xServer. - */ - iClient* me ; - - /** - * MyUplink is a pointer to the xServer to which this - * client is attached. - */ - xServer *MyUplink ; - - /** - * This bot's nick name. - */ - std::string nickName ; - - /** - * This bot's user name. - */ - std::string userName ; - - /** - * This bot's host name. - */ - std::string hostName ; - - /** - * This bot's description. - */ - std::string userDescription ; - - /** - * Connected is true when we are connected to an xServer. - * It says nothing of whether the xServer is connected - * to a network. - */ - bool Connected ; - - /** - * This is the user mode of this client. - */ - modeType mode ; - - /** - * The name of the config file from which this client read - * its configuration information. - */ - std::string configFileName ; - - /** - * Logger instance. - */ - std::unique_ptr< Logger > logger ; -} ; +class xClient : public TimerHandler, public NetworkTarget { + /// Let xServer access our protected members. + friend class xServer; + + /// Let xNetwork access our protected members. + friend class xNetwork; + + public: + /** + * Declare the type for the xClient's internal + * mode representation. Note that this typedef + * is deliberately public. + */ + typedef iClient::modeType modeType; + + /** + * Construct a new xClient from a config file. + */ + xClient(const std::string&); + + /** + * The primary purpose of this method is do call the + * deallocation methods of any xClient's which are storing + * data in the customDataMap. + * Client responsibilities: + * Removing all timers registered with the xServer + * Removing all custom data members held in the iClient's + */ + virtual ~xClient(); + + /** + * This method must call xServer::BurstChannel() with appropriate + * channel modes for any channel it wishes to own. + */ + virtual void BurstChannels(); + + /** + * BurstGlines is called before eob, for the client to burst + * all of its glines + */ + virtual bool BurstGlines(); + + /** + * Kill will issue a KILL command to the network for + * the given iClient (network generic client). + */ + virtual bool Kill(iClient*, const std::string&); + virtual bool Kill(iClient*, const std::string&, bool); + + /** + * QuoteAsServer will send data to the network as the + * server itself. Try to avoid using this method. + */ + virtual bool QuoteAsServer(const std::string& Command); + + /** + * Write a string of data to the network. + */ + virtual bool Write(const std::string& s) { return QuoteAsServer(s); } + + /** + * Write a string of data to the network. + */ + virtual bool Write(const std::stringstream& s) { return QuoteAsServer(s.str()); } + + /** + * Write a variable length argument list to the network. + */ + virtual bool Write(const char*, ...); + + /** + * This method will change modes in a channel. + * If the fourth argument is true, then the modes will be + * changed as the server, otherwise the client will set + * the modes (joining and parting the channel if necessary). + * Removing mode 'k' expects an argument, but it doesn't matter + * what the argument is. + * Removing mode 'l' requires NO argument to be issued. + */ + virtual bool Mode(const std::string& chanName, const std::string& modes, + const std::string& args, bool modeAsServer = false); + + /** + * This method will change modes in a channel. + * If the fourth argument is true, then the modes will be + * changed as the server, otherwise the client will set + * the modes (joining and parting the channel if necessary). + * Removing mode 'k' expects an argument, but it doesn't matter + * what the argument is. + * Removing mode 'l' requires NO argument to be issued. + */ + virtual bool Mode(Channel*, const std::string& modes, const std::string& args, + bool modeAsServer = false); + + /** + * Mode is used to set the bot's modes. If connected to the + * network already, these new modes will be written to the + * network. + */ + virtual bool Mode(const std::string& Mode); + + /** + * Issue a clearmode (CM) for the given channel and update + * all internal structures. + * This method will also post a channel event for each + * mode. + */ + virtual bool ClearMode(Channel* theChan, const std::string& modes, bool modeAsServer = false); + + /** + * OnConnect is called when the server connects to the + * network, during burst time. The client's NICK + * information has already been sent to the network. + */ + virtual void OnConnect(); + + /** + * Invoked when the uplink has been terminated. + */ + virtual void OnDisconnect(); + + /** + * This method is invoked when the server has been requested + * to shutdown. If currently connected to the network, this + * method gives xClient's a chance to gracefully QUIT from + * the network, or whatever other processing is useful. + * To force data to be written before final shutdown (again, + * if connected), set xServer::FlushData(). + * Timers will be executed after this method is invoked, once, + * depending upon target time of course :) + */ + virtual void OnShutdown(const std::string& reason); + + /** + * Invoked after the client has been loaded, perform + * initialization stuff here. + */ + virtual void OnAttach(); + + /** + * This method will be invoked when the server is unloading + * the client for whatever reason. + */ + virtual void OnDetach(const std::string& = std::string("Server Shutdown")); + + /** + * OnKill() is called when the client has been KILL'd. + */ + virtual void OnKill(); + + /** + * This method is called when a network client performs + * a whois on this xClient. + */ + virtual void OnWhois(iClient* sourceClient, iClient* targetClient); + + /** + * This method is called when a network client invites + * a services client to a channel. + */ + virtual void OnInvite(iClient* sourceClient, Channel* theChan); + + /** + * OnEvent is called when a network event occurs. + * To receive a particular event, the client must + * first register for that event with the xServer. + */ + virtual void OnEvent(const eventType& theEvent, void* Data1 = NULL, void* Data2 = NULL, + void* Data3 = NULL, void* Data4 = NULL); + + /** + * OnChannelEvent is called when a requested channel + * event occurs. + */ + virtual void OnChannelEvent(const channelEventType&, Channel*, void* Data1 = NULL, + void* Data2 = NULL, void* Data3 = NULL, void* Data4 = NULL); + + /** + * 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 OnNetworkKick(Channel* theChan, + iClient* srcClient, // may be NULL + iClient* destClient, const std::string& kickMessage, + bool authoritative); + + /** + * This method is invoked when one or more "simple" (no argument) + * channel modes are set or unset. + * The ChannelUser* (source) user may be NULL if the modes + * are being changed by a server. + */ + virtual void OnChannelMode(Channel*, ChannelUser*, const xServer::modeVectorType&); + + /** + * This method is invoked when a user sets or removes + * channel mode l (limit). Keep in mind that the + * source ChannelUser may be NULL if a server is + * setting the mode. + * If the mode is being removed, the limit argument + * will be 0. + */ + virtual void OnChannelModeL(Channel*, bool polarity, ChannelUser*, const unsigned int&); + + /** + * This method is invoked when a user sets or removes + * channel mode k (key). Keep in mind that the + * source ChannelUser may be NULL if a server is + * setting the mode. + * If the mode is being removed, the key argument will + * be empty. + */ + virtual void OnChannelModeK(Channel*, bool polarity, ChannelUser*, const std::string&); + + /** + * This method is invoked when a user sets or removes + * channel mode A (Apass). Keep in mind that the + * source ChannelUser may be NULL if a server is + * setting the mode. + * If the mode is being removed, the Apass argument will + * be empty. + */ + virtual void OnChannelModeA(Channel*, bool polarity, ChannelUser*, const std::string&); + + /** + * This method is invoked when a user sets or removes + * channel mode U (Upass). Keep in mind that the + * source ChannelUser may be NULL if a server is + * setting the mode. + * If the mode is being removed, the Upass argument will + * be empty. + */ + virtual void OnChannelModeU(Channel*, bool polarity, ChannelUser*, const std::string&); + + /** + * This method is invoked when a user sets or removes + * one or more channel mode (o). Keep in mind that the + * source ChannelUser may be NULL if a server is + * setting the mode. + */ + virtual void OnChannelModeO(Channel*, ChannelUser*, const xServer::opVectorType&); + + /** + * This method is invoked when a user sets or removes + * one or more channel mode (v). Keep in mind that the + * source ChannelUser may be NULL if a server is + * setting the mode. + */ + virtual void OnChannelModeV(Channel*, ChannelUser*, const xServer::voiceVectorType&); + + /** + * This method is invoked when a user sets or removes + * one or more channel mode (b). Keep in mind that the + * source ChannelUser may be NULL if a server is + * setting the mode. + */ + virtual void OnChannelModeB(Channel*, ChannelUser*, const xServer::banVectorType&); + + /** + * This method is called for each signal that occurs + * in the system. There is no registration needed to + * receive signals, just overload this method. Be + * sure to end the method with a call to the base + * class OnSignal (or the closest base class). + */ + virtual void OnSignal(int); + + /** + * OnCTCP is called when a CTCP command is issued to + * the client. + */ + virtual void OnCTCP(iClient* Sender, const std::string& CTCP, const std::string& Message, + bool Secure = false); + + /** + * OnFakeCTCP is called when a CTCP command is issued to + * one of this xClient's fake clients. + */ + virtual void OnFakeCTCP(iClient* Sender, iClient* fakeClient, const std::string& CTCP, + const std::string& Message, bool Secure = false); + + /** + * This method is called when a channel CTCP occurs + * in a channel in which an xClient resides, and the + * xClient is user mode -d. + */ + virtual void OnChannelCTCP(iClient* Sender, Channel* theChan, const std::string& CTCPCommand, + const std::string& Message); + + /** + * This method is called when a channel CTCP occurs + * in a channel in which an xClient resides, and the + * xClient is user mode -d. + */ + virtual void OnFakeChannelCTCP(iClient* Sender, iClient* fakeClient, Channel* theChan, + const std::string& CTCPCommand, const std::string& Message); + + /** + * OnPrivateMessage is called when a PRIVMSG command + * is issued to the client. + */ + virtual void OnPrivateMessage(iClient* Sender, const std::string& Message, bool secure = false); + + /** + * Invoked when a private message arives for a fake client + * owned by this xClient. + */ + virtual void OnFakePrivateMessage(iClient* Sender, iClient* Target, const std::string& Message, + bool secure = false); + + /** + * This method is called when a channel message occurs + * in a channel in which an xClient resides, and the + * xClient is user mode -d. + */ + virtual void OnChannelMessage(iClient* Sender, Channel* theChan, const std::string& Message); + + /** + * Invoked when a fake client in a channel receives + * a channel message. + */ + virtual void OnFakeChannelMessage(iClient* Sender, iClient* Target, Channel* theChan, + const std::string& Message); + + /** + * OnPrivateNotice is called when a NOTICE command + * is issued to the client. + */ + virtual void OnPrivateNotice(iClient* Sender, const std::string& Message, bool secure = false); + + /** + * Invoked when a private notice arives for a fake client + * owned by this xClient. + */ + virtual void OnFakePrivateNotice(iClient* Sender, iClient* Target, const std::string& Message, + bool secure = false); + + /** + * OnChannelNotice is called when a module receives + * channel notice, and is mode -d. + */ + virtual void OnChannelNotice(iClient* Sender, Channel* theChan, const std::string& Message); + + /** + * Invoked when a fake client in a channel receives + * a channel notice. + */ + virtual void OnFakeChannelNotice(iClient* Sender, iClient* Target, Channel* theChan, + const std::string& Message); + + /** + * OnServerMessage is called when a server messages + * a client. + */ + virtual void OnServerMessage(iServer* Sender, const std::string& Message, bool secure = false); + + /** + * Handle a timer event. The first argument is the + * handle for the timer registration, and the second is + * the arguments that were passed when registering the + * timer. + * This method overloads the pure virtual TimerHandler + * base class method declaration. + */ + virtual void OnTimer(const xServer::timerID&, void*); + + /** + * A timer has been destroyed by the server (such as during + * a shutdown). Perform cleanup for the timer here. + */ + virtual void OnTimerDestroy(xServer::timerID, void*); + + /* Utility methods */ + + /** + * Op a user on a channel, join/part the channel if necessary. + */ + virtual bool Op(Channel*, iClient*); + + /** + * Op one or more users on a channel, join/part the channel + * if necessary. + */ + virtual bool Op(Channel*, const std::vector&); + + /** + * Voice a user on a channel, join/part the channel if necessary. + */ + virtual bool Voice(Channel*, iClient*); + + /** + * Voice one or more users on a channel, join/part the channel + * if necessary. + */ + virtual bool Voice(Channel*, const std::vector&); + + /** + * Deop a user on a channel, join/part the channel if necessary. + */ + virtual bool DeOp(Channel*, iClient*); + + /** + * Deop a user on a channel, join/part the channel if necessary. + */ + virtual bool DeOp(Channel*, const std::vector&); + + /** + * Devoice a user on a channel, join/part the channel if necessary. + */ + virtual bool DeVoice(Channel*, iClient*); + + /** + * Devoice one or more users on a channel, join/part the channel + * if necessary. + */ + virtual bool DeVoice(Channel*, const std::vector&); + + /** + * Set a ban on a channel, join/part the channel if necessary. + */ + virtual bool Ban(Channel*, iClient*); + + /** + * Set a ban on a channel, join/part the channel if necessary. + */ + virtual bool Ban(Channel*, const std::vector&); + + /** + * Set bans on a channel from a banVector, join/part the channel if necessary. + * The banVector must not include duplicates. + */ + virtual bool Ban(Channel*, const xServer::banVectorType&); + + /** + * Ban kick a client from a channel for the given reason. + */ + virtual bool BanKick(Channel*, iClient*, const std::string&); + + /** + * Remove a channel ban. + */ + virtual bool UnBan(Channel*, const std::string&); + + /** + * Removes channel bans from a banVector, join/part the channel if necessary. + * The banVector must not include duplicates, and only include exact existing + * bans on the channel. + */ + virtual bool UnBan(Channel*, const xServer::banVectorType&); + + /** + * Kick a user from a channel, join/part if necessary. + */ + virtual bool Kick(Channel*, iClient*, const std::string&, bool modeAsServer = false); + + /** + * Kick several users from a channel, join/part if necessary. + */ + virtual bool Kick(Channel*, const std::vector&, const std::string&, + bool modeAsServer = false); + + /** + * Kick all users from a channel that matches the specified IP, join/part if necessary. + */ + virtual bool Kick(Channel*, const string&, const std::string&, bool modeAsServer = false); + + /** + * Set the topic in a channel, joining, opping, and parting + * the client if necessary. + */ + virtual bool Topic(Channel*, const std::string&); + + /** + * Join will cause the client to join a channel. + */ + virtual bool Join(const std::string& chanName, const std::string& modes = std::string(), + const time_t& joinTime = 0, bool getOps = false); + + /** + * Join the given channel. + */ + virtual bool Join(Channel* theChan, const std::string& modes = std::string(), + const time_t& joinTime = 0, bool getOps = false); + + /** + * This method is called when the bot joins a channel. + */ + virtual void OnJoin(Channel*); + + /** + * This method is called when the bot joins a channel. + */ + virtual void OnJoin(const std::string&); + + /** + * Part will cause the client to part a channel. + */ + virtual bool Part(const std::string&, const std::string& = std::string()); + + /** + * Part the given channel. + */ + virtual bool Part(Channel*); + + /** + * This method is called when the bot parts a channel. + */ + virtual void OnPart(Channel*); + + /** + * This method is called when the bot parts a channel. + */ + virtual void OnPart(const std::string&); + + /** + * Invite a user to a channel. Join the channel if necessary + * (and then part). + */ + virtual bool Invite(iClient*, const std::string&); + + /** + * Invite a user to a channel. Join the channel if necessary + * (and then part). + */ + virtual bool Invite(iClient*, Channel*); + + /** + * Return true if the bot is on the given channel. + */ + virtual bool isOnChannel(const std::string& chanName) const; + + /** + * Return true if the bot is on the given channel. + */ + virtual bool isOnChannel(const Channel* theChan) const; + + /** + * DoCTCP will issue a CTCP (reply) to the given iClient. + */ + virtual bool DoCTCP(iClient* Target, const std::string& CTCP, const std::string& Message); + + /** + * DoFakeCTCP will issue a CTCP (reply) to the given + * iClient with a fake client interface. + */ + virtual bool DoFakeCTCP(const iClient* Target, const iClient* srcClient, + const std::string& CTCP, const std::string& Message); + + /** + * Message will PRIVMSG a string of data to the given iClient. + */ + virtual bool Message(const iClient* Target, const char* Message, ...); + + /** + * Message an iClient with a fake client interface. + */ + virtual bool FakeMessage(const iClient* Target, const iClient* srcClient, + const std::string& Message); + + /** + * Message a channel with a fake client interface. + */ + virtual bool FakeMessage(const Channel* theChan, const iClient* srcClient, + const std::string& Message); + + /** + * Notice an iClient with a fake client interface. + */ + virtual bool FakeNotice(const iClient* Target, const iClient* srcClient, + const std::string& Message); + + /** + * Notice a channel with a fake client interface. + */ + virtual bool FakeNotice(const Channel* theChan, const iClient* srcClient, + const std::string& Message); + + /** + * Message will PRIVMSG a string of data to the given iClient. + */ + virtual bool Message(const iClient* Target, const std::string& Message); + + /** + * This format of Message will write a string of data + * to a channel. + */ + virtual bool Message(const std::string& Channel, const char* Message, ...); + + /** + * This format of Message will write a string of data + * to a channel. + */ + virtual bool Message(const std::string& Channel, const std::string& Message); + + /** + * This format of Message will write a string of data + * to a channel. + */ + virtual bool Message(const Channel* theChan, const std::string& Message); + + /** + * Have this module message a channel. + */ + virtual bool Message(const Channel* theChan, const char* Format, ...); + + /** + * Notice will send a NOTICE command to the given iClient. + */ + virtual bool Notice(const iClient* Target, const char* Message, ...); + + /** + * Notice will send a NOTICE command to the given iClient. + */ + virtual bool Notice(const iClient* Target, const std::string&); + + /** + * This Notice() signature will send a channel NOTICE. + */ + virtual bool Notice(const std::string& Channel, const char* Message, ...); + + /** + * This Notice() signature will send a channel NOTICE. + */ + virtual bool Notice(const Channel* theChan, const char* Message, ...); + + /** + * Notice channel operators with given message. + */ + virtual bool NoticeChannelOps(const Channel* theChan, const char* Message, ...); + + /** + * Notice channel operators with given message. + */ + virtual bool NoticeChannelOps(const string& chanName, const char* Message, ...); + + /** + * This Notice() signature will send a channel NOTICE. + */ + virtual bool Notice(const Channel*, const std::string&); + + /** + * Have this bot send a global wallops message. + */ + virtual bool Wallops(const std::string&); + + /** + * Have this bot send a global wallops message. + */ + virtual bool Wallops(const char* Format, ...); + + /** + * Have the server send a wallops. + */ + virtual bool WallopsAsServer(const std::string&); + + /** + * Have the server send a wallops. + */ + virtual bool WallopsAsServer(const char* Format, ...); + + /** + * Return this xClient's network instance (iClient*). + */ + inline iClient* getInstance() const { return me; } + + /** + * Return this bot's nick name. + */ + inline const std::string& getNickName() const { return nickName; } + + /** + * Retrieve this bot's user name. + */ + inline const std::string& getUserName() const { return userName; } + + /** + * Retrieve this bot's host name. + */ + inline const std::string& getHostName() const { return hostName; } + + /** + * Retrieve this bot's description. + */ + inline const std::string& getDescription() const { return userDescription; } + + /** + * Retrieve this bot's uplink's numeric, integer format. + */ + unsigned int getUplinkIntYY() const { return MyUplink->getIntYY(); } + + /** + * Retrieve this bot's uplink's highest client count + * numeric, integer format. + */ + inline unsigned int getUplinkIntXXX() const { return MyUplink->getIntXXX(); } + + /** + * Retrieve this bot's uplink's numeric, character + * array format. + */ + inline const std::string getUplinkCharYY() const { return MyUplink->getCharYY(); } + + /** + * Retrieve this bot's uplink's client count numeric, + * character array format. + */ + inline const std::string getUplinkCharXXX() const { return MyUplink->getCharXXX(); } + + /** + * Retrieve this bot's uplink's network numeric, + * std::string format. + */ + inline const std::string getUplinkCharYYXXX() const { return MyUplink->getCharYYXXX(); } + + /** + * Retrieve this bot's uplink's server name. + */ + inline const std::string& getUplinkName() const { return MyUplink->getName(); } + + /** + * Retrieve this bot's uplink's description. + */ + inline const std::string& getUplinkDescription() const { return MyUplink->getDescription(); } + + /** + * Accessor method for the bot's user modes. + */ + virtual std::string getModes() const; + + /** + * Return true if an arbitrary mode is set, false otherwise. + */ + inline bool getMode(const modeType& whichMode) const { + return ((mode & whichMode) == whichMode); + } + + /** + * Obtain a pointer to the single xServer instance, which + * is the uplink of every services bot. + * Use of this method is discouraged. + */ + inline xServer* getUplink() const { return MyUplink; } + + /** + * Return the name of the configuration file from which this + * client derived its configuration information. + */ + inline const std::string& getConfigFileName() const { return configFileName; } + + /** + * Returns a pointer to the logger object of this client. + */ + inline Logger* getLogger() { return logger.get(); } + + /** + * Return true if the server is connected to a network. + */ + inline bool isConnected() const { return (MyUplink && MyUplink->isConnected()); } + + /** + * Utility method for outputting client information to + * a gnuworld logging stream. + */ + friend ELog& operator<<(ELog& out, const xClient& theClient) { + out << theClient.nickName << '!' << theClient.userName << '@' << theClient.hostName + << " Numeric: " << theClient.getCharYYXXX() + << ", int YY/XXX/YYXXX: " << theClient.getIntYY() << '/' << theClient.getIntXXX() << '/' + << theClient.getIntYYXXX(); + return out; + } + + protected: + /** + * Allow sub classes to call default constructor + * This method is defined in the source file. + */ + xClient(); + + /** + * Disallow copying. + * This method is declared, but NOT defined. + */ + xClient(const xClient&); + + /** + * Disallow default assignment. + * This method is declared, but NOT defined. + */ + xClient operator=(const xClient&); + + /** + * This method is called by the xServer, and its purpose is + * to reset its iClient instance. + */ + inline void resetInstance() { me = 0; } + + /** + * This method is called to add a channel to the bot's + * internal channel database; typically called from + * OnJoin(). This is used to maintain the integrity + * of isOnChannel() calls. + */ + virtual bool addChan(Channel*); + + /** + * This method is called to remove a channel from the + * bot's internal database; typically called from OnPart(). + * This is used to maintain the integrity of isOnChannel() + * calls. + */ + virtual bool removeChan(Channel*); + + /** + * This method sets the iClient instance of this xClient. + */ + virtual void setInstance(iClient* me) { this->me = me; } + + /** + * The iClient representation of this xClient. + * This variable will be set by xNetwork once the + * xClient links to the xServer. + */ + iClient* me; + + /** + * MyUplink is a pointer to the xServer to which this + * client is attached. + */ + xServer* MyUplink; + + /** + * This bot's nick name. + */ + std::string nickName; + + /** + * This bot's user name. + */ + std::string userName; + + /** + * This bot's host name. + */ + std::string hostName; + + /** + * This bot's description. + */ + std::string userDescription; + + /** + * Connected is true when we are connected to an xServer. + * It says nothing of whether the xServer is connected + * to a network. + */ + bool Connected; + + /** + * This is the user mode of this client. + */ + modeType mode; + + /** + * The name of the config file from which this client read + * its configuration information. + */ + std::string configFileName; + + /** + * Logger instance. + */ + std::unique_ptr logger; +}; } // namespace gnuworld diff --git a/include/events.h b/include/events.h index d6979005..895ecf43 100644 --- a/include/events.h +++ b/include/events.h @@ -28,67 +28,64 @@ #ifndef __EVENTS_H #define __EVENTS_H "$Id: events.h,v 1.22 2010/09/05 17:26:35 denspike Exp $" -#include +#include -namespace gnuworld -{ +namespace gnuworld { /** * This is used to enumerate the possible network (non-channel) * events that gnuworld will track and deliver to registered * clients. */ -enum -{ - EVT_OPER, - EVT_NETBREAK, - EVT_NETJOIN, - EVT_BURST_CMPLT, - EVT_BURST_ACK, - EVT_EA_SENT, - EVT_GLINE, - EVT_REMGLINE, - EVT_JUPE, - EVT_UNJUPE, - EVT_QUIT, - EVT_KILL, - EVT_NICK, - EVT_CHNICK, - EVT_ACCOUNT, - EVT_ACCOUNT_FLAGS, - EVT_RAW, - EVT_XQUERY, - EVT_XREPLY, - EVT_NETCONF, +enum { + EVT_OPER, + EVT_NETBREAK, + EVT_NETJOIN, + EVT_BURST_CMPLT, + EVT_BURST_ACK, + EVT_EA_SENT, + EVT_GLINE, + EVT_REMGLINE, + EVT_JUPE, + EVT_UNJUPE, + EVT_QUIT, + EVT_KILL, + EVT_NICK, + EVT_CHNICK, + EVT_ACCOUNT, + EVT_ACCOUNT_FLAGS, + EVT_RAW, + EVT_XQUERY, + EVT_XREPLY, + EVT_NETCONF, - // EVT_NOOP must always be last - EVT_NOOP -} ; + // EVT_NOOP must always be last + EVT_NOOP +}; /** * The type used to represent network (non-channel) events. */ -typedef int eventType ; +typedef int eventType; /** * This enumerates the possible channel events that gnuworld will * track and deliver to registered clients. */ -enum -{ - EVT_JOIN = EVT_NOOP, - EVT_PART, - EVT_SERVERMODE, // when server performs modes. - EVT_TOPIC, // passed even if TRACK_TOPIC is disabled - EVT_KICK, // moved to xClient::OnNetworkKick() - EVT_CREATE, - EVT_BURST -} ; +enum { + EVT_JOIN = EVT_NOOP, + EVT_PART, + EVT_SERVERMODE, // when server performs modes. + EVT_TOPIC, // passed even if TRACK_TOPIC is disabled + EVT_KICK, // moved to xClient::OnNetworkKick() + EVT_CREATE, + EVT_BURST +}; /** * The type used to store possible channel events. */ -typedef int channelEventType ; +typedef int channelEventType; /** * Arguments for the various events: @@ -123,7 +120,7 @@ typedef int channelEventType ; * EVT_XQUERY * 1) iServer* source (might add iClient* later) * 2) string* - routing - * 3) string* - command + * 3) string* - command * EVT_XREPLY * 1) iServer* source * 2) string* - routing @@ -149,32 +146,32 @@ typedef int channelEventType ; */ const std::string eventNames[] = { - "Oper Up", /* EVT_OPER */ - "Net Break", /* EVT_NETBREAK */ - "Net Join", /* EVT_NETJOIN */ - "Burst Complete", /* EVT_BURST_CMPLT */ - "Burst Acknowledge", /* EVT_BURST_ACK */ - "Burst Acknowledge Sent", /* EVT_EA_SENT */ - "Gline Add", /* EVT_GLINE */ - "Gline Remove", /* EVT_REMGLINE */ - "Server Jupe", /* EVT_JUPE */ - "Server UnJupe", /* EVT_UNJUPE */ - "Client Quit", /* EVT_QUIT */ - "Client Kill", /* EVT_KILL */ - "Client Connect", /* EVT_NICK */ - "Nick Change", /* EVT_CHNICK */ - "Account Login", /* EVT_ACCOUNT */ - "Raw", /* EVT_RAW */ - "XQuery", /* EVT_XQUERY */ - "XReply", /* EVT_XREPLY */ - "Channel Join", /* EVT_JOIN */ - "Channel Part", /* EVT_PART */ - "Channel Mode By Server", /* EVT_SERVERMODE */ - "Channel Topic Change", /* EVT_TOPIC */ - "Channel Kick", /* EVT_KICK */ - "Channel Create", /* EVT_CREATE */ - "Channel Burst" /* EVT_BURST */ -} ; + "Oper Up", /* EVT_OPER */ + "Net Break", /* EVT_NETBREAK */ + "Net Join", /* EVT_NETJOIN */ + "Burst Complete", /* EVT_BURST_CMPLT */ + "Burst Acknowledge", /* EVT_BURST_ACK */ + "Burst Acknowledge Sent", /* EVT_EA_SENT */ + "Gline Add", /* EVT_GLINE */ + "Gline Remove", /* EVT_REMGLINE */ + "Server Jupe", /* EVT_JUPE */ + "Server UnJupe", /* EVT_UNJUPE */ + "Client Quit", /* EVT_QUIT */ + "Client Kill", /* EVT_KILL */ + "Client Connect", /* EVT_NICK */ + "Nick Change", /* EVT_CHNICK */ + "Account Login", /* EVT_ACCOUNT */ + "Raw", /* EVT_RAW */ + "XQuery", /* EVT_XQUERY */ + "XReply", /* EVT_XREPLY */ + "Channel Join", /* EVT_JOIN */ + "Channel Part", /* EVT_PART */ + "Channel Mode By Server", /* EVT_SERVERMODE */ + "Channel Topic Change", /* EVT_TOPIC */ + "Channel Kick", /* EVT_KICK */ + "Channel Create", /* EVT_CREATE */ + "Channel Burst" /* EVT_BURST */ +}; } // namespace gnuworld diff --git a/include/gnuworld_config.h b/include/gnuworld_config.h old mode 100755 new mode 100644 index f40486d1..e55adb0d --- a/include/gnuworld_config.h +++ b/include/gnuworld_config.h @@ -26,7 +26,7 @@ /* GNUWorld main configuration file */ /* All core settings are set/defined here. */ -#include "defs.h" +#include "defs.h" /** * CONFFILE diff --git a/include/iClient.h b/include/iClient.h index e5a301c0..d0538f5b 100644 --- a/include/iClient.h +++ b/include/iClient.h @@ -23,23 +23,22 @@ #ifndef __ICLIENT_H #define __ICLIENT_H "$Id: iClient.h,v 1.49 2009/07/26 18:30:37 mrbean_ Exp $" -#include -#include -#include +#include +#include +#include -#include +#include -#include "gnuworld_config.h" -#include "Channel.h" -#include "iServer.h" -#include "NetworkTarget.h" -#include "ELog.h" +#include "gnuworld_config.h" +#include "Channel.h" +#include "iServer.h" +#include "NetworkTarget.h" +#include "ELog.h" -namespace gnuworld -{ +namespace gnuworld { -class xClient ; -class Network ; +class xClient; +class Network; /** * iClient objects represent network users. This class provides @@ -47,814 +46,731 @@ class Network ; * Note that iClient is NOT used for services clients, see * class xClient for that. */ -class iClient : public NetworkTarget -{ - -protected: - - /** - * The type used to hold channel patronage information - * for each particular user. - */ - typedef std::list< Channel* > channelListType ; - -public: - - /** - * Define a type to be used for storing the - * iClient's modes. - */ - typedef unsigned int modeType ; - - /// MODE_OPER is true if the iClient is an IRC operator. - static constexpr modeType MODE_OPER = 0x0001 ; - - /// MODE_WALLOPS is true if the iClient is receiving wallops. - static constexpr modeType MODE_WALLOPS = 0x0002 ; - - /// MODE_INVISIBLE is true if the iClient is user mode invisible. - static constexpr modeType MODE_INVISIBLE = 0x0004 ; - - /// MODE_DEAF is true if the iClient is not receiving messages. - static constexpr modeType MODE_DEAF = 0x0008 ; - - /// MODE_SERVICES is true if the iClient is a service agent. - static constexpr modeType MODE_SERVICES = 0x0010 ; - - /// MODE_REGISTERED is true if the iClient has an account set. - static constexpr modeType MODE_REGISTERED = 0x0020 ; - - /// MODE_HIDDEN_HOST is true if the iClient has HIDDEN_HOST (+x) set. - static constexpr modeType MODE_HIDDEN_HOST = 0x0040 ; - - /// MODE_G is true if the iCilent has user mode g set. - static constexpr modeType MODE_G = 0x0080 ; - - /// MODE_SERVNOTICES is true if this user is receiving server - /// notices. This may not be transmitted on all networks. - static constexpr modeType MODE_SERVNOTICES = 0x0100 ; - - /** MODE_FAKE is true if this user is a fake client. */ - static constexpr modeType MODE_FAKE = 0x0200 ; - - /** MODE_TLS is true if this user is using TLS. */ - static constexpr modeType MODE_TLS = 0x0400 ; - - /** - * Define a type to be used for storing the - * iClient's account's flags. - */ - typedef unsigned short int flagType ; - static constexpr flagType X_TOTP_ENABLED = 0x001 ; - static constexpr flagType X_TOTP_REQ_IPR = 0x002 ; - static constexpr flagType X_GLOBAL_SUSPEND = 0x004 ; - static constexpr flagType X_FRAUD = 0x008 ; - static constexpr flagType X_CERTONLY = 0x010 ; - static constexpr flagType X_CERT_DISABLE_TOTP = 0x020 ; - static constexpr flagType X_WEB_DISABLE_TOTP = 0x040 ; - - /// Iterator for channels this user is on. - typedef channelListType::iterator channelIterator ; - - /// Constant iterator for channels this user is on. - typedef channelListType::const_iterator const_channelIterator ; - - /// Type used to store the number of channels for this iClient - typedef channelListType::size_type channels_sizeType ; - - /** - * Construct a new iClient given a large list of - * parameters for the client's state. - */ - iClient( const unsigned int& _uplink, - const std::string& _yyxxx, - const std::string& _nickName, - const std::string& _userName, - const std::string& _hostBase64, - const std::string& _insecureHost, - const std::string& _realInsecureHost, - const std::string& _mode, - const std::string& _account, - const unsigned int _account_id, - const flagType _account_flags, - const std::string& _tls_fingerprint, - const std::string& _description, - const time_t& _nick_ts ) ; - - /** - * Construct a new iClient given a large list of - * parameters for the client's state. - * This signature assumes that either/both of asuka are being - * used. - */ - iClient( const unsigned int& _uplink, - const std::string& _yyxxx, - const std::string& _nickName, - const std::string& _userName, - const std::string& _hostBase64, - const std::string& _insecureHost, - const std::string& _realInsecureHost, - const std::string& _mode, - const std::string& _account, - const unsigned int _account_id, - const flagType _account_flags, - const std::string& _tls_fingerprint, - const std::string& _setHost, - const std::string& _fakeHost, - const std::string& _description, - const time_t& _nick_ts ) ; - - /** - * Destruct the iClient. - * This will call xClient::deleteCustomData() for each - * xClient which is storing a data element in this iClient. - */ - virtual ~iClient() ; - - /* Accessor methods */ - - /** - * Retrieve the iClient's nick name. - */ - inline const std::string& getNickName() const - { return nickName ; } - - /** - * Retrieve the iClient's user name. - */ - inline const std::string& getUserName() const - { return userName ; } - - /** - * Retrieve the iClient's host name, NOT IP. - */ - inline const std::string& getInsecureHost() const - { return insecureHost ;} - - /** - * Retrieve the iClient's 'real' host name. - */ - inline const std::string& getRealInsecureHost() const - { return realInsecureHost ;} - - /** - * Retrieve a string of the form: nick!user for this user. - */ - inline const std::string getNickUser() const - { return (nickName + '!' + userName) ; } - - /** - * Retrieve a string of the form: nick!user@host for this user. - */ - inline const std::string getNickUserHost() const - { return (nickName + '!' + userName + '@' + insecureHost) ; } - - /** - * Retrieve a string of the form: user@real-host for this user. - */ - inline const std::string getRealUserHost() const - { return (userName + '@' + realInsecureHost) ; } - - /** - * Retrieve a string of the form: nick!user@real-host for this user. - */ - inline const std::string getRealNickUserHost() const - { return (nickName + '!' + userName + '@' + realInsecureHost) ; } - - /** - * Retrieve client's TLS fingerprint. - * Will return empty if the client is not using TLS. - */ - inline const std::string& getTlsFingerprint() const - { return tlsFingerprint ; } - - /** - * Returns true if the client has a fingerprint. - */ - inline bool hasTlsFingerprint() const - { return !tlsFingerprint.empty() ; } - - /** - * Retrieve client's 'real-name' field. - */ - inline const std::string& getDescription() const - { return description ; } - - /** - * Overwrite this clients "Real Host" with a "Hidden Host". - */ - inline void setHiddenHost() - { insecureHost = account + hiddenHostSuffix ; } - - /** - * This method will set the hidden host suffix. This value - * is only modified by the xServer on startup. - */ - inline static void setHiddenHostSuffix( const std::string& newVal ) - { hiddenHostSuffix = newVal ; } - - /** - * Retrieve client's 'account' field. - */ - inline const std::string& getAccount() const - { return account ; } - - /** - * Retrieve client's account id. - * - * @return the id of the account if set, else 0. - */ - inline const unsigned int& getAccountID() const - { return account_id; } - - /** - * Retrieve client's account flags. - * - * @return the flags of the account if set, else 0. - */ - inline const flagType& getAccountFlags() const - { return account_flags; } - - /** - * Return true if this client's account has the given flag set, - * false otherwise. - */ - inline bool getAccountFlag( const flagType& theFlag ) const - { return (theFlag == (account_flags & theFlag)) ; } - - /** - * Return the suffix hostname to be appended to the - * user's account name for use with host hiding. - */ - inline static const std::string& getHiddenHostSuffix() - { return hiddenHostSuffix ; } - - /** - * This method sets user mode +r and records the account - * domain for this network client. - */ - inline void setAccount( const std::string& _account ) - { - account = _account ; - setModeR() ; - - // We know that the user is mode R already - if (isModeX()) setHiddenHost(); - } - - /** - * Set the account ID for this iClient. - * Only valid if the iClient isModeR() - */ - inline void setAccountID( const unsigned int& _account_id ) - { - if( ! isModeR() ) { return ; } - account_id = _account_id ; - } - - /** - * Set the account flags for this iClient. - */ - inline void setAccountFlags( const flagType& newFlags ) - { - if( ! isModeR() ) { return ; } - account_flags = newFlags ; - } - - /** - * Set an account flag for this iClient. - */ - inline void setAccountFlag( const flagType& newFlag ) - { - if( ! isModeR() ) { return ; } - account_flags |= newFlag ; - } - - /** - * Set the TLS fingerprint for this iClient. - */ - inline void setTlsFingerprint( const std::string& _tls_fingerprint ) - { - if( ! isModeZ() ) { return ; } - tlsFingerprint = _tls_fingerprint ; - } +class iClient : public NetworkTarget { + + protected: + /** + * The type used to hold channel patronage information + * for each particular user. + */ + typedef std::list channelListType; + + public: + /** + * Define a type to be used for storing the + * iClient's modes. + */ + typedef unsigned int modeType; + + /// MODE_OPER is true if the iClient is an IRC operator. + static constexpr modeType MODE_OPER = 0x0001; + + /// MODE_WALLOPS is true if the iClient is receiving wallops. + static constexpr modeType MODE_WALLOPS = 0x0002; + + /// MODE_INVISIBLE is true if the iClient is user mode invisible. + static constexpr modeType MODE_INVISIBLE = 0x0004; + + /// MODE_DEAF is true if the iClient is not receiving messages. + static constexpr modeType MODE_DEAF = 0x0008; + + /// MODE_SERVICES is true if the iClient is a service agent. + static constexpr modeType MODE_SERVICES = 0x0010; + + /// MODE_REGISTERED is true if the iClient has an account set. + static constexpr modeType MODE_REGISTERED = 0x0020; + + /// MODE_HIDDEN_HOST is true if the iClient has HIDDEN_HOST (+x) set. + static constexpr modeType MODE_HIDDEN_HOST = 0x0040; + + /// MODE_G is true if the iCilent has user mode g set. + static constexpr modeType MODE_G = 0x0080; + + /// MODE_SERVNOTICES is true if this user is receiving server + /// notices. This may not be transmitted on all networks. + static constexpr modeType MODE_SERVNOTICES = 0x0100; + + /** MODE_FAKE is true if this user is a fake client. */ + static constexpr modeType MODE_FAKE = 0x0200; + + /** MODE_TLS is true if this user is using TLS. */ + static constexpr modeType MODE_TLS = 0x0400; + + /** + * Define a type to be used for storing the + * iClient's account's flags. + */ + typedef unsigned short int flagType; + static constexpr flagType X_TOTP_ENABLED = 0x001; + static constexpr flagType X_TOTP_REQ_IPR = 0x002; + static constexpr flagType X_GLOBAL_SUSPEND = 0x004; + static constexpr flagType X_FRAUD = 0x008; + static constexpr flagType X_CERTONLY = 0x010; + static constexpr flagType X_CERT_DISABLE_TOTP = 0x020; + static constexpr flagType X_WEB_DISABLE_TOTP = 0x040; + + /// Iterator for channels this user is on. + typedef channelListType::iterator channelIterator; + + /// Constant iterator for channels this user is on. + typedef channelListType::const_iterator const_channelIterator; + + /// Type used to store the number of channels for this iClient + typedef channelListType::size_type channels_sizeType; + + /** + * Construct a new iClient given a large list of + * parameters for the client's state. + */ + iClient(const unsigned int& _uplink, const std::string& _yyxxx, const std::string& _nickName, + const std::string& _userName, const std::string& _hostBase64, + const std::string& _insecureHost, const std::string& _realInsecureHost, + const std::string& _mode, const std::string& _account, const unsigned int _account_id, + const flagType _account_flags, const std::string& _tls_fingerprint, + const std::string& _description, const time_t& _nick_ts); + + /** + * Construct a new iClient given a large list of + * parameters for the client's state. + * This signature assumes that either/both of asuka are being + * used. + */ + iClient(const unsigned int& _uplink, const std::string& _yyxxx, const std::string& _nickName, + const std::string& _userName, const std::string& _hostBase64, + const std::string& _insecureHost, const std::string& _realInsecureHost, + const std::string& _mode, const std::string& _account, const unsigned int _account_id, + const flagType _account_flags, const std::string& _tls_fingerprint, + const std::string& _setHost, const std::string& _fakeHost, + const std::string& _description, const time_t& _nick_ts); + + /** + * Destruct the iClient. + * This will call xClient::deleteCustomData() for each + * xClient which is storing a data element in this iClient. + */ + virtual ~iClient(); + + /* Accessor methods */ + + /** + * Retrieve the iClient's nick name. + */ + inline const std::string& getNickName() const { return nickName; } + + /** + * Retrieve the iClient's user name. + */ + inline const std::string& getUserName() const { return userName; } + + /** + * Retrieve the iClient's host name, NOT IP. + */ + inline const std::string& getInsecureHost() const { return insecureHost; } + + /** + * Retrieve the iClient's 'real' host name. + */ + inline const std::string& getRealInsecureHost() const { return realInsecureHost; } + + /** + * Retrieve a string of the form: nick!user for this user. + */ + inline const std::string getNickUser() const { return (nickName + '!' + userName); } + + /** + * Retrieve a string of the form: nick!user@host for this user. + */ + inline const std::string getNickUserHost() const { + return (nickName + '!' + userName + '@' + insecureHost); + } + + /** + * Retrieve a string of the form: user@real-host for this user. + */ + inline const std::string getRealUserHost() const { return (userName + '@' + realInsecureHost); } + + /** + * Retrieve a string of the form: nick!user@real-host for this user. + */ + inline const std::string getRealNickUserHost() const { + return (nickName + '!' + userName + '@' + realInsecureHost); + } + + /** + * Retrieve client's TLS fingerprint. + * Will return empty if the client is not using TLS. + */ + inline const std::string& getTlsFingerprint() const { return tlsFingerprint; } + + /** + * Returns true if the client has a fingerprint. + */ + inline bool hasTlsFingerprint() const { return !tlsFingerprint.empty(); } + + /** + * Retrieve client's 'real-name' field. + */ + inline const std::string& getDescription() const { return description; } + + /** + * Overwrite this clients "Real Host" with a "Hidden Host". + */ + inline void setHiddenHost() { insecureHost = account + hiddenHostSuffix; } + + /** + * This method will set the hidden host suffix. This value + * is only modified by the xServer on startup. + */ + inline static void setHiddenHostSuffix(const std::string& newVal) { hiddenHostSuffix = newVal; } + + /** + * Retrieve client's 'account' field. + */ + inline const std::string& getAccount() const { return account; } + + /** + * Retrieve client's account id. + * + * @return the id of the account if set, else 0. + */ + inline const unsigned int& getAccountID() const { return account_id; } + + /** + * Retrieve client's account flags. + * + * @return the flags of the account if set, else 0. + */ + inline const flagType& getAccountFlags() const { return account_flags; } + + /** + * Return true if this client's account has the given flag set, + * false otherwise. + */ + inline bool getAccountFlag(const flagType& theFlag) const { + return (theFlag == (account_flags & theFlag)); + } + + /** + * Return the suffix hostname to be appended to the + * user's account name for use with host hiding. + */ + inline static const std::string& getHiddenHostSuffix() { return hiddenHostSuffix; } + + /** + * This method sets user mode +r and records the account + * domain for this network client. + */ + inline void setAccount(const std::string& _account) { + account = _account; + setModeR(); + + // We know that the user is mode R already + if (isModeX()) + setHiddenHost(); + } + + /** + * Set the account ID for this iClient. + * Only valid if the iClient isModeR() + */ + inline void setAccountID(const unsigned int& _account_id) { + if (!isModeR()) { + return; + } + account_id = _account_id; + } + + /** + * Set the account flags for this iClient. + */ + inline void setAccountFlags(const flagType& newFlags) { + if (!isModeR()) { + return; + } + account_flags = newFlags; + } + + /** + * Set an account flag for this iClient. + */ + inline void setAccountFlag(const flagType& newFlag) { + if (!isModeR()) { + return; + } + account_flags |= newFlag; + } + + /** + * Set the TLS fingerprint for this iClient. + */ + inline void setTlsFingerprint(const std::string& _tls_fingerprint) { + if (!isModeZ()) { + return; + } + tlsFingerprint = _tls_fingerprint; + } #ifdef ASUKA - /** - * Retrieve the iClient's sethost. - */ - inline const std::string& getSetHost() const - { return setHost ; } + /** + * Retrieve the iClient's sethost. + */ + inline const std::string& getSetHost() const { return setHost; } #endif #ifdef SRVX - /** - * Retrieve the iClient's fakehost. - */ - inline const std::string& getFakeHost() const - { return fakeHost ; } + /** + * Retrieve the iClient's fakehost. + */ + inline const std::string& getFakeHost() const { return fakeHost; } #endif - /** - * Retrieve the iClient's server - */ - const iServer* getServer(); - - /** - * Retrieve the iClient's nickname timestamp. - */ - inline const time_t& getNickTS() const - { return nick_ts ; } - - /** - * Retrieve the first nickname timestamp recorded - * for an iClient. - * For clients having connected prior to gnuworld being linked, - * the timestamp will be the latter of their connection timestamp - * and the timestamp of any nickname changes after connection but - * prior to gnuworld linking. - * - * For clients connecting after gnuworld being linked, this will be - * their connection timestamp. - */ - inline const time_t& getFirstNickTS() const - { return first_nick_ts ; } - - /** - * Set the iClient's nickname timestamp. - */ - inline void setNickTS( const time_t& newTS ) - { nick_ts = newTS ; } - - /** - * Retrieve the iClient's IP. Network byte ordered - */ - inline const irc_in_addr& getIP() const - { return IP ; } - - /* - * Cut down all the numeric conversions, get it directly - */ - inline const std::string& getNumericIP() const - { return numericIP ; } - - /** - * Return the iClient's channelList. - */ - inline const channelListType channels() const - { return channelList ; } - - /** - * Obtain const iterator to beginning of this user's channel - * membership structure. - */ - inline const_channelIterator channels_begin() const - { return channelList.begin() ; } - - /** - * Obtain const iterator to end of this user's channel - * membership structure. - */ - inline const_channelIterator channels_end() const - { return channelList.end() ; } - - /** - * Obtain mutable iterator to beginning of this user's channel - * membership structure. - */ - inline channelIterator channels_begin() - { return channelList.begin() ; } - - /** - * Obtain mutable iterator to end of this user's channel - * membership structure. - */ - inline channelIterator channels_end() - { return channelList.end() ; } - - /** - * Return the number of channels which this user is on. - */ - inline channels_sizeType channels_size() const - { return channelList.size() ; } - - /* Mutator methods */ - - /** - * Add a channel to this user's channel patronage structure. - */ - bool addChannel( Channel* newChannel ) ; - - /** - * Remove a channel from this user's channel patronage structure. - */ - bool removeChannel( Channel* theChannel ) ; - - /** - * Return true if this iClient is in the given channel. - */ - bool findChannel( const Channel* theChannel ) const ; - - /** - * Clear this client's list of channels. No heap space needs - * to be deallocated here. - */ - inline void clearChannels() - { channelList.clear() ; } - - /** - * Change this iClient's nick name. - * During an iClient's lifetime on the network, the only - * thing that may change is its nickname. - */ - inline void setNickName( const std::string& newNick ) - { nickName = newNick ; } - - // The following methods are used to access and mutate - // the client's modes. - - /** - * Return true if this client has the given mode set, false - * otherwise. - */ - inline bool getMode( const modeType& theMode ) const - { return (theMode == (mode & theMode)) ; } - - /** - * Return true if this client has the +i mode set, false otherwise. - */ - inline bool isModeI() const - { return getMode( MODE_INVISIBLE ) ; } - - /** - * Return true if this client has the +w mode set, false otherwise. - */ - inline bool isModeW() const - { return getMode( MODE_WALLOPS ) ; } - - /** - * Return true if this client has the +k mode set, false otherwise. - */ - inline bool isModeK() const - { return getMode( MODE_SERVICES ) ; } - - /** - * Return true if this client has the +o mode set, false otherwise. - */ - inline bool isModeO() const - { return getMode( MODE_OPER ) ; } - - /** - * Return true if this client has the +d mode set, false otherwise. - */ - inline bool isModeD() const - { return getMode( MODE_DEAF ) ; } - - /** - * Return true if this client has the +r mode set, false otherwise. - */ - inline bool isModeR() const - { return getMode( MODE_REGISTERED ) ; } - - /** - * Return true if this client has the +x mode set, false otherwise. - */ - inline bool isModeX() const - { return getMode( MODE_HIDDEN_HOST ) ; } - - /** - * Return true if this client has the +g mode set, false otherwise. - */ - inline bool isModeG() const - { return getMode( MODE_G ) ; } - - /** - * Return true if this client has the +z mode set, - * indicating that the client is using TLS. False otherwise. - */ - inline bool isModeZ() const - { return getMode( MODE_TLS ) ; } - - /** - * Return true if this iClient is a fake, false otherwise. - */ - inline bool isFake() const - { return getMode( MODE_FAKE ) ; } - - /** - * Return true if this iClient is an oper, false otherwise. - */ - inline bool isOper() const - { return getMode( MODE_OPER ) ; } - - /** - * Return this iClient's current user modes. - */ - inline const modeType& getModes() const - { return mode ; } - - /** - * Set a user mode for this iClient. - */ - inline void setMode( const modeType& newMode ) - { mode |= newMode ; } - - /** - * Set mode +i for this user. - */ - inline void setModeI() - { setMode( MODE_INVISIBLE ) ; } - - /** - * Set mode +w for this user. - */ - inline void setModeW() - { setMode( MODE_WALLOPS ) ; } - - /** - * Set mode +k for this user. - */ - inline void setModeK() - { setMode( MODE_SERVICES ) ; } - - /** - * Set mode +d for this user. - */ - inline void setModeD() - { setMode( MODE_DEAF ) ; } - - /** - * Set mode +g for this user. - */ - inline void setModeG() - { setMode( MODE_G ) ; } - - /** - * Set mode +o for this user. - */ - inline void setModeO() - { setMode( MODE_OPER ) ; } - - /** - * Set mode +x for this user. - */ - inline void setModeX() - { - setMode( MODE_HIDDEN_HOST ) ; - if (isModeR() && isModeX()) setHiddenHost(); - } - - /** - * Set mode +r for this user. - */ - inline void setModeR() - { setMode( MODE_REGISTERED ) ; } - - /** - * Set mode +z for this user. - */ - inline void setModeZ() - { setMode( MODE_TLS ) ; } - - /** - * Designate this iClient as a fake. - */ - inline void setFake() - { setMode( MODE_FAKE ) ; } - - /** - * Remove a user mode for this iClient. - */ - inline void removeMode( const modeType& theMode ) - { mode &= ~theMode ; } - - /** - * Remove user mode 'i'. - */ - inline void removeModeI() - { removeMode( MODE_INVISIBLE ) ; } - - /** - * Remove user mode 'w'. - */ - inline void removeModeW() - { removeMode( MODE_WALLOPS ) ; } - - /** - * Remove user mode 'k'. - */ - inline void removeModeK() - { removeMode( MODE_SERVICES ) ; } - - /** - * Remove user mode 'd'. - */ - inline void removeModeD() - { removeMode( MODE_DEAF ) ; } - - /** - * Remove user mode 'g'. - */ - inline void removeModeG() - { removeMode( MODE_G ) ; } - - /** - * Remove user mode 'o'. - */ - inline void removeModeO() - { removeMode( MODE_OPER ) ; } - - /** - * Remove user mode 'x'. - */ - inline void removeModeX() - { removeMode( MODE_HIDDEN_HOST ) ; } - - /** - * Remove user mode 'r'. - */ - inline void removeModeR() - { removeMode( MODE_REGISTERED ) ; } - - /** - * Return a string representation of this iClient's user - * modes. - */ - const std::string getStringModes() const ; - - /** - * Add an xClient's personal data representation to this - * iClient. Only one element per xClient is permitted. - * This method will return false if the internal allocation - * fails, or if the xClient in question is already using - * a data element in this iClient, or if the addition to the - * internal data structure fails. - * Add a NULL value to this iClient is permitted. - */ - bool setCustomData( xClient*, void* ) ; - - /** - * Retrieve the custom data element for the given xClient. - * If none is found, NULL is returned. - */ - void* getCustomData( xClient* ) const ; - - /** - * Retrieve, remove, and return the custom data element - * for the given xClient. If none is found, NULL is - * returned. - */ - void* removeCustomData( xClient* ) ; - - /** - * operator<< is overloaded for debugging purposes, - * this makes it extremely easy to output this client's - * information to an output stream. - */ - friend ELog& operator<<( ELog& out, - const iClient& theClient ) - { - out << theClient.nickName << '!' - << theClient.userName << '@' - << theClient.insecureHost - << " Numeric: " << theClient.getCharYYXXX() - << ", int YY/XXX/YYXXX: " - << theClient.getIntYY() << '/' - << theClient.getIntXXX() << '/' - << theClient.getIntYYXXX() ; - return out ; - } - -protected: - - /** - * Disable copy constructor. This method is declared but - * NOT defined. - */ - iClient( const iClient& ) ; - - /** - * Disable default assignment. This method is declared but - * NOT defined. - */ - iClient operator=( const iClient& ) ; - - /** - * Parse a string of modes and set this iClient's - * modes appropriately. - * This is called by the constructor only. - */ - void setModes( const std::string& ) ; - - // The below variables are ordered to provide - // efficient instantiation. Do not alter order. - - /** - * This client's nick name. - */ - std::string nickName ; - - /** This client's user name. - */ - std::string userName ; - - /** - * This client's 128 bit IP, stored in - * network (bigendian) byte order. - */ - irc_in_addr IP ; - - /* - * Converted to string, for smoother usage everywhere - */ - std::string numericIP; - - /** - * This client's hostname as it appears to network users. - * (Possibly a hidden-hostname is the user is +x) - */ - std::string insecureHost ; - - /** - * This client's actual network hostname, unhidden and - * exposed. - */ - std::string realInsecureHost ; - - /** - * This client's 'real-name' field data. - */ - std::string description ; - - /** - * The time at which this iClient took its current nickname. - */ - time_t nick_ts ; - - /** - * The first nickname timestamp received for a client either at burst - * or at connect. - */ - time_t first_nick_ts ; - - /** - * This client's current user modes. - */ - modeType mode ; - - /** This client's "Account". */ - std::string account ; - - /** The id of this client's account. */ - unsigned int account_id ; - - /** The flags of this client's account. */ - unsigned short int account_flags ; - - /** The TLS fingerprint of this client. */ - std::string tlsFingerprint ; + /** + * Retrieve the iClient's server + */ + const iServer* getServer(); + + /** + * Retrieve the iClient's nickname timestamp. + */ + inline const time_t& getNickTS() const { return nick_ts; } + + /** + * Retrieve the first nickname timestamp recorded + * for an iClient. + * For clients having connected prior to gnuworld being linked, + * the timestamp will be the latter of their connection timestamp + * and the timestamp of any nickname changes after connection but + * prior to gnuworld linking. + * + * For clients connecting after gnuworld being linked, this will be + * their connection timestamp. + */ + inline const time_t& getFirstNickTS() const { return first_nick_ts; } + + /** + * Set the iClient's nickname timestamp. + */ + inline void setNickTS(const time_t& newTS) { nick_ts = newTS; } + + /** + * Retrieve the iClient's IP. Network byte ordered + */ + inline const irc_in_addr& getIP() const { return IP; } + + /* + * Cut down all the numeric conversions, get it directly + */ + inline const std::string& getNumericIP() const { return numericIP; } + + /** + * Return the iClient's channelList. + */ + inline const channelListType channels() const { return channelList; } + + /** + * Obtain const iterator to beginning of this user's channel + * membership structure. + */ + inline const_channelIterator channels_begin() const { return channelList.begin(); } + + /** + * Obtain const iterator to end of this user's channel + * membership structure. + */ + inline const_channelIterator channels_end() const { return channelList.end(); } + + /** + * Obtain mutable iterator to beginning of this user's channel + * membership structure. + */ + inline channelIterator channels_begin() { return channelList.begin(); } + + /** + * Obtain mutable iterator to end of this user's channel + * membership structure. + */ + inline channelIterator channels_end() { return channelList.end(); } + + /** + * Return the number of channels which this user is on. + */ + inline channels_sizeType channels_size() const { return channelList.size(); } + + /* Mutator methods */ + + /** + * Add a channel to this user's channel patronage structure. + */ + bool addChannel(Channel* newChannel); + + /** + * Remove a channel from this user's channel patronage structure. + */ + bool removeChannel(Channel* theChannel); + + /** + * Return true if this iClient is in the given channel. + */ + bool findChannel(const Channel* theChannel) const; + + /** + * Clear this client's list of channels. No heap space needs + * to be deallocated here. + */ + inline void clearChannels() { channelList.clear(); } + + /** + * Change this iClient's nick name. + * During an iClient's lifetime on the network, the only + * thing that may change is its nickname. + */ + inline void setNickName(const std::string& newNick) { nickName = newNick; } + + // The following methods are used to access and mutate + // the client's modes. + + /** + * Return true if this client has the given mode set, false + * otherwise. + */ + inline bool getMode(const modeType& theMode) const { return (theMode == (mode & theMode)); } + + /** + * Return true if this client has the +i mode set, false otherwise. + */ + inline bool isModeI() const { return getMode(MODE_INVISIBLE); } + + /** + * Return true if this client has the +w mode set, false otherwise. + */ + inline bool isModeW() const { return getMode(MODE_WALLOPS); } + + /** + * Return true if this client has the +k mode set, false otherwise. + */ + inline bool isModeK() const { return getMode(MODE_SERVICES); } + + /** + * Return true if this client has the +o mode set, false otherwise. + */ + inline bool isModeO() const { return getMode(MODE_OPER); } + + /** + * Return true if this client has the +d mode set, false otherwise. + */ + inline bool isModeD() const { return getMode(MODE_DEAF); } + + /** + * Return true if this client has the +r mode set, false otherwise. + */ + inline bool isModeR() const { return getMode(MODE_REGISTERED); } + + /** + * Return true if this client has the +x mode set, false otherwise. + */ + inline bool isModeX() const { return getMode(MODE_HIDDEN_HOST); } + + /** + * Return true if this client has the +g mode set, false otherwise. + */ + inline bool isModeG() const { return getMode(MODE_G); } + + /** + * Return true if this client has the +z mode set, + * indicating that the client is using TLS. False otherwise. + */ + inline bool isModeZ() const { return getMode(MODE_TLS); } + + /** + * Return true if this iClient is a fake, false otherwise. + */ + inline bool isFake() const { return getMode(MODE_FAKE); } + + /** + * Return true if this iClient is an oper, false otherwise. + */ + inline bool isOper() const { return getMode(MODE_OPER); } + + /** + * Return this iClient's current user modes. + */ + inline const modeType& getModes() const { return mode; } + + /** + * Set a user mode for this iClient. + */ + inline void setMode(const modeType& newMode) { mode |= newMode; } + + /** + * Set mode +i for this user. + */ + inline void setModeI() { setMode(MODE_INVISIBLE); } + + /** + * Set mode +w for this user. + */ + inline void setModeW() { setMode(MODE_WALLOPS); } + + /** + * Set mode +k for this user. + */ + inline void setModeK() { setMode(MODE_SERVICES); } + + /** + * Set mode +d for this user. + */ + inline void setModeD() { setMode(MODE_DEAF); } + + /** + * Set mode +g for this user. + */ + inline void setModeG() { setMode(MODE_G); } + + /** + * Set mode +o for this user. + */ + inline void setModeO() { setMode(MODE_OPER); } + + /** + * Set mode +x for this user. + */ + inline void setModeX() { + setMode(MODE_HIDDEN_HOST); + if (isModeR() && isModeX()) + setHiddenHost(); + } + + /** + * Set mode +r for this user. + */ + inline void setModeR() { setMode(MODE_REGISTERED); } + + /** + * Set mode +z for this user. + */ + inline void setModeZ() { setMode(MODE_TLS); } + + /** + * Designate this iClient as a fake. + */ + inline void setFake() { setMode(MODE_FAKE); } + + /** + * Remove a user mode for this iClient. + */ + inline void removeMode(const modeType& theMode) { mode &= ~theMode; } + + /** + * Remove user mode 'i'. + */ + inline void removeModeI() { removeMode(MODE_INVISIBLE); } + + /** + * Remove user mode 'w'. + */ + inline void removeModeW() { removeMode(MODE_WALLOPS); } + + /** + * Remove user mode 'k'. + */ + inline void removeModeK() { removeMode(MODE_SERVICES); } + + /** + * Remove user mode 'd'. + */ + inline void removeModeD() { removeMode(MODE_DEAF); } + + /** + * Remove user mode 'g'. + */ + inline void removeModeG() { removeMode(MODE_G); } + + /** + * Remove user mode 'o'. + */ + inline void removeModeO() { removeMode(MODE_OPER); } + + /** + * Remove user mode 'x'. + */ + inline void removeModeX() { removeMode(MODE_HIDDEN_HOST); } + + /** + * Remove user mode 'r'. + */ + inline void removeModeR() { removeMode(MODE_REGISTERED); } + + /** + * Return a string representation of this iClient's user + * modes. + */ + const std::string getStringModes() const; + + /** + * Add an xClient's personal data representation to this + * iClient. Only one element per xClient is permitted. + * This method will return false if the internal allocation + * fails, or if the xClient in question is already using + * a data element in this iClient, or if the addition to the + * internal data structure fails. + * Add a NULL value to this iClient is permitted. + */ + bool setCustomData(xClient*, void*); + + /** + * Retrieve the custom data element for the given xClient. + * If none is found, NULL is returned. + */ + void* getCustomData(xClient*) const; + + /** + * Retrieve, remove, and return the custom data element + * for the given xClient. If none is found, NULL is + * returned. + */ + void* removeCustomData(xClient*); + + /** + * operator<< is overloaded for debugging purposes, + * this makes it extremely easy to output this client's + * information to an output stream. + */ + friend ELog& operator<<(ELog& out, const iClient& theClient) { + out << theClient.nickName << '!' << theClient.userName << '@' << theClient.insecureHost + << " Numeric: " << theClient.getCharYYXXX() + << ", int YY/XXX/YYXXX: " << theClient.getIntYY() << '/' << theClient.getIntXXX() << '/' + << theClient.getIntYYXXX(); + return out; + } + + protected: + /** + * Disable copy constructor. This method is declared but + * NOT defined. + */ + iClient(const iClient&); + + /** + * Disable default assignment. This method is declared but + * NOT defined. + */ + iClient operator=(const iClient&); + + /** + * Parse a string of modes and set this iClient's + * modes appropriately. + * This is called by the constructor only. + */ + void setModes(const std::string&); + + // The below variables are ordered to provide + // efficient instantiation. Do not alter order. + + /** + * This client's nick name. + */ + std::string nickName; + + /** This client's user name. + */ + std::string userName; + + /** + * This client's 128 bit IP, stored in + * network (bigendian) byte order. + */ + irc_in_addr IP; + + /* + * Converted to string, for smoother usage everywhere + */ + std::string numericIP; + + /** + * This client's hostname as it appears to network users. + * (Possibly a hidden-hostname is the user is +x) + */ + std::string insecureHost; + + /** + * This client's actual network hostname, unhidden and + * exposed. + */ + std::string realInsecureHost; + + /** + * This client's 'real-name' field data. + */ + std::string description; + + /** + * The time at which this iClient took its current nickname. + */ + time_t nick_ts; + + /** + * The first nickname timestamp received for a client either at burst + * or at connect. + */ + time_t first_nick_ts; + + /** + * This client's current user modes. + */ + modeType mode; + + /** This client's "Account". */ + std::string account; + + /** The id of this client's account. */ + unsigned int account_id; + + /** The flags of this client's account. */ + unsigned short int account_flags; + + /** The TLS fingerprint of this client. */ + std::string tlsFingerprint; #ifdef ASUKA - /** - * This client's sethost. - */ - std::string setHost ; + /** + * This client's sethost. + */ + std::string setHost; #endif #ifdef SRVX - /** - * This client's fakehost. - */ - std::string fakeHost ; + /** + * This client's fakehost. + */ + std::string fakeHost; #endif - /** - * The structure used to store which channels this user is in. - */ - channelListType channelList ; - - /** - * This is the type used to represent the custom data map. - */ - typedef std::map< xClient*, void* > customDataMapType ; - - /** - * This structure is used to store generic data for - * individual xClient's. Only one element per xClient is - * permitted to be stored in this structure. A pointer is - * used here to reduce memory footprint for those iClient's - * whose customDataMap's aren't used. - */ - customDataMapType *customDataMap ; - - /** - * The suffix for all hidden host names. - * This variable is read from the .conf file, and - * has the form of "mynetwork.org". - */ - static std::string hiddenHostSuffix ; - -} ; + /** + * The structure used to store which channels this user is in. + */ + channelListType channelList; + + /** + * This is the type used to represent the custom data map. + */ + typedef std::map customDataMapType; + + /** + * This structure is used to store generic data for + * individual xClient's. Only one element per xClient is + * permitted to be stored in this structure. A pointer is + * used here to reduce memory footprint for those iClient's + * whose customDataMap's aren't used. + */ + customDataMapType* customDataMap; + + /** + * The suffix for all hidden host names. + * This variable is read from the .conf file, and + * has the form of "mynetwork.org". + */ + static std::string hiddenHostSuffix; +}; } // namespace gnuworld diff --git a/include/iServer.h b/include/iServer.h index 36f8ccb7..c9f88c0e 100644 --- a/include/iServer.h +++ b/include/iServer.h @@ -25,322 +25,281 @@ #ifndef __ISERVER_H #define __ISERVER_H "$Id: iServer.h,v 1.15 2006/12/22 06:41:41 kewlio Exp $" -#include -#include +#include +#include -#include +#include -#include "ELog.h" -#include "NetworkTarget.h" +#include "ELog.h" +#include "NetworkTarget.h" -namespace gnuworld -{ +namespace gnuworld { -class xServer ; -class xNetwork ; +class xServer; +class xNetwork; /** * This class represents a network server. */ -class iServer : public NetworkTarget -{ - /** - * Allow xServer to directly manipulate the - * internal state of this iServer. - */ - friend class xServer ; - - /** - * xNetwork needs access to setIntYY(). - */ - friend class xNetwork ; - -public: - - /// Type used to hold flags - typedef unsigned int flagType ; - - /** - * Flags that iServers may have. - */ - /* Set if this iServer is juped, false otherwise */ - static const flagType FLAG_JUPE ; - /* Set if this iServer is a hub (+h) */ - static const flagType FLAG_HUB ; - /* Set if this iServer is a service (+s) */ - static const flagType FLAG_SERVICE ; - /* Set if this iServer is IPv6-compatible (+6) */ - static const flagType FLAG_IPV6 ; - - /** - * Construct an iServer given its vital state variables - * as parameters. - */ - iServer( const unsigned int& _uplink, - const std::string& _yyxxx, - const std::string& _name, - const time_t& _connectTime, - const std::string& description = std::string() ) ; - - /** - * Destruct this iServer instance. - */ - virtual ~iServer() ; - - /* Accessor methods */ - - /** - * Return the iServer's flags. - */ - inline const flagType& getFlags() const - { return flags ; } - - /** - * Return true if a particular flag is set, false otherwise. - */ - inline bool getFlag( const flagType& whichFlag ) const - { return ((flags & whichFlag) == whichFlag) ; } - - /** - * Set a particular flags. - */ - inline void setFlag( const flagType& whichFlag ) - { flags |= whichFlag ; } - - /** - * Remove a particular flag. - */ - inline void removeFlag( const flagType& whichFlag ) - { flags &= ~whichFlag ; } - - /** - * Return true if this server is a jupe. - */ - inline bool isJupe() const - { return getFlag( FLAG_JUPE ) ; } - - /** - * Set this iServer as a juped server. - */ - inline void setJupe() - { setFlag( FLAG_JUPE ) ; } - - /** - * Return true if this server is a hub. - */ - inline bool isHub() const - { return getFlag( FLAG_HUB ) ; } - - /** - * Set this iServer as a hub. - */ - inline void setHub() - { setFlag( FLAG_HUB ) ; } - - /** - * Return true if this server is a service - */ - inline bool isService() const - { return getFlag( FLAG_SERVICE ) ; } - - /** - * Set this iServer as a service. - */ - inline void setService() - { setFlag( FLAG_SERVICE ) ; } - - /** - * Return true if this server is IPv6-compatible - */ - inline bool isIPv6() const - { return getFlag( FLAG_IPV6 ) ; } - - /** - * Set this iServer as IPv6-compatible - */ - inline void setIPv6() - { setFlag( FLAG_IPV6 ) ; } - - /** - * Return the server numeric of this server's uplink. - */ - inline const unsigned int& getUplinkIntYY() const - { return uplinkIntYY ; } - - /** - * Return the name of this server. - */ - inline const std::string& getName() const - { return name ; } - - /** - * Return the time at which this server connected to the network. - */ - inline const time_t& getConnectTime() const - { return connectTime ; } - - /** - * Return the time at which this server started. - */ - inline const time_t& getStartTime() const - { return startTime ; } - - /** - * Return the lag of this server (in seconds). - */ - inline const time_t& getLag() const - { return lag ; } - - /** - * Set the lag value and update lastLagTS to current TS. - */ - inline void setLag( const time_t& _lag ) - { - lag = _lag ; - lastLagTS = ::time(0) ; - } - - /** - * Return the TS of the last lag update - */ - inline const time_t& getLastLagTS() const - { return lastLagTS ; } - - /** - * Return the description of this server. - */ - inline const std::string& getDescription() const - { return description ; } - - /** - * Return true if no BURST state exists, false otherwise. - */ - virtual bool isBursting() const - { return bursting ; } - - /** - * This method is used by xServer to signify that this - * iServer is now in the bursting state. - */ - virtual void startBursting() - { bursting = true ; } - - /** - * This method is called by xServer to signify that this - * iServer has completed bursting. - */ - virtual void stopBursting() - { bursting = false ; } - - /** - * Permit setting an arbitrary value to the bursting - * variable. - */ - virtual void setBursting( bool newVal ) - { bursting = newVal ; } - - /** - * This method is called by class xServer once the uplink - * of the xServer is known. This method is only called - * for the single instance of the iServer for the core - * xServer. - */ - virtual void setUplinkIntYY( const unsigned int& newYY ) - { uplinkIntYY = newYY ; } - - /** - * Nice debugging method for outputting the iServer's - * information to an ELog stream. - */ - friend ELog& operator<<( ELog& out, - const iServer& serv ) - { - out << "Name: " << serv.getName() << ' ' - << "intYY: " << serv.getIntYY() << ' ' - << "uplinkIntYY: " - << serv.getUplinkIntYY() << ' ' - << "charYY: " << serv.getCharYY() ; - return out ; - } - - /** - * Nice debugging method for outputting the iServer's - * information to a standard c++ output stream. - */ - friend std::ostream& operator<<( std::ostream& out, - const iServer& serv ) - { - out << "Name: " << serv.getName() << ' ' - << "intYY: " << serv.getIntYY() << ' ' - << "uplinkIntYY: " - << serv.getUplinkIntYY() << ' ' - << "charYY: " << serv.getCharYY() ; - return out ; - } - - /* Mutator methods */ - - /** - * Interpret a server's flags. - */ - void setFlags( const std::string& ) ; - -protected: - - /** - * Allow friends to modify the iServer's description. This - * is used in the case of adding this server as a juped - * server. - */ - inline void setDescription( const std::string& newDescription ) - { description = newDescription ; } - - /** - * Integer numeric of this server's uplink. - */ - unsigned int uplinkIntYY ; - - /** - * Name of this server. - */ - std::string name ; - - /** - * The time at which this server joined the network. - */ - time_t connectTime ; - - /** - * The time at which this server was started. - */ - time_t startTime ; - - /** - * The server's description field. - */ - std::string description ; - - /** - * This variable is true when this server is bursting. - */ - bool bursting ; - - /** - * This server's flags. - */ - flagType flags ; - - /** - * This server's lag time (in seconds), based on the last nick change - * or new client connection from this server. - */ - time_t lag ; - - /** - * Timestamp of last update of the lag value for this server - */ - time_t lastLagTS ; -} ; +class iServer : public NetworkTarget { + /** + * Allow xServer to directly manipulate the + * internal state of this iServer. + */ + friend class xServer; + + /** + * xNetwork needs access to setIntYY(). + */ + friend class xNetwork; + + public: + /// Type used to hold flags + typedef unsigned int flagType; + + /** + * Flags that iServers may have. + */ + /* Set if this iServer is juped, false otherwise */ + static const flagType FLAG_JUPE; + /* Set if this iServer is a hub (+h) */ + static const flagType FLAG_HUB; + /* Set if this iServer is a service (+s) */ + static const flagType FLAG_SERVICE; + /* Set if this iServer is IPv6-compatible (+6) */ + static const flagType FLAG_IPV6; + + /** + * Construct an iServer given its vital state variables + * as parameters. + */ + iServer(const unsigned int& _uplink, const std::string& _yyxxx, const std::string& _name, + const time_t& _connectTime, const std::string& description = std::string()); + + /** + * Destruct this iServer instance. + */ + virtual ~iServer(); + + /* Accessor methods */ + + /** + * Return the iServer's flags. + */ + inline const flagType& getFlags() const { return flags; } + + /** + * Return true if a particular flag is set, false otherwise. + */ + inline bool getFlag(const flagType& whichFlag) const { + return ((flags & whichFlag) == whichFlag); + } + + /** + * Set a particular flags. + */ + inline void setFlag(const flagType& whichFlag) { flags |= whichFlag; } + + /** + * Remove a particular flag. + */ + inline void removeFlag(const flagType& whichFlag) { flags &= ~whichFlag; } + + /** + * Return true if this server is a jupe. + */ + inline bool isJupe() const { return getFlag(FLAG_JUPE); } + + /** + * Set this iServer as a juped server. + */ + inline void setJupe() { setFlag(FLAG_JUPE); } + + /** + * Return true if this server is a hub. + */ + inline bool isHub() const { return getFlag(FLAG_HUB); } + + /** + * Set this iServer as a hub. + */ + inline void setHub() { setFlag(FLAG_HUB); } + + /** + * Return true if this server is a service + */ + inline bool isService() const { return getFlag(FLAG_SERVICE); } + + /** + * Set this iServer as a service. + */ + inline void setService() { setFlag(FLAG_SERVICE); } + + /** + * Return true if this server is IPv6-compatible + */ + inline bool isIPv6() const { return getFlag(FLAG_IPV6); } + + /** + * Set this iServer as IPv6-compatible + */ + inline void setIPv6() { setFlag(FLAG_IPV6); } + + /** + * Return the server numeric of this server's uplink. + */ + inline const unsigned int& getUplinkIntYY() const { return uplinkIntYY; } + + /** + * Return the name of this server. + */ + inline const std::string& getName() const { return name; } + + /** + * Return the time at which this server connected to the network. + */ + inline const time_t& getConnectTime() const { return connectTime; } + + /** + * Return the time at which this server started. + */ + inline const time_t& getStartTime() const { return startTime; } + + /** + * Return the lag of this server (in seconds). + */ + inline const time_t& getLag() const { return lag; } + + /** + * Set the lag value and update lastLagTS to current TS. + */ + inline void setLag(const time_t& _lag) { + lag = _lag; + lastLagTS = ::time(0); + } + + /** + * Return the TS of the last lag update + */ + inline const time_t& getLastLagTS() const { return lastLagTS; } + + /** + * Return the description of this server. + */ + inline const std::string& getDescription() const { return description; } + + /** + * Return true if no BURST state exists, false otherwise. + */ + virtual bool isBursting() const { return bursting; } + + /** + * This method is used by xServer to signify that this + * iServer is now in the bursting state. + */ + virtual void startBursting() { bursting = true; } + + /** + * This method is called by xServer to signify that this + * iServer has completed bursting. + */ + virtual void stopBursting() { bursting = false; } + + /** + * Permit setting an arbitrary value to the bursting + * variable. + */ + virtual void setBursting(bool newVal) { bursting = newVal; } + + /** + * This method is called by class xServer once the uplink + * of the xServer is known. This method is only called + * for the single instance of the iServer for the core + * xServer. + */ + virtual void setUplinkIntYY(const unsigned int& newYY) { uplinkIntYY = newYY; } + + /** + * Nice debugging method for outputting the iServer's + * information to an ELog stream. + */ + friend ELog& operator<<(ELog& out, const iServer& serv) { + out << "Name: " << serv.getName() << ' ' << "intYY: " << serv.getIntYY() << ' ' + << "uplinkIntYY: " << serv.getUplinkIntYY() << ' ' << "charYY: " << serv.getCharYY(); + return out; + } + + /** + * Nice debugging method for outputting the iServer's + * information to a standard c++ output stream. + */ + friend std::ostream& operator<<(std::ostream& out, const iServer& serv) { + out << "Name: " << serv.getName() << ' ' << "intYY: " << serv.getIntYY() << ' ' + << "uplinkIntYY: " << serv.getUplinkIntYY() << ' ' << "charYY: " << serv.getCharYY(); + return out; + } + + /* Mutator methods */ + + /** + * Interpret a server's flags. + */ + void setFlags(const std::string&); + + protected: + /** + * Allow friends to modify the iServer's description. This + * is used in the case of adding this server as a juped + * server. + */ + inline void setDescription(const std::string& newDescription) { description = newDescription; } + + /** + * Integer numeric of this server's uplink. + */ + unsigned int uplinkIntYY; + + /** + * Name of this server. + */ + std::string name; + + /** + * The time at which this server joined the network. + */ + time_t connectTime; + + /** + * The time at which this server was started. + */ + time_t startTime; + + /** + * The server's description field. + */ + std::string description; + + /** + * This variable is true when this server is bursting. + */ + bool bursting; + + /** + * This server's flags. + */ + flagType flags; + + /** + * This server's lag time (in seconds), based on the last nick change + * or new client connection from this server. + */ + time_t lag; + + /** + * Timestamp of last update of the lag value for this server + */ + time_t lastLagTS; +}; } // namespace gnuworld diff --git a/include/ip.h b/include/ip.h index d6166420..1004ccf8 100644 --- a/include/ip.h +++ b/include/ip.h @@ -26,71 +26,66 @@ #ifndef __IP_H #define __IP_H "$Id: ip.h,v 1.7 2004/01/07 03:08:29 dan_karrels Exp $" -#include -#include "Numeric.h" +#include +#include "Numeric.h" -namespace gnuworld -{ +namespace gnuworld { /** * A utility class that is used to retrieve information about * IP addresses. */ -class xIP -{ - -public: - - /** - * Construct an xIP instance given an address in std::string - * format. - */ - xIP( const std::string& IP, bool Base64 = false ) ; - - /** - * Construct an xIP instance given an IP in irc_in_addr struct format. - */ - xIP( const irc_in_addr& IP ) ; - - /** - * Copy constructor. - */ - xIP( const xIP& IP ) ; - - /** - * Destruct this xIP instance. No heap space is allocated. - */ - ~xIP() {} - - /** - * Retrieve the IP in xxx.xxx.xxx.xxx/xx:xx::xx:xx character array format. - */ - std::string GetNumericIP(bool fixedToCIDR64 = false) const ; - - /** - * Retrieve the IP as an irc_in_addr struct. - */ - const irc_in_addr& GetLongIP() const ; - - /** - * Return a character array representation of the base 64 - * IP. - */ - std::string GetBase64IP() const ; - - /** - * Get the 32 bit integer representation of a current IPv4 address. - */ - unsigned int getIP32() const; - -protected: - - /** - * The IP number itself. - */ - irc_in_addr IP; - -} ; +class xIP { + + public: + /** + * Construct an xIP instance given an address in std::string + * format. + */ + xIP(const std::string& IP, bool Base64 = false); + + /** + * Construct an xIP instance given an IP in irc_in_addr struct format. + */ + xIP(const irc_in_addr& IP); + + /** + * Copy constructor. + */ + xIP(const xIP& IP); + + /** + * Destruct this xIP instance. No heap space is allocated. + */ + ~xIP() {} + + /** + * Retrieve the IP in xxx.xxx.xxx.xxx/xx:xx::xx:xx character array format. + */ + std::string GetNumericIP(bool fixedToCIDR64 = false) const; + + /** + * Retrieve the IP as an irc_in_addr struct. + */ + const irc_in_addr& GetLongIP() const; + + /** + * Return a character array representation of the base 64 + * IP. + */ + std::string GetBase64IP() const; + + /** + * Get the 32 bit integer representation of a current IPv4 address. + */ + unsigned int getIP32() const; + + protected: + /** + * The IP number itself. + */ + irc_in_addr IP; +}; } // namespace gnuworld diff --git a/include/moduleLoader.h b/include/moduleLoader.h index dffc5649..7a941005 100644 --- a/include/moduleLoader.h +++ b/include/moduleLoader.h @@ -24,218 +24,182 @@ #ifndef __MODULELOADER_H #define __MODULELOADER_H "$Id: moduleLoader.h,v 1.21 2004/05/18 16:50:57 dan_karrels Exp $" -#include -#include +#include +#include -#include // exit() -#include "ltdl.h" +#include // exit() +#include "ltdl.h" -#include "ELog.h" +#include "ELog.h" -namespace gnuworld -{ +namespace gnuworld { /** * This is a templated module loader class. The templated type is the * type of object to retrieve from the module. This class is used with * libtool for maximum portability. */ -template< typename modType, typename argType = std::string > -class moduleLoader -{ - -protected: - - /** - * This is the type of the bootstrap function. - */ - typedef modType (*GNUWModuleFunc)(argType arg) ; - - /** - * Pointer to the loaded module. - */ - lt_dlhandle moduleHandle ; - - /** - * Pointer to the initialisation function. - */ - GNUWModuleFunc modFunc ; - - /** - * Pointer to the object being retrieved from the - * module. - */ - modType modPtr ; - - /** - * The name of the module which this instance represents. - */ - std::string moduleName ; - - /** - * This variable is true if there was an error in loading - * or resolving a symbol, false otherwise. - */ - bool hasError ; - - /** - * Provide a protected mutator for this class to use to modify - * the error value. - */ - inline void setError( bool newVal = true ) - { hasError = newVal ; } - -public: - /** - * Constructor, takes a module filename as the only - * parameter. - */ - moduleLoader( const std::string& _moduleName ) - : moduleName( _moduleName ), - hasError( false ) - { - // Initialize the function pointer to 0 - modFunc = 0 ; - - // Must call lt_dlinit() to initialize libltdl. - // This method may be called more than once - if( lt_dlinit() != 0 ) - { - elog << "moduleLoader> Failed to initialize " - << "module loading system: " - << lt_dlerror() - << std::endl ; - setError() ; - return ; - } - - std::string fileName( moduleName ) ; - if( fileName[ 0 ] != '/' ) - { - // No absolute path specified - // Attempt to find the module in the currect directory - fileName = std::string( "./" ) + fileName ; - } - - // Libtool libraries end with .la, and at this point, this class - // only supports libtool libraries - if( std::string::npos == fileName.find( ".la" ) ) - { - // TODO: This should be more thorough - fileName += ".la" ; - } - -// elog << "moduleLoader> Attempting to load module " -// << fileName -// << std::endl; - - // lt_dlopenext() will do all that lt_dlopen() does, - // but also check for .la, .so, .sl, etc extensions - moduleHandle = lt_dlopen( fileName.c_str() ) ; - - if( 0 == moduleHandle ) - { - elog << "moduleLoader> Error opening module (" - << moduleName - << "): " - << lt_dlerror() - << std::endl; - setError() ; - return ; - } - -// elog << "moduleLoader> Module " -// << moduleName -// << " successfully loaded" -// << std::endl; - } - - /** - * The destructor closes the module, but does not perform - * any other deallocation. - */ - virtual ~moduleLoader() - { - if( lt_dlclose( moduleHandle ) != 0 ) - { - elog << "~moduleLoader> Error closing module: " - << lt_dlerror() - << std::endl ; - } - moduleHandle = 0 ; - } - - /** - * Extracts an instance of modType - * derived object from this module, and returns it. - * This method will execute only once for each instance. - * Each additional call after the initial call to laodObject() - * will return the object previously created. - * The symbolSuffix is used to distinguish between similarly - * named symbols to be loaded from the same module. - */ - modType loadObject( argType arg, - const std::string& symbolSuffix = std::string() ) - { - if( getError() ) - { - // Error already present - return 0 ; - } - - const std::string symbolName = - std::string( "_gnuwinit" ) + symbolSuffix ; - modFunc = (GNUWModuleFunc) lt_dlsym( moduleHandle, - symbolName.c_str() ) ; - if( 0 == modFunc ) - { - elog << "moduleLoader::loadObject> Error: " - << lt_dlerror() - << std::endl ; - setError() ; - return 0 ; - } - - modPtr = modFunc( arg ); - - // Types usable by this class must support comparison against 0 - if( 0 == modPtr ) - { - elog << "moduleLoader> Unable to instantiate modType." - << std::endl; - setError() ; - } - - return modPtr ; - } - - /** - * Return a string containing the module's name, as passed - * to the constructor - */ - inline const std::string& getModuleName() const - { return moduleName ; } - - /** - * Return the last error seen by the module system. - */ - inline const char* getLastError() const - { return ::lt_dlerror(); } - - /** - * Return by value the object being loaded from the module. - */ - inline modType getObject() const - { return modPtr ; } - - /** - * Return true if an error occured, false otherwise. - */ - inline bool getError() const - { return hasError ; } - -} ; - -} /* gnuworld */ - +template class moduleLoader { + + protected: + /** + * This is the type of the bootstrap function. + */ + typedef modType (*GNUWModuleFunc)(argType arg); + + /** + * Pointer to the loaded module. + */ + lt_dlhandle moduleHandle; + + /** + * Pointer to the initialisation function. + */ + GNUWModuleFunc modFunc; + + /** + * Pointer to the object being retrieved from the + * module. + */ + modType modPtr; + + /** + * The name of the module which this instance represents. + */ + std::string moduleName; + + /** + * This variable is true if there was an error in loading + * or resolving a symbol, false otherwise. + */ + bool hasError; + + /** + * Provide a protected mutator for this class to use to modify + * the error value. + */ + inline void setError(bool newVal = true) { hasError = newVal; } + + public: + /** + * Constructor, takes a module filename as the only + * parameter. + */ + moduleLoader(const std::string& _moduleName) : moduleName(_moduleName), hasError(false) { + // Initialize the function pointer to 0 + modFunc = 0; + + // Must call lt_dlinit() to initialize libltdl. + // This method may be called more than once + if (lt_dlinit() != 0) { + elog << "moduleLoader> Failed to initialize " + << "module loading system: " << lt_dlerror() << std::endl; + setError(); + return; + } + + std::string fileName(moduleName); + if (fileName[0] != '/') { + // No absolute path specified + // Attempt to find the module in the currect directory + fileName = std::string("./") + fileName; + } + + // Libtool libraries end with .la, and at this point, this class + // only supports libtool libraries + if (std::string::npos == fileName.find(".la")) { + // TODO: This should be more thorough + fileName += ".la"; + } + + // elog << "moduleLoader> Attempting to load module " + // << fileName + // << std::endl; + + // lt_dlopenext() will do all that lt_dlopen() does, + // but also check for .la, .so, .sl, etc extensions + moduleHandle = lt_dlopen(fileName.c_str()); + + if (0 == moduleHandle) { + elog << "moduleLoader> Error opening module (" << moduleName << "): " << lt_dlerror() + << std::endl; + setError(); + return; + } + + // elog << "moduleLoader> Module " + // << moduleName + // << " successfully loaded" + // << std::endl; + } + + /** + * The destructor closes the module, but does not perform + * any other deallocation. + */ + virtual ~moduleLoader() { + if (lt_dlclose(moduleHandle) != 0) { + elog << "~moduleLoader> Error closing module: " << lt_dlerror() << std::endl; + } + moduleHandle = 0; + } + + /** + * Extracts an instance of modType + * derived object from this module, and returns it. + * This method will execute only once for each instance. + * Each additional call after the initial call to laodObject() + * will return the object previously created. + * The symbolSuffix is used to distinguish between similarly + * named symbols to be loaded from the same module. + */ + modType loadObject(argType arg, const std::string& symbolSuffix = std::string()) { + if (getError()) { + // Error already present + return 0; + } + + const std::string symbolName = std::string("_gnuwinit") + symbolSuffix; + modFunc = (GNUWModuleFunc)lt_dlsym(moduleHandle, symbolName.c_str()); + if (0 == modFunc) { + elog << "moduleLoader::loadObject> Error: " << lt_dlerror() << std::endl; + setError(); + return 0; + } + + modPtr = modFunc(arg); + + // Types usable by this class must support comparison against 0 + if (0 == modPtr) { + elog << "moduleLoader> Unable to instantiate modType." << std::endl; + setError(); + } + + return modPtr; + } + + /** + * Return a string containing the module's name, as passed + * to the constructor + */ + inline const std::string& getModuleName() const { return moduleName; } + + /** + * Return the last error seen by the module system. + */ + inline const char* getLastError() const { return ::lt_dlerror(); } + + /** + * Return by value the object being loaded from the module. + */ + inline modType getObject() const { return modPtr; } + + /** + * Return true if an error occured, false otherwise. + */ + inline bool getError() const { return hasError; } +}; + +} // namespace gnuworld + #endif /* __MODULELOADER_H */ diff --git a/include/server.h b/include/server.h index 76d33078..69d50177 100644 --- a/include/server.h +++ b/include/server.h @@ -24,1590 +24,1479 @@ #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 -{ +#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 ; +class xClient; /// Forward declaration of Channel -class 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 parsed configuration - * parameters from the command line. - */ - xServer( bool verbose, bool doDebug, bool logSocket, - const std::string& elogFileName, - const std::string& socketFileName, - const std::string& configFileName, - const std::string& simFileName ) ; - - /** - * 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* ) override ; - - /** - * This method is called when a Connection attempt succeeds. - * Inherited from ConnectionHandler. - */ - virtual void OnConnect( Connection* ) override ; - - /** - * This method is called when a Connection attempt fails. - * Inherited from ConnectionHandler. - */ - virtual void OnConnectFail( Connection* ) override ; - - /** - * This method is called when a line of data is read from - * Connection. - * Inherited from ConnectionHandler. - */ - virtual void OnRead( Connection*, const std::string& ) override ; - - /** - * 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& ) ; - virtual bool Notice( iClient*, const char*, ... ) ; - - /** - * Sent a notice to a channel as the server. - */ - virtual bool serverNotice( Channel*, const char*, ... ) ; - - virtual bool serverNotice( Channel*, 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 fifth 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&, - const unsigned int, const unsigned short int, 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 && serverConnection->isConnected()) ; } - - /** - * Return true if verbosity is enabled. - */ - virtual bool isVerbose() const - { return verbose ; } - - /** - * Return true if debug is enabled - */ - virtual bool isDebug() const - { return doDebug ; } - - /** - * 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() ; - - /** - * Start logging. - */ - virtual void startLogging(bool logrotate = false) ; - - /** - * Rotate logs. - */ - virtual void rotateLogs() ; - - /** - * 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 '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 ) ; - - /** - * This method overrides ConnectionHandler's OnTimeout method. - * This method is called if a connection timeout occurs. - * The given Connection is no longer valid when this method - * is called. - */ - virtual void OnTimeout( Connection* ) override; - - -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 ; - - /** - * Whether or not TLS encrypted connections are enabled (and required) - * for the server uplink - */ - bool tlsEnabled ; - - /** - * 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 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 all elog data should be output to clog. - */ - bool verbose ; - - /** - * True if debug is enabled. - */ - bool doDebug ; - - /** - * True if logging of raw input data to file is enabled. - */ - bool logSocket ; - - - /** - * The name of the file for which elog to write all - * debugging information. - */ - std::string elogFileName ; - - /** - * The name of the file to write socket info - */ - std::string socketFileName ; - - /** - * 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 path to the TLS key file - */ - std::string tlsKeyFile ; - - /** - * The path to the TLS cert file - */ - std::string tlsCertFile ; - - /** - * 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() ; - - - /** - * This method initializes all of the TLS contexts - */ - bool initTls() ; - - /** - * 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 ; - -} ; +class xServer : public ConnectionManager, public ConnectionHandler, public NetworkTarget { + + protected: + /** + * The type of the structure to hold Gline's internally. + */ + typedef std::map glineListType; + + public: + /** + * The xServer constructor. It takes parsed configuration + * parameters from the command line. + */ + xServer(bool verbose, bool doDebug, bool logSocket, const std::string& elogFileName, + const std::string& socketFileName, const std::string& configFileName, + const std::string& simFileName); + + /** + * 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> 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> banVectorType; + + /** + * This type is used for passing multiple argument-less modes + * to handler methods of simple channel modes. + */ + typedef std::vector> 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*) override; + + /** + * This method is called when a Connection attempt succeeds. + * Inherited from ConnectionHandler. + */ + virtual void OnConnect(Connection*) override; + + /** + * This method is called when a Connection attempt fails. + * Inherited from ConnectionHandler. + */ + virtual void OnConnectFail(Connection*) override; + + /** + * This method is called when a line of data is read from + * Connection. + * Inherited from ConnectionHandler. + */ + virtual void OnRead(Connection*, const std::string&) override; + + /** + * 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 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&); + virtual bool Notice(iClient*, const char*, ...); + + /** + * Sent a notice to a channel as the server. + */ + virtual bool serverNotice(Channel*, const char*, ...); + + virtual bool serverNotice(Channel*, 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 fifth 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&, const unsigned int, + const unsigned short int, 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 && serverConnection->isConnected()); + } + + /** + * Return true if verbosity is enabled. + */ + virtual bool isVerbose() const { return verbose; } + + /** + * Return true if debug is enabled + */ + virtual bool isDebug() const { return doDebug; } + + /** + * 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(); + + /** + * Start logging. + */ + virtual void startLogging(bool logrotate = false); + + /** + * Rotate logs. + */ + virtual void rotateLogs(); + + /** + * 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 '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); + + /** + * This method overrides ConnectionHandler's OnTimeout method. + * This method is called if a connection timeout occurs. + * The given Connection is no longer valid when this method + * is called. + */ + virtual void OnTimeout(Connection*) override; + + 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& lhs, + const std::pair& 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> 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*, 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; + + /** + * Whether or not TLS encrypted connections are enabled (and required) + * for the server uplink + */ + bool tlsEnabled; + + /** + * 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*> 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 commandModuleType; + + /** + * A vector of modules representing ServerCommandHandlers. + */ + typedef std::vector 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 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::vector>, 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 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 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 all elog data should be output to clog. + */ + bool verbose; + + /** + * True if debug is enabled. + */ + bool doDebug; + + /** + * True if logging of raw input data to file is enabled. + */ + bool logSocket; + + /** + * The name of the file for which elog to write all + * debugging information. + */ + std::string elogFileName; + + /** + * The name of the file to write socket info + */ + std::string socketFileName; + + /** + * 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 path to the TLS key file + */ + std::string tlsKeyFile; + + /** + * The path to the TLS cert file + */ + std::string tlsCertFile; + + /** + * 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(); + + /** + * This method initializes all of the TLS contexts + */ + bool initTls(); + + /** + * 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 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 allowControlSetType; + + /** + * The structure used to store the AC account usernames allowed to + * issue control commands. + */ + allowControlSetType allowControlSet; +}; } // namespace gnuworld diff --git a/libgnuworld/Buffer.cc b/libgnuworld/Buffer.cc old mode 100755 new mode 100644 index ff9ac835..26f9d1c0 --- a/libgnuworld/Buffer.cc +++ b/libgnuworld/Buffer.cc @@ -1,89 +1,79 @@ /** * Buffer.cc * Author: Daniel Karrels dan@karrels.com - * Copyright (C) 2002 Daniel Karrels - * + * Copyright (C) 2002 Daniel Karrels + * * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License + * 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 + * 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: Buffer.cc,v 1.6 2003/07/20 14:13:15 dan_karrels Exp $ */ -#include -#include "Buffer.h" +#include +#include "Buffer.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -Buffer::Buffer( char delimiter ) - : delim( delimiter ) -{} +Buffer::Buffer(char delimiter) : delim(delimiter) {} -Buffer::~Buffer() -{ /* No heap space allocated */ } +Buffer::~Buffer() { /* No heap space allocated */ } -bool Buffer::ReadLine( string& retMe ) -{ -/* remove any leading new line characters */ -while( !empty() && ('\n' == buf[ 0 ]) ) - { - /* just remove the first char */ - buf.erase( buf.begin() ) ; - } +bool Buffer::ReadLine(string& retMe) { + /* remove any leading new line characters */ + while (!empty() && ('\n' == buf[0])) { + /* just remove the first char */ + buf.erase(buf.begin()); + } -/* Check to see if there is anything left */ -if( empty() ) - { - return false ; - } + /* Check to see if there is anything left */ + if (empty()) { + return false; + } -/* find() returns the index of the character, or - * npos if it was not found - */ -size_type pos = buf.find( delim ) ; + /* find() returns the index of the character, or + * npos if it was not found + */ + size_type pos = buf.find(delim); -if( string::npos == pos ) - { - // Unable to find the delimiter - return false ; - } + if (string::npos == pos) { + // Unable to find the delimiter + return false; + } -// else I need to add this substring into retMe -// and remove it from buf -retMe = buf.substr( 0, pos + 1 ) ; -buf.erase( 0, pos + 1 ) ; + // else I need to add this substring into retMe + // and remove it from buf + retMe = buf.substr(0, pos + 1); + buf.erase(0, pos + 1); -return true ; + return true; } // Delete numBytes bytes from the beginning // of the Buffer -void Buffer::Delete( const size_type& numBytes ) -{ -if( numBytes >= size() ) - { - // Clear the entire Buffer -// buf.clear() ; - buf.erase() ; - return ; - } +void Buffer::Delete(const size_type& numBytes) { + if (numBytes >= size()) { + // Clear the entire Buffer + // buf.clear() ; + buf.erase(); + return; + } -// Else just erase the number of bytes given -buf.erase( 0, numBytes ) ; + // Else just erase the number of bytes given + buf.erase(0, numBytes); } } // namespace gnuworld diff --git a/libgnuworld/Buffer.h b/libgnuworld/Buffer.h old mode 100755 new mode 100644 index bf49eeb9..94d1e141 --- a/libgnuworld/Buffer.h +++ b/libgnuworld/Buffer.h @@ -16,7 +16,7 @@ * * 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, + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. * * $Id: Buffer.h,v 1.7 2003/12/29 23:59:36 dan_karrels Exp $ @@ -25,11 +25,10 @@ #ifndef __BUFFER_H #define __BUFFER_H "$Id: Buffer.h,v 1.7 2003/12/29 23:59:36 dan_karrels Exp $" -#include -#include +#include +#include -namespace gnuworld -{ +namespace gnuworld { /** * This class represents a dynamic buffer capable or parsing out @@ -39,179 +38,172 @@ namespace gnuworld * because it is unlimited in size and provides a Delete() method * to delete an arbitrary number of bytes. */ -class Buffer -{ - -public: - - /** - * The type used to represent the string, could be useful - * if this class is ever templated (again). - */ - typedef std::string stringType ; - - /** - * Initialize the Buffer with the given string and - * delimiting character - */ - Buffer( char = '\n' ) ; - - /** - * Destroy this Buffer object. No internal allocation - * is done, so this method is a no-op. - */ - virtual ~Buffer() ; - - /** - * Read a (delimiter) delimited token from the - * buffer and write it into the string - * passed as argument, erasing the line from - * the Buffer once complete. - */ - virtual bool ReadLine( std::string& ) ; - - /** - * Define the type of the variable used to maintain - * size (number of bytes) of Buffer. - */ - typedef std::string::size_type size_type ; - - /** - * Return the the number of characters currently in - * the Buffer. - */ - virtual size_type size() const - { return buf.size() ; } - - /** - * Return the the number of characters currently in - * the Buffer. - */ - virtual size_type length() const - { return buf.length() ; } - - /** - * Return true if the buffer is empty, false otherwise. - */ - virtual bool empty() const - { return buf.empty() ; } - - /** - * Clear all data from the Buffer. - * For some reason, GNU gcc's implementation of std::string doesn't - * include clear(), do it the old fashion way here. - */ - virtual void clear() - { buf.erase() ; } - - /** - * Remove the given number of bytes from the - * beginning of the Buffer. - */ - virtual void Delete( const size_type& ) ; - - /** - * Return a substring of this Buffer, starting at (index), - * and continuing (len) characters into the Buffer. - * This method is const, and therefore does not alter the - * Buffer. - */ - inline std::string substr( const size_type& index, - const size_type& len ) const - { return buf.substr( index, len ) ; } - - /** - * Return a const reference to a C++ string - * representation of this Buffer. - */ - inline const std::string& toString() const - { return buf ; } - - /** - * Return a const reference to a C++ string representation - * of this Buffer. - */ - inline const std::string& operator*() const - { return buf ; } - - /** - * Return a pointer to the C NULL terminated character - * array representation of this array. Note that the - * data is const, and thus cannot be altered by the - * pointer returned by this method. - */ - inline const char* c_str() const - { return buf.c_str() ; } - - /** - * Return a pointer to the character array representation - * of this buffer. - * Note that conforming to the C++ standard on std::string, - * this data may NOT be null terminated. - */ - inline const char* data() const - { return buf.data() ; } - - /** - * Append a give number of bytes from appendMe to this - * Buffer. This is useful for storing binary data in an - * object of this class. - */ - inline void append( const char* appendMe, size_t numBytes ) - { buf.append( appendMe, numBytes ) ; } - - /** - * Concatenate the given C++ string to the end of the - * Buffer. - */ - inline Buffer& operator+=( const std::string& addMe ) - { buf += addMe ; return *this ; } - - /** - * Concatenate the given Buffer onto the end of this - * Buffer. - */ - inline Buffer& operator+=( const Buffer& addMe ) - { buf += addMe.buf ; return *this ; } - - /** - * Assign to this Buffer the contents of the C++ string - * passed as argument. - */ - inline Buffer& operator=( const std::string& replaceWithMe ) - { buf = replaceWithMe ; return *this ; } - - /** - * Assign to this Buffer the contents of the Buffer passed - * as argument. - */ - inline Buffer& operator=( const Buffer& replaceWithMe ) - { buf = replaceWithMe.buf ; return *this ; } - - /** - * Debugging function for output of this Buffer to a C++ - * output stream. - */ - inline friend std::ostream& operator<<( std::ostream& o, - const Buffer& b ) - { - o << b.buf ; - return o ; - } - -protected: - - /** - * This is the internal representation of this Buffer. - */ - std::string buf ; - - /** - * This is the delimiting character. - */ - char delim ; - -} ; +class Buffer { + + public: + /** + * The type used to represent the string, could be useful + * if this class is ever templated (again). + */ + typedef std::string stringType; + + /** + * Initialize the Buffer with the given string and + * delimiting character + */ + Buffer(char = '\n'); + + /** + * Destroy this Buffer object. No internal allocation + * is done, so this method is a no-op. + */ + virtual ~Buffer(); + + /** + * Read a (delimiter) delimited token from the + * buffer and write it into the string + * passed as argument, erasing the line from + * the Buffer once complete. + */ + virtual bool ReadLine(std::string&); + + /** + * Define the type of the variable used to maintain + * size (number of bytes) of Buffer. + */ + typedef std::string::size_type size_type; + + /** + * Return the the number of characters currently in + * the Buffer. + */ + virtual size_type size() const { return buf.size(); } + + /** + * Return the the number of characters currently in + * the Buffer. + */ + virtual size_type length() const { return buf.length(); } + + /** + * Return true if the buffer is empty, false otherwise. + */ + virtual bool empty() const { return buf.empty(); } + + /** + * Clear all data from the Buffer. + * For some reason, GNU gcc's implementation of std::string doesn't + * include clear(), do it the old fashion way here. + */ + virtual void clear() { buf.erase(); } + + /** + * Remove the given number of bytes from the + * beginning of the Buffer. + */ + virtual void Delete(const size_type&); + + /** + * Return a substring of this Buffer, starting at (index), + * and continuing (len) characters into the Buffer. + * This method is const, and therefore does not alter the + * Buffer. + */ + inline std::string substr(const size_type& index, const size_type& len) const { + return buf.substr(index, len); + } + + /** + * Return a const reference to a C++ string + * representation of this Buffer. + */ + inline const std::string& toString() const { return buf; } + + /** + * Return a const reference to a C++ string representation + * of this Buffer. + */ + inline const std::string& operator*() const { return buf; } + + /** + * Return a pointer to the C NULL terminated character + * array representation of this array. Note that the + * data is const, and thus cannot be altered by the + * pointer returned by this method. + */ + inline const char* c_str() const { return buf.c_str(); } + + /** + * Return a pointer to the character array representation + * of this buffer. + * Note that conforming to the C++ standard on std::string, + * this data may NOT be null terminated. + */ + inline const char* data() const { return buf.data(); } + + /** + * Append a give number of bytes from appendMe to this + * Buffer. This is useful for storing binary data in an + * object of this class. + */ + inline void append(const char* appendMe, size_t numBytes) { buf.append(appendMe, numBytes); } + + /** + * Concatenate the given C++ string to the end of the + * Buffer. + */ + inline Buffer& operator+=(const std::string& addMe) { + buf += addMe; + return *this; + } + + /** + * Concatenate the given Buffer onto the end of this + * Buffer. + */ + inline Buffer& operator+=(const Buffer& addMe) { + buf += addMe.buf; + return *this; + } + + /** + * Assign to this Buffer the contents of the C++ string + * passed as argument. + */ + inline Buffer& operator=(const std::string& replaceWithMe) { + buf = replaceWithMe; + return *this; + } + + /** + * Assign to this Buffer the contents of the Buffer passed + * as argument. + */ + inline Buffer& operator=(const Buffer& replaceWithMe) { + buf = replaceWithMe.buf; + return *this; + } + + /** + * Debugging function for output of this Buffer to a C++ + * output stream. + */ + inline friend std::ostream& operator<<(std::ostream& o, const Buffer& b) { + o << b.buf; + return o; + } + + protected: + /** + * This is the internal representation of this Buffer. + */ + std::string buf; + + /** + * This is the delimiting character. + */ + char delim; +}; } // namespace gnuworld diff --git a/libgnuworld/Connection.cc b/libgnuworld/Connection.cc old mode 100755 new mode 100644 index bbc057f5..639ed5b9 --- a/libgnuworld/Connection.cc +++ b/libgnuworld/Connection.cc @@ -21,77 +21,54 @@ * $Id: Connection.cc,v 1.5 2004/01/07 18:33:42 dan_karrels Exp $ */ -#include -#include -#include -#include -#include -#include -#include -#include "Connection.h" -#include "Buffer.h" +#include +#include +#include +#include +#include +#include +#include +#include "Connection.h" +#include "Buffer.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; // Simply initialize the object -Connection::Connection( const string& _hostname, - const unsigned short int _remotePort, - const char _delimiter, - bool _tlsEnabled ) -: hostname( _hostname ), - localPort( 0 ), - remotePort( _remotePort ), - inputBuffer( _delimiter ), - outputBuffer( _delimiter ), - tlsEnabled( _tlsEnabled ), - IP( string() ), - sockFD( -1 ), - flags( F_PENDING ), - connectTime( 0 ), - bytesRead( 0 ), - bytesWritten( 0 ) +Connection::Connection(const string& _hostname, const unsigned short int _remotePort, + const char _delimiter, bool _tlsEnabled) + : hostname(_hostname), localPort(0), remotePort(_remotePort), inputBuffer(_delimiter), + outputBuffer(_delimiter), tlsEnabled(_tlsEnabled), IP(string()), sockFD(-1), flags(F_PENDING), + connectTime(0), bytesRead(0), bytesWritten(0) #ifdef HAVE_LIBSSL - , tlsState( nullptr ) + , + tlsState(nullptr) #endif { -memset( &addr, 0, sizeof( struct sockaddr_in ) ) ; + memset(&addr, 0, sizeof(struct sockaddr_in)); } -Connection::Connection( const char _delimiter ) -: localPort( 0 ), - remotePort( 0 ), - inputBuffer( _delimiter ), - outputBuffer( _delimiter ), - tlsEnabled( false ), - sockFD( -1 ), - flags( F_PENDING ), - connectTime( 0 ), - bytesRead( 0 ), - bytesWritten( 0 ) +Connection::Connection(const char _delimiter) + : localPort(0), remotePort(0), inputBuffer(_delimiter), outputBuffer(_delimiter), + tlsEnabled(false), sockFD(-1), flags(F_PENDING), connectTime(0), bytesRead(0), bytesWritten(0) #ifdef HAVE_LIBSSL - , tlsState( nullptr ) + , + tlsState(nullptr) #endif { -memset( &addr, 0, sizeof( struct sockaddr_in ) ) ; + memset(&addr, 0, sizeof(struct sockaddr_in)); } -Connection::~Connection() -{ +Connection::~Connection() { #ifdef HAVE_LIBSSL -if( tlsState ) - { - SSL_free( tlsState ) ; - tlsState = nullptr ; - } + if (tlsState) { + SSL_free(tlsState); + tlsState = nullptr; + } #endif } -void Connection::Write( const string& writeMe ) -{ -outputBuffer += writeMe ; -} +void Connection::Write(const string& writeMe) { outputBuffer += writeMe; } } // namespace gnuworld diff --git a/libgnuworld/Connection.h b/libgnuworld/Connection.h old mode 100755 new mode 100644 index fa01955a..8e3d708b --- a/libgnuworld/Connection.h +++ b/libgnuworld/Connection.h @@ -24,552 +24,497 @@ #ifndef __CONNECTION_H #define __CONNECTION_H "$Id: Connection.h,v 1.7 2004/01/07 18:33:42 dan_karrels Exp $" -#include -#include -#include // sockaddr -#include -#include +#include +#include +#include // sockaddr +#include +#include -#include -#include +#include +#include -#include "Buffer.h" -#include "ELog.h" -#include "defs.h" +#include "Buffer.h" +#include "ELog.h" +#include "defs.h" #ifdef HAVE_LIBSSL -#include -#include -#include +#include +#include +#include #endif -namespace gnuworld -{ +namespace gnuworld { /// Forward declaration of the manager class -class ConnectionManager ; +class ConnectionManager; /** * This class represents an individual connection to be used with * the ConnectionManager class. * It is basically just a data storage class. */ -class Connection -{ - - /// Allow the manager class to have access to this class's - /// protected members - friend class ConnectionManager ; - -public: - - /** - * The destructor does nothing since this is a helper class - * of ConnectionManager. - */ - virtual ~Connection() ; - - /** - * Return the hostname which this connection represents. - * The hostname may be empty if it represents a listening - * socket. Otherwise, the hostname will contain either - * a valid hostname, or a string representation of the - * Connection's IP address. - */ - inline const std::string& getHostname() const - { return hostname ; } - - /** - * Return the IP for this connection. - * The IP may be empty if it represents a listening - * socket. - */ - inline const std::string& getIP() const - { return IP ; } - - /** - * Return the local port number for this Connection. - */ - inline unsigned short int getLocalPort() const - { return localPort ; } - - /** - * Return the remote port number for this Connection. - */ - inline unsigned short int getRemotePort() const - { return remotePort ; } - - /** - * This type is used to represent flags of this connection, - * both for this class and any subclasses. - */ - typedef unsigned int flagType ; - - /** - * This flag is true if the connection is currently fully - * connected. - */ - static constexpr flagType F_CONNECTED = 0x01 ; - - /** - * This flag is true if the connection is still pending, - * not yet complete. - */ - static constexpr flagType F_PENDING = 0x02 ; - - /** - * This flag is true if this Connection represents a - * connection created by a remote host connecting to the - * localhost. - * The F_INCOMING flag exists throughout the life ot - * the Connection. - */ - static constexpr flagType F_INCOMING = 0x04 ; - - /** - * This flag is true if this Connection represents a - * socket which is listening for incoming connections. - * This flag exists for the life of this connection. - * A listening Connection is never connected. - */ - static constexpr flagType F_LISTEN = 0x08 ; - - /** - * This flag is true when the Connection represents a - * connection to a file, rather than a network connection. - */ - static constexpr flagType F_FILE = 0x10 ; - - /** - * This flag will be set if the next write is to flush all - * data from the output buffer. - * The flag will be reset after the send(). - */ - static constexpr flagType F_FLUSH = 0x20 ; - - /** - * This flag will be set upon initiating a TLS connection. - * The flag will be reset after the handshake is completed. - */ - static constexpr flagType F_TLS_HANDSHAKING = 0x40 ; - - /** - * This flag will be set upon shutting down a TLS connection. - */ - static constexpr flagType F_TLS_SHUTTING_DOWN = 0x80 ; - - /** - * This flags a TLS connection as having a fatal error, i.e. ssl_shutdown() will not be called. - */ - static constexpr flagType F_TLS_FATAL_ERROR = 0x100 ; - - /** - * Append a string to the Connection's output buffer. - */ - virtual void Write( const std::string& ) ; - - /** - * Return the flags of this connection. - */ - inline const flagType& getFlags() const - { return flags ; } - - /** - * Check if an individual flag is present on this connection. - */ - inline bool hasFlag( const flagType& whichFlag ) const - { return (whichFlag == (flags & whichFlag)) ; } - - /** - * Return true if this is object represents a fully-connected - * socket, false otherwise. - * Note that this flag is mutually exclusive with F_PENDING. - */ - inline bool isConnected() const - { return (flags & F_CONNECTED) ; } - - /** - * Return true if this connection is still pending. - * Note that this flag is mutually exclusive with F_CONNECTED. - */ - inline bool isPending() const - { return (flags & F_PENDING) ; } - - /** - * Return true if this connection was received by a listening - * Connection. - * Note that this flag remains true for the life of the - * connection, and is not present for connection established - * with ConnectionManager::Connect(). - */ - inline bool isIncoming() const - { return (flags & F_INCOMING) ; } - - /** - * Return true if this connection is listening for new - * incoming connections, as a result of calling - * ConnectionManager::Listen(). - * Note that this flag remains true for the life of the - * connection. - */ - inline bool isListening() const - { return (flags & F_LISTEN ) ; } - - /** - * Return true if this Connection is a file connection, false - * otherwise. - */ - inline bool isFile() const - { return (flags & F_FILE) ; } - - /** - * Return true if the flush flag is set, indicating that the - * next send() should write all available data, blocking - * if necessary. - */ - inline bool isFlush() const - { return (flags & F_FLUSH) ; } - - /** - * Return true if the negotiating TLS flag is set, indicating that - * the TLS handshake has not completed. - */ - inline bool isNegotiatingTLS() const - { return (flags & F_TLS_HANDSHAKING) ; } - - /** - * Return true if the TLS connection has initiating shutdown. - */ - inline bool isShuttingDownTLS() const - { return (flags & F_TLS_SHUTTING_DOWN) ; } - - /** - * Return the total number of bytes read from this - * Connection. - */ - inline size_t getBytesRead() const - { return bytesRead ; } - - /** - * Return the total number of bytes successfully written - * to this Connection (does not count amount currently - * in the output buffer). - */ - inline size_t getBytesWritten() const - { return bytesWritten ; } - - /** - * Return the time at which this Connection object established - * connection. This value is 0 for listening sockets. - */ - inline time_t getConnectTime() const - { return connectTime ; } - - /** - * Return the number of bytes currently in the output - * buffer. - */ - inline size_t getOutputBufferSize() const - { return outputBuffer.size() ; } - - /** - * Return the number of bytes currently in the input - * buffer. - */ - inline size_t getInputBufferSize() const - { return inputBuffer.size() ; } - - /** - * Return whether or not this connection has TLS enabled - */ - inline bool isTLS() const - { return tlsEnabled ; } - - /** - * Set the F_FLUSH flag to true. - */ - inline void Flush() - { setFlag( F_FLUSH ) ; } - - /** - * This friend operator allows for the easy output of a - * Connection object to a given output stream. - */ - friend std::ostream& operator<<( std::ostream& out, const - Connection& con ) - { - out << "Host: " << con.getHostname() - << ", IP: " << con.getIP() - << ", localPort: " << con.getLocalPort() - << ", remotePort: " << con.getRemotePort() - << ", sockFD: " << con.getSockFD() - << ", TLS: " << (con.isTLS() ? "yes" : "no") - << ", state: " - << (con.isConnected() ? "connected" : "pending") ; - if( con.isIncoming() ) - { - out << ",incoming" ; - } - if( con.isListening() ) - { - out << ",listening" ; - } - return out ; - } - - /** - * This friend operator allows for the easy output of a - * Connection object to a given ELog output stream. - */ - friend ELog& operator<<( ELog& out, const Connection& con ) - { - out << "Host: " << con.getHostname() - << ", IP: " << con.getIP() - << ", localPort: " << con.getLocalPort() - << ", remotePort: " << con.getRemotePort() - << ", sockFD: " << con.getSockFD() - << ", TLS: " << (con.isTLS() ? "yes" : "no") - << ", state: " - << (con.isConnected() ? "connected" : "pending") ; - if( con.isIncoming() ) - { - out << ",incoming" ; - } - if( con.isListening() ) - { - out << ",listening" ; - } - return out ; - } - -protected: - - /** - * Create a new instance of this class given the remote - * host (may be empty), the IP, remote port number. - */ - Connection( const std::string& host, - const unsigned short int remotePort, - const char delimiter, - bool tlsEnabled ) ; - - /** - * Create a new instance of this class, set all variables - * to default initial state. - */ - Connection( const char delimiter ) ; - - /** - * Set an arbitrary flag for this connection - */ - inline void setFlag( const flagType& whichFlag ) - { flags |= whichFlag ; } - - /** - * Remove an arbitrary flag for this connection - */ - inline void removeFlag( const flagType& whichFlag ) - { flags &= ~whichFlag ; } - - /** - * Set this Connection to fully connected state, which also - * removes the PENDING state - */ - inline void setConnected() - { removeFlag( F_PENDING ) ; setFlag( F_CONNECTED ) ; } - - /** - * Set this Connection to the pending state, and remove - * the CONNECTED state - */ - inline void setPending() - { removeFlag( F_CONNECTED ) ; setFlag( F_PENDING ) ; } - - /** - * Mark that this Connection as an incoming connection - */ - inline void setIncoming() - { setFlag( F_INCOMING ) ; } - - /** - * Mark that this Connection is a listening for connections - */ - inline void setListen() - { setFlag( F_LISTEN ) ; } - - /** - * Mark that this Connection represents a file - */ - inline void setFile() - { setFlag( F_FILE ) ; } - - /** - * Mark that this Connection as pending TLS negotiation. - */ - inline void setNegotiatingTLS() - { setFlag( F_TLS_HANDSHAKING ) ; } - - /** - * Mark that this Connection as pending TLS negotiation. - */ - inline void clrNegotiatingTLS() - { removeFlag( F_TLS_HANDSHAKING ) ; } - - /** - * Mark that this Connection as pending TLS negotiation. - */ - inline void setShuttingDownTLS() - { setFlag( F_TLS_SHUTTING_DOWN ) ; } - - /** - * Set this connection's local port number - */ - inline void setLocalPort( - const unsigned short int newLocalPort ) - { localPort = newLocalPort ; } - - /** - * Set this connection's remote port number - */ - inline void setRemotePort( - const unsigned short int newRemotePort ) - { remotePort = newRemotePort ; } - - /** - * Return the socket (file) descriptor for this connection - */ - inline int getSockFD() const - { return sockFD ; } - - /** - * Return a pointer to the socket address structure - */ - inline struct sockaddr_in* getAddr() - { return &addr ; } - - /** - * Set the Connection's IP to the new IP - */ - inline void setIP( const std::string& newIP ) - { IP = newIP ; } - - /** - * Set the Connection's hostname to newHost - */ - inline void setHostname( const std::string& newHost ) - { hostname = newHost ; } - - /** - * Set the Connection's FD to the new FD - */ - inline void setSockFD( int newSockFD ) - { sockFD = newSockFD ; } - - /** - * Set the Connection absTimeout to the new absTimeOut - */ - inline void setAbsTimeout( const time_t newAbsTimeout ) - { absTimeout = newAbsTimeout ; } - - /** - * Return the time at which this connection attempt will - * be terminated (its absolute timeout value). - */ - inline time_t getAbsTimeout() const - { return absTimeout ; } - +class Connection { + + /// Allow the manager class to have access to this class's + /// protected members + friend class ConnectionManager; + + public: + /** + * The destructor does nothing since this is a helper class + * of ConnectionManager. + */ + virtual ~Connection(); + + /** + * Return the hostname which this connection represents. + * The hostname may be empty if it represents a listening + * socket. Otherwise, the hostname will contain either + * a valid hostname, or a string representation of the + * Connection's IP address. + */ + inline const std::string& getHostname() const { return hostname; } + + /** + * Return the IP for this connection. + * The IP may be empty if it represents a listening + * socket. + */ + inline const std::string& getIP() const { return IP; } + + /** + * Return the local port number for this Connection. + */ + inline unsigned short int getLocalPort() const { return localPort; } + + /** + * Return the remote port number for this Connection. + */ + inline unsigned short int getRemotePort() const { return remotePort; } + + /** + * This type is used to represent flags of this connection, + * both for this class and any subclasses. + */ + typedef unsigned int flagType; + + /** + * This flag is true if the connection is currently fully + * connected. + */ + static constexpr flagType F_CONNECTED = 0x01; + + /** + * This flag is true if the connection is still pending, + * not yet complete. + */ + static constexpr flagType F_PENDING = 0x02; + + /** + * This flag is true if this Connection represents a + * connection created by a remote host connecting to the + * localhost. + * The F_INCOMING flag exists throughout the life ot + * the Connection. + */ + static constexpr flagType F_INCOMING = 0x04; + + /** + * This flag is true if this Connection represents a + * socket which is listening for incoming connections. + * This flag exists for the life of this connection. + * A listening Connection is never connected. + */ + static constexpr flagType F_LISTEN = 0x08; + + /** + * This flag is true when the Connection represents a + * connection to a file, rather than a network connection. + */ + static constexpr flagType F_FILE = 0x10; + + /** + * This flag will be set if the next write is to flush all + * data from the output buffer. + * The flag will be reset after the send(). + */ + static constexpr flagType F_FLUSH = 0x20; + + /** + * This flag will be set upon initiating a TLS connection. + * The flag will be reset after the handshake is completed. + */ + static constexpr flagType F_TLS_HANDSHAKING = 0x40; + + /** + * This flag will be set upon shutting down a TLS connection. + */ + static constexpr flagType F_TLS_SHUTTING_DOWN = 0x80; + + /** + * This flags a TLS connection as having a fatal error, i.e. ssl_shutdown() will not be called. + */ + static constexpr flagType F_TLS_FATAL_ERROR = 0x100; + + /** + * Append a string to the Connection's output buffer. + */ + virtual void Write(const std::string&); + + /** + * Return the flags of this connection. + */ + inline const flagType& getFlags() const { return flags; } + + /** + * Check if an individual flag is present on this connection. + */ + inline bool hasFlag(const flagType& whichFlag) const { + return (whichFlag == (flags & whichFlag)); + } + + /** + * Return true if this is object represents a fully-connected + * socket, false otherwise. + * Note that this flag is mutually exclusive with F_PENDING. + */ + inline bool isConnected() const { return (flags & F_CONNECTED); } + + /** + * Return true if this connection is still pending. + * Note that this flag is mutually exclusive with F_CONNECTED. + */ + inline bool isPending() const { return (flags & F_PENDING); } + + /** + * Return true if this connection was received by a listening + * Connection. + * Note that this flag remains true for the life of the + * connection, and is not present for connection established + * with ConnectionManager::Connect(). + */ + inline bool isIncoming() const { return (flags & F_INCOMING); } + + /** + * Return true if this connection is listening for new + * incoming connections, as a result of calling + * ConnectionManager::Listen(). + * Note that this flag remains true for the life of the + * connection. + */ + inline bool isListening() const { return (flags & F_LISTEN); } + + /** + * Return true if this Connection is a file connection, false + * otherwise. + */ + inline bool isFile() const { return (flags & F_FILE); } + + /** + * Return true if the flush flag is set, indicating that the + * next send() should write all available data, blocking + * if necessary. + */ + inline bool isFlush() const { return (flags & F_FLUSH); } + + /** + * Return true if the negotiating TLS flag is set, indicating that + * the TLS handshake has not completed. + */ + inline bool isNegotiatingTLS() const { return (flags & F_TLS_HANDSHAKING); } + + /** + * Return true if the TLS connection has initiating shutdown. + */ + inline bool isShuttingDownTLS() const { return (flags & F_TLS_SHUTTING_DOWN); } + + /** + * Return the total number of bytes read from this + * Connection. + */ + inline size_t getBytesRead() const { return bytesRead; } + + /** + * Return the total number of bytes successfully written + * to this Connection (does not count amount currently + * in the output buffer). + */ + inline size_t getBytesWritten() const { return bytesWritten; } + + /** + * Return the time at which this Connection object established + * connection. This value is 0 for listening sockets. + */ + inline time_t getConnectTime() const { return connectTime; } + + /** + * Return the number of bytes currently in the output + * buffer. + */ + inline size_t getOutputBufferSize() const { return outputBuffer.size(); } + + /** + * Return the number of bytes currently in the input + * buffer. + */ + inline size_t getInputBufferSize() const { return inputBuffer.size(); } + + /** + * Return whether or not this connection has TLS enabled + */ + inline bool isTLS() const { return tlsEnabled; } + + /** + * Set the F_FLUSH flag to true. + */ + inline void Flush() { setFlag(F_FLUSH); } + + /** + * This friend operator allows for the easy output of a + * Connection object to a given output stream. + */ + friend std::ostream& operator<<(std::ostream& out, const Connection& con) { + out << "Host: " << con.getHostname() << ", IP: " << con.getIP() + << ", localPort: " << con.getLocalPort() << ", remotePort: " << con.getRemotePort() + << ", sockFD: " << con.getSockFD() << ", TLS: " << (con.isTLS() ? "yes" : "no") + << ", state: " << (con.isConnected() ? "connected" : "pending"); + if (con.isIncoming()) { + out << ",incoming"; + } + if (con.isListening()) { + out << ",listening"; + } + return out; + } + + /** + * This friend operator allows for the easy output of a + * Connection object to a given ELog output stream. + */ + friend ELog& operator<<(ELog& out, const Connection& con) { + out << "Host: " << con.getHostname() << ", IP: " << con.getIP() + << ", localPort: " << con.getLocalPort() << ", remotePort: " << con.getRemotePort() + << ", sockFD: " << con.getSockFD() << ", TLS: " << (con.isTLS() ? "yes" : "no") + << ", state: " << (con.isConnected() ? "connected" : "pending"); + if (con.isIncoming()) { + out << ",incoming"; + } + if (con.isListening()) { + out << ",listening"; + } + return out; + } + + protected: + /** + * Create a new instance of this class given the remote + * host (may be empty), the IP, remote port number. + */ + Connection(const std::string& host, const unsigned short int remotePort, const char delimiter, + bool tlsEnabled); + + /** + * Create a new instance of this class, set all variables + * to default initial state. + */ + Connection(const char delimiter); + + /** + * Set an arbitrary flag for this connection + */ + inline void setFlag(const flagType& whichFlag) { flags |= whichFlag; } + + /** + * Remove an arbitrary flag for this connection + */ + inline void removeFlag(const flagType& whichFlag) { flags &= ~whichFlag; } + + /** + * Set this Connection to fully connected state, which also + * removes the PENDING state + */ + inline void setConnected() { + removeFlag(F_PENDING); + setFlag(F_CONNECTED); + } + + /** + * Set this Connection to the pending state, and remove + * the CONNECTED state + */ + inline void setPending() { + removeFlag(F_CONNECTED); + setFlag(F_PENDING); + } + + /** + * Mark that this Connection as an incoming connection + */ + inline void setIncoming() { setFlag(F_INCOMING); } + + /** + * Mark that this Connection is a listening for connections + */ + inline void setListen() { setFlag(F_LISTEN); } + + /** + * Mark that this Connection represents a file + */ + inline void setFile() { setFlag(F_FILE); } + + /** + * Mark that this Connection as pending TLS negotiation. + */ + inline void setNegotiatingTLS() { setFlag(F_TLS_HANDSHAKING); } + + /** + * Mark that this Connection as pending TLS negotiation. + */ + inline void clrNegotiatingTLS() { removeFlag(F_TLS_HANDSHAKING); } + + /** + * Mark that this Connection as pending TLS negotiation. + */ + inline void setShuttingDownTLS() { setFlag(F_TLS_SHUTTING_DOWN); } + + /** + * Set this connection's local port number + */ + inline void setLocalPort(const unsigned short int newLocalPort) { localPort = newLocalPort; } + + /** + * Set this connection's remote port number + */ + inline void setRemotePort(const unsigned short int newRemotePort) { + remotePort = newRemotePort; + } + + /** + * Return the socket (file) descriptor for this connection + */ + inline int getSockFD() const { return sockFD; } + + /** + * Return a pointer to the socket address structure + */ + inline struct sockaddr_in* getAddr() { return &addr; } + + /** + * Set the Connection's IP to the new IP + */ + inline void setIP(const std::string& newIP) { IP = newIP; } + + /** + * Set the Connection's hostname to newHost + */ + inline void setHostname(const std::string& newHost) { hostname = newHost; } + + /** + * Set the Connection's FD to the new FD + */ + inline void setSockFD(int newSockFD) { sockFD = newSockFD; } + + /** + * Set the Connection absTimeout to the new absTimeOut + */ + inline void setAbsTimeout(const time_t newAbsTimeout) { absTimeout = newAbsTimeout; } + + /** + * Return the time at which this connection attempt will + * be terminated (its absolute timeout value). + */ + inline time_t getAbsTimeout() const { return absTimeout; } + #ifdef HAVE_LIBSSL - /** - * Return the current TLS state for this connection - */ - inline SSL* getTlsState() const - { return tlsState ; } - - inline void setTlsState( SSL* newState ) - { tlsState = newState ; } + /** + * Return the current TLS state for this connection + */ + inline SSL* getTlsState() const { return tlsState; } + + inline void setTlsState(SSL* newState) { tlsState = newState; } #endif - /** - * The remote hostname of this connection - * This variable is empty() if this Connection is a listener - */ - std::string hostname ; - - /** - * The local port number of this connection - */ - unsigned short int localPort ; - - /** - * The remote port number of this connection - */ - unsigned short int remotePort ; - - /** - * The input buffer for this connection - */ - Buffer inputBuffer ; - - /** - * The output buffer for this connection - */ - Buffer outputBuffer ; - - /** - * Whether or not this connection is encrypted - */ - bool tlsEnabled ; - - /** - * The remote IP of this connection - * This variable is empty() if this Connection is a listener - */ - std::string IP ; - - /** - * The socket (file) descriptor for the socket of this - * connection. - */ - int sockFD ; - - /** - * The flags associated with this connection - */ - flagType flags ; - - /** - * The socket address structure for this connection - */ - struct sockaddr_in addr ; - - /** - * The time at which this connection attempt began - */ - time_t absTimeout ; - - /** - * The time at which this Connection completed connection, - * 0 for listening socket. - */ - time_t connectTime ; - - /** - * The total number of bytes read - */ - size_t bytesRead ; - - /** - * The total number of bytes written - */ - size_t bytesWritten ; + /** + * The remote hostname of this connection + * This variable is empty() if this Connection is a listener + */ + std::string hostname; + + /** + * The local port number of this connection + */ + unsigned short int localPort; + + /** + * The remote port number of this connection + */ + unsigned short int remotePort; + + /** + * The input buffer for this connection + */ + Buffer inputBuffer; + + /** + * The output buffer for this connection + */ + Buffer outputBuffer; + + /** + * Whether or not this connection is encrypted + */ + bool tlsEnabled; + + /** + * The remote IP of this connection + * This variable is empty() if this Connection is a listener + */ + std::string IP; + + /** + * The socket (file) descriptor for the socket of this + * connection. + */ + int sockFD; + + /** + * The flags associated with this connection + */ + flagType flags; + + /** + * The socket address structure for this connection + */ + struct sockaddr_in addr; + + /** + * The time at which this connection attempt began + */ + time_t absTimeout; + + /** + * The time at which this Connection completed connection, + * 0 for listening socket. + */ + time_t connectTime; + + /** + * The total number of bytes read + */ + size_t bytesRead; + + /** + * The total number of bytes written + */ + size_t bytesWritten; #ifdef HAVE_LIBSSL - /** - * The current OpenSSL TLS state for this connection - */ - SSL* tlsState ; + /** + * The current OpenSSL TLS state for this connection + */ + SSL* tlsState; #endif -} ; +}; } // namespace gnuworld diff --git a/libgnuworld/ConnectionHandler.cc b/libgnuworld/ConnectionHandler.cc old mode 100755 new mode 100644 index a8e1ffbe..f9681933 --- a/libgnuworld/ConnectionHandler.cc +++ b/libgnuworld/ConnectionHandler.cc @@ -21,63 +21,48 @@ * $Id: ConnectionHandler.cc,v 1.3 2003/08/05 01:59:14 dan_karrels Exp $ */ -#include -#include +#include +#include -#include "ConnectionHandler.h" -#include "Connection.h" +#include "ConnectionHandler.h" +#include "Connection.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::cout ; -using std::endl ; +using std::cout; +using std::endl; +using std::string; /** * These methods are empty. * Simply output a little debugging message if uncommented. */ -ConnectionHandler::ConnectionHandler() -{} +ConnectionHandler::ConnectionHandler() {} -ConnectionHandler::~ConnectionHandler() -{} +ConnectionHandler::~ConnectionHandler() {} -void ConnectionHandler::OnConnect( Connection* cPtr ) -{ -cout << "ConnectionHandler::OnConnect> " - << *cPtr - << endl ; +void ConnectionHandler::OnConnect(Connection* cPtr) { + cout << "ConnectionHandler::OnConnect> " << *cPtr << endl; } -void ConnectionHandler::OnConnectFail( Connection* cPtr ) -{ -cout << "ConnectionHandler::OnConnectFail> " - << *cPtr - << endl ; +void ConnectionHandler::OnConnectFail(Connection* cPtr) { + cout << "ConnectionHandler::OnConnectFail> " << *cPtr << endl; } -void ConnectionHandler::OnRead( Connection*, const string& ) -{ -//cout << "ConnectionHandler::OnRead> " -// << *cPtr -// << ", line: " -// << line -// << endl ; +void ConnectionHandler::OnRead(Connection*, const string&) { + // cout << "ConnectionHandler::OnRead> " + // << *cPtr + // << ", line: " + // << line + // << endl ; } -void ConnectionHandler::OnDisconnect( Connection* cPtr ) -{ -cout << "ConnectionHandler::OnDisconnect> " - << *cPtr - << endl ; +void ConnectionHandler::OnDisconnect(Connection* cPtr) { + cout << "ConnectionHandler::OnDisconnect> " << *cPtr << endl; } /* This method is now overridden by xServer's onTimeout() method */ -void ConnectionHandler::OnTimeout( Connection * ) -{ -} +void ConnectionHandler::OnTimeout(Connection*) {} } // namespace gnuworld diff --git a/libgnuworld/ConnectionHandler.h b/libgnuworld/ConnectionHandler.h old mode 100755 new mode 100644 index 23d1fa45..a45dea52 --- a/libgnuworld/ConnectionHandler.h +++ b/libgnuworld/ConnectionHandler.h @@ -24,16 +24,15 @@ #ifndef __CONNECTIONHANDLER_H #define __CONNECTIONHANDLER_H "$Id: ConnectionHandler.h,v 1.3 2003/12/29 23:59:36 dan_karrels Exp $" -#include +#include -#include +#include -#include "Connection.h" +#include "Connection.h" -namespace gnuworld -{ +namespace gnuworld { -class ConnectionManager ; +class ConnectionManager; /** * The purpose of this class is to provide a concrete base class @@ -45,77 +44,74 @@ class ConnectionManager ; * These methods are information for the Clients of the ConnectionManager * class, and are meant to be one-way. */ -class ConnectionHandler -{ - -public: - - /** - * Create a ConnectionHandler instance with default - * arguments. - */ - ConnectionHandler() ; - - /** - * Destroy this ConnectionHandler instance. - * This does *not* destroy any associated Connections - * which may be in any associated ConnectionManager - * objects. - */ - virtual ~ConnectionHandler() ; - - /** - * This method is called when a host connection succeeds. - * This method is NOOP in the base class, and should NOT - * be called by clients of this class. - */ - virtual void OnConnect( Connection* ) ; - - /** - * This method is called when the given connection attempt - * fails. This could be for either an incoming or outgoing - * attempt -- see the Connection's flags for determining - * which it is. - * The given Connection is no longer valid when this method - * is called. - */ - virtual void OnConnectFail( Connection* ) ; - - /** - * This method is called when a string of data is available - * from the remote connection referred to by the Connection. - * The string of data (line) is passed as determined by - * the delimiter passed to the constructor of the associated - * ConnectionManager instance. - */ - virtual void OnRead( Connection*, const std::string& ) ; - - /** - * This is a handler method called when a connection is - * established but is then closed by the remote end. Note - * that connections terminated with Disconnect() are NOT - * reflected by calling OnDisconnect(). Connections closed - * using Disconnect() are closed without notification to - * the handler. - * This method is also called when a listening (incoming) - * socket is no longer valid. If this occurs, the Connection - * flags will have F_INCOMING set, and that further listening - * on the given port will no longer proceed. - * The given Connection is no longer valid when this method - * is called. - */ - virtual void OnDisconnect( Connection* ) ; - - /** - * This method is called if a connection timeout occurs. - * The given Connection is no longer valid when this method - * is called. - */ - virtual void OnTimeout( Connection* ) ; - -protected: - -} ; +class ConnectionHandler { + + public: + /** + * Create a ConnectionHandler instance with default + * arguments. + */ + ConnectionHandler(); + + /** + * Destroy this ConnectionHandler instance. + * This does *not* destroy any associated Connections + * which may be in any associated ConnectionManager + * objects. + */ + virtual ~ConnectionHandler(); + + /** + * This method is called when a host connection succeeds. + * This method is NOOP in the base class, and should NOT + * be called by clients of this class. + */ + virtual void OnConnect(Connection*); + + /** + * This method is called when the given connection attempt + * fails. This could be for either an incoming or outgoing + * attempt -- see the Connection's flags for determining + * which it is. + * The given Connection is no longer valid when this method + * is called. + */ + virtual void OnConnectFail(Connection*); + + /** + * This method is called when a string of data is available + * from the remote connection referred to by the Connection. + * The string of data (line) is passed as determined by + * the delimiter passed to the constructor of the associated + * ConnectionManager instance. + */ + virtual void OnRead(Connection*, const std::string&); + + /** + * This is a handler method called when a connection is + * established but is then closed by the remote end. Note + * that connections terminated with Disconnect() are NOT + * reflected by calling OnDisconnect(). Connections closed + * using Disconnect() are closed without notification to + * the handler. + * This method is also called when a listening (incoming) + * socket is no longer valid. If this occurs, the Connection + * flags will have F_INCOMING set, and that further listening + * on the given port will no longer proceed. + * The given Connection is no longer valid when this method + * is called. + */ + virtual void OnDisconnect(Connection*); + + /** + * This method is called if a connection timeout occurs. + * The given Connection is no longer valid when this method + * is called. + */ + virtual void OnTimeout(Connection*); + + protected: +}; } // namespace gnuworld diff --git a/libgnuworld/ConnectionManager.cc b/libgnuworld/ConnectionManager.cc old mode 100755 new mode 100644 index 85397302..1deb99f5 --- a/libgnuworld/ConnectionManager.cc +++ b/libgnuworld/ConnectionManager.cc @@ -21,1592 +21,1398 @@ * $Id: ConnectionManager.cc,v 1.20 2007/09/25 16:57:54 dan_karrels Exp $ */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "ConnectionManager.h" -#include "Connection.h" -#include "ConnectionHandler.h" -#include "Buffer.h" -#include "ELog.h" - - -namespace gnuworld -{ - -using std::endl ; -using std::string ; -using std::map ; -using std::nothrow ; -using std::stringstream ; - -ConnectionManager::ConnectionManager( const time_t defaultTimeoutDuration, - const char defaultDelimiter ) -: timeoutDuration( defaultTimeoutDuration ), - delimiter( defaultDelimiter ), - inputBufferSize( 131072 ) -{ -inputBuffer = new char[ inputBufferSize ] ; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ConnectionManager.h" +#include "Connection.h" +#include "ConnectionHandler.h" +#include "Buffer.h" +#include "ELog.h" + +namespace gnuworld { + +using std::endl; +using std::map; +using std::nothrow; +using std::string; +using std::stringstream; + +ConnectionManager::ConnectionManager(const time_t defaultTimeoutDuration, + const char defaultDelimiter) + : timeoutDuration(defaultTimeoutDuration), delimiter(defaultDelimiter), + inputBufferSize(131072) { + inputBuffer = new char[inputBufferSize]; } -ConnectionManager::~ConnectionManager() -{ -delete[] inputBuffer ; inputBuffer = 0 ; - -// There is no reason to iterate through the eraseMap because -// that structure simply holds iterators to the connectionMap. -// Since the below loop invalidates all of those iterators, let's -// just be clean about it and clear the eraseMap now -eraseMap.clear() ; - -// Iterate through the list of currently active/pending -// Connections -for( handlerMapIterator handlerItr = handlerMap.begin() ; - handlerItr != handlerMap.end() ; ++handlerItr ) - { - for( connectionMapIterator connectionItr = - handlerItr->second.begin() ; - connectionItr != handlerItr->second.end() ; - ++connectionItr ) - { - // Convenience variable - // Obtain a pointer to the Connection object - Connection* connectionPtr = *connectionItr ; - - // Close this Connection's socket - closeSocket( connectionPtr->getSockFD() ) ; - - // Deallocate the space for this Connection object - delete connectionPtr ; - } - } - -// Clean up, even if not strictly necessary, it's good habit -handlerMap.clear() ; +ConnectionManager::~ConnectionManager() { + delete[] inputBuffer; + inputBuffer = 0; + + // There is no reason to iterate through the eraseMap because + // that structure simply holds iterators to the connectionMap. + // Since the below loop invalidates all of those iterators, let's + // just be clean about it and clear the eraseMap now + eraseMap.clear(); + + // Iterate through the list of currently active/pending + // Connections + for (handlerMapIterator handlerItr = handlerMap.begin(); handlerItr != handlerMap.end(); + ++handlerItr) { + for (connectionMapIterator connectionItr = handlerItr->second.begin(); + connectionItr != handlerItr->second.end(); ++connectionItr) { + // Convenience variable + // Obtain a pointer to the Connection object + Connection* connectionPtr = *connectionItr; + + // Close this Connection's socket + closeSocket(connectionPtr->getSockFD()); + + // Deallocate the space for this Connection object + delete connectionPtr; + } + } + + // Clean up, even if not strictly necessary, it's good habit + handlerMap.clear(); } -Connection* ConnectionManager::Connect( ConnectionHandler* hPtr, - const string& host, - const unsigned short int remotePort, - bool tlsEnabled = false ) -{ -// Handler must be valid -assert( hPtr != 0 ) ; - -// An empty host is invalid -if( host.empty() ) - { - return 0 ; - } - -//elog << "Connect> " -// << host -// << ":" -// << remotePort -// << endl ; - -// Allocate a new Connection object -Connection* newConnection = new (nothrow) - Connection( host, remotePort, delimiter, tlsEnabled ) ; -assert( newConnection != 0 ) ; - -// Set the absolute time for this Connection's timeout to occur -newConnection->setAbsTimeout( time( 0 ) + timeoutDuration ) ; - -// The new connection will automatically set itself to the pending state - -// Check if the hostname given is a hostname or numbers and dots -if( isIpAddress( host ) ) - { - // Numbers and dots - newConnection->setIP( host ) ; - } -else - { - // Canonical host name - newConnection->setIP( ipAddrOf( host ) ) ; - - // Make sure that lookup was successful - // If it fails, ipAddrOf() returns an empty - // string, and inet_addr() will crash - if( newConnection->getIP().empty() ) - { - // No good - delete newConnection ; newConnection = 0 ; - - elog << "ConnectionManager::Connect> Unable " - << "to find valid IP" - << endl ; - - return 0 ; - } - } // else() - -// Open a non-blocking socket -int sockFD = openSocket() ; -if( -1 == sockFD ) - { - delete newConnection ; - - elog << "Connect> openSocket() failed" - << endl ; - - return 0 ; - } - -// Setup some basic options -struct sockaddr_in* addr = newConnection->getAddr() ; -addr->sin_family = AF_INET ; -addr->sin_port = htons( static_cast< u_short >( remotePort ) ) ; -addr->sin_addr.s_addr = inet_addr( newConnection->getIP().c_str() ) ; - -// Update the new Connection object -newConnection->setSockFD( sockFD ) ; +Connection* ConnectionManager::Connect(ConnectionHandler* hPtr, const string& host, + const unsigned short int remotePort, + bool tlsEnabled = false) { + // Handler must be valid + assert(hPtr != 0); + + // An empty host is invalid + if (host.empty()) { + return 0; + } + + // elog << "Connect> " + // << host + // << ":" + // << remotePort + // << endl ; + + // Allocate a new Connection object + Connection* newConnection = new (nothrow) Connection(host, remotePort, delimiter, tlsEnabled); + assert(newConnection != 0); + + // Set the absolute time for this Connection's timeout to occur + newConnection->setAbsTimeout(time(0) + timeoutDuration); + + // The new connection will automatically set itself to the pending state + + // Check if the hostname given is a hostname or numbers and dots + if (isIpAddress(host)) { + // Numbers and dots + newConnection->setIP(host); + } else { + // Canonical host name + newConnection->setIP(ipAddrOf(host)); + + // Make sure that lookup was successful + // If it fails, ipAddrOf() returns an empty + // string, and inet_addr() will crash + if (newConnection->getIP().empty()) { + // No good + delete newConnection; + newConnection = 0; + + elog << "ConnectionManager::Connect> Unable " + << "to find valid IP" << endl; + + return 0; + } + } // else() + + // Open a non-blocking socket + int sockFD = openSocket(); + if (-1 == sockFD) { + delete newConnection; + + elog << "Connect> openSocket() failed" << endl; + + return 0; + } + + // Setup some basic options + struct sockaddr_in* addr = newConnection->getAddr(); + addr->sin_family = AF_INET; + addr->sin_port = htons(static_cast(remotePort)); + addr->sin_addr.s_addr = inet_addr(newConnection->getIP().c_str()); + + // Update the new Connection object + newConnection->setSockFD(sockFD); #ifdef HAVE_LIBSSL -if (tlsEnabled) { - SSL* state = SSL_new(sslCtx); - if (!state) { - elog << "Connect> Could not create SSL session" << endl; - return 0; - } - newConnection->setTlsState(state); - newConnection->setNegotiatingTLS(); - SSL_set_fd(state, sockFD); - BIO_set_nbio(SSL_get_rbio(state), 1); - BIO_set_nbio(SSL_get_wbio(state), 1); - SSL_set_connect_state(state); -} + if (tlsEnabled) { + SSL* state = SSL_new(sslCtx); + if (!state) { + elog << "Connect> Could not create SSL session" << endl; + return 0; + } + newConnection->setTlsState(state); + newConnection->setNegotiatingTLS(); + SSL_set_fd(state, sockFD); + BIO_set_nbio(SSL_get_rbio(state), 1); + BIO_set_nbio(SSL_get_wbio(state), 1); + SSL_set_connect_state(state); + } #endif -// Attempt to initiate the connect. -// The socket is non-blocking, so a failure is expected -// In the case of a UDP socket, this call to ::connect() will just -// fill the socket address structure with relevant information -if( ::connect( sockFD, reinterpret_cast< sockaddr* >( addr ), - sizeof( struct sockaddr_in ) ) < 0 ) - { - // Let's check what the error was - switch( errno ) - { - case EISCONN: - // EISCONN means the connection is successful - // This will still work fine when another - // connect() is attempted in Poll() - break ; - - // EINPROGRESS means that the socket is nonblocking and - // the connection attempt is in progress - case EINPROGRESS: - break ; - - // All other errors are failures - default: - // Close the socket - closeSocket( newConnection->getSockFD() ) ; - - // Deallocate the Connection object and - // set it to NULL for return to caller - delete newConnection ; - newConnection = 0 ; - - elog << "ConnectionManager::Connect> Error " - << "detected in connect(): " - << strerror( errno ) - << endl ; - - // No need to call OnConnectFail() here since - // this method will return a NULL Connection - // to the caller, which indicates that the - // attempt failed. - break ; - } // switch() - } // if() - -if( newConnection != 0 ) - { -// elog << "Connect> Adding new connection attempt: " -// << *newConnection -// << endl ; - - // Connection in progress - // Add to the handlerMap - bool insertOK = handlerMap[ hPtr ].insert( newConnection ).second ; - - // It's possible the connection could fail (?) - // Either way, the container is nice enough to tell us - // if it was successful, so let's check. - if( !insertOK ) - { - // Insertion failed - // Close the socket - closeSocket( newConnection->getSockFD() ) ; - - elog << "ConnectionManager::Connect> Failed to " - << "add new connection to handlerMap: " - << *newConnection - << endl ; - - // Deallocate and set to 0 for return to caller - delete newConnection ; newConnection = 0 ; - } - } - -if( newConnection != 0 ) - { - // Obtain the local machine's port number for this Connection - struct sockaddr_in sockAddr ; - memset( &sockAddr, 0, sizeof( struct sockaddr_in ) ) ; - - socklen_t sockAddrLen = - static_cast< socklen_t >( sizeof( struct sockaddr ) ) ; - - // Get the information for the socket on this machine - if( ::getsockname( newConnection->getSockFD(), - reinterpret_cast< struct sockaddr* >( &sockAddr ), - &sockAddrLen ) < 0 ) - { - // getsockname() failed - elog << "finishConnect> getsockname() failed: " - << strerror( errno ) - << endl ; - - closeSocket( newConnection->getSockFD() ) ; - delete newConnection ; newConnection = 0 ; - - // Return failure - return 0 ; - } - - // Update remote port number for this Connection - newConnection->setLocalPort( ntohs( sockAddr.sin_port ) ) ; - } -// Return a pointer to the Connection object, whether or not -// it's NULL -return newConnection ; + // Attempt to initiate the connect. + // The socket is non-blocking, so a failure is expected + // In the case of a UDP socket, this call to ::connect() will just + // fill the socket address structure with relevant information + if (::connect(sockFD, reinterpret_cast(addr), sizeof(struct sockaddr_in)) < 0) { + // Let's check what the error was + switch (errno) { + case EISCONN: + // EISCONN means the connection is successful + // This will still work fine when another + // connect() is attempted in Poll() + break; + + // EINPROGRESS means that the socket is nonblocking and + // the connection attempt is in progress + case EINPROGRESS: + break; + + // All other errors are failures + default: + // Close the socket + closeSocket(newConnection->getSockFD()); + + // Deallocate the Connection object and + // set it to NULL for return to caller + delete newConnection; + newConnection = 0; + + elog << "ConnectionManager::Connect> Error " + << "detected in connect(): " << strerror(errno) << endl; + + // No need to call OnConnectFail() here since + // this method will return a NULL Connection + // to the caller, which indicates that the + // attempt failed. + break; + } // switch() + } // if() + + if (newConnection != 0) { + // elog << "Connect> Adding new connection attempt: " + // << *newConnection + // << endl ; + + // Connection in progress + // Add to the handlerMap + bool insertOK = handlerMap[hPtr].insert(newConnection).second; + + // It's possible the connection could fail (?) + // Either way, the container is nice enough to tell us + // if it was successful, so let's check. + if (!insertOK) { + // Insertion failed + // Close the socket + closeSocket(newConnection->getSockFD()); + + elog << "ConnectionManager::Connect> Failed to " + << "add new connection to handlerMap: " << *newConnection << endl; + + // Deallocate and set to 0 for return to caller + delete newConnection; + newConnection = 0; + } + } + + if (newConnection != 0) { + // Obtain the local machine's port number for this Connection + struct sockaddr_in sockAddr; + memset(&sockAddr, 0, sizeof(struct sockaddr_in)); + + socklen_t sockAddrLen = static_cast(sizeof(struct sockaddr)); + + // Get the information for the socket on this machine + if (::getsockname(newConnection->getSockFD(), reinterpret_cast(&sockAddr), + &sockAddrLen) < 0) { + // getsockname() failed + elog << "finishConnect> getsockname() failed: " << strerror(errno) << endl; + + closeSocket(newConnection->getSockFD()); + delete newConnection; + newConnection = 0; + + // Return failure + return 0; + } + + // Update remote port number for this Connection + newConnection->setLocalPort(ntohs(sockAddr.sin_port)); + } + // Return a pointer to the Connection object, whether or not + // it's NULL + return newConnection; } -bool ConnectionManager::DisconnectByHost( ConnectionHandler* hPtr, - const string& hostname, - const unsigned short int remotePort, - const unsigned short int localPort ) -{ -// Public method, check method arguments -assert( hPtr != 0 ) ; - -// An empty hostname is ok here, it indicates that a listening -// Connection is to be removed from the given port - -// Attempt to find the handler in the handlerMap -handlerMapIterator handlerItr = handlerMap.find( hPtr ) ; -if( handlerItr == handlerMap.end() ) - { - // This ConnectionHandler has no Connections registered - // *shrug* - return false ; - } - -// Walk the connectionMap, looking for one or more matching Connections -for( connectionMapIterator connectionItr = handlerItr->second.begin(), - connectionEndItr = handlerItr->second.end() ; - connectionItr != connectionEndItr ; ++connectionItr ) - { - // Store the address of the Connection object in cPtr - // Convenience variable - Connection* cPtr = *connectionItr ; - - // If the hostname is empty, then we are attempting to remove - // a listening socket - if( hostname.empty() && cPtr->isListening() ) - { - // We are looking for a listening Connection, and - // we found one. - // The only criteria for a listening Connection is - // the localPort. - if( localPort == cPtr->getLocalPort() ) - { - // Found the listener we seek - scheduleErasure( hPtr, connectionItr ) ; - - // Since a machine (in most cases, in this - // one at least) may only have a single - // listener for a given port, there is no - // use in continuing with this loop. - // Return success - return true ; - } - } - - // Not looking for a listener - // If localPort == 0, then remove all Connections matching - // hostname/remotePort - - // First check for a remotePort match - if( remotePort != cPtr->getRemotePort() ) - { - // No match, continue with next item - continue ; - } - - // Look for a match on the hostname - if( !strcasecmp( hostname.c_str(), cPtr->getHostname().c_str() ) ) - { - // Found a match on the hostname - - // Check if we are to remove all Connections matching - // the two previous criteria, regardless of localPort - if( 0 == localPort ) - { - // Remove all - scheduleErasure( hPtr, connectionItr ) ; - - // Keep going until end of connectionMap - } - - // Check now if the localPorts match exactly - else if( localPort == cPtr->getLocalPort() ) - { - // Exact match - scheduleErasure( hPtr, connectionItr ) ; - - // Since there can only be a single (by - // definition of TCP connections) connection - // based on a unique set of hostname/localport/ - // remoteport, there is no need to continue - // looking for more matches: there are none. - return true ; - } - } // if( hostname == ... ) - } // for() - -// Unable to find a matching Connection, return failure -return false ; +bool ConnectionManager::DisconnectByHost(ConnectionHandler* hPtr, const string& hostname, + const unsigned short int remotePort, + const unsigned short int localPort) { + // Public method, check method arguments + assert(hPtr != 0); + + // An empty hostname is ok here, it indicates that a listening + // Connection is to be removed from the given port + + // Attempt to find the handler in the handlerMap + handlerMapIterator handlerItr = handlerMap.find(hPtr); + if (handlerItr == handlerMap.end()) { + // This ConnectionHandler has no Connections registered + // *shrug* + return false; + } + + // Walk the connectionMap, looking for one or more matching Connections + for (connectionMapIterator connectionItr = handlerItr->second.begin(), + connectionEndItr = handlerItr->second.end(); + connectionItr != connectionEndItr; ++connectionItr) { + // Store the address of the Connection object in cPtr + // Convenience variable + Connection* cPtr = *connectionItr; + + // If the hostname is empty, then we are attempting to remove + // a listening socket + if (hostname.empty() && cPtr->isListening()) { + // We are looking for a listening Connection, and + // we found one. + // The only criteria for a listening Connection is + // the localPort. + if (localPort == cPtr->getLocalPort()) { + // Found the listener we seek + scheduleErasure(hPtr, connectionItr); + + // Since a machine (in most cases, in this + // one at least) may only have a single + // listener for a given port, there is no + // use in continuing with this loop. + // Return success + return true; + } + } + + // Not looking for a listener + // If localPort == 0, then remove all Connections matching + // hostname/remotePort + + // First check for a remotePort match + if (remotePort != cPtr->getRemotePort()) { + // No match, continue with next item + continue; + } + + // Look for a match on the hostname + if (!strcasecmp(hostname.c_str(), cPtr->getHostname().c_str())) { + // Found a match on the hostname + + // Check if we are to remove all Connections matching + // the two previous criteria, regardless of localPort + if (0 == localPort) { + // Remove all + scheduleErasure(hPtr, connectionItr); + + // Keep going until end of connectionMap + } + + // Check now if the localPorts match exactly + else if (localPort == cPtr->getLocalPort()) { + // Exact match + scheduleErasure(hPtr, connectionItr); + + // Since there can only be a single (by + // definition of TCP connections) connection + // based on a unique set of hostname/localport/ + // remoteport, there is no need to continue + // looking for more matches: there are none. + return true; + } + } // if( hostname == ... ) + } // for() + + // Unable to find a matching Connection, return failure + return false; } -bool ConnectionManager::DisconnectByIP( ConnectionHandler* hPtr, - const string& IP, - const unsigned short int remotePort, - const unsigned short int localPort ) -{ -// Public method, check args -assert( hPtr != 0 ) ; - -// An empty IP is ok here, it indicates that a listening Connection -// is to be removed from the given port - -// Attempt to lookup the given handler -// handlerItr will be equivalent to handlerMap.end() if the handler -// is not found. -handlerMapIterator handlerItr = handlerMap.find( hPtr ) ; -if( handlerItr == handlerMap.end() ) - { - // This ConnectionHandler has no Connections registered - // *shrug* - return false ; - } - -// Walk the connectionMap, looking for one or more matching Connections -for( connectionMapIterator connectionItr = handlerItr->second.begin(), - connectionEndItr = handlerItr->second.end() ; - connectionItr != connectionEndItr ; ++connectionItr ) - { - // Store the address of the Connection object in cPtr - // Convenience variable - Connection* cPtr = *connectionItr ; - - // If the IP is empty, then we are attempting to remove - // a listening socket - if( IP.empty() && cPtr->isListening() ) - { - // We are looking for a listening Connection, and - // we found one. - // The only criteria for a listening Connection is - // the localPort. - if( localPort == cPtr->getLocalPort() ) - { - // Found the listener we seek - scheduleErasure( hPtr, connectionItr ) ; - - // Since a machine (in most cases, in this - // one at least) may only have a single - // listener for a given port, there is no - // use in continuing with this loop. - // Return success - return true ; - } - } - - // Not looking for a listener - // If localPort == 0, then remove all Connections matching - // IP/remotePort - - // First check for a remotePort match - if( remotePort != cPtr->getRemotePort() ) - { - // No match, continue with next item - continue ; - } - - // Look for a match on the IP - if( IP == cPtr->getIP() ) - { - // Found a match on the IP - - // Check if we are to remove all Connections matching - // the two previous criteria, regardless of localPort - if( 0 == localPort ) - { - // Remove all - scheduleErasure( hPtr, connectionItr ) ; - - // Keep going until end of connectionMap - } - - // Check now if the localPorts match exactly - else if( localPort == cPtr->getLocalPort() ) - { - // Exact match - scheduleErasure( hPtr, connectionItr ) ; - - // Since there can only be a single (by - // definition of TCP connections) connection - // based on a unique set of IP/localport/ - // remoteport, there is no need to continue - // looking for more matches: there are none. - return true ; - } - } // if( hostname == ... ) - } // for() - -// Unable to find a matching Connection, return failure -return false ; +bool ConnectionManager::DisconnectByIP(ConnectionHandler* hPtr, const string& IP, + const unsigned short int remotePort, + const unsigned short int localPort) { + // Public method, check args + assert(hPtr != 0); + + // An empty IP is ok here, it indicates that a listening Connection + // is to be removed from the given port + + // Attempt to lookup the given handler + // handlerItr will be equivalent to handlerMap.end() if the handler + // is not found. + handlerMapIterator handlerItr = handlerMap.find(hPtr); + if (handlerItr == handlerMap.end()) { + // This ConnectionHandler has no Connections registered + // *shrug* + return false; + } + + // Walk the connectionMap, looking for one or more matching Connections + for (connectionMapIterator connectionItr = handlerItr->second.begin(), + connectionEndItr = handlerItr->second.end(); + connectionItr != connectionEndItr; ++connectionItr) { + // Store the address of the Connection object in cPtr + // Convenience variable + Connection* cPtr = *connectionItr; + + // If the IP is empty, then we are attempting to remove + // a listening socket + if (IP.empty() && cPtr->isListening()) { + // We are looking for a listening Connection, and + // we found one. + // The only criteria for a listening Connection is + // the localPort. + if (localPort == cPtr->getLocalPort()) { + // Found the listener we seek + scheduleErasure(hPtr, connectionItr); + + // Since a machine (in most cases, in this + // one at least) may only have a single + // listener for a given port, there is no + // use in continuing with this loop. + // Return success + return true; + } + } + + // Not looking for a listener + // If localPort == 0, then remove all Connections matching + // IP/remotePort + + // First check for a remotePort match + if (remotePort != cPtr->getRemotePort()) { + // No match, continue with next item + continue; + } + + // Look for a match on the IP + if (IP == cPtr->getIP()) { + // Found a match on the IP + + // Check if we are to remove all Connections matching + // the two previous criteria, regardless of localPort + if (0 == localPort) { + // Remove all + scheduleErasure(hPtr, connectionItr); + + // Keep going until end of connectionMap + } + + // Check now if the localPorts match exactly + else if (localPort == cPtr->getLocalPort()) { + // Exact match + scheduleErasure(hPtr, connectionItr); + + // Since there can only be a single (by + // definition of TCP connections) connection + // based on a unique set of IP/localport/ + // remoteport, there is no need to continue + // looking for more matches: there are none. + return true; + } + } // if( hostname == ... ) + } // for() + + // Unable to find a matching Connection, return failure + return false; } -bool ConnectionManager::disconnectAll( ConnectionHandler* hPtr ) -{ -// Precondition: hPtr != 0 -handlerMapType::iterator hmItr = handlerMap.find( hPtr ) ; -if( handlerMap.end() == hmItr ) - { - // No Connections owned by the ConnectionHandler - return true ; - } - -bool returnMe = true ; - -// This is safe because Disconnect() calls scheduleErasure() -// which modifies only the eraseMap. -for( connectionMapIterator connItr = hmItr->second.begin() ; - connItr != hmItr->second.end() ; ++connItr ) - { - // Track if any of the Disconnect()'s fail - bool disReturn = Disconnect( hPtr, *connItr ) ; - if( !disReturn ) - { - returnMe = false ; - } - } -return returnMe ; +bool ConnectionManager::disconnectAll(ConnectionHandler* hPtr) { + // Precondition: hPtr != 0 + handlerMapType::iterator hmItr = handlerMap.find(hPtr); + if (handlerMap.end() == hmItr) { + // No Connections owned by the ConnectionHandler + return true; + } + + bool returnMe = true; + + // This is safe because Disconnect() calls scheduleErasure() + // which modifies only the eraseMap. + for (connectionMapIterator connItr = hmItr->second.begin(); connItr != hmItr->second.end(); + ++connItr) { + // Track if any of the Disconnect()'s fail + bool disReturn = Disconnect(hPtr, *connItr); + if (!disReturn) { + returnMe = false; + } + } + return returnMe; } -bool ConnectionManager::Disconnect( ConnectionHandler* hPtr, - Connection* cPtr ) -{ -// Public method, verify method arguments -assert( hPtr != 0 ) ; - -if( 0 == cPtr ) - { - // Disconnect all Connections held by the ConnectionHandler - return disconnectAll( hPtr ) ; - } - -// Attempt to locate the handler in the handler map -handlerMapIterator handlerItr = handlerMap.find( hPtr ) ; -if( handlerItr == handlerMap.end() ) - { - // Handler not found - return false ; - } - -// Attempt to locate the Connection in the handler's connectionMap -connectionMapIterator connectionItr = handlerItr->second.find( cPtr ) ; -if( connectionItr == handlerItr->second.end() ) - { - // Connection was not found for this handler - return false ; - } - -elog << "ConnectionManager::Disconnect> Scheduling connection " - << "for removal: " - << *cPtr - << endl ; - -// Schedule the connection to be erased during the next call -// to Poll() -scheduleErasure( hPtr, connectionItr ) ; - -// Flush buffer. -cPtr->Flush() ; +bool ConnectionManager::Disconnect(ConnectionHandler* hPtr, Connection* cPtr) { + // Public method, verify method arguments + assert(hPtr != 0); + + if (0 == cPtr) { + // Disconnect all Connections held by the ConnectionHandler + return disconnectAll(hPtr); + } + + // Attempt to locate the handler in the handler map + handlerMapIterator handlerItr = handlerMap.find(hPtr); + if (handlerItr == handlerMap.end()) { + // Handler not found + return false; + } + + // Attempt to locate the Connection in the handler's connectionMap + connectionMapIterator connectionItr = handlerItr->second.find(cPtr); + if (connectionItr == handlerItr->second.end()) { + // Connection was not found for this handler + return false; + } + + elog << "ConnectionManager::Disconnect> Scheduling connection " + << "for removal: " << *cPtr << endl; + + // Schedule the connection to be erased during the next call + // to Poll() + scheduleErasure(hPtr, connectionItr); + + // Flush buffer. + cPtr->Flush(); #ifdef HAVE_LIBSSL -// Attempt to shutdown TLS connection. -if( cPtr->isTLS() && !cPtr->isNegotiatingTLS() && !cPtr->hasFlag( Connection::F_TLS_FATAL_ERROR ) ) - { - // Flag the connections as shutting down. - cPtr->setShuttingDownTLS() ; - - int res = SSL_shutdown( cPtr->getTlsState() ) ; - if( res > 0 ) - { - elog << "ConnectionManager::Disconnect> TLS connection gracefully shut down." << endl ; - } - } + // Attempt to shutdown TLS connection. + if (cPtr->isTLS() && !cPtr->isNegotiatingTLS() && + !cPtr->hasFlag(Connection::F_TLS_FATAL_ERROR)) { + // Flag the connections as shutting down. + cPtr->setShuttingDownTLS(); + + int res = SSL_shutdown(cPtr->getTlsState()); + if (res > 0) { + elog << "ConnectionManager::Disconnect> TLS connection gracefully shut down." << endl; + } + } #endif -// Connection located and scheduled for erasure, return success -return true ; + // Connection located and scheduled for erasure, return success + return true; } -void ConnectionManager::Poll( const long seconds, - const long milliseconds ) -{ -//elog << "Poll()" << endl ; - -// Only execute this method if: -// - The handlerMap is not empty, OR the eraseMap is not empty -// Either of these cases indicates that some processing must be -// performed. -if( handlerMap.empty() && eraseMap.empty() ) - { -// elog << "ConnectionManager::Poll> handlerMap.empty()" -// << endl ; - return ; - } - -// highestFD is passed to select() as the largest FD for which to -// obtain state information. -int highestFD = 0 ; - -// These variables are used for select() -fd_set writefds ; -fd_set readfds ; -FD_ZERO( &writefds ) ; -FD_ZERO( &readfds ) ; - -// Iterate through the table of Connection's to setup select() -// FD information -for( constHandlerMapIterator handlerItr = handlerMap.begin(), - handlerEndItr = handlerMap.end() ; - handlerItr != handlerEndItr ; ++handlerItr ) - { - for( constConnectionMapIterator connectionItr = - handlerItr->second.begin(), - connectionEndItr = handlerItr->second.end() ; - connectionItr != connectionEndItr ; - ++connectionItr ) - { - // Create a couple of convenience variables - const Connection* connectionPtr = *connectionItr ; - int tempFD = connectionPtr->getSockFD() ; - -// elog << "Poll> Before select(), tempFD: " -// << tempFD -// << endl ; - - assert( tempFD >= 0 ) ; - - // The order of the below if/else structure is important - // First check for the fully connected sockets. - if( connectionPtr->isConnected() ) - { - // This connection already connected - // Check to see if we can read - FD_SET( tempFD, &readfds ) ; - - // Is the connection's output buffer empty? - if( !connectionPtr->outputBuffer.empty() ) - { - // There is data present to be written - FD_SET( tempFD, &writefds ) ; - } - } - // Because listening sockets are technically pending - // sockets as well, process those first since they - // are handled differently than outgoing pending - // connections. - else if( connectionPtr->isListening() ) - { - // Server socket, it is always pending :) - FD_SET( tempFD, &readfds ) ; - } - - // Check for a still pending outgoing socket connection. - else if( connectionPtr->isPending() ) - { - // Not yet fully connected, check for write - FD_SET( tempFD, &writefds ) ; - } - - // Keep track of the highest FD - if( tempFD > highestFD ) - { - highestFD = tempFD ; - } - } // for( connectionItr ) - } // for( handlerItr ) - -//elog << "ConnectionManager::Poll> select()" -// << endl ; - -int selectRet = 0 ; -struct timeval to = { seconds, milliseconds * 1000 } ; - -// Call select() -selectRet = ::select( 1 + highestFD, &readfds, &writefds, 0, - (-1 == seconds) ? NULL : &to ) ; - -//elog << "ConnectionManager::Poll()> seconds: " -// << seconds -// << ", selectRet: " -// << selectRet -// << endl ; - -// Continue even if select() returned 0, there may be connections -// waiting to be erased - -// Is there an error from select()? -if( selectRet < 0 ) - { - // Error in select() - elog << "ConnectionManager::Poll> Error in Poll(): " - << strerror( errno ) - << endl ; - return ; - } - -// Continue with the rest of the loop, even if no connections were found -// to be awaiting service: a pending Connection still needs to have its -// timeout checked. - -// This variable is used for checking timeouts -time_t now = ::time( 0 ) ; - -// Walk the handler list, checking connections for each connectionMap. -for( constHandlerMapIterator handlerItr = handlerMap.begin(), - handlerEndItr = handlerMap.end() ; - handlerItr != handlerEndItr ; ++handlerItr ) - { - // Convenience variable for the long loop ahead - ConnectionHandler* hPtr = handlerItr->first ; - - // Iterate through this handler's connectionMap, similar - // as the above loops. - for( connectionMapIterator connectionItr = - handlerItr->second.begin(), - connectionEndItr = handlerItr->second.end() ; - connectionItr != connectionEndItr ; - ++connectionItr ) - { - - // This variable indicates if the connection should be - // kept (true) or removed (false) from the tables - bool connectOK = true ; - - // Obtain a pointer to the Connection object being inspected - Connection* connectionPtr = *connectionItr ; - - // Temporary variable, this is the value of the current - // Connection's socket (file) descriptor - int tempFD = connectionPtr->getSockFD() ; - -// elog << "Poll> Before select(), tempFD: " -// << tempFD -// << endl ; - - assert( tempFD >= 0 ) ; - - // Order of this if/else is important here. - // First check for fully connected sockets - if( connectionPtr->isConnected() ) - { - // Check for ability to read - if( FD_ISSET( tempFD, &readfds ) ) - { - // Data available, or error - // handleRead() will perform the read()/recv() - // and distribute event to virtual methods - // (including OnDisconnect()) - // - // Connected sockets are always checked - // for read - connectOK = handleRead( hPtr, - connectionPtr ) ; - } // if( FD_ISSET( read ) ) - - // Attempt to write any buffered data - // if the connection is valid - // A Connection's outputBuffer cannot - // be modified since when we last checked, - // so no threat of a possibly blocking - // call here. - if( connectOK && FD_ISSET( tempFD, &writefds ) ) - { - connectOK = handleWrite( hPtr, - connectionPtr ) ; - } - } // if( connectionPtr->isConnected() ) - - // Next let's check if this is a listening (server) socket - else if( connectionPtr->isListening() ) - { -// elog << "Poll> Checking listener: " -// << *connectionPtr -// << endl ; - - // Yup. See if anyone is waiting to connect - if( FD_ISSET( tempFD, &readfds ) ) - { - // Could be, attempt an accept() - connectOK = finishAccept( hPtr, - connectionPtr ) ; - } - } - - // Check for pending outgoing connection - else if( connectionPtr->isPending() ) - { -// elog << "Poll> Checking pending: " -// << *connectionPtr -// << endl ; - - // Ready for write state? - if( FD_ISSET( tempFD, &writefds ) ) - { - // Yup, attempt to complete the connection - connectOK = finishConnect( hPtr, - connectionPtr ) ; - } // if( FD_ISSET() ) - else - { - // FD is NOT set, and the connection is - // still pending; let's check for a timeout - if( now >= connectionPtr->getAbsTimeout() ) - { - // This connection attempt has - // timed out - // Notify the handler - hPtr->OnTimeout( connectionPtr ) ; - - // Mark this connection for erasure - connectOK = false ; - - } // if( now >= ... ) - } // else() - } // if( connectionPtr->isPending() ) - - // Check if the connection is still valid - if( !connectOK ) - { - // Nope, the connection is invalid - // Schedule it for erasure - scheduleErasure( hPtr, connectionItr ) ; - } // if( !connectOK ) - - } // for( connectionItr ) - } // for( handlerItr ) - -// Handler methods have the freedom to call Disconnect() at will, -// however disconnecting/deallocating Connection objects in a handler -// will invalidate the iterator used in the above loop (since handlers -// are called in the above loop). -// Therefore, we are using a separate container to hold pointers to -// the Connection objects to be erased, and are erasing them here -// in synchronous fashion to simplify the process. -// Elements can get themselves into the eraseMap by -// either having a read/write/accept/connect error, or by a client -// class calling some form of Disconnect(). -// Either way, all terminal processing is done here. -// -// Note that the reason for using an associative container for the -// eraseMap, instead of a linear one, is to increase efficiency here. -// If the Connection*'s were unsorted in the eraseMap, then this -// loop would be performing many handlerMap.find()'s looking for the -// ConnectionHandler for each Connection. -// With the eraseMap being associative, we can work a single -// ConnectionHandler at a time to its completion, which saves -// lookups. -// No increment is done in this for loop, because it is done -// in the inner for loop. -// Because all Connections are erased by calling scheduleErasure(), -// we are guaranteed that an iterator to a connection is not entered -// into the eraseMap more than once. -// -for( eraseMapIterator eraseItr = eraseMap.begin(), - eraseEndItr = eraseMap.end() ; - eraseItr != eraseEndItr ; ) - { - // First lookup the handlerItr. - // No error checking is performed here, because the above - // loop was able to find the handler, and no removes have - // been done (it is done here). - // Because the lookups are performed based on what is found - // in the eraseMap, handlerItr is guaranteed to have - // at least one Connection which must be removed. - // - handlerMapIterator handlerItr = handlerMap.find( - eraseItr->first ) ; - - // Continue in the loop, erasing elements, until the - // handler in the eraseMap changes - // This loop guard will be evaluated to true at least once. - // The below loop will terminate when either of two conditions - // are present after incrementing eraseItr: - // - eraseItr is equivalent to eraseEndItr - // - eraseItr->first != handlerItr->first - // Be sure to check both, beginning with the case that could - // crash the process :) - // There is no reason to call the notification methods of - // the handlers here, all of that processing is performed - // by the above for() loops (either directly, or through calls - // to finishAccept(),finishConnect(),handleRead(),handleWrite()) - // - for( ; (eraseItr != eraseEndItr) && - (eraseItr->first == handlerItr->first) ; ++eraseItr ) - { - // Obtain a convenience pointer for readability - Connection* connectionPtr = *(eraseItr->second) ; - -// elog << "Poll> Removing connection: " -// << *connectionPtr -// << endl ; +void ConnectionManager::Poll(const long seconds, const long milliseconds) { + // elog << "Poll()" << endl ; + + // Only execute this method if: + // - The handlerMap is not empty, OR the eraseMap is not empty + // Either of these cases indicates that some processing must be + // performed. + if (handlerMap.empty() && eraseMap.empty()) { + // elog << "ConnectionManager::Poll> handlerMap.empty()" + // << endl ; + return; + } + + // highestFD is passed to select() as the largest FD for which to + // obtain state information. + int highestFD = 0; + + // These variables are used for select() + fd_set writefds; + fd_set readfds; + FD_ZERO(&writefds); + FD_ZERO(&readfds); + + // Iterate through the table of Connection's to setup select() + // FD information + for (constHandlerMapIterator handlerItr = handlerMap.begin(), handlerEndItr = handlerMap.end(); + handlerItr != handlerEndItr; ++handlerItr) { + for (constConnectionMapIterator connectionItr = handlerItr->second.begin(), + connectionEndItr = handlerItr->second.end(); + connectionItr != connectionEndItr; ++connectionItr) { + // Create a couple of convenience variables + const Connection* connectionPtr = *connectionItr; + int tempFD = connectionPtr->getSockFD(); + + // elog << "Poll> Before select(), tempFD: " + // << tempFD + // << endl ; + + assert(tempFD >= 0); + + // The order of the below if/else structure is important + // First check for the fully connected sockets. + if (connectionPtr->isConnected()) { + // This connection already connected + // Check to see if we can read + FD_SET(tempFD, &readfds); + + // Is the connection's output buffer empty? + if (!connectionPtr->outputBuffer.empty()) { + // There is data present to be written + FD_SET(tempFD, &writefds); + } + } + // Because listening sockets are technically pending + // sockets as well, process those first since they + // are handled differently than outgoing pending + // connections. + else if (connectionPtr->isListening()) { + // Server socket, it is always pending :) + FD_SET(tempFD, &readfds); + } + + // Check for a still pending outgoing socket connection. + else if (connectionPtr->isPending()) { + // Not yet fully connected, check for write + FD_SET(tempFD, &writefds); + } + + // Keep track of the highest FD + if (tempFD > highestFD) { + highestFD = tempFD; + } + } // for( connectionItr ) + } // for( handlerItr ) + + // elog << "ConnectionManager::Poll> select()" + // << endl ; + + int selectRet = 0; + struct timeval to = {seconds, milliseconds * 1000}; + + // Call select() + selectRet = ::select(1 + highestFD, &readfds, &writefds, 0, (-1 == seconds) ? NULL : &to); + + // elog << "ConnectionManager::Poll()> seconds: " + // << seconds + // << ", selectRet: " + // << selectRet + // << endl ; + + // Continue even if select() returned 0, there may be connections + // waiting to be erased + + // Is there an error from select()? + if (selectRet < 0) { + // Error in select() + elog << "ConnectionManager::Poll> Error in Poll(): " << strerror(errno) << endl; + return; + } + + // Continue with the rest of the loop, even if no connections were found + // to be awaiting service: a pending Connection still needs to have its + // timeout checked. + + // This variable is used for checking timeouts + time_t now = ::time(0); + + // Walk the handler list, checking connections for each connectionMap. + for (constHandlerMapIterator handlerItr = handlerMap.begin(), handlerEndItr = handlerMap.end(); + handlerItr != handlerEndItr; ++handlerItr) { + // Convenience variable for the long loop ahead + ConnectionHandler* hPtr = handlerItr->first; + + // Iterate through this handler's connectionMap, similar + // as the above loops. + for (connectionMapIterator connectionItr = handlerItr->second.begin(), + connectionEndItr = handlerItr->second.end(); + connectionItr != connectionEndItr; ++connectionItr) { + + // This variable indicates if the connection should be + // kept (true) or removed (false) from the tables + bool connectOK = true; + + // Obtain a pointer to the Connection object being inspected + Connection* connectionPtr = *connectionItr; + + // Temporary variable, this is the value of the current + // Connection's socket (file) descriptor + int tempFD = connectionPtr->getSockFD(); + + // elog << "Poll> Before select(), tempFD: " + // << tempFD + // << endl ; + + assert(tempFD >= 0); + + // Order of this if/else is important here. + // First check for fully connected sockets + if (connectionPtr->isConnected()) { + // Check for ability to read + if (FD_ISSET(tempFD, &readfds)) { + // Data available, or error + // handleRead() will perform the read()/recv() + // and distribute event to virtual methods + // (including OnDisconnect()) + // + // Connected sockets are always checked + // for read + connectOK = handleRead(hPtr, connectionPtr); + } // if( FD_ISSET( read ) ) + + // Attempt to write any buffered data + // if the connection is valid + // A Connection's outputBuffer cannot + // be modified since when we last checked, + // so no threat of a possibly blocking + // call here. + if (connectOK && FD_ISSET(tempFD, &writefds)) { + connectOK = handleWrite(hPtr, connectionPtr); + } + } // if( connectionPtr->isConnected() ) + + // Next let's check if this is a listening (server) socket + else if (connectionPtr->isListening()) { + // elog << "Poll> Checking listener: " + // << *connectionPtr + // << endl ; + + // Yup. See if anyone is waiting to connect + if (FD_ISSET(tempFD, &readfds)) { + // Could be, attempt an accept() + connectOK = finishAccept(hPtr, connectionPtr); + } + } + + // Check for pending outgoing connection + else if (connectionPtr->isPending()) { + // elog << "Poll> Checking pending: " + // << *connectionPtr + // << endl ; + + // Ready for write state? + if (FD_ISSET(tempFD, &writefds)) { + // Yup, attempt to complete the connection + connectOK = finishConnect(hPtr, connectionPtr); + } // if( FD_ISSET() ) + else { + // FD is NOT set, and the connection is + // still pending; let's check for a timeout + if (now >= connectionPtr->getAbsTimeout()) { + // This connection attempt has + // timed out + // Notify the handler + hPtr->OnTimeout(connectionPtr); + + // Mark this connection for erasure + connectOK = false; + + } // if( now >= ... ) + } // else() + } // if( connectionPtr->isPending() ) + + // Check if the connection is still valid + if (!connectOK) { + // Nope, the connection is invalid + // Schedule it for erasure + scheduleErasure(hPtr, connectionItr); + } // if( !connectOK ) + + } // for( connectionItr ) + } // for( handlerItr ) + + // Handler methods have the freedom to call Disconnect() at will, + // however disconnecting/deallocating Connection objects in a handler + // will invalidate the iterator used in the above loop (since handlers + // are called in the above loop). + // Therefore, we are using a separate container to hold pointers to + // the Connection objects to be erased, and are erasing them here + // in synchronous fashion to simplify the process. + // Elements can get themselves into the eraseMap by + // either having a read/write/accept/connect error, or by a client + // class calling some form of Disconnect(). + // Either way, all terminal processing is done here. + // + // Note that the reason for using an associative container for the + // eraseMap, instead of a linear one, is to increase efficiency here. + // If the Connection*'s were unsorted in the eraseMap, then this + // loop would be performing many handlerMap.find()'s looking for the + // ConnectionHandler for each Connection. + // With the eraseMap being associative, we can work a single + // ConnectionHandler at a time to its completion, which saves + // lookups. + // No increment is done in this for loop, because it is done + // in the inner for loop. + // Because all Connections are erased by calling scheduleErasure(), + // we are guaranteed that an iterator to a connection is not entered + // into the eraseMap more than once. + // + for (eraseMapIterator eraseItr = eraseMap.begin(), eraseEndItr = eraseMap.end(); + eraseItr != eraseEndItr;) { + // First lookup the handlerItr. + // No error checking is performed here, because the above + // loop was able to find the handler, and no removes have + // been done (it is done here). + // Because the lookups are performed based on what is found + // in the eraseMap, handlerItr is guaranteed to have + // at least one Connection which must be removed. + // + handlerMapIterator handlerItr = handlerMap.find(eraseItr->first); + + // Continue in the loop, erasing elements, until the + // handler in the eraseMap changes + // This loop guard will be evaluated to true at least once. + // The below loop will terminate when either of two conditions + // are present after incrementing eraseItr: + // - eraseItr is equivalent to eraseEndItr + // - eraseItr->first != handlerItr->first + // Be sure to check both, beginning with the case that could + // crash the process :) + // There is no reason to call the notification methods of + // the handlers here, all of that processing is performed + // by the above for() loops (either directly, or through calls + // to finishAccept(),finishConnect(),handleRead(),handleWrite()) + // + for (; (eraseItr != eraseEndItr) && (eraseItr->first == handlerItr->first); ++eraseItr) { + // Obtain a convenience pointer for readability + Connection* connectionPtr = *(eraseItr->second); + + // elog << "Poll> Removing connection: " + // << *connectionPtr + // << endl ; #ifdef HAVE_LIBSSL - // Attempt to shutdown TLS connection if not already closed. - if( connectionPtr->isTLS() && !connectionPtr->isNegotiatingTLS() && !connectionPtr->hasFlag( Connection::F_TLS_FATAL_ERROR )) - { - int res = SSL_shutdown( connectionPtr->getTlsState() ) ; - if( res > 0 ) - { - elog << "ConnectionManager::Poll> TLS connection gracefully shut down." << endl ; - } - else - { - elog << "ConnectionManager::Poll> TLS failed to shut down gracefully (" << res << "): " - << ERR_error_string( ERR_get_error(), nullptr ) - << endl ; - } - } + // Attempt to shutdown TLS connection if not already closed. + if (connectionPtr->isTLS() && !connectionPtr->isNegotiatingTLS() && + !connectionPtr->hasFlag(Connection::F_TLS_FATAL_ERROR)) { + int res = SSL_shutdown(connectionPtr->getTlsState()); + if (res > 0) { + elog << "ConnectionManager::Poll> TLS connection gracefully shut down." << endl; + } else { + elog << "ConnectionManager::Poll> TLS failed to shut down gracefully (" << res + << "): " << ERR_error_string(ERR_get_error(), nullptr) << endl; + } + } #endif - // Close the Connection's socket (file) descriptor - closeSocket( connectionPtr->getSockFD() ) ; - - // Remove the Connection from the connectionMap - // for this handler - handlerItr->second.erase( eraseItr->second ) ; - - // Deallocate the memory associated with the Connection - delete connectionPtr ; - - } // for( ; eraseItr->first == handlerItr->first ; ) - - } // for( eraseItr != eraseEndItr ) - -// Now that all elements in the eraseMap have been handled, clear -// the map for future use. -eraseMap.clear() ; - -// Check if the connectionMap for any particular handler is empty -for( handlerMapIterator handlerItr = handlerMap.begin() ; - handlerItr != handlerMap.end() ; ++handlerItr ) - { - // From SGI STL website: - // Map has the important property that inserting a new element - // into a map does not invalidate iterators that point to - // existing elements. Erasing an element from a map also does - // not invalidate any iterators, except, of course, for iterators - // that actually point to the element that is being erased. - if( handlerItr->second.empty() ) - { - // The connectionMap for this handler is empty - // Erase it - handlerMap.erase( handlerItr ) ; - } - if (handlerMap.begin() == handlerMap.end()) - break; - } // for() - -//elog << "Poll> End" -// << endl ; + // Close the Connection's socket (file) descriptor + closeSocket(connectionPtr->getSockFD()); + + // Remove the Connection from the connectionMap + // for this handler + handlerItr->second.erase(eraseItr->second); + + // Deallocate the memory associated with the Connection + delete connectionPtr; + + } // for( ; eraseItr->first == handlerItr->first ; ) + + } // for( eraseItr != eraseEndItr ) + + // Now that all elements in the eraseMap have been handled, clear + // the map for future use. + eraseMap.clear(); + + // Check if the connectionMap for any particular handler is empty + for (handlerMapIterator handlerItr = handlerMap.begin(); handlerItr != handlerMap.end(); + ++handlerItr) { + // From SGI STL website: + // Map has the important property that inserting a new element + // into a map does not invalidate iterators that point to + // existing elements. Erasing an element from a map also does + // not invalidate any iterators, except, of course, for iterators + // that actually point to the element that is being erased. + if (handlerItr->second.empty()) { + // The connectionMap for this handler is empty + // Erase it + handlerMap.erase(handlerItr); + } + if (handlerMap.begin() == handlerMap.end()) + break; + } // for() + + // elog << "Poll> End" + // << endl ; } // Poll() -int ConnectionManager::openSocket() -{ -// Let's get right to it, open the socket -int sockFD = ::socket( AF_INET, SOCK_STREAM, 0 ) ; - -// Was the socket creation successful? -if( sockFD < 0 ) - { - // Nope - elog << "openSocket> socket() failed: " - << strerror( errno ) - << endl ; - return -1 ; - } - -// Attempt to set this socket's options. -if( !setSocketOptions( sockFD ) ) - { - // setSocketOptions() failed, the socket is now invalid. - close( sockFD ) ; - - elog << "openSocket> Failed to set SO_LINGER: " - << strerror( errno ) - << endl ; - - // Return error to the caller - return -1 ; - } - -// The socket() was opened and configured properly, return the -// new sockFD to the caller. -return sockFD ; +int ConnectionManager::openSocket() { + // Let's get right to it, open the socket + int sockFD = ::socket(AF_INET, SOCK_STREAM, 0); + + // Was the socket creation successful? + if (sockFD < 0) { + // Nope + elog << "openSocket> socket() failed: " << strerror(errno) << endl; + return -1; + } + + // Attempt to set this socket's options. + if (!setSocketOptions(sockFD)) { + // setSocketOptions() failed, the socket is now invalid. + close(sockFD); + + elog << "openSocket> Failed to set SO_LINGER: " << strerror(errno) << endl; + + // Return error to the caller + return -1; + } + + // The socket() was opened and configured properly, return the + // new sockFD to the caller. + return sockFD; } // Static method, no const needed -bool ConnectionManager::isIpAddress( const string& host ) -{ -// decimalPoints counts the number of decimalPoints in the given -// string referred to by (host). Note that a valid IP address -// has exactly 3 decimalPoints. -unsigned short int decimalPoints = 0 ; - -// Iterate through the host string, looking for valid characters. -// Break when we reach the end of the string, when decimalPoints == 4, -// or we encounter an invalid character (non-digit). -for( string::size_type i = 0 ; - (i < host.size()) && (decimalPoints < 4) ; ++i ) - { - // characters in an IP address may only be - // digits or decimal points - if( '.' == host[ i ] ) - { - ++decimalPoints ; - } - else if( !isdigit( host[ i ] ) ) - { - // Found a non-digit, return false, this is not a - // valid IP address - return false ; - } - } - -// there are exactly three decimal points in an IP address -return (3 == decimalPoints) ; +bool ConnectionManager::isIpAddress(const string& host) { + // decimalPoints counts the number of decimalPoints in the given + // string referred to by (host). Note that a valid IP address + // has exactly 3 decimalPoints. + unsigned short int decimalPoints = 0; + + // Iterate through the host string, looking for valid characters. + // Break when we reach the end of the string, when decimalPoints == 4, + // or we encounter an invalid character (non-digit). + for (string::size_type i = 0; (i < host.size()) && (decimalPoints < 4); ++i) { + // characters in an IP address may only be + // digits or decimal points + if ('.' == host[i]) { + ++decimalPoints; + } else if (!isdigit(host[i])) { + // Found a non-digit, return false, this is not a + // valid IP address + return false; + } + } + + // there are exactly three decimal points in an IP address + return (3 == decimalPoints); } // Static, so no const necessary -string ConnectionManager::ipAddrOf( const string& host ) -{ -// Attempt to lookup the hostname -struct hostent *hostEntry = ::gethostbyname( host.c_str() ) ; -if( NULL == hostEntry ) - { - // hostname not found, return an empty string - return string() ; - } - -// Attempt to extract the IP address from the hostent struct -struct in_addr in ; -char **p = hostEntry->h_addr_list ; -memcpy( &in.s_addr, *p, sizeof( in.s_addr ) ) ; - -// This initial allocation is just for readability -char ipAddr[] = "000.000.000.000" ; -sprintf( ipAddr,"%s", inet_ntoa( in ) ) ; - -// Return the ipAddr, wrapped in a std::string -return string( ipAddr ) ; +string ConnectionManager::ipAddrOf(const string& host) { + // Attempt to lookup the hostname + struct hostent* hostEntry = ::gethostbyname(host.c_str()); + if (NULL == hostEntry) { + // hostname not found, return an empty string + return string(); + } + + // Attempt to extract the IP address from the hostent struct + struct in_addr in; + char** p = hostEntry->h_addr_list; + memcpy(&in.s_addr, *p, sizeof(in.s_addr)); + + // This initial allocation is just for readability + char ipAddr[] = "000.000.000.000"; + sprintf(ipAddr, "%s", inet_ntoa(in)); + + // Return the ipAddr, wrapped in a std::string + return string(ipAddr); } -void ConnectionManager::closeSocket( int fd ) -{ -::close( fd ) ; -} +void ConnectionManager::closeSocket(int fd) { ::close(fd); } // Caller handles erasing/closing upon a failed call to handleRead(). -bool ConnectionManager::handleRead( ConnectionHandler* hPtr, - Connection* cPtr ) -{ -// Don't allow reads if the connection is shutting down. -if( cPtr->isTLS() && cPtr->isShuttingDownTLS() ) - return true ; +bool ConnectionManager::handleRead(ConnectionHandler* hPtr, Connection* cPtr) { + // Don't allow reads if the connection is shutting down. + if (cPtr->isTLS() && cPtr->isShuttingDownTLS()) + return true; #ifdef HAVE_LIBSSL -// Don't allow reads until TLS handshake is complete -if( cPtr->isTLS() && cPtr->isNegotiatingTLS() ) - { - return negotiateTLS( hPtr, cPtr ) ; - } + // Don't allow reads until TLS handshake is complete + if (cPtr->isTLS() && cPtr->isNegotiatingTLS()) { + return negotiateTLS(hPtr, cPtr); + } #endif -// protected member, no error checking - -// Attempt the read from the socket -errno = 0 ; -int readResult = -1 ; - -// Check for simulation mode -if( cPtr->isFile() ) - { - // Connected to file - readResult = ::read( cPtr->getSockFD(), inputBuffer, - inputBufferSize ) ; - } -else - { - // Network connection - if( cPtr->isTLS() ) - { + // protected member, no error checking + + // Attempt the read from the socket + errno = 0; + int readResult = -1; + + // Check for simulation mode + if (cPtr->isFile()) { + // Connected to file + readResult = ::read(cPtr->getSockFD(), inputBuffer, inputBufferSize); + } else { + // Network connection + if (cPtr->isTLS()) { #ifdef HAVE_LIBSSL - readResult = SSL_read( cPtr->getTlsState(), inputBuffer, inputBufferSize ) ; - if( readResult <= 0 ) - { - int err = SSL_get_error( cPtr->getTlsState(), readResult ) ; - switch( err ) - { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - // Not ready - try again later - return true ; - - case SSL_ERROR_ZERO_RETURN: - // Clean shutdown - hPtr->OnDisconnect( cPtr ) ; - return false ; - - default: - elog << "ConnectionManager::handleRead> TLS read error: " - << ERR_error_string( ERR_get_error(), nullptr ) << endl ; - cPtr->setFlag( Connection::F_TLS_FATAL_ERROR ) ; - hPtr->OnDisconnect( cPtr ) ; - return false ; - } - } + readResult = SSL_read(cPtr->getTlsState(), inputBuffer, inputBufferSize); + if (readResult <= 0) { + int err = SSL_get_error(cPtr->getTlsState(), readResult); + switch (err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + // Not ready - try again later + return true; + + case SSL_ERROR_ZERO_RETURN: + // Clean shutdown + hPtr->OnDisconnect(cPtr); + return false; + + default: + elog << "ConnectionManager::handleRead> TLS read error: " + << ERR_error_string(ERR_get_error(), nullptr) << endl; + cPtr->setFlag(Connection::F_TLS_FATAL_ERROR); + hPtr->OnDisconnect(cPtr); + return false; + } + } #endif - } - else - { - readResult = ::recv( cPtr->getSockFD(), inputBuffer, - inputBufferSize, 0 ) ; - } - } - -if( EAGAIN == errno ) - { - // Nonblocking type error - // Ignore it -// elog << "ConnectionManager::handleRead> EAGAIN" -// << endl ; - return true ; - } - -//elog << "ConnectionManager::handleRead> Read " -// << readResult -// << " bytes" -// << endl ; - -// Check for error on read() -if( readResult <= 0 ) - { - elog << "ConnectionManager::handleRead> Read error: " - << strerror( errno ) - << endl ; - - // Error on read, socket no longer valid - // Notify handler - hPtr->OnDisconnect( cPtr ) ; - - // Read error - return false ; - } - -// Read was successful - -// Add to Connection input buffer -cPtr->inputBuffer.append( inputBuffer, readResult ) ; -cPtr->bytesRead += readResult ; - -// Check if a complete command was read -string line ; -while( cPtr->inputBuffer.ReadLine( line ) ) - { - // Line available - // Notify handler - hPtr->OnRead( cPtr, line ) ; - } - -// The read was successful, return success -return true ; + } else { + readResult = ::recv(cPtr->getSockFD(), inputBuffer, inputBufferSize, 0); + } + } + + if (EAGAIN == errno) { + // Nonblocking type error + // Ignore it + // elog << "ConnectionManager::handleRead> EAGAIN" + // << endl ; + return true; + } + + // elog << "ConnectionManager::handleRead> Read " + // << readResult + // << " bytes" + // << endl ; + + // Check for error on read() + if (readResult <= 0) { + elog << "ConnectionManager::handleRead> Read error: " << strerror(errno) << endl; + + // Error on read, socket no longer valid + // Notify handler + hPtr->OnDisconnect(cPtr); + + // Read error + return false; + } + + // Read was successful + + // Add to Connection input buffer + cPtr->inputBuffer.append(inputBuffer, readResult); + cPtr->bytesRead += readResult; + + // Check if a complete command was read + string line; + while (cPtr->inputBuffer.ReadLine(line)) { + // Line available + // Notify handler + hPtr->OnRead(cPtr, line); + } + + // The read was successful, return success + return true; } // Caller handles erasing/closing upon a failed call to handleWrite(). -bool ConnectionManager::handleWrite( ConnectionHandler* hPtr, - Connection* cPtr ) -{ -// Don't allow reads if the connection is shutting down. -if( cPtr->isTLS() && cPtr->isShuttingDownTLS() ) - return true ; +bool ConnectionManager::handleWrite(ConnectionHandler* hPtr, Connection* cPtr) { + // Don't allow reads if the connection is shutting down. + if (cPtr->isTLS() && cPtr->isShuttingDownTLS()) + return true; #ifdef HAVE_LIBSSL -// Don't allow writes until TLS handshake is complete -if( cPtr->isTLS() && cPtr->isNegotiatingTLS() ) - { - return negotiateTLS( hPtr, cPtr ) ; - } + // Don't allow writes until TLS handshake is complete + if (cPtr->isTLS() && cPtr->isNegotiatingTLS()) { + return negotiateTLS(hPtr, cPtr); + } #endif -// protected member, no error checking - -// Attempt the write to the socket -// According to W. Richard Stevens, Unix Network Programming, Vol 1: -// If there is some room in the socket send buffer, the return value -// will be the number of bytes that the kernel was able to copy -// into the buffer. ( This is called a short count). -// Therefore, just place the entire Connection output buffer into -// the send(), and the system will send() as much as it can -// The above applies to NONBLOCKING sockets. -// - -// Does this Connection represent a file? -if( cPtr->isFile() ) - { - // Just ignore writes to the file - cPtr->outputBuffer.clear() ; - return true ; - } - -if( cPtr->isFlush() ) - { - return handleFlush( hPtr, cPtr ) ; - } - -errno = 0 ; -int writeResult = 0 ; -if ( !cPtr->isTLS() ) { - writeResult = ::send( cPtr->getSockFD(), - cPtr->outputBuffer.data(), - cPtr->outputBuffer.size(), - 0 ) ; -} else { + // protected member, no error checking + + // Attempt the write to the socket + // According to W. Richard Stevens, Unix Network Programming, Vol 1: + // If there is some room in the socket send buffer, the return value + // will be the number of bytes that the kernel was able to copy + // into the buffer. ( This is called a short count). + // Therefore, just place the entire Connection output buffer into + // the send(), and the system will send() as much as it can + // The above applies to NONBLOCKING sockets. + // + + // Does this Connection represent a file? + if (cPtr->isFile()) { + // Just ignore writes to the file + cPtr->outputBuffer.clear(); + return true; + } + + if (cPtr->isFlush()) { + return handleFlush(hPtr, cPtr); + } + + errno = 0; + int writeResult = 0; + if (!cPtr->isTLS()) { + writeResult = + ::send(cPtr->getSockFD(), cPtr->outputBuffer.data(), cPtr->outputBuffer.size(), 0); + } else { #ifdef HAVE_LIBSSL - writeResult = SSL_write( cPtr->getTlsState(), - cPtr->outputBuffer.data(), - cPtr->outputBuffer.size() ) ; - if( writeResult < 0 ) - { - int err = SSL_get_error( cPtr->getTlsState(), writeResult) ; - switch( err ) - { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - return true ; /* Retry when the socket is ready. */ - case SSL_ERROR_ZERO_RETURN: - // Clean shutdown - hPtr->OnDisconnect( cPtr ) ; - return false ; - default: - elog << "ConnectionManager::handleWrite> TLS write error: " - << ERR_error_string( ERR_get_error(), nullptr ) << endl ; - cPtr->setFlag( Connection::F_TLS_FATAL_ERROR ) ; - hPtr->OnDisconnect( cPtr ) ; - return false ; - } - } + writeResult = + SSL_write(cPtr->getTlsState(), cPtr->outputBuffer.data(), cPtr->outputBuffer.size()); + if (writeResult < 0) { + int err = SSL_get_error(cPtr->getTlsState(), writeResult); + switch (err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + return true; /* Retry when the socket is ready. */ + case SSL_ERROR_ZERO_RETURN: + // Clean shutdown + hPtr->OnDisconnect(cPtr); + return false; + default: + elog << "ConnectionManager::handleWrite> TLS write error: " + << ERR_error_string(ERR_get_error(), nullptr) << endl; + cPtr->setFlag(Connection::F_TLS_FATAL_ERROR); + hPtr->OnDisconnect(cPtr); + return false; + } + } #endif -} - -if( (ENOBUFS == errno) || (EWOULDBLOCK == errno) || (EAGAIN == errno) ) - { - // Nonblocking type error - // Ignore it for now - elog << "ConnectionManager::handleWrite> errno: (" << errno << ") " - << strerror( errno ) - << endl ; - return true ; - } - -//elog << "ConnectionManager::handleWrite> Wrote " -// << writeResult -// << " bytes, remaining in buffer: " -// << (cPtr->outputBuffer.size() - writeResult) -// << endl ; - -// Check for write error -if( writeResult < 0 ) - { - // Error on write, socket no longer valid - // Notify the handler. - hPtr->OnDisconnect( cPtr ) ; - - // Write error - return false ; - } - -//elog << "ConnectionManager::handleWrite> Wrote: " -// << cPtr->outputBuffer.substr( 0, writeResult ) -// << endl ; - -// Successful write, update the Connection's output buffer -cPtr->outputBuffer.Delete( writeResult ) ; -cPtr->bytesWritten += writeResult ; - -// Write was successful, return succes -return true ; + } + + if ((ENOBUFS == errno) || (EWOULDBLOCK == errno) || (EAGAIN == errno)) { + // Nonblocking type error + // Ignore it for now + elog << "ConnectionManager::handleWrite> errno: (" << errno << ") " << strerror(errno) + << endl; + return true; + } + + // elog << "ConnectionManager::handleWrite> Wrote " + // << writeResult + // << " bytes, remaining in buffer: " + // << (cPtr->outputBuffer.size() - writeResult) + // << endl ; + + // Check for write error + if (writeResult < 0) { + // Error on write, socket no longer valid + // Notify the handler. + hPtr->OnDisconnect(cPtr); + + // Write error + return false; + } + + // elog << "ConnectionManager::handleWrite> Wrote: " + // << cPtr->outputBuffer.substr( 0, writeResult ) + // << endl ; + + // Successful write, update the Connection's output buffer + cPtr->outputBuffer.Delete(writeResult); + cPtr->bytesWritten += writeResult; + + // Write was successful, return succes + return true; } // Caller handles erasing/closing upon a failed call to handleWrite(). -bool ConnectionManager::handleFlush( ConnectionHandler* hPtr, - Connection* cPtr ) -{ -// protected member, no error checking +bool ConnectionManager::handleFlush(ConnectionHandler* hPtr, Connection* cPtr) { + // protected member, no error checking #ifdef HAVE_LIBSSL -// This function returns false if TLS handshake negotiations are not completed. -if( !negotiateTLS( hPtr, cPtr ) ) - return false ; + // This function returns false if TLS handshake negotiations are not completed. + if (!negotiateTLS(hPtr, cPtr)) + return false; #endif -// Make sure the Connection's F_FLUSH flag is cleared, so do it first -cPtr->removeFlag( Connection::F_FLUSH ) ; - -// Set to blocking so that the send() will block - -// Retrieve the current flags -int flags = ::fcntl( cPtr->getSockFD(), F_GETFL, 0 ) ; -if( flags < 0 ) - { - elog << "ConnectionManager::handleFlush> Unable to set " - << "blocking for connection: " - << strerror( errno ) - << endl ; - - // Terminal error - hPtr->OnDisconnect( cPtr ) ; - return false ; - } - -// Remove nonblocking flag -flags &= ~O_NONBLOCK ; - -// Attempt to set new flag (blocking) -if( ::fcntl( cPtr->getSockFD(), F_SETFL, flags ) < 0 ) - { - elog << "ConnectionManger::handleFlush> Failed to set " - << "to blocking: " - << strerror( errno ) - << endl ; - - // Terminal error - hPtr->OnDisconnect( cPtr ) ; - return false ; - } - -while( !cPtr->outputBuffer.empty() ) - { - errno = 0 ; - int writeResult = 0 ; - if( !cPtr->isTLS()) - writeResult = ::send( cPtr->getSockFD(), - cPtr->outputBuffer.data(), - cPtr->outputBuffer.size(), - 0 ) ; - #ifdef HAVE_LIBSSL - else - { - writeResult = SSL_write( cPtr->getTlsState(), - cPtr->outputBuffer.data(), - cPtr->outputBuffer.size() ) ; - if( writeResult < 0 ) - { - int err = SSL_get_error( cPtr->getTlsState(), writeResult ) ; - - switch( err ) - { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - return true ; // Retry when the socket is ready. - case SSL_ERROR_ZERO_RETURN: - // Clean shutdown - hPtr->OnDisconnect( cPtr ) ; - return false ; - default: - elog << "ConnectionManager::HandleFlush> Fatal TLS error encountered." << endl ; - cPtr->setFlag( Connection::F_TLS_FATAL_ERROR ) ; - hPtr->OnDisconnect( cPtr ) ; - return false ; - } - } - } - #endif - - if( (ENOBUFS == errno) || (EWOULDBLOCK == errno) || (EAGAIN == errno) ) - { - // Nonblocking type error - // Ignore it for now - elog << "ConnectionManager::handleFlush> errno: " - << strerror( errno ) - << endl ; - return true ; - } - - //elog << "ConnectionManager::handleFlush> Wrote " - // << writeResult - // << " bytes, remaining in buffer: " - // << (cPtr->outputBuffer.size() - writeResult) - // << endl ; - - // Check for write error - if( writeResult < 0 ) - { - // Error on write, socket no longer valid - // Notify the handler. - hPtr->OnDisconnect( cPtr ) ; - - // Write error - return false ; - } - - //elog << "ConnectionManager::handleFlush> Wrote: " - // << cPtr->outputBuffer.substr( 0, writeResult ) - // << endl ; - - // Successful write, update the Connection's output buffer - cPtr->outputBuffer.Delete( writeResult ) ; - cPtr->bytesWritten += writeResult ; - } // while( !empty() ) - -// Reset to nonblocking -flags |= O_NONBLOCK ; - -if( ::fcntl( cPtr->getSockFD(), F_SETFL, flags ) < 0 ) - { - elog << "ConnectionManager::handleFlush> Failed to set to " - << "nonblocking: " - << strerror( errno ) - << endl ; - - // Terminal error - hPtr->OnDisconnect( cPtr ) ; - return false ; - } - -// Write was successful, return succes -return true ; + // Make sure the Connection's F_FLUSH flag is cleared, so do it first + cPtr->removeFlag(Connection::F_FLUSH); + + // Set to blocking so that the send() will block + + // Retrieve the current flags + int flags = ::fcntl(cPtr->getSockFD(), F_GETFL, 0); + if (flags < 0) { + elog << "ConnectionManager::handleFlush> Unable to set " + << "blocking for connection: " << strerror(errno) << endl; + + // Terminal error + hPtr->OnDisconnect(cPtr); + return false; + } + + // Remove nonblocking flag + flags &= ~O_NONBLOCK; + + // Attempt to set new flag (blocking) + if (::fcntl(cPtr->getSockFD(), F_SETFL, flags) < 0) { + elog << "ConnectionManger::handleFlush> Failed to set " + << "to blocking: " << strerror(errno) << endl; + + // Terminal error + hPtr->OnDisconnect(cPtr); + return false; + } + + while (!cPtr->outputBuffer.empty()) { + errno = 0; + int writeResult = 0; + if (!cPtr->isTLS()) + writeResult = + ::send(cPtr->getSockFD(), cPtr->outputBuffer.data(), cPtr->outputBuffer.size(), 0); +#ifdef HAVE_LIBSSL + else { + writeResult = SSL_write(cPtr->getTlsState(), cPtr->outputBuffer.data(), + cPtr->outputBuffer.size()); + if (writeResult < 0) { + int err = SSL_get_error(cPtr->getTlsState(), writeResult); + + switch (err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + return true; // Retry when the socket is ready. + case SSL_ERROR_ZERO_RETURN: + // Clean shutdown + hPtr->OnDisconnect(cPtr); + return false; + default: + elog << "ConnectionManager::HandleFlush> Fatal TLS error encountered." << endl; + cPtr->setFlag(Connection::F_TLS_FATAL_ERROR); + hPtr->OnDisconnect(cPtr); + return false; + } + } + } +#endif + + if ((ENOBUFS == errno) || (EWOULDBLOCK == errno) || (EAGAIN == errno)) { + // Nonblocking type error + // Ignore it for now + elog << "ConnectionManager::handleFlush> errno: " << strerror(errno) << endl; + return true; + } + + // elog << "ConnectionManager::handleFlush> Wrote " + // << writeResult + // << " bytes, remaining in buffer: " + // << (cPtr->outputBuffer.size() - writeResult) + // << endl ; + + // Check for write error + if (writeResult < 0) { + // Error on write, socket no longer valid + // Notify the handler. + hPtr->OnDisconnect(cPtr); + + // Write error + return false; + } + + // elog << "ConnectionManager::handleFlush> Wrote: " + // << cPtr->outputBuffer.substr( 0, writeResult ) + // << endl ; + + // Successful write, update the Connection's output buffer + cPtr->outputBuffer.Delete(writeResult); + cPtr->bytesWritten += writeResult; + } // while( !empty() ) + + // Reset to nonblocking + flags |= O_NONBLOCK; + + if (::fcntl(cPtr->getSockFD(), F_SETFL, flags) < 0) { + elog << "ConnectionManager::handleFlush> Failed to set to " + << "nonblocking: " << strerror(errno) << endl; + + // Terminal error + hPtr->OnDisconnect(cPtr); + return false; + } + + // Write was successful, return succes + return true; } // Caller handles erasing/closing upon a failed call to finishConnect(). -bool ConnectionManager::finishConnect( ConnectionHandler* hPtr, - Connection* cPtr ) -{ -// Protected member method, no error checking performed on -// method arguments - -//elog << "ConnectionManager::finishConnect> " -// << *cPtr -// << endl ; - -// Attempt to connect() -int connectResult = ::connect( cPtr->getSockFD(), - reinterpret_cast< sockaddr* >( cPtr->getAddr() ), - sizeof( struct sockaddr_in ) ) ; - -// Was the connect successful? -if( connectResult < 0 ) - { - // EISCONN means that the connection succeeded with the - // first attempt - if( errno != EISCONN ) - { -// elog << "finishConnect> Failed connect: " -// << strerror( errno ) -// << endl ; - - // Unable to establish connection - // Notify handler - hPtr->OnConnectFail( cPtr ) ; - - // Return failure - return false ; - } // if( errno != EISCONN ) - } - -// Update the Connection's state -cPtr->setConnected() ; -cPtr->connectTime = ::time( 0 ) ; - -// Notify handler -hPtr->OnConnect( cPtr ) ; - -// Return success -return true ; +bool ConnectionManager::finishConnect(ConnectionHandler* hPtr, Connection* cPtr) { + // Protected member method, no error checking performed on + // method arguments + + // elog << "ConnectionManager::finishConnect> " + // << *cPtr + // << endl ; + + // Attempt to connect() + int connectResult = ::connect(cPtr->getSockFD(), reinterpret_cast(cPtr->getAddr()), + sizeof(struct sockaddr_in)); + + // Was the connect successful? + if (connectResult < 0) { + // EISCONN means that the connection succeeded with the + // first attempt + if (errno != EISCONN) { + // elog << "finishConnect> Failed connect: " + // << strerror( errno ) + // << endl ; + + // Unable to establish connection + // Notify handler + hPtr->OnConnectFail(cPtr); + + // Return failure + return false; + } // if( errno != EISCONN ) + } + + // Update the Connection's state + cPtr->setConnected(); + cPtr->connectTime = ::time(0); + + // Notify handler + hPtr->OnConnect(cPtr); + + // Return success + return true; } // Caller handles erasing/closing upon a failed call to finishAccept(). -bool ConnectionManager::finishAccept( ConnectionHandler* hPtr, - Connection* cPtr ) -{ -// Protected member, no arguments verified here -// (cPtr) is the server socket, which is listen()'ing - -// Allocate and configure a new Connection object -Connection* newConnection = new (std::nothrow) Connection( delimiter ) ; -assert( newConnection != 0 ) ; - -newConnection->setIncoming() ; -newConnection->setPending() ; - -// len is the size of a sockaddr structure, for use by accept() -socklen_t len = sizeof( struct sockaddr ) ; - -// Attempt to receive a pending connection. -// The socket descriptor passed in is that of the listening socket. -// The sockaddr structure is that of the new connection, and will be -// populated with host information of the connecting client. -// accept() returns the fd of the new connection, with "mostly" -// the same options as the server socket, or -1 on error. -int newFD = ::accept( cPtr->getSockFD(), - reinterpret_cast< sockaddr* >( newConnection->getAddr() ), - &len ) ; - -/* - * From man page: - * There may not always be a connection waiting after a SIGIO - * is delivered or select(2) or poll(2) return a readability - * event because the connection might have been removed by an - * asynchronous network error or another thread before accept - * is called. If this happens then the call will block waiting for - * the next connection to arrive. To ensure that - * accept never blocks, the passed socket s needs to have the - * O_NONBLOCK flag set. - */ -if( (newFD < 0) && (EAGAIN != errno) && (EWOULDBLOCK != errno)) - { - // The only use of notifying the handler here is - // so the handler can check for newConnection->isIncoming() - // to know that an incoming connection failed; it can - // obtain no other information about the Connection. - hPtr->OnConnectFail( newConnection ) ; - - // Clean up memory - delete newConnection ; newConnection = 0 ; - - // Return error - return false ; - } - -// Connect OK, update newConnection accordingly -newConnection->setConnected() ; -newConnection->setSockFD( newFD ) ; -newConnection->connectTime = ::time( 0 ) ; - -// Store the remote machine's IP address into the Connection's memory -const char* IP = inet_ntoa( newConnection->getAddr()->sin_addr ) ; -newConnection->setIP( IP ) ; - -// Because a reverse lookup is flaky at best (and blocks), just assign -// the newConnection's hostname to be the same as its IP; this will -// allow DisconnectByHost() to still function properly. -newConnection->setHostname( IP ) ; - -// Update remote port number for this Connection -newConnection->setRemotePort( - ntohs( newConnection->getAddr()->sin_port ) ) ; - -// The new connection's localPort is the port to which it connected, -// which is the port of the listener -newConnection->setLocalPort( cPtr->getLocalPort() ) ; - -// From man page: -// Note that any per file descriptor flags (everything that can be set -// with the F_SETFL fcntl, like non blocking or async state) -// are not inherited across an accept(). -if( !setSocketOptions( newFD ) ) - { - // Failed to set socket options - // The Connection now has the IP of the failed Connection - // Notify handler - hPtr->OnConnectFail( newConnection ) ; - - elog << "ConnectionManager::finishAccept> Failed to set " - << "socket options for connection: " - << *newConnection - << endl ; - - // Close the socket associated with this connection - closeSocket( newConnection->getSockFD() ) ; - - // Clean up - delete newConnection ; newConnection = 0 ; - - // Return error - return false ; - } - -// Attempt to insert the new Connection into the appropriate -// connectionMap for its handler -if( !handlerMap[ hPtr ].insert( newConnection ).second ) - { - // Failed to insert into handlerMap - // Notify the handler of a failure in connection - // TODO: The handler expects errno to be set appropriately. - hPtr->OnConnectFail( newConnection ) ; - - elog << "ConnectionManager::finishAccept> Failed to add " - << "new connection to table: " - << *newConnection - << endl ; - - // Socket is valid, but something went wrong with the - // insertion...make sure to close the socket. - closeSocket( newConnection->getSockFD() ) ; - - // Clean up memory - delete newConnection ; newConnection = 0 ; - - // Return error - return false ; - } - -// Notify the responsible handler of the new incoming connection -hPtr->OnConnect( newConnection ) ; - -// Return success -return true ; +bool ConnectionManager::finishAccept(ConnectionHandler* hPtr, Connection* cPtr) { + // Protected member, no arguments verified here + // (cPtr) is the server socket, which is listen()'ing + + // Allocate and configure a new Connection object + Connection* newConnection = new (std::nothrow) Connection(delimiter); + assert(newConnection != 0); + + newConnection->setIncoming(); + newConnection->setPending(); + + // len is the size of a sockaddr structure, for use by accept() + socklen_t len = sizeof(struct sockaddr); + + // Attempt to receive a pending connection. + // The socket descriptor passed in is that of the listening socket. + // The sockaddr structure is that of the new connection, and will be + // populated with host information of the connecting client. + // accept() returns the fd of the new connection, with "mostly" + // the same options as the server socket, or -1 on error. + int newFD = + ::accept(cPtr->getSockFD(), reinterpret_cast(newConnection->getAddr()), &len); + + /* + * From man page: + * There may not always be a connection waiting after a SIGIO + * is delivered or select(2) or poll(2) return a readability + * event because the connection might have been removed by an + * asynchronous network error or another thread before accept + * is called. If this happens then the call will block waiting for + * the next connection to arrive. To ensure that + * accept never blocks, the passed socket s needs to have the + * O_NONBLOCK flag set. + */ + if ((newFD < 0) && (EAGAIN != errno) && (EWOULDBLOCK != errno)) { + // The only use of notifying the handler here is + // so the handler can check for newConnection->isIncoming() + // to know that an incoming connection failed; it can + // obtain no other information about the Connection. + hPtr->OnConnectFail(newConnection); + + // Clean up memory + delete newConnection; + newConnection = 0; + + // Return error + return false; + } + + // Connect OK, update newConnection accordingly + newConnection->setConnected(); + newConnection->setSockFD(newFD); + newConnection->connectTime = ::time(0); + + // Store the remote machine's IP address into the Connection's memory + const char* IP = inet_ntoa(newConnection->getAddr()->sin_addr); + newConnection->setIP(IP); + + // Because a reverse lookup is flaky at best (and blocks), just assign + // the newConnection's hostname to be the same as its IP; this will + // allow DisconnectByHost() to still function properly. + newConnection->setHostname(IP); + + // Update remote port number for this Connection + newConnection->setRemotePort(ntohs(newConnection->getAddr()->sin_port)); + + // The new connection's localPort is the port to which it connected, + // which is the port of the listener + newConnection->setLocalPort(cPtr->getLocalPort()); + + // From man page: + // Note that any per file descriptor flags (everything that can be set + // with the F_SETFL fcntl, like non blocking or async state) + // are not inherited across an accept(). + if (!setSocketOptions(newFD)) { + // Failed to set socket options + // The Connection now has the IP of the failed Connection + // Notify handler + hPtr->OnConnectFail(newConnection); + + elog << "ConnectionManager::finishAccept> Failed to set " + << "socket options for connection: " << *newConnection << endl; + + // Close the socket associated with this connection + closeSocket(newConnection->getSockFD()); + + // Clean up + delete newConnection; + newConnection = 0; + + // Return error + return false; + } + + // Attempt to insert the new Connection into the appropriate + // connectionMap for its handler + if (!handlerMap[hPtr].insert(newConnection).second) { + // Failed to insert into handlerMap + // Notify the handler of a failure in connection + // TODO: The handler expects errno to be set appropriately. + hPtr->OnConnectFail(newConnection); + + elog << "ConnectionManager::finishAccept> Failed to add " + << "new connection to table: " << *newConnection << endl; + + // Socket is valid, but something went wrong with the + // insertion...make sure to close the socket. + closeSocket(newConnection->getSockFD()); + + // Clean up memory + delete newConnection; + newConnection = 0; + + // Return error + return false; + } + + // Notify the responsible handler of the new incoming connection + hPtr->OnConnect(newConnection); + + // Return success + return true; } /** @@ -1614,341 +1420,298 @@ return true ; * If we encounter an error, return false, and let the * calling method decide what to do with the socket. */ -bool ConnectionManager::setSocketOptions( int sockFD ) -{ -// Protected member, no error checking on args - -// Get current flags -int optval = ::fcntl( sockFD, F_GETFL, 0 ) ; -if( optval < 0 ) - { - return false ; - } - -// Set to non-blocking -optval = ::fcntl( sockFD, F_SETFL, optval | O_NONBLOCK ) ; -if( optval < 0 ) - { - return false ; - } - -optval = 1 ; -// Detect closed connection -optval = ::setsockopt( sockFD, SOL_SOCKET, SO_KEEPALIVE, - reinterpret_cast< const char* >( &optval ), sizeof( optval ) ) ; -if( optval < 0 ) - { - return false ; - } - -// Disable linger -struct linger setLinger ; -setLinger.l_onoff = 0 ; -setLinger.l_linger = 0 ; - -optval = ::setsockopt( sockFD, SOL_SOCKET, SO_LINGER, - reinterpret_cast< const char* >( &setLinger ), - sizeof( setLinger ) ) ; -if( optval < 0 ) - { - return false ; - } - -// All options set successfully -return true ; +bool ConnectionManager::setSocketOptions(int sockFD) { + // Protected member, no error checking on args + + // Get current flags + int optval = ::fcntl(sockFD, F_GETFL, 0); + if (optval < 0) { + return false; + } + + // Set to non-blocking + optval = ::fcntl(sockFD, F_SETFL, optval | O_NONBLOCK); + if (optval < 0) { + return false; + } + + optval = 1; + // Detect closed connection + optval = ::setsockopt(sockFD, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast(&optval), + sizeof(optval)); + if (optval < 0) { + return false; + } + + // Disable linger + struct linger setLinger; + setLinger.l_onoff = 0; + setLinger.l_linger = 0; + + optval = ::setsockopt(sockFD, SOL_SOCKET, SO_LINGER, reinterpret_cast(&setLinger), + sizeof(setLinger)); + if (optval < 0) { + return false; + } + + // All options set successfully + return true; } -Connection* ConnectionManager::Listen( ConnectionHandler* hPtr, - const unsigned short int localPort ) -{ -// Public method, check arguments -assert( hPtr != 0 ) ; - -elog << "ConnectionManager::Listen> Port: " - << localPort - << endl ; - -// Attempt to open a socket -// openSocket() will also call setSocketOptions() -int listenFD = openSocket() ; -if( listenFD < 0 ) - { - elog << "ConnectionManager::Listen> Failed to open socket" - << endl ; - return 0 ; - } - -// setSocketOptions() does not set SO_REUSEADDR. -// However, for server sockets, it's important to set SO_REUSEADDR, -// to allow fast rebinds. -int optVal = 1 ; -if( ::setsockopt( listenFD, SOL_SOCKET, SO_REUSEADDR, - reinterpret_cast< const char* >( &optVal ), - sizeof( optVal ) ) < 0 ) - { - // Failed to set SO_REUSEADDR - elog << "ConnectionManager::Listen> Failed to set " - << "SO_REUSEADDR: " - << strerror( errno ) - << endl ; - - // Close the socket - closeSocket( listenFD ) ; - - // Return failure - return 0 ; - } - -// Create and configure a new Connection -Connection* newConnection = new (std::nothrow) Connection( delimiter ) ; -assert( newConnection != 0 ) ; - -newConnection->setSockFD( listenFD ) ; -newConnection->setListen() ; -newConnection->setPending() ; -newConnection->setLocalPort( localPort ) ; -// Leave hostname/IP empty for the new Connection. This will -// distinguish the connection more easily for use in -// DisconnectByHost() and DisconnectByIP() - -// Setup the sockaddr structure -struct sockaddr_in* addr = newConnection->getAddr() ; -addr->sin_family = AF_INET ; -addr->sin_port = htons( static_cast< u_short >( localPort ) ) ; - -// Attempt to bind to the given port -if( ::bind( listenFD, - reinterpret_cast< sockaddr* >( newConnection->getAddr() ), - static_cast< socklen_t >( sizeof( struct sockaddr ) ) ) < 0 ) - { - // bind() failed - elog << "ConnectionManager::Listen> bind() failed: " - << strerror( errno ) - << endl ; - - // Close the socket - closeSocket( listenFD ) ; - - // Clean up memory area - delete newConnection ; newConnection = 0 ; - - // Return failure - return 0 ; - } - -// Attempt to establish listener on the given socket -if( ::listen( listenFD, 5 ) < 0 ) - { - // listen() failed - elog << "ConnectionManager::Listen> listen() failed: " - << strerror( errno ) - << endl ; - - // Close the socket - closeSocket( listenFD ) ; - - // Clean up memory - delete newConnection ; newConnection = 0 ; - - // Return error - return 0 ; - } - -// Attempt to add this new connection into the handler map for -// the given handler -if( !handlerMap[ hPtr ].insert( newConnection ).second ) - { - // Addition to handlerMap failed :( - elog << "ConnectionManager::Listen> Failed to add new " - << "connection to handlerMap: " - << *newConnection - << endl ; - - // Close the socket - closeSocket( listenFD ) ; - - // Clean up memory - delete newConnection ; newConnection = 0 ; - - // Return error - return 0 ; - } - -// There is no need to call accept() once here, as we did -// with connect(), because the Poll() loop will work properly -// without it. - -// Return the new connection to the caller -return newConnection ; +Connection* ConnectionManager::Listen(ConnectionHandler* hPtr, const unsigned short int localPort) { + // Public method, check arguments + assert(hPtr != 0); + + elog << "ConnectionManager::Listen> Port: " << localPort << endl; + + // Attempt to open a socket + // openSocket() will also call setSocketOptions() + int listenFD = openSocket(); + if (listenFD < 0) { + elog << "ConnectionManager::Listen> Failed to open socket" << endl; + return 0; + } + + // setSocketOptions() does not set SO_REUSEADDR. + // However, for server sockets, it's important to set SO_REUSEADDR, + // to allow fast rebinds. + int optVal = 1; + if (::setsockopt(listenFD, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&optVal), + sizeof(optVal)) < 0) { + // Failed to set SO_REUSEADDR + elog << "ConnectionManager::Listen> Failed to set " + << "SO_REUSEADDR: " << strerror(errno) << endl; + + // Close the socket + closeSocket(listenFD); + + // Return failure + return 0; + } + + // Create and configure a new Connection + Connection* newConnection = new (std::nothrow) Connection(delimiter); + assert(newConnection != 0); + + newConnection->setSockFD(listenFD); + newConnection->setListen(); + newConnection->setPending(); + newConnection->setLocalPort(localPort); + // Leave hostname/IP empty for the new Connection. This will + // distinguish the connection more easily for use in + // DisconnectByHost() and DisconnectByIP() + + // Setup the sockaddr structure + struct sockaddr_in* addr = newConnection->getAddr(); + addr->sin_family = AF_INET; + addr->sin_port = htons(static_cast(localPort)); + + // Attempt to bind to the given port + if (::bind(listenFD, reinterpret_cast(newConnection->getAddr()), + static_cast(sizeof(struct sockaddr))) < 0) { + // bind() failed + elog << "ConnectionManager::Listen> bind() failed: " << strerror(errno) << endl; + + // Close the socket + closeSocket(listenFD); + + // Clean up memory area + delete newConnection; + newConnection = 0; + + // Return failure + return 0; + } + + // Attempt to establish listener on the given socket + if (::listen(listenFD, 5) < 0) { + // listen() failed + elog << "ConnectionManager::Listen> listen() failed: " << strerror(errno) << endl; + + // Close the socket + closeSocket(listenFD); + + // Clean up memory + delete newConnection; + newConnection = 0; + + // Return error + return 0; + } + + // Attempt to add this new connection into the handler map for + // the given handler + if (!handlerMap[hPtr].insert(newConnection).second) { + // Addition to handlerMap failed :( + elog << "ConnectionManager::Listen> Failed to add new " + << "connection to handlerMap: " << *newConnection << endl; + + // Close the socket + closeSocket(listenFD); + + // Clean up memory + delete newConnection; + newConnection = 0; + + // Return error + return 0; + } + + // There is no need to call accept() once here, as we did + // with connect(), because the Poll() loop will work properly + // without it. + + // Return the new connection to the caller + return newConnection; } -void ConnectionManager::scheduleErasure( ConnectionHandler* hPtr, - connectionMapIterator connectionItr ) -{ -// Protected member, no error checking performed on arguments -eraseMapIterator eraseItr = eraseMap.find( hPtr ) ; - -// Walk through the container -// Continue walking until we find the duplicate (in which case -// return from this method), we encounter the end of the eraseMap, -// or we are no longer examining the connections for the given -// handler (we can do this because a multimap guarantees its -// entries to be kept in a strict weak order) -for( ; (eraseItr != eraseMap.end()) && (eraseItr->first == hPtr) ; - ++eraseItr ) - { - if( eraseItr->second == connectionItr ) - { - // Found a duplicate - // No need to perform any further processing, - // this connection is already scheduled for - // erasure and will be removed on the next call - // to Poll() (assuming this method isn't already - // being called from Poll() ) - return ; - } - } // while() - -// The connectionItr is not present in the eraseMap, go ahead -// and add it to the eraseMap to be erased by Poll() -eraseMap.insert( eraseMapType::value_type( hPtr, connectionItr ) ) ; +void ConnectionManager::scheduleErasure(ConnectionHandler* hPtr, + connectionMapIterator connectionItr) { + // Protected member, no error checking performed on arguments + eraseMapIterator eraseItr = eraseMap.find(hPtr); + + // Walk through the container + // Continue walking until we find the duplicate (in which case + // return from this method), we encounter the end of the eraseMap, + // or we are no longer examining the connections for the given + // handler (we can do this because a multimap guarantees its + // entries to be kept in a strict weak order) + for (; (eraseItr != eraseMap.end()) && (eraseItr->first == hPtr); ++eraseItr) { + if (eraseItr->second == connectionItr) { + // Found a duplicate + // No need to perform any further processing, + // this connection is already scheduled for + // erasure and will be removed on the next call + // to Poll() (assuming this method isn't already + // being called from Poll() ) + return; + } + } // while() + + // The connectionItr is not present in the eraseMap, go ahead + // and add it to the eraseMap to be erased by Poll() + eraseMap.insert(eraseMapType::value_type(hPtr, connectionItr)); } /** * This method is used for debugging in general, but can certainly * be used to read a file. */ -Connection* ConnectionManager::ConnectToFile( ConnectionHandler* hPtr, - const string& fileName ) -{ -// public method, verify parameter -assert( hPtr != 0 ) ; - -// Make sure the filename is valid (or at least, not blatantly invalid) -if( fileName.empty() ) - { - return 0 ; - } - -//elog << "Connecting to file: " -// << fileName -// << endl ; - -// Open the file -int fd = ::open( fileName.c_str(), O_CREAT ) ; -if( fd < 0 ) - { - // Failed to open the file - elog << "ConnectToFile> Unable to open file " - << fileName - << ": " - << strerror( errno ) - << endl ; - return 0 ; - } - -// Create a new Connection object to represent this open file -Connection* newConnect = new (std::nothrow) - Connection( fileName, fd, delimiter, false ) ; -assert( newConnect != 0 ) ; - -// Set the Connection's state -newConnect->setConnected() ; -newConnect->setSockFD( fd ) ; - -// Tag the new Connection as a file -newConnect->setFile() ; - -// Insert the new Connection into the Connection map -bool insertOK = handlerMap[ hPtr ].insert( newConnect ).second ; -if( !insertOK ) - { - elog << "ConnectToFile> Failed to insert new Connection" - << endl ; - - // Posting OnConnectFail() doesn't make sense here because - // we haven't notified the handler of the Connection in - // the first place - closeSocket( fd ) ; - - // Clean up memory - delete newConnect ; newConnect = 0 ; - } - -// Should we notify the handler of the new conncetion? -if( newConnect != 0 ) - { - // Yes, all is valid - hPtr->OnConnect( newConnect ) ; - } - -// Return the new connection to the caller -return newConnect ; +Connection* ConnectionManager::ConnectToFile(ConnectionHandler* hPtr, const string& fileName) { + // public method, verify parameter + assert(hPtr != 0); + + // Make sure the filename is valid (or at least, not blatantly invalid) + if (fileName.empty()) { + return 0; + } + + // elog << "Connecting to file: " + // << fileName + // << endl ; + + // Open the file + int fd = ::open(fileName.c_str(), O_CREAT); + if (fd < 0) { + // Failed to open the file + elog << "ConnectToFile> Unable to open file " << fileName << ": " << strerror(errno) + << endl; + return 0; + } + + // Create a new Connection object to represent this open file + Connection* newConnect = new (std::nothrow) Connection(fileName, fd, delimiter, false); + assert(newConnect != 0); + + // Set the Connection's state + newConnect->setConnected(); + newConnect->setSockFD(fd); + + // Tag the new Connection as a file + newConnect->setFile(); + + // Insert the new Connection into the Connection map + bool insertOK = handlerMap[hPtr].insert(newConnect).second; + if (!insertOK) { + elog << "ConnectToFile> Failed to insert new Connection" << endl; + + // Posting OnConnectFail() doesn't make sense here because + // we haven't notified the handler of the Connection in + // the first place + closeSocket(fd); + + // Clean up memory + delete newConnect; + newConnect = 0; + } + + // Should we notify the handler of the new conncetion? + if (newConnect != 0) { + // Yes, all is valid + hPtr->OnConnect(newConnect); + } + + // Return the new connection to the caller + return newConnect; } // Retrieve the number of connections that a given handler // present has outstanding -size_t ConnectionManager::numConnections( ConnectionHandler* hPtr ) const -{ -// public method, check parameter -assert( hPtr != 0 ) ; - -// Lookup the handler -constHandlerMapIterator hItr = handlerMap.find( hPtr ) ; -if( hItr == handlerMap.end() ) - { - // Handler not found - return 0 ; - } - -// Return the number of active/pending connections the handler posesses -return hItr->second.size() ; +size_t ConnectionManager::numConnections(ConnectionHandler* hPtr) const { + // public method, check parameter + assert(hPtr != 0); + + // Lookup the handler + constHandlerMapIterator hItr = handlerMap.find(hPtr); + if (hItr == handlerMap.end()) { + // Handler not found + return 0; + } + + // Return the number of active/pending connections the handler posesses + return hItr->second.size(); } #ifdef HAVE_LIBSSL -bool ConnectionManager::negotiateTLS( ConnectionHandler* hPtr, Connection* cPtr ) -{ -/* Return true if negotiations are completed. */ -if( !cPtr->isNegotiatingTLS() ) - return true ; - -if( ::time( 0 ) > ( cPtr->connectTime + 5 ) ) - { - elog << "ConnectionManager::negotiateTLS> TLS handshake timed out" << endl ; - hPtr->OnDisconnect( cPtr ) ; - return false ; - } - -int res = SSL_connect( cPtr->getTlsState() ) ; -if( res == 1 ) - { - elog << "ConnectionManager::negotiateTLS> TLS handshake completed successfully." << endl ; - cPtr->clrNegotiatingTLS() ; - return true ; - } - -int err = SSL_get_error( cPtr->getTlsState(), res ) ; -switch( err ) - { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - // This is normal for non-blocking - return true to continue in next poll - return true ; - - case SSL_ERROR_ZERO_RETURN: - // Clean shutdown - elog << "ConnectionManager::negotiateTLS> TLS connection closed cleanly" << endl ; - hPtr->OnDisconnect( cPtr ) ; - return false ; - - default: - // Fatal error - elog << "ConnectionManager::negotiateTLS> TLS handshake failed: " - << ERR_error_string( ERR_get_error(), nullptr ) << endl ; - cPtr->setFlag( Connection::F_TLS_FATAL_ERROR ) ; - hPtr->OnDisconnect( cPtr ) ; - return false ; - } +bool ConnectionManager::negotiateTLS(ConnectionHandler* hPtr, Connection* cPtr) { + /* Return true if negotiations are completed. */ + if (!cPtr->isNegotiatingTLS()) + return true; + + if (::time(0) > (cPtr->connectTime + 5)) { + elog << "ConnectionManager::negotiateTLS> TLS handshake timed out" << endl; + hPtr->OnDisconnect(cPtr); + return false; + } + + int res = SSL_connect(cPtr->getTlsState()); + if (res == 1) { + elog << "ConnectionManager::negotiateTLS> TLS handshake completed successfully." << endl; + cPtr->clrNegotiatingTLS(); + return true; + } + + int err = SSL_get_error(cPtr->getTlsState(), res); + switch (err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + // This is normal for non-blocking - return true to continue in next poll + return true; + + case SSL_ERROR_ZERO_RETURN: + // Clean shutdown + elog << "ConnectionManager::negotiateTLS> TLS connection closed cleanly" << endl; + hPtr->OnDisconnect(cPtr); + return false; + + default: + // Fatal error + elog << "ConnectionManager::negotiateTLS> TLS handshake failed: " + << ERR_error_string(ERR_get_error(), nullptr) << endl; + cPtr->setFlag(Connection::F_TLS_FATAL_ERROR); + hPtr->OnDisconnect(cPtr); + return false; + } } #endif } // namespace gnuworld diff --git a/libgnuworld/ConnectionManager.h b/libgnuworld/ConnectionManager.h old mode 100755 new mode 100644 index c9987b55..72f32166 --- a/libgnuworld/ConnectionManager.h +++ b/libgnuworld/ConnectionManager.h @@ -24,27 +24,26 @@ #ifndef __CONNECTIONMANAGER_H #define __CONNECTIONMANAGER_H "$Id: ConnectionManager.h,v 1.8 2005/01/12 04:36:43 dan_karrels Exp $" -#include +#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -#include +#include -#include "Connection.h" -#include "ConnectionHandler.h" +#include "Connection.h" +#include "ConnectionHandler.h" #ifdef HAVE_LIBSSL -#include -#include -#include +#include +#include +#include #endif -namespace gnuworld -{ +namespace gnuworld { /** * The purpose of this class it to manage multiple incoming and @@ -68,377 +67,362 @@ namespace gnuworld * for example), and the ConnectionManager will update the state * of those Connections. */ -class ConnectionManager -{ - - /** - * This type is used to store Connection's in a weak sorted - * manner. - * There is a single instance of a connectionMapType for - * each handler which has one or more Connection's registered. - */ - typedef std::set< Connection* > connectionMapType ; - - /** - * This type is used as convenience to define an iterator - * type for the connectionMap. - */ - typedef connectionMapType::iterator connectionMapIterator ; - - /** - * A const iterator used to iterate through a connectionMap. - */ - typedef connectionMapType::const_iterator constConnectionMapIterator ; - - /** - * This map stores connectionMapType's, keyed by the handler - * which registered the connection(s). - */ - typedef std::map< ConnectionHandler*, connectionMapType > - handlerMapType ; - - /** - * This type is used as convenience to define an iterator - * type for the handlerMap. - */ - typedef handlerMapType::iterator handlerMapIterator ; - - /** - * A const iterator used to iterate through the handlerMap. - */ - typedef handlerMapType::const_iterator constHandlerMapIterator ; - - /** - * The type is used to store Connection objects to be erased. - * This structure stores an iterator to each Connection - * to be removed. Removal is synchronous to prevent - * iterator invalidation of the handlerMap. - * Because more than one item may be associated with any - * given key, we need a multimap here. While that may - * be a useful trait for handling more than one Connection - * for any given ConnectionHandler, it also has the unfortunate - * side effect of allowing a Connection to be scheduled for - * closure more than once. The scheduleErasure() method is - * used to prevent multiple entries of the same Connection - * into the eraseMap. - */ - typedef std::multimap< ConnectionHandler*, connectionMapType::iterator > - eraseMapType ; - - /** - * This type is used as convenience to define an iterator - * type for the eraseMap. - */ - typedef eraseMapType::iterator eraseMapIterator ; - -public: - /** - * Default constructor. The first argument which (may) be - * supplied is the default timeout value for establishing - * individual connections (in seconds). If the (outgoing) - * connection is not established within that time period, - * then the connection's handler is notified via OnTimeout(), - * and the Connection scheduled for erasure. Note that - * listening Connections do not have a timeout. - * Delimiter is the line delimiter for determining when a - * full line/command has been read from each connection. - * Once this delimiter is encountered, the line/command is - * passed to OnRead(). - */ - ConnectionManager( const time_t defaultTimeout = 10, - const char defaultDelimiter = '\n' ) ; - - /** - * The destructor will deallocate any memory and close all - * connections. - * Handlers for the given connections will *not* be - * notified. - */ - virtual ~ConnectionManager() ; - - /** - * This method will set the timeout duraction for connection - * attempts to the new value given to the method. - */ - void setTimeoutDuration( const time_t newTimeoutDuration ) - { timeoutDuration = newTimeoutDuration ; } - - /** - * Return a string with (host)'s IP address in numbers - * and dots format. - * Returns an empty string if no IP address found. - */ - static std::string ipAddrOf( const std::string& host ) ; - - /** - * Return true if the given string is in the proper - * IP format of numbers and dots. - */ - static bool isIpAddress( const std::string& host ) ; - - /** - * Connect() will attempt to establish a new connection to - * the given host, on the given port. The (host) field may - * be the canonical host name, or the IP in the form of - * numbres and dots. - * This method creates a non-blocking socket with which to - * connect to the remote host, thus a return value of non-NULL - * does not necessarily mean that the connection is valid, - * just that the attempt is in progress. - * A return value of NULL indicates that some part of the - * connection process failed, and errno is set appropriately. - * UDP sockets are currently not implemented fully, and will - * not work properly. - * The ConnectionHandler must be non-NULL. - */ - virtual Connection* Connect( - ConnectionHandler*, - const std::string& host, - const unsigned short int remotePort, - bool tlsEnabled ) ; - - /** - * Connect to a file instead of a network host. This method - * has the same semantics as Connect(), except that OnConnect() - * may be called during the call to ConnectToFile(). - */ - virtual Connection* ConnectToFile( ConnectionHandler*, - const std::string& ) ; - - /** - * Attempt to establish a listening Connection on the - * given port number. If successful, the Connection is - * returned. The Connection returned is of no functional - * use except to indicate success or failure. That - * Connection is the actual listening socket, and cannot - * be written to or read from directly. - * The ConnectionHandler must be non-NULL. - */ - virtual Connection* Listen( - ConnectionHandler*, - const unsigned short int localPort ) ; - - /** - * DisConnect() forces the connection(s) associated with - * hostname/ports to be disconnected and deallocated. - * By specifying the optional localPort, only outgoing - * connections which match all 3 search criteria will be - * removed; not specifying a third parameter will cause all - * connections which match the first two search criteria to - * be removed. - * OnDisconnect() is NOT called. - * The ConnectionHandler must be non-NULL. - * The Connection will not be removed if the ConnectionHandler - * does not own the particular Connection. - * This method schedules the given Connection to be disconnected - * in the next call to Poll(). - * To close a listening Connection, pass an empty hostname, in - * which case the remotePort will be ignored. - */ - virtual bool DisconnectByHost( ConnectionHandler*, - const std::string& hostname, - const unsigned short int remotePort, - const unsigned short int localPort = 0 ) ; - - /** - * DisConnect() forces the connection(s) associated with - * IP/ports to be disconnected and deallocated. - * By specifying the optional localPort, only outgoing - * connections which match all 3 search criteria will be - * removed; not specifying a third parameter will cause all - * connections which match the first two search criteria to - * be removed. - * OnDisconnect() is NOT called. - * The ConnectionHandler must be non-NULL. - * The Connection will not be removed if the ConnectionHandler - * does not own the particular Connection. - * This method schedules the given Connection to be disconnected - * in the next call to Poll(). - * To close a listening Connection, pass an empty hostname, in - * which case the remotePort will be ignored. - */ - virtual bool DisconnectByIP( ConnectionHandler*, - const std::string& IP, - const unsigned short int remotePort, - const unsigned short int localPort = 0 ) ; - - /** - * Disconnect the given Connection from ConnectionHandler's - * list of Connections. - * The Connection will not be removed if the ConnectionHandler - * does not own the particular Connection. - * Return true if removal was successful, false if the - * Connection was not found under ConnectionHandler's control. - * Both the ConnectionHandler and the Connection must - * be non-NULL. - * This method schedules the given Connection to be disconnected - * in the next call to Poll(). - * Passing NULL as the Connection* will remove ALL connections - * belonging to the ConnectionHandler. - */ - virtual bool Disconnect( ConnectionHandler*, - Connection* ) ; - - /** - * Return the number of outstanding connections for the given - * ConnectionHandler. - * If anyone figures out why gcc won't let me declare - * the ConnectionHandler* as const here please let me know. - */ - virtual size_t numConnections( ConnectionHandler* ) const ; - - /** - * This method performs the actual read/write calls for all - * sockets. This method will check for any - * pending outgoing connections (and call OnConnect() for - * all that succeed), check for read state on all sockets - * which are currently connected (and call OnRead() if conditions - * are met), check for dead connections (and call OnDisconnect() - * for each), and check for connection time outs (and call - * OnTimeout() for each). - * (seconds) and (milliseconds) is how long to wait for a - * state change on any of the Connections, in seconds and - * milliseconds, respectively. The default is to return - * immediately (poll). - * If -1 is passed for seconds, then the process will block - * indefinitely waiting for a state change. - */ - virtual void Poll( const long seconds = 0, - const long milliseconds = 0 ) ; - -protected: - - /** - * The duration to wait for outgoing connections to be - * established. - */ - time_t timeoutDuration ; - - /** - * The line delimiter, 0 if none - */ - char delimiter ; - - /** - * Stores connectionMap's, one for each handler (key) - */ - handlerMapType handlerMap ; - - /** - * Allow for asynchronous calls to Disconnect() - * This structure contains Connections to be removed from - * the connection tables. - */ - eraseMapType eraseMap ; - - /** - * The size of the scratch buffer - */ - size_t inputBufferSize ; - - /** - * Scratch buffer for reads - */ - char* inputBuffer ; +class ConnectionManager { + + /** + * This type is used to store Connection's in a weak sorted + * manner. + * There is a single instance of a connectionMapType for + * each handler which has one or more Connection's registered. + */ + typedef std::set connectionMapType; + + /** + * This type is used as convenience to define an iterator + * type for the connectionMap. + */ + typedef connectionMapType::iterator connectionMapIterator; + + /** + * A const iterator used to iterate through a connectionMap. + */ + typedef connectionMapType::const_iterator constConnectionMapIterator; + + /** + * This map stores connectionMapType's, keyed by the handler + * which registered the connection(s). + */ + typedef std::map handlerMapType; + + /** + * This type is used as convenience to define an iterator + * type for the handlerMap. + */ + typedef handlerMapType::iterator handlerMapIterator; + + /** + * A const iterator used to iterate through the handlerMap. + */ + typedef handlerMapType::const_iterator constHandlerMapIterator; + + /** + * The type is used to store Connection objects to be erased. + * This structure stores an iterator to each Connection + * to be removed. Removal is synchronous to prevent + * iterator invalidation of the handlerMap. + * Because more than one item may be associated with any + * given key, we need a multimap here. While that may + * be a useful trait for handling more than one Connection + * for any given ConnectionHandler, it also has the unfortunate + * side effect of allowing a Connection to be scheduled for + * closure more than once. The scheduleErasure() method is + * used to prevent multiple entries of the same Connection + * into the eraseMap. + */ + typedef std::multimap eraseMapType; + + /** + * This type is used as convenience to define an iterator + * type for the eraseMap. + */ + typedef eraseMapType::iterator eraseMapIterator; + + public: + /** + * Default constructor. The first argument which (may) be + * supplied is the default timeout value for establishing + * individual connections (in seconds). If the (outgoing) + * connection is not established within that time period, + * then the connection's handler is notified via OnTimeout(), + * and the Connection scheduled for erasure. Note that + * listening Connections do not have a timeout. + * Delimiter is the line delimiter for determining when a + * full line/command has been read from each connection. + * Once this delimiter is encountered, the line/command is + * passed to OnRead(). + */ + ConnectionManager(const time_t defaultTimeout = 10, const char defaultDelimiter = '\n'); + + /** + * The destructor will deallocate any memory and close all + * connections. + * Handlers for the given connections will *not* be + * notified. + */ + virtual ~ConnectionManager(); + + /** + * This method will set the timeout duraction for connection + * attempts to the new value given to the method. + */ + void setTimeoutDuration(const time_t newTimeoutDuration) { + timeoutDuration = newTimeoutDuration; + } + + /** + * Return a string with (host)'s IP address in numbers + * and dots format. + * Returns an empty string if no IP address found. + */ + static std::string ipAddrOf(const std::string& host); + + /** + * Return true if the given string is in the proper + * IP format of numbers and dots. + */ + static bool isIpAddress(const std::string& host); + + /** + * Connect() will attempt to establish a new connection to + * the given host, on the given port. The (host) field may + * be the canonical host name, or the IP in the form of + * numbres and dots. + * This method creates a non-blocking socket with which to + * connect to the remote host, thus a return value of non-NULL + * does not necessarily mean that the connection is valid, + * just that the attempt is in progress. + * A return value of NULL indicates that some part of the + * connection process failed, and errno is set appropriately. + * UDP sockets are currently not implemented fully, and will + * not work properly. + * The ConnectionHandler must be non-NULL. + */ + virtual Connection* Connect(ConnectionHandler*, const std::string& host, + const unsigned short int remotePort, bool tlsEnabled); + + /** + * Connect to a file instead of a network host. This method + * has the same semantics as Connect(), except that OnConnect() + * may be called during the call to ConnectToFile(). + */ + virtual Connection* ConnectToFile(ConnectionHandler*, const std::string&); + + /** + * Attempt to establish a listening Connection on the + * given port number. If successful, the Connection is + * returned. The Connection returned is of no functional + * use except to indicate success or failure. That + * Connection is the actual listening socket, and cannot + * be written to or read from directly. + * The ConnectionHandler must be non-NULL. + */ + virtual Connection* Listen(ConnectionHandler*, const unsigned short int localPort); + + /** + * DisConnect() forces the connection(s) associated with + * hostname/ports to be disconnected and deallocated. + * By specifying the optional localPort, only outgoing + * connections which match all 3 search criteria will be + * removed; not specifying a third parameter will cause all + * connections which match the first two search criteria to + * be removed. + * OnDisconnect() is NOT called. + * The ConnectionHandler must be non-NULL. + * The Connection will not be removed if the ConnectionHandler + * does not own the particular Connection. + * This method schedules the given Connection to be disconnected + * in the next call to Poll(). + * To close a listening Connection, pass an empty hostname, in + * which case the remotePort will be ignored. + */ + virtual bool DisconnectByHost(ConnectionHandler*, const std::string& hostname, + const unsigned short int remotePort, + const unsigned short int localPort = 0); + + /** + * DisConnect() forces the connection(s) associated with + * IP/ports to be disconnected and deallocated. + * By specifying the optional localPort, only outgoing + * connections which match all 3 search criteria will be + * removed; not specifying a third parameter will cause all + * connections which match the first two search criteria to + * be removed. + * OnDisconnect() is NOT called. + * The ConnectionHandler must be non-NULL. + * The Connection will not be removed if the ConnectionHandler + * does not own the particular Connection. + * This method schedules the given Connection to be disconnected + * in the next call to Poll(). + * To close a listening Connection, pass an empty hostname, in + * which case the remotePort will be ignored. + */ + virtual bool DisconnectByIP(ConnectionHandler*, const std::string& IP, + const unsigned short int remotePort, + const unsigned short int localPort = 0); + + /** + * Disconnect the given Connection from ConnectionHandler's + * list of Connections. + * The Connection will not be removed if the ConnectionHandler + * does not own the particular Connection. + * Return true if removal was successful, false if the + * Connection was not found under ConnectionHandler's control. + * Both the ConnectionHandler and the Connection must + * be non-NULL. + * This method schedules the given Connection to be disconnected + * in the next call to Poll(). + * Passing NULL as the Connection* will remove ALL connections + * belonging to the ConnectionHandler. + */ + virtual bool Disconnect(ConnectionHandler*, Connection*); + + /** + * Return the number of outstanding connections for the given + * ConnectionHandler. + * If anyone figures out why gcc won't let me declare + * the ConnectionHandler* as const here please let me know. + */ + virtual size_t numConnections(ConnectionHandler*) const; + + /** + * This method performs the actual read/write calls for all + * sockets. This method will check for any + * pending outgoing connections (and call OnConnect() for + * all that succeed), check for read state on all sockets + * which are currently connected (and call OnRead() if conditions + * are met), check for dead connections (and call OnDisconnect() + * for each), and check for connection time outs (and call + * OnTimeout() for each). + * (seconds) and (milliseconds) is how long to wait for a + * state change on any of the Connections, in seconds and + * milliseconds, respectively. The default is to return + * immediately (poll). + * If -1 is passed for seconds, then the process will block + * indefinitely waiting for a state change. + */ + virtual void Poll(const long seconds = 0, const long milliseconds = 0); + + protected: + /** + * The duration to wait for outgoing connections to be + * established. + */ + time_t timeoutDuration; + + /** + * The line delimiter, 0 if none + */ + char delimiter; + + /** + * Stores connectionMap's, one for each handler (key) + */ + handlerMapType handlerMap; + + /** + * Allow for asynchronous calls to Disconnect() + * This structure contains Connections to be removed from + * the connection tables. + */ + eraseMapType eraseMap; + + /** + * The size of the scratch buffer + */ + size_t inputBufferSize; + + /** + * Scratch buffer for reads + */ + char* inputBuffer; #ifdef HAVE_LIBSSL - /** - * The OpenSSL context for TLS connections - */ - SSL_CTX* sslCtx ; + /** + * The OpenSSL context for TLS connections + */ + SSL_CTX* sslCtx; #endif - /** - * Open a socket. - * Return -1 on error - */ - virtual int openSocket() ; - - /** - * Close a socket - */ - virtual void closeSocket( int ) ; - - /** - * Set the options for a socket - * Return true is all options were set properly, false - * otherwise. - */ - virtual bool setSocketOptions( int ) ; - - /** - * Attempt to read()/recv() from the given Connection. - * Post event(s) OnRead() or OnDisconnect(). - * Return true if the read was successful, false if - * connection is no longer valid. - */ - virtual bool handleRead( ConnectionHandler*, Connection* ) ; - - /** - * Attempt to write()/send() to the given Connection. - * Post event OnDisconnect() if necessary. - * Return true if the write was successful, false if - * the connection is no longer valid. - */ - virtual bool handleWrite( ConnectionHandler*, Connection* ) ; - - /** - * Attempt to flush all data from the given Connection. - * Reset the F_FLUSH flag. - * Post event OnDisconnect() if necessary. - * Return true if the write(s) was successful, false if - * the connection is no longer valid. - */ - virtual bool handleFlush( ConnectionHandler*, Connection* ) ; - - /** - * Attempt to complete the connection to the given Connection. - * Post event(s) OnConnect() or OnConnectFail(). - * Return true if connect was successful, false if Connection - * is invalid. - */ - virtual bool finishConnect( ConnectionHandler*, Connection* ) ; - - /** - * Attempt to complete an incoming connection creation. - * The ConnectionHandler will be notified either by a call - * to OnConnect() or OnConnectFail(), depending if the incoming - * connection attempt was successful or unsuccessful, - * respectively. - * Return true if connection attempt was successful, false - * otherwise. - */ - virtual bool finishAccept( ConnectionHandler*, Connection* ) ; - - /** - * Because the eraseMap is a multimap, it is possible to insert - * more than one value for each key. This is useful for - * removing more than a single connection for any single handler, - * but it also permits the insertion of the same connection - * more than once. This would create a problem when closing - * connections, because the second (and third, fourth, etc) - * instance of a particular iterator would be invalidated - * once the iterator is removed once -- this would cause - * a process crash. - * This method performs a simple check to see if the connection - * iterator is already present in the eraseMap. If so, just - * return because the connection is already scheduled to be - * removed, and this will occur in Poll(). Otherwise, add - * the connection to be erased to the eraseMap. - */ - virtual void scheduleErasure( ConnectionHandler*, - connectionMapType::iterator ) ; - - /** - * Call Disconnect() for each Connection owned by the - * given ConnectionHandler. - */ - virtual bool disconnectAll( ConnectionHandler* ) ; + /** + * Open a socket. + * Return -1 on error + */ + virtual int openSocket(); + + /** + * Close a socket + */ + virtual void closeSocket(int); + + /** + * Set the options for a socket + * Return true is all options were set properly, false + * otherwise. + */ + virtual bool setSocketOptions(int); + + /** + * Attempt to read()/recv() from the given Connection. + * Post event(s) OnRead() or OnDisconnect(). + * Return true if the read was successful, false if + * connection is no longer valid. + */ + virtual bool handleRead(ConnectionHandler*, Connection*); + + /** + * Attempt to write()/send() to the given Connection. + * Post event OnDisconnect() if necessary. + * Return true if the write was successful, false if + * the connection is no longer valid. + */ + virtual bool handleWrite(ConnectionHandler*, Connection*); + + /** + * Attempt to flush all data from the given Connection. + * Reset the F_FLUSH flag. + * Post event OnDisconnect() if necessary. + * Return true if the write(s) was successful, false if + * the connection is no longer valid. + */ + virtual bool handleFlush(ConnectionHandler*, Connection*); + + /** + * Attempt to complete the connection to the given Connection. + * Post event(s) OnConnect() or OnConnectFail(). + * Return true if connect was successful, false if Connection + * is invalid. + */ + virtual bool finishConnect(ConnectionHandler*, Connection*); + + /** + * Attempt to complete an incoming connection creation. + * The ConnectionHandler will be notified either by a call + * to OnConnect() or OnConnectFail(), depending if the incoming + * connection attempt was successful or unsuccessful, + * respectively. + * Return true if connection attempt was successful, false + * otherwise. + */ + virtual bool finishAccept(ConnectionHandler*, Connection*); + + /** + * Because the eraseMap is a multimap, it is possible to insert + * more than one value for each key. This is useful for + * removing more than a single connection for any single handler, + * but it also permits the insertion of the same connection + * more than once. This would create a problem when closing + * connections, because the second (and third, fourth, etc) + * instance of a particular iterator would be invalidated + * once the iterator is removed once -- this would cause + * a process crash. + * This method performs a simple check to see if the connection + * iterator is already present in the eraseMap. If so, just + * return because the connection is already scheduled to be + * removed, and this will occur in Poll(). Otherwise, add + * the connection to be erased to the eraseMap. + */ + virtual void scheduleErasure(ConnectionHandler*, connectionMapType::iterator); + + /** + * Call Disconnect() for each Connection owned by the + * given ConnectionHandler. + */ + virtual bool disconnectAll(ConnectionHandler*); #ifdef HAVE_LIBSSL - virtual bool negotiateTLS( ConnectionHandler*, Connection* ) ; + virtual bool negotiateTLS(ConnectionHandler*, Connection*); #endif -} ; +}; } // namespace gnuworld diff --git a/libgnuworld/EConfig.cc b/libgnuworld/EConfig.cc old mode 100755 new mode 100644 index f9eb9589..aba7aa23 --- a/libgnuworld/EConfig.cc +++ b/libgnuworld/EConfig.cc @@ -20,468 +20,366 @@ * $Id: EConfig.cc,v 1.9 2005/10/01 13:13:55 kewlio Exp $ */ -#include // unlink() - -#include -#include -#include -#include -#include - -#include -#include // rename() -#include // strerror() -#include - -#include "EConfig.h" -#include "StringTokenizer.h" -#include "ELog.h" -#include "misc.h" - - -namespace gnuworld -{ - -using std::ifstream ; -using std::ofstream ; -using std::string ; -using std::endl ; -using std::map ; - -EConfig::EConfig( const string& _configFileName ) - : configFileName( _configFileName ), - error( false ) -{ - openConfigFile(); +#include // unlink() + +#include +#include +#include +#include +#include + +#include +#include // rename() +#include // strerror() +#include + +#include "EConfig.h" +#include "StringTokenizer.h" +#include "ELog.h" +#include "misc.h" + +namespace gnuworld { + +using std::endl; +using std::ifstream; +using std::map; +using std::ofstream; +using std::string; + +EConfig::EConfig(const string& _configFileName) : configFileName(_configFileName), error(false) { + openConfigFile(); } -EConfig::~EConfig() -{ -// No heap space allocated -valueMap.clear() ; -lineList.clear() ; +EConfig::~EConfig() { + // No heap space allocated + valueMap.clear(); + lineList.clear(); } -EConfig::iterator EConfig::Find( const string& findMe ) -{ -return valueMap.find( findMe ) ; -} +EConfig::iterator EConfig::Find(const string& findMe) { return valueMap.find(findMe); } -EConfig::const_iterator EConfig::Find( const string& findMe ) const -{ -return valueMap.find( findMe ) ; -} +EConfig::const_iterator EConfig::Find(const string& findMe) const { return valueMap.find(findMe); } + +EConfig::iterator EConfig::Require(const string& key) { + // Attempt to find the key in the map + iterator ptr = valueMap.find(key); + + // Was it found? + if (ptr == valueMap.end()) { + // Nope, this method is intended to "require" the config file + // to have a certain key/value pair. Since this is not the + // case, print out an error and quit. + elog << "EConfig::Require> Configuration requires value " + << "for key \"" << key << "\"" << endl; + ::exit(0); + } -EConfig::iterator EConfig::Require( const string& key ) -{ -// Attempt to find the key in the map -iterator ptr = valueMap.find( key ) ; - -// Was it found? -if( ptr == valueMap.end() ) - { - // Nope, this method is intended to "require" the config file - // to have a certain key/value pair. Since this is not the - // case, print out an error and quit. - elog << "EConfig::Require> Configuration requires value " - << "for key \"" - << key << "\"" - << endl ; - ::exit( 0 ) ; - } - -// At least one key/value pair for this key exists; return it -return ptr ; + // At least one key/value pair for this key exists; return it + return ptr; } -bool EConfig::openConfigFile() -{ - //elog << "EConfig> Opening configFile: " - // << configFileName - // << ", hasError(): " - // << hasError() - // << endl ; - - ifstream configFile( configFileName.c_str() ) ; - if( !configFile.is_open() ) - { - elog << "EConfig> Unable to open file: " - << configFileName - << endl ; - setError() ; - return false; - } - //else - // { - // elog << "EConfig> Successfully opened" - // << endl ; - // } - - if( !readFile( configFile ) ) - { - setError() ; - configFile.close() ; - return false; - } - //else - // { - // elog << "EConfig> Successfully parsed" - // << endl ; - // } - configFile.close() ; - return true; +bool EConfig::openConfigFile() { + // elog << "EConfig> Opening configFile: " + // << configFileName + // << ", hasError(): " + // << hasError() + // << endl ; + + ifstream configFile(configFileName.c_str()); + if (!configFile.is_open()) { + elog << "EConfig> Unable to open file: " << configFileName << endl; + setError(); + return false; + } + // else + // { + // elog << "EConfig> Successfully opened" + // << endl ; + // } + + if (!readFile(configFile)) { + setError(); + configFile.close(); + return false; + } + // else + // { + // elog << "EConfig> Successfully parsed" + // << endl ; + // } + configFile.close(); + return true; } -bool EConfig::readFile( ifstream& configFile ) -{ -size_t lineNumber = 0 ; -string tmp ; - -while( getline( configFile, tmp ) ) - { - // Increment lineNumber before - // any continue statements - lineNumber++ ; - - if( !removeSpaces( tmp ) ) - { - // Parse error - elog << "EConfig: Parse error at line: " - << lineNumber - << endl ; - return false ; - } - - if( tmp.empty() || '#' == tmp[ 0 ] ) - { - lineInfo addMe( tmp ) ; - lineList.push_back( addMe ) ; - - // Ignore this line - continue ; - } - - // The line should now be of the form: - // variablename=value - StringTokenizer st( tmp, '=' ) ; - - if( st.size() < 2 ) - { - elog << "EConfig: Improper number of fields " - << "at line: " - << lineNumber - << std::endl ; - elog << "EConfig: Perhaps you meant for an empty " - << "value? Use: key = '' to specify empty values" - << std::endl ; - return false ; - } - - // Looks ok - mapType::iterator mapItr = - valueMap.insert( mapPairType( st[ 0 ], - st.assemble( 1 ) ) ) ; - - lineList.push_back( lineInfo( st[ 0 ], st.assemble( 1 ), - mapItr ) ) ; - } - -return true ; +bool EConfig::readFile(ifstream& configFile) { + size_t lineNumber = 0; + string tmp; + + while (getline(configFile, tmp)) { + // Increment lineNumber before + // any continue statements + lineNumber++; + + if (!removeSpaces(tmp)) { + // Parse error + elog << "EConfig: Parse error at line: " << lineNumber << endl; + return false; + } + + if (tmp.empty() || '#' == tmp[0]) { + lineInfo addMe(tmp); + lineList.push_back(addMe); + + // Ignore this line + continue; + } + + // The line should now be of the form: + // variablename=value + StringTokenizer st(tmp, '='); + + if (st.size() < 2) { + elog << "EConfig: Improper number of fields " + << "at line: " << lineNumber << std::endl; + elog << "EConfig: Perhaps you meant for an empty " + << "value? Use: key = '' to specify empty values" << std::endl; + return false; + } + + // Looks ok + mapType::iterator mapItr = valueMap.insert(mapPairType(st[0], st.assemble(1))); + + lineList.push_back(lineInfo(st[0], st.assemble(1), mapItr)); + } + + return true; } -bool EConfig::removeSpaces( string& line ) -{ -// If the first character is '#', just return true -if( !line.empty() && ('#' == line[ 0 ]) ) - { - return true ; - } - -string::iterator ptr = line.begin() ; - -bool inValue = false ; - -// Only continue up until the value field -while( ptr != line.end() ) - { - if( ('=' == *ptr) && !inValue ) - { - // We've reached the value field - // Only remove comments from this point - // on. - if( ((ptr + 1) != line.end()) && (*(ptr + 1) == ' ') ) - { - ptr = line.erase( ptr + 1 ) ; - } - inValue = true ; - } - - // Remove any white space characters, so long - // as we're not in the value field - else if( (' ' == *ptr || '\t' == *ptr) && !inValue ) - { - - // erase() invalidates the iterator - ptr = line.erase( ptr ) ; - - continue ; - } - - else - { - ++ptr ; - } - } - -// Remove trailing whitespace -while( !line.empty() - && ((' ' == line[ line.size() - 1 ]) - || ('\t' == line[ line.size() - 1 ])) ) - { - line.erase( line.size() - 1 ) ; - } - -return true ; +bool EConfig::removeSpaces(string& line) { + // If the first character is '#', just return true + if (!line.empty() && ('#' == line[0])) { + return true; + } + + string::iterator ptr = line.begin(); + + bool inValue = false; + + // Only continue up until the value field + while (ptr != line.end()) { + if (('=' == *ptr) && !inValue) { + // We've reached the value field + // Only remove comments from this point + // on. + if (((ptr + 1) != line.end()) && (*(ptr + 1) == ' ')) { + ptr = line.erase(ptr + 1); + } + inValue = true; + } + + // Remove any white space characters, so long + // as we're not in the value field + else if ((' ' == *ptr || '\t' == *ptr) && !inValue) { + + // erase() invalidates the iterator + ptr = line.erase(ptr); + + continue; + } + + else { + ++ptr; + } + } + + // Remove trailing whitespace + while (!line.empty() && ((' ' == line[line.size() - 1]) || ('\t' == line[line.size() - 1]))) { + line.erase(line.size() - 1); + } + + return true; } -bool EConfig::Add( const string& key, const string& value ) -{ -// TODO: Add timestamp info? -// Update the valueMap, which is used by clients of this class -iterator mapItr = - valueMap.insert( mapType::value_type( key, value ) ) ; +bool EConfig::Add(const string& key, const string& value) { + // TODO: Add timestamp info? + // Update the valueMap, which is used by clients of this class + iterator mapItr = valueMap.insert(mapType::value_type(key, value)); -// Update the fileMap, which is used to keep track of the -// format of the config file -lineInfo addMe( key, value, mapItr ) ; -lineList.push_back( addMe ) ; + // Update the fileMap, which is used to keep track of the + // format of the config file + lineInfo addMe(key, value, mapItr); + lineList.push_back(addMe); -return writeFile() ; + return writeFile(); } -bool EConfig::writeFile() -{ -// Move the old file to the /tmp directory to ensure we have -// a backup. -string backupFileName( configFileName ) ; - -// Remove any leading directory path information -string::size_type slashPos = backupFileName.find_last_of( '/' ) ; -if( string::npos != slashPos ) - { - // There is leading path information - backupFileName = backupFileName.substr( slashPos, string::npos ) ; - } -backupFileName = string( "/tmp/" ) + backupFileName ; - -//elog << "EConfig::writeFile> Renaming " -// << configFileName -// << " to " -// << backupFileName -// << endl ; - -if( ::rename( configFileName.c_str(), backupFileName.c_str() ) < 0 ) - { - elog << "EConfig::writeFile> Unable to rename " - << configFileName - << " to " - << backupFileName - << " because: " - << strerror( errno ) - << endl ; - - // Ok to leave the file open per class conditions. - return false ; - } - -std::ofstream configFile( configFileName.c_str() ) ; -if( !configFile.is_open() ) - { - elog << "EConfig::writeFile> Unable to open file: " - << configFileName - << ", because: " - << strerror( errno ) - << endl ; - - if( ::rename( backupFileName.c_str(), configFileName.c_str() ) < 0 ) - { - elog << "EConfig::writeFile> Unable to restore " - << "original file \"" - << configFileName - << "\" from backup \"" - << backupFileName - << "\" because: " - << strerror( errno ) - << endl ; - } - return false ; - } - -for( lineListType::const_iterator fileItr = lineList.begin() ; - fileItr != lineList.end() ; ++fileItr ) - { - const lineInfo& theInfo = *fileItr ; - if( theInfo.value.empty() ) - { -// elog << "EConfig::writeFile> Writing: " -// << theInfo.key -// << endl ; - - // comment line - configFile << theInfo.key - << endl ; - - continue ; - } - -// elog << "EConfig::writeFile> Writing: " -// << theInfo.key -// << " = " -// << theInfo.value -// << endl ; - - configFile << theInfo.key - << " = " - << theInfo.value - << endl ; - } // for() - -configFile.close() ; - -// Writing of new file succeeded, remove the backup -if( ::unlink( backupFileName.c_str() ) < 0 ) - { - elog << "EConfig::writeFile> Unable to unlink " - << "backup file " - << backupFileName - << " because: " - << strerror( errno ) - << endl ; - - // This is not a critical failure - // Allow the method to return true - } - -return true ; +bool EConfig::writeFile() { + // Move the old file to the /tmp directory to ensure we have + // a backup. + string backupFileName(configFileName); + + // Remove any leading directory path information + string::size_type slashPos = backupFileName.find_last_of('/'); + if (string::npos != slashPos) { + // There is leading path information + backupFileName = backupFileName.substr(slashPos, string::npos); + } + backupFileName = string("/tmp/") + backupFileName; + + // elog << "EConfig::writeFile> Renaming " + // << configFileName + // << " to " + // << backupFileName + // << endl ; + + if (::rename(configFileName.c_str(), backupFileName.c_str()) < 0) { + elog << "EConfig::writeFile> Unable to rename " << configFileName << " to " + << backupFileName << " because: " << strerror(errno) << endl; + + // Ok to leave the file open per class conditions. + return false; + } + + std::ofstream configFile(configFileName.c_str()); + if (!configFile.is_open()) { + elog << "EConfig::writeFile> Unable to open file: " << configFileName + << ", because: " << strerror(errno) << endl; + + if (::rename(backupFileName.c_str(), configFileName.c_str()) < 0) { + elog << "EConfig::writeFile> Unable to restore " + << "original file \"" << configFileName << "\" from backup \"" << backupFileName + << "\" because: " << strerror(errno) << endl; + } + return false; + } + + for (lineListType::const_iterator fileItr = lineList.begin(); fileItr != lineList.end(); + ++fileItr) { + const lineInfo& theInfo = *fileItr; + if (theInfo.value.empty()) { + // elog << "EConfig::writeFile> Writing: " + // << theInfo.key + // << endl ; + + // comment line + configFile << theInfo.key << endl; + + continue; + } + + // elog << "EConfig::writeFile> Writing: " + // << theInfo.key + // << " = " + // << theInfo.value + // << endl ; + + configFile << theInfo.key << " = " << theInfo.value << endl; + } // for() + + configFile.close(); + + // Writing of new file succeeded, remove the backup + if (::unlink(backupFileName.c_str()) < 0) { + elog << "EConfig::writeFile> Unable to unlink " + << "backup file " << backupFileName << " because: " << strerror(errno) << endl; + + // This is not a critical failure + // Allow the method to return true + } + + return true; } // writeFile() -bool EConfig::Delete( const string& key ) -{ -iterator itr = valueMap.find( key ) ; -if( itr == valueMap.end() ) - { - return false ; - } -return Delete( itr ) ; +bool EConfig::Delete(const string& key) { + iterator itr = valueMap.find(key); + if (itr == valueMap.end()) { + return false; + } + return Delete(itr); } -bool EConfig::Delete( iterator itr ) -{ -if( itr == valueMap.end() ) - { - elog << "EConfig::Delete> Attempting to delete " - << "valueMap.end()" - << endl ; - return false ; - } -valueMap.erase( itr ) ; - -bool foundIt = false ; -for( lineListType::iterator lineItr = lineList.begin() ; - lineItr != lineList.end() ; ++lineItr ) - { - if( itr == (*lineItr).mapItr ) - { - // Found it - foundIt = true ; - lineList.erase( lineItr ) ; - - break ; - } - } - -if( !foundIt ) - { - elog << "EConfig::Delete> Unable to find lineList " - << "entry corresponding to iterator: " - << itr->first - << '/' - << itr->second - << endl ; - } - -return (foundIt ? writeFile() : false) ; +bool EConfig::Delete(iterator itr) { + if (itr == valueMap.end()) { + elog << "EConfig::Delete> Attempting to delete " + << "valueMap.end()" << endl; + return false; + } + valueMap.erase(itr); + + bool foundIt = false; + for (lineListType::iterator lineItr = lineList.begin(); lineItr != lineList.end(); ++lineItr) { + if (itr == (*lineItr).mapItr) { + // Found it + foundIt = true; + lineList.erase(lineItr); + + break; + } + } + + if (!foundIt) { + elog << "EConfig::Delete> Unable to find lineList " + << "entry corresponding to iterator: " << itr->first << '/' << itr->second << endl; + } + + return (foundIt ? writeFile() : false); } -bool EConfig::Replace( iterator itr, const string& newValue ) -{ -if( newValue.empty() ) - { - return false ; - } - -if( itr == valueMap.end() ) - { - return false ; - } -valueMap.erase( itr ) ; - -bool foundIt = false ; - -// Replacing the value in-place here should maintain the -// relative location of the key/value pair in the file. -for( lineListType::iterator listItr = lineList.begin() ; - listItr != lineList.end() ; ++listItr ) - { - if( (*listItr).mapItr == itr ) - { - // Found it - foundIt = true ; - (*listItr).value = newValue ; - break ; - } - } - -if( !foundIt ) - { - elog << "EConfig::Replace> Unable to find lineList " - << "entry corresponding to iterator: " - << itr->first - << '/' - << itr->second - << endl ; - } - -valueMap.insert( mapType::value_type( itr->first, newValue ) ) ; - -return writeFile() ; +bool EConfig::Replace(iterator itr, const string& newValue) { + if (newValue.empty()) { + return false; + } + + if (itr == valueMap.end()) { + return false; + } + valueMap.erase(itr); + + bool foundIt = false; + + // Replacing the value in-place here should maintain the + // relative location of the key/value pair in the file. + for (lineListType::iterator listItr = lineList.begin(); listItr != lineList.end(); ++listItr) { + if ((*listItr).mapItr == itr) { + // Found it + foundIt = true; + (*listItr).value = newValue; + break; + } + } + + if (!foundIt) { + elog << "EConfig::Replace> Unable to find lineList " + << "entry corresponding to iterator: " << itr->first << '/' << itr->second << endl; + } + + valueMap.insert(mapType::value_type(itr->first, newValue)); + + return writeFile(); } -void EConfig::Clear() -{ - error = false; - configErrors.clear(); - valueMap.clear(); +void EConfig::Clear() { + error = false; + configErrors.clear(); + valueMap.clear(); } -bool EConfig::AddComment( const string& commentData ) -{ -string newComment( commentData ) ; +bool EConfig::AddComment(const string& commentData) { + string newComment(commentData); -// If this command is not empty and does not begin with the -// proper comment delimiter, then add the delimiter. -if( !newComment.empty() && ('#' != newComment[ 0 ]) ) - { - newComment = string( "# " ) + newComment ; - } + // If this command is not empty and does not begin with the + // proper comment delimiter, then add the delimiter. + if (!newComment.empty() && ('#' != newComment[0])) { + newComment = string("# ") + newComment; + } -// For some reason the compiler won't let me use the 3 argument -// constructor for lineInfo here -- dan -lineInfo addMe ; -addMe.key = newComment ; -lineList.push_back( addMe ) ; + // For some reason the compiler won't let me use the 3 argument + // constructor for lineInfo here -- dan + lineInfo addMe; + addMe.key = newComment; + lineList.push_back(addMe); -return writeFile() ; + return writeFile(); } } // namespace gnuworld diff --git a/libgnuworld/EConfig.h b/libgnuworld/EConfig.h old mode 100755 new mode 100644 index fbc5e679..9c2e1d49 --- a/libgnuworld/EConfig.h +++ b/libgnuworld/EConfig.h @@ -23,18 +23,17 @@ #ifndef __ECONFIG_H #define __ECONFIG_H "$Id: EConfig.h,v 1.7 2004/01/16 00:59:47 dan_karrels Exp $" -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include -#include "ELog.h" -#include "misc.h" // noCaseCompare +#include "ELog.h" +#include "misc.h" // noCaseCompare -namespace gnuworld -{ +namespace gnuworld { /** * A simple configuration file parser. @@ -51,430 +50,378 @@ namespace gnuworld */ template -concept ConfigType = std::is_same_v< T, std::string > || - std::is_same_v< T, int > || - std::is_same_v< T, unsigned int > || - std::is_same_v< T, double > || - std::is_same_v< T, bool > ; - -class EConfig -{ - - /** - * The type of the map used to store the key/value pairs. - */ - typedef std::multimap< std::string, std::string, noCaseCompare > - mapType ; - - /** - * This struct is used to store information about an entry - * into the physical configuration file. - */ - struct lineInfo - { - /** - * The key for the key/value pair. - */ - std::string key ; - - /** - * The value for the key/value pair. - * An empty value string indicates that this line - * is a comment, and key contains the comment - * (including preceeding '#' where necessary. - */ - std::string value ; - - /** - * An iterator into the key/value map for this line, - * so that modifications to this key/value pair can - * can be placed in the correct location in the file. - */ - mapType::iterator mapItr ; - - /** - * Default constructor relies upon the default constructors - * of the member variables. - */ - lineInfo() - {} - - /** - * This constructor is called when there is a comment - * line. Even though there are no value tokens, be sure - * to record whatever comment is present. - */ - lineInfo( const std::string& key ) - : key( key ) - {} - - /** - * Copy constructor, used in assignment (as in the key/value map). - */ - lineInfo( const lineInfo& rhs ) - : key( rhs.key ), value( rhs.value ), mapItr( rhs.mapItr ) - {} - - /** - * Constructor receives the key, value, and map iterator. - */ - lineInfo( const std::string& key, const std::string& value, - const mapType::iterator& mapItr ) - : key( key ), value( value ), mapItr( mapItr ) - {} - - /** - * Permit assignment. - */ - lineInfo& operator=( const lineInfo& rhs ) - { - key = rhs.key ; - value = rhs.value ; - mapItr = rhs.mapItr ; - return *this ; - } - - } ; - - /** - * Type used to store configuration file format. - */ - typedef std::list< lineInfo > lineListType ; - -public: - - /** - * The pair type for the mapType, it holds the key/value pairs. - */ - typedef mapType::value_type mapPairType ; - - /** - * The type used to store the number of significant key/value - * pairs stored. - */ - typedef mapType::size_type size_type ; - - /** - * A const iterator that users of this class may use - * to safely walk through the structure. - */ - typedef mapType::const_iterator const_iterator ; - - /** - * A non-const iterator for walking through this - * structure. - */ - typedef mapType::iterator iterator ; - - /** - * Create a new config parser for the given config file name. - */ - EConfig( const std::string& fileName ) ; - - /** - * Destroy the EConfig object. This will also close the - * input file. - */ - ~EConfig() ; - - /** - * Obtain a const iterator to the beginning of the map - * of key/value pairs. - */ - inline const_iterator begin() const - { return valueMap.begin() ; } - - /** - * Obtain a const iterator to the end of the map of - * key/value pairs. - */ - inline const_iterator end() const - { return valueMap.end() ; } - - /** - * Obtain a iterator to the beginning of the map - * of key/value pairs. - */ - inline iterator begin() - { return valueMap.begin() ; } - - /** - * Obtain a iterator to the end of the map of - * key/value pairs. - */ - inline iterator end() - { return valueMap.end() ; } - - /** - * Return the number of significant key/value pairs stored. - */ - inline size_type size() const - { return valueMap.size() ; } - - /** - * Return true if there was an error in processing - * the file. - */ - inline bool hasError() const - { return error ; } - - - /** - * Returns the config errors. - */ - inline const std::vector< std::string >& getErrors() const - { return configErrors ; } - - /** - * Find the first key/value pair for the given key. - */ - iterator Find( const std::string& findMe ) ; - - /** - * Find the first key/value pair for the given key. - */ - const_iterator Find( const std::string& findMe ) const ; - - /** - * Call this method to retrieve a const_iterator to the first - * value associated with the key (findMe). If the key is - * not found, then an error message will be output and the - * program will terminate. - */ - iterator Require( const std::string& findMe ) ; - - - /** - * Call this method to retrieve a value with the type specified. - * If the value does not match the given type, an error message - * will be output and the program will terminate. - */ - template - T Require( const std::string& key, bool fatal = true ) - { - iterator it = Require( key ) ; - const std::string& value = it->second ; - - try - { - if constexpr( std::is_same_v ) - return value ; - - else if constexpr( std::is_same_v ) - { - size_t idx ; - int result = std::stoi( value, &idx ) ; - if( idx != value.length() ) - throw std::invalid_argument("contains trailing characters") ; - return result ; - } - else if constexpr (std::is_same_v) - { - size_t idx ; - unsigned long result = std::stoul( value, &idx ) ; - if( idx != value.length() ) - throw std::invalid_argument("contains trailing characters") ; - return static_cast( result ) ; - } - else if constexpr( std::is_same_v ) - { - size_t idx ; - double result = std::stod( value, &idx ) ; - if( idx != value.length() ) - throw std::invalid_argument("contains trailing characters") ; - return result ; - } - else if constexpr( std::is_same_v ) - { - std::string lower = string_lower( value ) ; - if( lower == "true" || lower == "yes" || lower == "on" || lower == "1" ) - return true ; - if( lower == "false" || lower == "no" || lower == "off" || lower == "0" ) - return false ; - throw std::invalid_argument("must be true/false, yes/no, on/off, or 1/0") ; - } - else - { - throw std::invalid_argument("unsupported config type"); - } - } - catch( const std::invalid_argument& e ) - { - std::ostringstream msg; - msg << "Invalid value for key \"" << key << "\": \"" << value << "\" - " - << e.what(); - - if constexpr (std::is_same_v) - msg << " (must be a signed integer)"; - else if constexpr (std::is_same_v) - msg << " (must be an unsigned integer)"; - else if constexpr (std::is_same_v) - msg << " (must be a floating point number)"; - else if constexpr (std::is_same_v) - msg << " (must be true/false, yes/no, on/off, or 1/0)"; - - elog << "EConfig::Require<>: " << msg.str() << std::endl; - if( fatal ) - ::exit(1) ; - throw std::runtime_error( msg.str() ) ; - } - catch( const std::out_of_range& e ) - { - std::string msg = "Value out of range for key \"" + key + "\": " + e.what() ; - elog << "EConfig::Require<>: " << msg << std::endl ; - if( fatal ) - ::exit(1) ; - throw std::runtime_error( msg ) ; - } - } - - /** - * Call this method to try to retrieve a value with the type specified. - * The function takes the existing value as an argument (fallback). - * If the config value does not match the given type, the function will return - * the fallback value and not exit. - */ - template - T TryRequire( const std::string& key, const T& fallback ) - { - try - { - return Require( key, false ) ; // non-fatal - } - catch( const std::exception& e ) - { - std::ostringstream err ; - err << "Failed to parse key \"" << key << "\". Keeping old value. Reason: " << e.what(); - elog << "EConfig::TryRequire<>: " << err.str() << std::endl; - configErrors.push_back( err.str() ) ; - setError() ; - return fallback ; - } - } - - /** - * Add a key/value pair to the config file. - * Note that this will not delete any existing entry, but - * will add a duplicate, which is supported by the EConfig - * class. - */ - bool Add( const std::string& key, - const std::string& value ) ; - - /** - * Add a comment to the end of the file. - * This comment line may be empty. - */ - bool AddComment( const std::string& newComment ) ; - - /** - * Delete a key/value pair by key. Only one pair whose key - * matches the given key will be deleted, and no guarantee - * is made about which one. - * If you have duplicates, and would like to remove a specific - * entry, use the other form of Delete(). - */ - bool Delete( const std::string& key ) ; - - /** - * Remove a key value pair given its iterator. - */ - bool Delete( iterator itr ) ; - - /** - * Replace the value of a given key/value pair. - * It is important to use this method rather than just - * modifying the iterator itself. - */ - bool Replace( iterator itr, - const std::string& newValue ) ; - - /* - * Clear valueMap - */ - void Clear(); - - /** - * Open the input file. - */ - bool openConfigFile(); - - /** - * Debugging function for outputting the entire map to - * an output stream. - */ - friend ELog& operator<<( ELog& out, const EConfig& conf ) - { - EConfig::const_iterator ptr = conf.begin() ; - while( ptr != conf.end() ) - { - out << "Key: " << ptr->first << ", " - << "Value: " << ptr->second << std::endl ; - ++ptr ; - } - return out ; - } - -protected: - - /** - * Disable copying, this method is declared but NOT defined. - */ - EConfig( const EConfig& ) ; - - /** - * Disable assignment, this method is declared but NOT defined. - */ - EConfig operator=( const EConfig& ) ; - - /** - * Remove blank spaces from the line of text. - */ - bool removeSpaces( std::string& ) ; - - /** - * Parse the input file. - */ - bool readFile( std::ifstream& ) ; - - /** - * Write the current memory configuration to disk. - */ - bool writeFile() ; - - /** - * Record that an error has occured. - */ - inline void setError() - { error = true ; } - - /** - * The name of the configuration file. - */ - std::string configFileName ; - - /** - * The error status field. - */ - bool error ; - - /** - * A vector containing config errors. - */ - std::vector< std::string > configErrors ; - - /** - * The map used to store the file's key/value pairs. - */ - mapType valueMap ; - - /** - * The DS used to store the actual format of the config - * file. - */ - lineListType lineList ; - -} ; // class EConfig +concept ConfigType = + std::is_same_v || std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v; + +class EConfig { + + /** + * The type of the map used to store the key/value pairs. + */ + typedef std::multimap mapType; + + /** + * This struct is used to store information about an entry + * into the physical configuration file. + */ + struct lineInfo { + /** + * The key for the key/value pair. + */ + std::string key; + + /** + * The value for the key/value pair. + * An empty value string indicates that this line + * is a comment, and key contains the comment + * (including preceeding '#' where necessary. + */ + std::string value; + + /** + * An iterator into the key/value map for this line, + * so that modifications to this key/value pair can + * can be placed in the correct location in the file. + */ + mapType::iterator mapItr; + + /** + * Default constructor relies upon the default constructors + * of the member variables. + */ + lineInfo() {} + + /** + * This constructor is called when there is a comment + * line. Even though there are no value tokens, be sure + * to record whatever comment is present. + */ + lineInfo(const std::string& key) : key(key) {} + + /** + * Copy constructor, used in assignment (as in the key/value map). + */ + lineInfo(const lineInfo& rhs) : key(rhs.key), value(rhs.value), mapItr(rhs.mapItr) {} + + /** + * Constructor receives the key, value, and map iterator. + */ + lineInfo(const std::string& key, const std::string& value, const mapType::iterator& mapItr) + : key(key), value(value), mapItr(mapItr) {} + + /** + * Permit assignment. + */ + lineInfo& operator=(const lineInfo& rhs) { + key = rhs.key; + value = rhs.value; + mapItr = rhs.mapItr; + return *this; + } + }; + + /** + * Type used to store configuration file format. + */ + typedef std::list lineListType; + + public: + /** + * The pair type for the mapType, it holds the key/value pairs. + */ + typedef mapType::value_type mapPairType; + + /** + * The type used to store the number of significant key/value + * pairs stored. + */ + typedef mapType::size_type size_type; + + /** + * A const iterator that users of this class may use + * to safely walk through the structure. + */ + typedef mapType::const_iterator const_iterator; + + /** + * A non-const iterator for walking through this + * structure. + */ + typedef mapType::iterator iterator; + + /** + * Create a new config parser for the given config file name. + */ + EConfig(const std::string& fileName); + + /** + * Destroy the EConfig object. This will also close the + * input file. + */ + ~EConfig(); + + /** + * Obtain a const iterator to the beginning of the map + * of key/value pairs. + */ + inline const_iterator begin() const { return valueMap.begin(); } + + /** + * Obtain a const iterator to the end of the map of + * key/value pairs. + */ + inline const_iterator end() const { return valueMap.end(); } + + /** + * Obtain a iterator to the beginning of the map + * of key/value pairs. + */ + inline iterator begin() { return valueMap.begin(); } + + /** + * Obtain a iterator to the end of the map of + * key/value pairs. + */ + inline iterator end() { return valueMap.end(); } + + /** + * Return the number of significant key/value pairs stored. + */ + inline size_type size() const { return valueMap.size(); } + + /** + * Return true if there was an error in processing + * the file. + */ + inline bool hasError() const { return error; } + + /** + * Returns the config errors. + */ + inline const std::vector& getErrors() const { return configErrors; } + + /** + * Find the first key/value pair for the given key. + */ + iterator Find(const std::string& findMe); + + /** + * Find the first key/value pair for the given key. + */ + const_iterator Find(const std::string& findMe) const; + + /** + * Call this method to retrieve a const_iterator to the first + * value associated with the key (findMe). If the key is + * not found, then an error message will be output and the + * program will terminate. + */ + iterator Require(const std::string& findMe); + + /** + * Call this method to retrieve a value with the type specified. + * If the value does not match the given type, an error message + * will be output and the program will terminate. + */ + template T Require(const std::string& key, bool fatal = true) { + iterator it = Require(key); + const std::string& value = it->second; + + try { + if constexpr (std::is_same_v) + return value; + + else if constexpr (std::is_same_v) { + size_t idx; + int result = std::stoi(value, &idx); + if (idx != value.length()) + throw std::invalid_argument("contains trailing characters"); + return result; + } else if constexpr (std::is_same_v) { + size_t idx; + unsigned long result = std::stoul(value, &idx); + if (idx != value.length()) + throw std::invalid_argument("contains trailing characters"); + return static_cast(result); + } else if constexpr (std::is_same_v) { + size_t idx; + double result = std::stod(value, &idx); + if (idx != value.length()) + throw std::invalid_argument("contains trailing characters"); + return result; + } else if constexpr (std::is_same_v) { + std::string lower = string_lower(value); + if (lower == "true" || lower == "yes" || lower == "on" || lower == "1") + return true; + if (lower == "false" || lower == "no" || lower == "off" || lower == "0") + return false; + throw std::invalid_argument("must be true/false, yes/no, on/off, or 1/0"); + } else { + throw std::invalid_argument("unsupported config type"); + } + } catch (const std::invalid_argument& e) { + std::ostringstream msg; + msg << "Invalid value for key \"" << key << "\": \"" << value << "\" - " << e.what(); + + if constexpr (std::is_same_v) + msg << " (must be a signed integer)"; + else if constexpr (std::is_same_v) + msg << " (must be an unsigned integer)"; + else if constexpr (std::is_same_v) + msg << " (must be a floating point number)"; + else if constexpr (std::is_same_v) + msg << " (must be true/false, yes/no, on/off, or 1/0)"; + + elog << "EConfig::Require<>: " << msg.str() << std::endl; + if (fatal) + ::exit(1); + throw std::runtime_error(msg.str()); + } catch (const std::out_of_range& e) { + std::string msg = "Value out of range for key \"" + key + "\": " + e.what(); + elog << "EConfig::Require<>: " << msg << std::endl; + if (fatal) + ::exit(1); + throw std::runtime_error(msg); + } + } + + /** + * Call this method to try to retrieve a value with the type specified. + * The function takes the existing value as an argument (fallback). + * If the config value does not match the given type, the function will return + * the fallback value and not exit. + */ + template T TryRequire(const std::string& key, const T& fallback) { + try { + return Require(key, false); // non-fatal + } catch (const std::exception& e) { + std::ostringstream err; + err << "Failed to parse key \"" << key << "\". Keeping old value. Reason: " << e.what(); + elog << "EConfig::TryRequire<>: " << err.str() << std::endl; + configErrors.push_back(err.str()); + setError(); + return fallback; + } + } + + /** + * Add a key/value pair to the config file. + * Note that this will not delete any existing entry, but + * will add a duplicate, which is supported by the EConfig + * class. + */ + bool Add(const std::string& key, const std::string& value); + + /** + * Add a comment to the end of the file. + * This comment line may be empty. + */ + bool AddComment(const std::string& newComment); + + /** + * Delete a key/value pair by key. Only one pair whose key + * matches the given key will be deleted, and no guarantee + * is made about which one. + * If you have duplicates, and would like to remove a specific + * entry, use the other form of Delete(). + */ + bool Delete(const std::string& key); + + /** + * Remove a key value pair given its iterator. + */ + bool Delete(iterator itr); + + /** + * Replace the value of a given key/value pair. + * It is important to use this method rather than just + * modifying the iterator itself. + */ + bool Replace(iterator itr, const std::string& newValue); + + /* + * Clear valueMap + */ + void Clear(); + + /** + * Open the input file. + */ + bool openConfigFile(); + + /** + * Debugging function for outputting the entire map to + * an output stream. + */ + friend ELog& operator<<(ELog& out, const EConfig& conf) { + EConfig::const_iterator ptr = conf.begin(); + while (ptr != conf.end()) { + out << "Key: " << ptr->first << ", " + << "Value: " << ptr->second << std::endl; + ++ptr; + } + return out; + } + + protected: + /** + * Disable copying, this method is declared but NOT defined. + */ + EConfig(const EConfig&); + + /** + * Disable assignment, this method is declared but NOT defined. + */ + EConfig operator=(const EConfig&); + + /** + * Remove blank spaces from the line of text. + */ + bool removeSpaces(std::string&); + + /** + * Parse the input file. + */ + bool readFile(std::ifstream&); + + /** + * Write the current memory configuration to disk. + */ + bool writeFile(); + + /** + * Record that an error has occured. + */ + inline void setError() { error = true; } + + /** + * The name of the configuration file. + */ + std::string configFileName; + + /** + * The error status field. + */ + bool error; + + /** + * A vector containing config errors. + */ + std::vector configErrors; + + /** + * The map used to store the file's key/value pairs. + */ + mapType valueMap; + + /** + * The DS used to store the actual format of the config + * file. + */ + lineListType lineList; + +}; // class EConfig } // namespace gnuworld diff --git a/libgnuworld/ELog.cc b/libgnuworld/ELog.cc old mode 100755 new mode 100644 index a5045187..133384d1 --- a/libgnuworld/ELog.cc +++ b/libgnuworld/ELog.cc @@ -21,106 +21,87 @@ * $Id: ELog.cc,v 1.8 2005/02/20 15:49:21 dan_karrels Exp $ */ -#include -#include -#include -#include -#include -#include "ELog.h" +#include +#include +#include +#include +#include +#include "ELog.h" -namespace gnuworld -{ +namespace gnuworld { -using std::stringstream ; -using std::string ; -using std::endl ; +using std::endl; +using std::string; +using std::stringstream; // Instantiate the global instance -ELog elog ; +ELog elog; -ELog::ELog() - : outStream( 0 ), - logFile( false ), - newline(true) -{} +ELog::ELog() : outStream(0), logFile(false), newline(true) {} -ELog::ELog( const string& fileName ) - : outStream( 0 ), - logFile( false ), - newline(true) -{ -openFile( fileName ) ; +ELog::ELog(const string& fileName) : outStream(0), logFile(false), newline(true) { + openFile(fileName); } -ELog::~ELog() -{ -if( logFile ) - { - closeFile() ; - } +ELog::~ELog() { + if (logFile) { + closeFile(); + } } -bool ELog::openFile( const string& fileName ) -{ -bool isAlreadyOpen = false; -if( isOpen() ) - { - isAlreadyOpen = true; - closeFile() ; - } -logFile = true ; -if (isAlreadyOpen) - outFile.open( fileName.c_str(), std::ios::out | std::ios::app ) ; -else - outFile.open( fileName.c_str(), std::ios::out | std::ios::trunc ) ; +bool ELog::openFile(const string& fileName) { + bool isAlreadyOpen = false; + if (isOpen()) { + isAlreadyOpen = true; + closeFile(); + } + logFile = true; + if (isAlreadyOpen) + outFile.open(fileName.c_str(), std::ios::out | std::ios::app); + else + outFile.open(fileName.c_str(), std::ios::out | std::ios::trunc); -if( !isOpen() ) - { - logFile = false ; - } -return isOpen() ; + if (!isOpen()) { + logFile = false; + } + return isOpen(); } -void ELog::closeFile() -{ -if( isOpen() ) - { - outFile << endl ; - outFile.close() ; - } +void ELog::closeFile() { + if (isOpen()) { + outFile << endl; + outFile.close(); + } } -ELog& ELog::operator<<( __E_omanip var ) -{ -if( logFile ) - { - outFile << var ; - } -if( outStream ) *outStream << var ; -newline = true; -return *this ; +ELog& ELog::operator<<(__E_omanip var) { + if (logFile) { + outFile << var; + } + if (outStream) + *outStream << var; + newline = true; + return *this; } -ELog& ELog::operator<<( __E_manip var ) -{ -if( logFile ) - { - outFile << var ; - } -if( outStream ) *outStream << var ; -newline = true; -return *this ; +ELog& ELog::operator<<(__E_manip var) { + if (logFile) { + outFile << var; + } + if (outStream) + *outStream << var; + newline = true; + return *this; } -std::string ELog::getLocalTime() -{ - time_t theTime; - time(&theTime); /* get current time; same as: theTime = time(NULL) */ - struct tm* timeinfo = localtime(&theTime); - char buffer[20] = {0}; +std::string ELog::getLocalTime() { + time_t theTime; + time(&theTime); /* get current time; same as: theTime = time(NULL) */ + struct tm* timeinfo = localtime(&theTime); + char buffer[20] = {0}; - std::strftime(buffer,20,"%Y-%m-%d %H:%M:%S",timeinfo); - return string("[" + string(buffer) + "] "); + std::strftime(buffer, 20, "%Y-%m-%d %H:%M:%S", timeinfo); + return string("[" + string(buffer) + "] "); } } // namespace gnuworld diff --git a/libgnuworld/ELog.h b/libgnuworld/ELog.h old mode 100755 new mode 100644 index 30d9708d..a83c53b7 --- a/libgnuworld/ELog.h +++ b/libgnuworld/ELog.h @@ -23,13 +23,12 @@ #ifndef __ELOG_H #define __ELOG_H "$Id: ELog.h,v 1.8 2005/02/20 15:49:21 dan_karrels Exp $" -#include -#include -#include -#include +#include +#include +#include +#include -namespace gnuworld -{ +namespace gnuworld { /** * This class handles logging for GNUWorld. It maintains a pointer @@ -37,138 +36,127 @@ namespace gnuworld * are logged to this stream. All messages are also logged to the * file whose name is specified in the constructor. */ -class ELog -{ - -protected: - - typedef std::ostream& (*__E_omanip)( std::ostream& ) ; - typedef std::ostream& (*__E_manip)( std::ios& ) ; - - /** - * A pointer to a C++ output stream for logging. If this - * stream is non-NULL, then all messages will be logged - * to this stream. - */ - std::ostream *outStream ; - - /** - * The file output stream to which to log all messages. - */ - std::ofstream outFile ; - - /** - * True if logging to an output file. - */ - bool logFile ; - - bool newline; - -public: - - /** - * Instantiate an instance of this class. No output file - * is opened, and no output stream is specified for - * logging. - */ - ELog() ; - - /** - * Instantiate an instance of this class, specifying the - * name of the file to which to log messages. This log file - * will be created if it does not already exist. If it - * exists, it will be truncated. - */ - ELog( const std::string& ) ; - - /** - * Destroy an instance of this class. This method will - * close the output file if it is open. - */ - virtual ~ELog() ; - - /** - * Open an output file for logging messages. If an output - * file is currently open, it will be flushed and closed. - * This method will create the file if it does not already - * exist, otherwise the existing file will be truncated. - * This method returns true on success, false otherwise. - * Keep in mind that even if this method return false, - * any existing output file will be closed. - */ - bool openFile( const std::string& fileName ) ; - - /** - * Close the output log file, if it is open. - */ - void closeFile() ; - - /** - * Return true if an output log file is open, false otherwise. - * For some reason, std::fstream::is_open() is not const. - */ - inline bool isOpen() - { return (logFile && outFile.is_open()) ; } - - /** - * Use this method to specify which stream to which - * to log messages. Specifying NULL will stop all - * output logging to any stream (except for the output file, - * if it exists). - */ - inline void setStream( std::ostream* newStream ) - { outStream = newStream ; } - - /** - * Get the stream to which to log messages. - */ - - inline std::ostream* getStream() - { return outStream ; } - - /* - * Get local time in [hh:mm:ss] format - */ - std::string getLocalTime(); - - /** - * Output the endl function. - */ - ELog& operator<<( __E_omanip func ) ; - - /** - * Output the endl function. - */ - ELog& operator<<( __E_manip func ) ; - - /** - * Output any other type supported by std::ostream. - */ - template< typename T > - ELog& operator<<( const T& var ) - { - if (logFile) - { - if (newline) - outFile << getLocalTime() << var; - else - outFile << var; - } - if (outStream) - { - if (newline) - *outStream << getLocalTime() << var; - else - *outStream << var; - } - newline = false; - return *this ; - } - -} ; +class ELog { + + protected: + typedef std::ostream& (*__E_omanip)(std::ostream&); + typedef std::ostream& (*__E_manip)(std::ios&); + + /** + * A pointer to a C++ output stream for logging. If this + * stream is non-NULL, then all messages will be logged + * to this stream. + */ + std::ostream* outStream; + + /** + * The file output stream to which to log all messages. + */ + std::ofstream outFile; + + /** + * True if logging to an output file. + */ + bool logFile; + + bool newline; + + public: + /** + * Instantiate an instance of this class. No output file + * is opened, and no output stream is specified for + * logging. + */ + ELog(); + + /** + * Instantiate an instance of this class, specifying the + * name of the file to which to log messages. This log file + * will be created if it does not already exist. If it + * exists, it will be truncated. + */ + ELog(const std::string&); + + /** + * Destroy an instance of this class. This method will + * close the output file if it is open. + */ + virtual ~ELog(); + + /** + * Open an output file for logging messages. If an output + * file is currently open, it will be flushed and closed. + * This method will create the file if it does not already + * exist, otherwise the existing file will be truncated. + * This method returns true on success, false otherwise. + * Keep in mind that even if this method return false, + * any existing output file will be closed. + */ + bool openFile(const std::string& fileName); + + /** + * Close the output log file, if it is open. + */ + void closeFile(); + + /** + * Return true if an output log file is open, false otherwise. + * For some reason, std::fstream::is_open() is not const. + */ + inline bool isOpen() { return (logFile && outFile.is_open()); } + + /** + * Use this method to specify which stream to which + * to log messages. Specifying NULL will stop all + * output logging to any stream (except for the output file, + * if it exists). + */ + inline void setStream(std::ostream* newStream) { outStream = newStream; } + + /** + * Get the stream to which to log messages. + */ + + inline std::ostream* getStream() { return outStream; } + + /* + * Get local time in [hh:mm:ss] format + */ + std::string getLocalTime(); + + /** + * Output the endl function. + */ + ELog& operator<<(__E_omanip func); + + /** + * Output the endl function. + */ + ELog& operator<<(__E_manip func); + + /** + * Output any other type supported by std::ostream. + */ + template ELog& operator<<(const T& var) { + if (logFile) { + if (newline) + outFile << getLocalTime() << var; + else + outFile << var; + } + if (outStream) { + if (newline) + *outStream << getLocalTime() << var; + else + *outStream << var; + } + newline = false; + return *this; + } +}; /// The global logging instance. -extern ELog elog ; +extern ELog elog; } // namespace gnuworld diff --git a/libgnuworld/MTrie.cc b/libgnuworld/MTrie.cc old mode 100755 new mode 100644 index ebf74dcf..6d4a845e --- a/libgnuworld/MTrie.cc +++ b/libgnuworld/MTrie.cc @@ -20,767 +20,638 @@ * $Id: MTrie.cc,v 1.14 2004/05/18 16:50:57 dan_karrels Exp $ */ -#include -#include -#include -#include +#include +#include +#include +#include -#include +#include -#include "MTrie.h" -#include "StringTokenizer.h" -#include "match.h" +#include "MTrie.h" +#include "StringTokenizer.h" +#include "match.h" // TODO: allow comparison functor (case insensitive) -using std::map ; -using std::clog ; -using std::endl ; -using std::list ; -using std::string ; -using std::ostream ; -using gnuworld::StringTokenizer ; - -template< typename _valueT > -MTrie< _valueT >::MTrie( const char delimiter ) - : numElements( 0 ), - parent( 0 ), - delimiter( delimiter ) -{} - -template< typename _valueT > -MTrie< _valueT >::~MTrie() -{ -for( nodes_iterator itr = nodesMap.begin() ; - itr != nodesMap.end() ; ++itr ) - { - delete itr->second ; - } -nodesMap.clear() ; +using gnuworld::StringTokenizer; +using std::clog; +using std::endl; +using std::list; +using std::map; +using std::ostream; +using std::string; + +template +MTrie<_valueT>::MTrie(const char delimiter) : numElements(0), parent(0), delimiter(delimiter) {} + +template MTrie<_valueT>::~MTrie() { + for (nodes_iterator itr = nodesMap.begin(); itr != nodesMap.end(); ++itr) { + delete itr->second; + } + nodesMap.clear(); } -template< typename _valueT > -bool MTrie< _valueT >::insert( const string& key, const _valueT& value ) -{ -// Ensure there are no wildcard characters in the key. -if( key.find( '*' ) != string::npos ) - { -// clog << "MTrie::insert> Found \'*\' in key: " -// << key -// << endl ; - return false ; - } - -if( key.find( '?' ) != string::npos ) - { -// clog << "MTrie::insert> Found \'?\' in key: " -// << key -// << endl ; - return false ; - } - -// Tokenize the key -// The key is of the form "www.yahoo.com" or "ns1.switch.abc.net" -StringTokenizer st( key, delimiter ) ; - -MTrie< _valueT >* currentNode = this ; - -// The purpose of this loop is to iterate to the level in which -// to place the new item. -// The proper level is found when the tokenItr is no longer valid, -// i.e., an empty token is found (works for top level also). -for( StringTokenizer::const_reverse_iterator tokenItr = st.rbegin() ; - tokenItr != st.rend() ; ++tokenItr ) - { - if( currentNode->nodesMap.find( *tokenItr ) == - currentNode->nodesMap.end() ) - { - // This node does not exist - MTrie< _valueT >* newNode = - new (std::nothrow) MTrie< _valueT > ; - assert( newNode != 0 ) ; - - currentNode->nodesMap[ *tokenItr ] = newNode ; - newNode->parent = currentNode ; - -// clog << "MTrie::insert> Added node for key: " -// << *tokenItr -// << endl ; - - currentNode = newNode ; - } - else - { - currentNode = currentNode->nodesMap[ *tokenItr ] ; - } - } - -// currentNode now points to the level at which to add this item -currentNode->valuesList.push_back( value ) ; - -//clog << "MTrie::insert> Added key: " -// << key -// << endl ; - -++numElements ; -return true ; +template bool MTrie<_valueT>::insert(const string& key, const _valueT& value) { + // Ensure there are no wildcard characters in the key. + if (key.find('*') != string::npos) { + // clog << "MTrie::insert> Found \'*\' in key: " + // << key + // << endl ; + return false; + } + + if (key.find('?') != string::npos) { + // clog << "MTrie::insert> Found \'?\' in key: " + // << key + // << endl ; + return false; + } + + // Tokenize the key + // The key is of the form "www.yahoo.com" or "ns1.switch.abc.net" + StringTokenizer st(key, delimiter); + + MTrie<_valueT>* currentNode = this; + + // The purpose of this loop is to iterate to the level in which + // to place the new item. + // The proper level is found when the tokenItr is no longer valid, + // i.e., an empty token is found (works for top level also). + for (StringTokenizer::const_reverse_iterator tokenItr = st.rbegin(); tokenItr != st.rend(); + ++tokenItr) { + if (currentNode->nodesMap.find(*tokenItr) == currentNode->nodesMap.end()) { + // This node does not exist + MTrie<_valueT>* newNode = new (std::nothrow) MTrie<_valueT>; + assert(newNode != 0); + + currentNode->nodesMap[*tokenItr] = newNode; + newNode->parent = currentNode; + + // clog << "MTrie::insert> Added node for key: " + // << *tokenItr + // << endl ; + + currentNode = newNode; + } else { + currentNode = currentNode->nodesMap[*tokenItr]; + } + } + + // currentNode now points to the level at which to add this item + currentNode->valuesList.push_back(value); + + // clog << "MTrie::insert> Added key: " + // << key + // << endl ; + + ++numElements; + return true; } -template< typename _valueT > -list< typename MTrie< _valueT >::value_type > -MTrie< _valueT >::find( const string& key ) const -{ -//clog << "MTrie::find> Searching for key: " -// << key -// << endl ; - -// base tracks the keys used to iterate to the different levels. -// It is used when matching for '*', since '*' may cross -// levels. -base.clear() ; -returnMe.clear() ; -origKey = key ; - -StringTokenizer tokens( key, delimiter ) ; -StringTokenizer::const_reverse_iterator tokenItr = tokens.rbegin() ; - -// key may have wildcards, which is trickier than it may sound. -// A key may be "w*w.yahoo.com" which matches to both -// "www.yahoo.com" and "www.wwwww.yahoo.com" -// The recursive find will handle all cases of '?', '*', and -// normal non-wildcard keys. -find( this, tokens, tokenItr ) ; - -return returnMe ; +template +list::value_type> MTrie<_valueT>::find(const string& key) const { + // clog << "MTrie::find> Searching for key: " + // << key + // << endl ; + + // base tracks the keys used to iterate to the different levels. + // It is used when matching for '*', since '*' may cross + // levels. + base.clear(); + returnMe.clear(); + origKey = key; + + StringTokenizer tokens(key, delimiter); + StringTokenizer::const_reverse_iterator tokenItr = tokens.rbegin(); + + // key may have wildcards, which is trickier than it may sound. + // A key may be "w*w.yahoo.com" which matches to both + // "www.yahoo.com" and "www.wwwww.yahoo.com" + // The recursive find will handle all cases of '?', '*', and + // normal non-wildcard keys. + find(this, tokens, tokenItr); + + return returnMe; } -template< typename _valueT > -void MTrie< _valueT >::find( - const MTrie< _valueT >* currentNode, - const StringTokenizer& tokens, - StringTokenizer::const_reverse_iterator tokenItr ) const -{ -// If the key is empty, that means that we have reached the -// final node. All values at this node are matches. -// This happens when the left most token has a '?' in it: -// "n?ws.abs.net" -if( tokenItr == tokens.rend() ) - { -// clog << "MTrie::find> Found end of tokens, numValues: " -// << currentNode->valuesList.size() -// << endl ; - - for( const_values_iterator vItr = currentNode->valuesList.begin(), - vEndItr = currentNode->valuesList.end() ; - vItr != vEndItr ; ++vItr ) - { - returnMe.push_back( value_type( getBase(), *vItr ) ) ; - } - return ; - } - -//clog << "MTrie::find> tokens: " -// << tokens -// << ", tokenItr: " -// << *tokenItr -// << endl ; - -bool foundQuestionMark = false ; - -// Iterate as far as possible -for( ; tokenItr != tokens.rend() ; ++tokenItr ) - { - if( string::npos != (*tokenItr).find( '*' ) ) - { - // Wildcard - break ; - } - - // Make sure this is after the search for '*' - if( string::npos != (*tokenItr).find( '?') ) - { -// clog << "MTrie::find> Found question mark in token: " -// << *tokenItr -// << endl ; - foundQuestionMark = true ; - break ; - } - - // No wildcard, continue to next level - const_nodes_iterator nItr = currentNode->nodesMap.find( *tokenItr ) ; - if( currentNode->nodesMap.end() == nItr ) - { - // This node does not exist - -// clog << "MTrie::find> Unable to find key: " -// << key -// << endl ; - - return ; - } - currentNode = nItr->second ; - - // Add to base - base.push_front( *tokenItr ) ; - } // for( tokenItr ) - -if( tokenItr == tokens.rend() ) - { - // We are at a matching node - for( const_values_iterator vItr = currentNode->valuesList.begin(), - vEndItr = currentNode->valuesList.end() ; - vItr != vEndItr ; ++vItr ) - { - returnMe.push_back( value_type( getBase(), *vItr ) ) ; - } - return ; - } - -//clog << "MTrie::find> *tokenItr: " -// << *tokenItr -// << endl ; - -// Because of the precondition, the only way to exit the above -// loop is by finding a wildcard, tokenItr must be valid -// tokenItr now points to a token of the form "w*w" or "*w*w*" -// We can prevent some unnecessary searching by creating a -// search token with as many real characters as possible. -// In the above cases, it would be "w" and "*", respectively. -// That is, if we are searching for "w*w", there is no reason -// to recursively check the currentNode's nodesMap element whose -// key is "moo". -// Construct the most known token. -string localKey( *tokenItr ) ; - -//clog << "MTrie::find> localKey: " -// << localKey -// << endl ; - -// Move to the next token for calls to find() -++tokenItr ; - -// This variable is true if the localKey determined below -// is '*' alone. -bool loneStar = false ; - -// Prepare localKey if a '*' was found -if( !foundQuestionMark ) - { - // '*' was found in localKey - - // localKey starts out as "n*ws" - // Setup localKey to "*ws" - // In the case of a key like "*adsl*", there is no - // sense in trimming down localKey just to perform - // a match(), since all nodes match. - - // starPos is the index of the right-most '*' - const string::size_type starPos = localKey.rfind( '*' ) ; - - if( starPos == (localKey.size() - 1) ) - { - // The '*' is the right-most character, "*adsl*" -// cout << "find> Found lonestar" -// << endl ; - loneStar = true ; - } - else - { - // Not a generic '*' search, it's the case of "n*ws" - // Trim localKey to look like "*ws" - localKey.erase( 0, starPos ) ; - } - } // if( !foundQuestionMark ) - -// Everything is set, begin recursion -// Match localKey against all nodes -for( const_nodes_iterator nItr = currentNode->nodesMap.begin(), - nEndItr = currentNode->nodesMap.end() ; - nItr != nEndItr ; ++nItr ) - { -// clog << "MTrie::find> match( " -// << localKey -// << ", " -// << nItr->first -// << " ): " ; - - if( foundQuestionMark ) - { - if( !gnuworld::match( localKey, nItr->first ) ) - { -// clog << "true" << endl ; - base.push_front( nItr->first ) ; - - // Question mark only, no '*' in the token. - find( nItr->second, - tokens, - tokenItr ) ; - - base.pop_front() ; - } -// else -// { -// clog << "false" << endl ; -// } - continue ; - } - - // '*' - if( loneStar ) - { - /* NO-OP, fall through, all nodes match */ - } - else if( gnuworld::match( localKey, nItr->first ) ) - { - // Not a match, do not recursiveFind() on this node - continue ; - } - -// clog << "true" << endl ; - - base.push_front( nItr->first ) ; - recursiveFind( nItr->second ) ; - base.pop_front() ; - } // for( nItr ) +template +void MTrie<_valueT>::find(const MTrie<_valueT>* currentNode, const StringTokenizer& tokens, + StringTokenizer::const_reverse_iterator tokenItr) const { + // If the key is empty, that means that we have reached the + // final node. All values at this node are matches. + // This happens when the left most token has a '?' in it: + // "n?ws.abs.net" + if (tokenItr == tokens.rend()) { + // clog << "MTrie::find> Found end of tokens, numValues: " + // << currentNode->valuesList.size() + // << endl ; + + for (const_values_iterator vItr = currentNode->valuesList.begin(), + vEndItr = currentNode->valuesList.end(); + vItr != vEndItr; ++vItr) { + returnMe.push_back(value_type(getBase(), *vItr)); + } + return; + } + + // clog << "MTrie::find> tokens: " + // << tokens + // << ", tokenItr: " + // << *tokenItr + // << endl ; + + bool foundQuestionMark = false; + + // Iterate as far as possible + for (; tokenItr != tokens.rend(); ++tokenItr) { + if (string::npos != (*tokenItr).find('*')) { + // Wildcard + break; + } + + // Make sure this is after the search for '*' + if (string::npos != (*tokenItr).find('?')) { + // clog << "MTrie::find> Found question mark in token: " + // << *tokenItr + // << endl ; + foundQuestionMark = true; + break; + } + + // No wildcard, continue to next level + const_nodes_iterator nItr = currentNode->nodesMap.find(*tokenItr); + if (currentNode->nodesMap.end() == nItr) { + // This node does not exist + + // clog << "MTrie::find> Unable to find key: " + // << key + // << endl ; + + return; + } + currentNode = nItr->second; + + // Add to base + base.push_front(*tokenItr); + } // for( tokenItr ) + + if (tokenItr == tokens.rend()) { + // We are at a matching node + for (const_values_iterator vItr = currentNode->valuesList.begin(), + vEndItr = currentNode->valuesList.end(); + vItr != vEndItr; ++vItr) { + returnMe.push_back(value_type(getBase(), *vItr)); + } + return; + } + + // clog << "MTrie::find> *tokenItr: " + // << *tokenItr + // << endl ; + + // Because of the precondition, the only way to exit the above + // loop is by finding a wildcard, tokenItr must be valid + // tokenItr now points to a token of the form "w*w" or "*w*w*" + // We can prevent some unnecessary searching by creating a + // search token with as many real characters as possible. + // In the above cases, it would be "w" and "*", respectively. + // That is, if we are searching for "w*w", there is no reason + // to recursively check the currentNode's nodesMap element whose + // key is "moo". + // Construct the most known token. + string localKey(*tokenItr); + + // clog << "MTrie::find> localKey: " + // << localKey + // << endl ; + + // Move to the next token for calls to find() + ++tokenItr; + + // This variable is true if the localKey determined below + // is '*' alone. + bool loneStar = false; + + // Prepare localKey if a '*' was found + if (!foundQuestionMark) { + // '*' was found in localKey + + // localKey starts out as "n*ws" + // Setup localKey to "*ws" + // In the case of a key like "*adsl*", there is no + // sense in trimming down localKey just to perform + // a match(), since all nodes match. + + // starPos is the index of the right-most '*' + const string::size_type starPos = localKey.rfind('*'); + + if (starPos == (localKey.size() - 1)) { + // The '*' is the right-most character, "*adsl*" + // cout << "find> Found lonestar" + // << endl ; + loneStar = true; + } else { + // Not a generic '*' search, it's the case of "n*ws" + // Trim localKey to look like "*ws" + localKey.erase(0, starPos); + } + } // if( !foundQuestionMark ) + + // Everything is set, begin recursion + // Match localKey against all nodes + for (const_nodes_iterator nItr = currentNode->nodesMap.begin(), + nEndItr = currentNode->nodesMap.end(); + nItr != nEndItr; ++nItr) { + // clog << "MTrie::find> match( " + // << localKey + // << ", " + // << nItr->first + // << " ): " ; + + if (foundQuestionMark) { + if (!gnuworld::match(localKey, nItr->first)) { + // clog << "true" << endl ; + base.push_front(nItr->first); + + // Question mark only, no '*' in the token. + find(nItr->second, tokens, tokenItr); + + base.pop_front(); + } + // else + // { + // clog << "false" << endl ; + // } + continue; + } + + // '*' + if (loneStar) { + /* NO-OP, fall through, all nodes match */ + } else if (gnuworld::match(localKey, nItr->first)) { + // Not a match, do not recursiveFind() on this node + continue; + } + + // clog << "true" << endl ; + + base.push_front(nItr->first); + recursiveFind(nItr->second); + base.pop_front(); + } // for( nItr ) } -template< typename _valueT > -void MTrie< _valueT >::recursiveFind( - const MTrie< _valueT >* currentNode, - bool blindRecursion ) const -{ -// blindRecursion: -// If we encounter a '*' as the first character of origKey (the original -// search string), and the current node matches that key, then by -// definition all nodes under the current node must also match. -// In this case, use a "blind recursion," simply adding all values -// under this node without performing a match() on any of them. - -//clog << "MTrie::recursiveFind> key: " -// << origKey -// << ", base: " -// << getBase() -// << endl ; - -// '*' -// No need to create a new string and perform a match -// if this node has no values -if( !currentNode->valuesList.empty() ) - { - // We need the stringBase either way - string stringBase = getBase() ; - - if( blindRecursion || !gnuworld::match( origKey, stringBase ) ) - { - // clog << "MTrie::recursiveFind> match" - // << endl ; - - if( !blindRecursion && '*' == origKey[ 0 ] ) - { - // Found a match starting at this node - blindRecursion = true ; - } - - // This node matches - for( const_values_iterator vItr = - currentNode->valuesList.begin(), - vEndItr = currentNode->valuesList.end() ; - vItr != vEndItr ; ++vItr ) - { - // clog << "MTrie::recursiveFind> vItr: " - // << *vItr - // << endl ; - value_type addMe( stringBase, *vItr ) ; - returnMe.push_back( addMe ) ; - } // for( vItr ) - } // if( !match() ) - } // if( !empty() ) - -for( const_nodes_iterator nItr = currentNode->nodesMap.begin(), - nEndItr = currentNode->nodesMap.end() ; - nItr != nEndItr ; ++nItr ) - { - // match() is not important here, since we are doing - // a blind '*' search, check every node from here down - base.push_front( nItr->first ) ; - recursiveFind( nItr->second, blindRecursion ) ; - base.pop_front() ; - } // for( nItr ) +template +void MTrie<_valueT>::recursiveFind(const MTrie<_valueT>* currentNode, bool blindRecursion) const { + // blindRecursion: + // If we encounter a '*' as the first character of origKey (the original + // search string), and the current node matches that key, then by + // definition all nodes under the current node must also match. + // In this case, use a "blind recursion," simply adding all values + // under this node without performing a match() on any of them. + + // clog << "MTrie::recursiveFind> key: " + // << origKey + // << ", base: " + // << getBase() + // << endl ; + + // '*' + // No need to create a new string and perform a match + // if this node has no values + if (!currentNode->valuesList.empty()) { + // We need the stringBase either way + string stringBase = getBase(); + + if (blindRecursion || !gnuworld::match(origKey, stringBase)) { + // clog << "MTrie::recursiveFind> match" + // << endl ; + + if (!blindRecursion && '*' == origKey[0]) { + // Found a match starting at this node + blindRecursion = true; + } + + // This node matches + for (const_values_iterator vItr = currentNode->valuesList.begin(), + vEndItr = currentNode->valuesList.end(); + vItr != vEndItr; ++vItr) { + // clog << "MTrie::recursiveFind> vItr: " + // << *vItr + // << endl ; + value_type addMe(stringBase, *vItr); + returnMe.push_back(addMe); + } // for( vItr ) + } // if( !match() ) + } // if( !empty() ) + + for (const_nodes_iterator nItr = currentNode->nodesMap.begin(), + nEndItr = currentNode->nodesMap.end(); + nItr != nEndItr; ++nItr) { + // match() is not important here, since we are doing + // a blind '*' search, check every node from here down + base.push_front(nItr->first); + recursiveFind(nItr->second, blindRecursion); + base.pop_front(); + } // for( nItr ) } -template< typename _valueT > -string MTrie< _valueT >::getBase() const -{ -string retMe ; -retMe.reserve( 128 ) ; -bool doneALoop = false ; - -for( list< string >::const_iterator rtItr = base.begin(), - rtEndItr = base.end() ; rtItr != rtEndItr ; ++rtItr ) - { - if( doneALoop ) - { - retMe += delimiter ; - } - retMe += *rtItr ; - doneALoop = true ; - } -return retMe ; +template string MTrie<_valueT>::getBase() const { + string retMe; + retMe.reserve(128); + bool doneALoop = false; + + for (list::const_iterator rtItr = base.begin(), rtEndItr = base.end(); + rtItr != rtEndItr; ++rtItr) { + if (doneALoop) { + retMe += delimiter; + } + retMe += *rtItr; + doneALoop = true; + } + return retMe; } -template< typename _valueT > -typename MTrie< _valueT >::size_type -MTrie< _valueT >::erase( const string& key ) -{ -//clog << "MTrie::erase> Erasing key: " -// << key -// << endl ; +template +typename MTrie<_valueT>::size_type MTrie<_valueT>::erase(const string& key) { + // clog << "MTrie::erase> Erasing key: " + // << key + // << endl ; -// key may have wildcards, which is trickier than it may sound. -// A key may be "w*w.yahoo.com" which matches to both -// "www.yahoo.com" and "www.wwwww.yahoo.com" + // key may have wildcards, which is trickier than it may sound. + // A key may be "w*w.yahoo.com" which matches to both + // "www.yahoo.com" and "www.wwwww.yahoo.com" -list< string > base ; -return erase( this, base, key, key ) ; + list base; + return erase(this, base, key, key); } -template< typename _valueT > -typename MTrie< _valueT >::size_type -MTrie< _valueT >::erase( - MTrie< _valueT >* currentNode, - list< string >& base, - const string& origKey, - const string& key ) -{ -size_type eraseCount = 0 ; -if( key.empty() ) - { - // Everything on this level is a match - eraseCount = currentNode->valuesList.size() ; - currentNode->valuesList.clear() ; - - return eraseCount ; - } - -//clog << "MTrie::erase> Erasing key: " -// << key -// << endl ; - -StringTokenizer tokens( key, delimiter ) ; -StringTokenizer::const_reverse_iterator tokenItr = tokens.rbegin() ; - -bool foundQuestionMark = false ; - -// Iterate as far as possible before beginning wild card match() -// searches. -for( ; tokenItr != tokens.rend() ; ++tokenItr ) - { - if( string::npos != (*tokenItr).find( '*' ) ) - { - // Wildcard - break ; - } - - // Make sure this is after the search for '*' - if( string::npos != (*tokenItr).find( '?') ) - { - foundQuestionMark = true ; - break ; - } - - // No wildcard, continue to next level - nodes_iterator nItr = currentNode->nodesMap.find( *tokenItr ) ; - if( currentNode->nodesMap.end() == nItr ) - { - // This node does not exist - // Since we are not at the last token, - // this key does not exist -// clog << "MTrie::erase> Unable to find key: " -// << key -// << endl ; - - return 0 ; - } - currentNode = nItr->second ; - - // Add to base - base.push_front( *tokenItr ) ; - } // for( tokenItr ) - -if( tokenItr == tokens.rend() ) - { - // Everything on this level is a match - eraseCount = currentNode->valuesList.size() ; - currentNode->valuesList.clear() ; - - return eraseCount ; - } - -//clog << "MTrie::erase> *tokenItr: " -// << *tokenItr -// << endl ; - -// Because of the precondition, the only way to exit the above -// loop is by finding a wildcard, tokenItr must be valid -// tokenItr now points to a token of the form "w*w" or "*w*w*" -// We can prevent some unnecessary searching by creating a -// search token with as many real characters as possible. -// In the above cases, it would be "w" and "*", respectively. -// That is, if we are searching for "w*w", there is no reason -// to recursively check the currentNode's nodesMap element whose -// key is "moo". -// Construct the most known token. -string localKey( *tokenItr ) ; - -// starPos is the index of the '*' -string::size_type starPos = localKey.rfind( '*' ) ; - -// Here we must: -// setup localKey to be the star and everything to its right -// setup the rest of the string to be everything left of -// and including the star - -if( !foundQuestionMark ) - { - // localKey starts out as "n*ws" - // Setup localKey to "*ws" - localKey.erase( 0, starPos ) ; - } - -//clog << "MTrie::erase> starPos: " -// << starPos -// << ", localKey: " -// << localKey -// << ", base: " -// << getBase() -// << endl ; - -// Everything is set, begin recursion -// Match localKey against all nodes -for( nodes_iterator nItr = currentNode->nodesMap.begin() ; - nItr != currentNode->nodesMap.end() ; ++nItr ) - { -// clog << "MTrie::erase> match( " -// << localKey -// << ", " -// << nItr->first -// << " ): " ; - - if( gnuworld::match( localKey, nItr->first ) ) - { -// clog << "false" << endl ; - continue ; - } - -// clog << "true" << endl ; - - base.push_front( nItr->first ) ; - if( foundQuestionMark ) - { - // Question mark only, no '*' in the - // token - // Reassemble the key - string newKey ; - for( ++tokenItr; tokenItr != tokens.rend() ; - ++tokenItr ) - { - if( !newKey.empty() ) - { - newKey.insert( newKey.begin(), - delimiter ) ; - } - newKey.insert( 0, *tokenItr ) ; - } - -// clog << "MTrie::erase> (?) newKey: " -// << newKey -// << endl ; - - eraseCount += erase( nItr->second, - base, - origKey, - newKey ) ; - } - else - { - eraseCount += recursiveErase( nItr->second, // MTrie* - base, - origKey ) ; - } // if( questionMarkFound ) - base.pop_front() ; - - if( currentNode->valuesList.empty() && - currentNode->nodesMap.empty() ) - { -// clog << "MTrie::erase> Erasing empty node" -// << endl ; - - // This does NOT invalidate the iterator - delete nItr->second ; - currentNode->nodesMap.erase( nItr ) ; - } - } // for( nItr ) -return eraseCount ; +template +typename MTrie<_valueT>::size_type MTrie<_valueT>::erase(MTrie<_valueT>* currentNode, + list& base, const string& origKey, + const string& key) { + size_type eraseCount = 0; + if (key.empty()) { + // Everything on this level is a match + eraseCount = currentNode->valuesList.size(); + currentNode->valuesList.clear(); + + return eraseCount; + } + + // clog << "MTrie::erase> Erasing key: " + // << key + // << endl ; + + StringTokenizer tokens(key, delimiter); + StringTokenizer::const_reverse_iterator tokenItr = tokens.rbegin(); + + bool foundQuestionMark = false; + + // Iterate as far as possible before beginning wild card match() + // searches. + for (; tokenItr != tokens.rend(); ++tokenItr) { + if (string::npos != (*tokenItr).find('*')) { + // Wildcard + break; + } + + // Make sure this is after the search for '*' + if (string::npos != (*tokenItr).find('?')) { + foundQuestionMark = true; + break; + } + + // No wildcard, continue to next level + nodes_iterator nItr = currentNode->nodesMap.find(*tokenItr); + if (currentNode->nodesMap.end() == nItr) { + // This node does not exist + // Since we are not at the last token, + // this key does not exist + // clog << "MTrie::erase> Unable to find key: " + // << key + // << endl ; + + return 0; + } + currentNode = nItr->second; + + // Add to base + base.push_front(*tokenItr); + } // for( tokenItr ) + + if (tokenItr == tokens.rend()) { + // Everything on this level is a match + eraseCount = currentNode->valuesList.size(); + currentNode->valuesList.clear(); + + return eraseCount; + } + + // clog << "MTrie::erase> *tokenItr: " + // << *tokenItr + // << endl ; + + // Because of the precondition, the only way to exit the above + // loop is by finding a wildcard, tokenItr must be valid + // tokenItr now points to a token of the form "w*w" or "*w*w*" + // We can prevent some unnecessary searching by creating a + // search token with as many real characters as possible. + // In the above cases, it would be "w" and "*", respectively. + // That is, if we are searching for "w*w", there is no reason + // to recursively check the currentNode's nodesMap element whose + // key is "moo". + // Construct the most known token. + string localKey(*tokenItr); + + // starPos is the index of the '*' + string::size_type starPos = localKey.rfind('*'); + + // Here we must: + // setup localKey to be the star and everything to its right + // setup the rest of the string to be everything left of + // and including the star + + if (!foundQuestionMark) { + // localKey starts out as "n*ws" + // Setup localKey to "*ws" + localKey.erase(0, starPos); + } + + // clog << "MTrie::erase> starPos: " + // << starPos + // << ", localKey: " + // << localKey + // << ", base: " + // << getBase() + // << endl ; + + // Everything is set, begin recursion + // Match localKey against all nodes + for (nodes_iterator nItr = currentNode->nodesMap.begin(); nItr != currentNode->nodesMap.end(); + ++nItr) { + // clog << "MTrie::erase> match( " + // << localKey + // << ", " + // << nItr->first + // << " ): " ; + + if (gnuworld::match(localKey, nItr->first)) { + // clog << "false" << endl ; + continue; + } + + // clog << "true" << endl ; + + base.push_front(nItr->first); + if (foundQuestionMark) { + // Question mark only, no '*' in the + // token + // Reassemble the key + string newKey; + for (++tokenItr; tokenItr != tokens.rend(); ++tokenItr) { + if (!newKey.empty()) { + newKey.insert(newKey.begin(), delimiter); + } + newKey.insert(0, *tokenItr); + } + + // clog << "MTrie::erase> (?) newKey: " + // << newKey + // << endl ; + + eraseCount += erase(nItr->second, base, origKey, newKey); + } else { + eraseCount += recursiveErase(nItr->second, // MTrie* + base, origKey); + } // if( questionMarkFound ) + base.pop_front(); + + if (currentNode->valuesList.empty() && currentNode->nodesMap.empty()) { + // clog << "MTrie::erase> Erasing empty node" + // << endl ; + + // This does NOT invalidate the iterator + delete nItr->second; + currentNode->nodesMap.erase(nItr); + } + } // for( nItr ) + return eraseCount; } -template< typename _valueT > -typename MTrie< _valueT >::size_type -MTrie< _valueT >::recursiveErase( - MTrie< _valueT >* currentNode, - list< string >& base, - const string& key ) -{ -//clog << "MTrie::recursiveErase(*)> base: " -// << getBase() -// << ", key: " -// << key -// << endl ; - -size_type eraseCount = 0 ; - -// '*' -string stringBase = getBase() ; -if( !gnuworld::match( key, stringBase ) ) - { - // This node matches - eraseCount = currentNode->valuesList.size() ; - currentNode->valuesList.clear() ; - } // if( !match() ) - -for( nodes_iterator nItr = currentNode->nodesMap.begin() ; - nItr != currentNode->nodesMap.end() ; ++nItr ) - { - // match() is not important here, since we are doing - // a blind '*' search, check every node from here down - base.push_front( nItr->first ) ; - eraseCount += recursiveErase( nItr->second, // MTrie* - base, - key ) ; - base.pop_front() ; - - if( currentNode->valuesList.empty() && - currentNode->nodesMap.empty() ) - { -// clog << "MTrie::recursiveErase> Erasing empty node" -// << endl ; - - // This does NOT invalidate the iterator - delete nItr->second ; - currentNode->nodesMap.erase( nItr ) ; - } - } // for( nItr ) -return eraseCount ; +template +typename MTrie<_valueT>::size_type +MTrie<_valueT>::recursiveErase(MTrie<_valueT>* currentNode, list& base, const string& key) { + // clog << "MTrie::recursiveErase(*)> base: " + // << getBase() + // << ", key: " + // << key + // << endl ; + + size_type eraseCount = 0; + + // '*' + string stringBase = getBase(); + if (!gnuworld::match(key, stringBase)) { + // This node matches + eraseCount = currentNode->valuesList.size(); + currentNode->valuesList.clear(); + } // if( !match() ) + + for (nodes_iterator nItr = currentNode->nodesMap.begin(); nItr != currentNode->nodesMap.end(); + ++nItr) { + // match() is not important here, since we are doing + // a blind '*' search, check every node from here down + base.push_front(nItr->first); + eraseCount += recursiveErase(nItr->second, // MTrie* + base, key); + base.pop_front(); + + if (currentNode->valuesList.empty() && currentNode->nodesMap.empty()) { + // clog << "MTrie::recursiveErase> Erasing empty node" + // << endl ; + + // This does NOT invalidate the iterator + delete nItr->second; + currentNode->nodesMap.erase(nItr); + } + } // for( nItr ) + return eraseCount; } -template< typename _valueT > -void MTrie< _valueT >::dumpDebug( ostream& out ) const -{ -recursiveDebug( out, 1, this ) ; +template void MTrie<_valueT>::dumpDebug(ostream& out) const { + recursiveDebug(out, 1, this); } -template< typename _valueT > -void MTrie< _valueT >::recursiveDebug( ostream& out, - size_t levelNum, - const MTrie< _valueT >* currentNode ) const -{ -for( const_nodes_iterator nItr = currentNode->nodesMap.begin() ; - nItr != currentNode->nodesMap.end() ; ++nItr ) - { - recursiveDebug( out, levelNum + 1, nItr->second ) ; - } -out << levelNum << ' ' - << currentNode->nodesMap.size() << ' ' - << currentNode->valuesList.size() << ' ' - << endl ; +template +void MTrie<_valueT>::recursiveDebug(ostream& out, size_t levelNum, + const MTrie<_valueT>* currentNode) const { + for (const_nodes_iterator nItr = currentNode->nodesMap.begin(); + nItr != currentNode->nodesMap.end(); ++nItr) { + recursiveDebug(out, levelNum + 1, nItr->second); + } + out << levelNum << ' ' << currentNode->nodesMap.size() << ' ' << currentNode->valuesList.size() + << ' ' << endl; } -template< typename _valueT > -void MTrie< _valueT >::levelDebug( ostream& out, size_t searchLevel ) - const -{ -out << "Searching for level " - << searchLevel - << endl ; -levelDebug( out, 0, searchLevel, this ) ; +template +void MTrie<_valueT>::levelDebug(ostream& out, size_t searchLevel) const { + out << "Searching for level " << searchLevel << endl; + levelDebug(out, 0, searchLevel, this); } -template< typename _valueT > -void MTrie< _valueT >::levelDebug( ostream& out, size_t currentLevel, - size_t searchLevel, const MTrie< _valueT >* currentNode ) const -{ -if( (currentLevel + 1) == searchLevel ) - { - // Next level is the winner - for( const_nodes_iterator nItr = currentNode->nodesMap.begin() ; - nItr != currentNode->nodesMap.end() ; ++nItr ) - { - out << "Key: " - << nItr->first - << ", number of values: " - << value_size( nItr->second ) - << endl ; - } - } -else - { - for( const_nodes_iterator nItr = currentNode->nodesMap.begin() ; - nItr != currentNode->nodesMap.end() ; ++nItr ) - { - levelDebug( out, currentLevel + 1, searchLevel, - currentNode ) ; - } - } +template +void MTrie<_valueT>::levelDebug(ostream& out, size_t currentLevel, size_t searchLevel, + const MTrie<_valueT>* currentNode) const { + if ((currentLevel + 1) == searchLevel) { + // Next level is the winner + for (const_nodes_iterator nItr = currentNode->nodesMap.begin(); + nItr != currentNode->nodesMap.end(); ++nItr) { + out << "Key: " << nItr->first << ", number of values: " << value_size(nItr->second) + << endl; + } + } else { + for (const_nodes_iterator nItr = currentNode->nodesMap.begin(); + nItr != currentNode->nodesMap.end(); ++nItr) { + levelDebug(out, currentLevel + 1, searchLevel, currentNode); + } + } } -template< typename _valueT > -size_t MTrie< _valueT >::value_size( const MTrie< _valueT >* currentNode ) - const -{ -size_t returnMe = currentNode->valuesList.size() ; -for( const_nodes_iterator nItr = currentNode->nodesMap.begin() ; - nItr != currentNode->nodesMap.end() ; ++nItr ) - { - returnMe += value_size( nItr->second ) ; - } -return returnMe ; +template +size_t MTrie<_valueT>::value_size(const MTrie<_valueT>* currentNode) const { + size_t returnMe = currentNode->valuesList.size(); + for (const_nodes_iterator nItr = currentNode->nodesMap.begin(); + nItr != currentNode->nodesMap.end(); ++nItr) { + returnMe += value_size(nItr->second); + } + return returnMe; } -template< typename _valueT > -list< string > -MTrie< _valueT >::findMinLength( size_t minLength ) const -{ -base.clear() ; -list< string > retMe ; +template list MTrie<_valueT>::findMinLength(size_t minLength) const { + base.clear(); + list retMe; -findMinLength( minLength, retMe, this ) ; + findMinLength(minLength, retMe, this); -return retMe ; + return retMe; } -template< typename _valueT > -void -MTrie< _valueT >::findMinLength( size_t minLength, - list< string >& retMe, - const MTrie< _valueT >* currentNode ) const -{ -if( (base.size() >= minLength) && !currentNode->valuesList.empty() ) - { - // We are at or past the min length, and this node - // has at least one value to add - // Only one entry into returnMe is necessary - retMe.push_back( getBase() ) ; - } -else - { - // Continue to all subnodes - for( const_nodes_iterator nItr = currentNode->nodesMap.begin() ; - nItr != currentNode->nodesMap.end() ; ++nItr ) - { - base.push_front( nItr->first ) ; - findMinLength( minLength, - retMe, - nItr->second ) ; - base.pop_front() ; - } - } +template +void MTrie<_valueT>::findMinLength(size_t minLength, list& retMe, + const MTrie<_valueT>* currentNode) const { + if ((base.size() >= minLength) && !currentNode->valuesList.empty()) { + // We are at or past the min length, and this node + // has at least one value to add + // Only one entry into returnMe is necessary + retMe.push_back(getBase()); + } else { + // Continue to all subnodes + for (const_nodes_iterator nItr = currentNode->nodesMap.begin(); + nItr != currentNode->nodesMap.end(); ++nItr) { + base.push_front(nItr->first); + findMinLength(minLength, retMe, nItr->second); + base.pop_front(); + } + } } diff --git a/libgnuworld/MTrie.h b/libgnuworld/MTrie.h old mode 100755 new mode 100644 index caa3bb92..99875ca5 --- a/libgnuworld/MTrie.h +++ b/libgnuworld/MTrie.h @@ -23,14 +23,14 @@ #ifndef __MTRIE_H #define __MTRIE_H -#include -#include -#include -#include +#include +#include +#include +#include -#include "StringTokenizer.h" +#include "StringTokenizer.h" -using gnuworld::StringTokenizer ; +using gnuworld::StringTokenizer; /** * This class is used to store elements keyed by a decimalized string, @@ -40,246 +40,229 @@ using gnuworld::StringTokenizer ; * For example, clients of this class can search for all elements * whose keys match 'ab*ef.foo.ba?.net'. */ -template< typename _valueT > -class MTrie -{ -public: - /** - * Initialize an MTrie. - */ - MTrie( const char delimiter = '.' ) ; - - /** - * Destructor will deallocate all internally allocated - * memory, but will not touch data stored here on behalf - * the client. - */ - virtual ~MTrie() ; - - /** - * The type being stored in this structure - */ - typedef _valueT data_type ; - - /** - * The key/value pair type - */ - typedef std::pair< std::string, _valueT > value_type ; - - /** - * The type used to represent the number of elements - * in this MTrie - */ - typedef size_t size_type ; - - /** - * Return the current number of elements being stored - * in this MTrie. - */ - inline size_type size() const - { return numElements ; } - - /** - * Insert a key/value pair. The key must NOT have any - * wildcard characters. - */ - bool insert( const std::string& key, const data_type& value ) ; - - /** - * Return a list of the key/value pairs that match the given - * wildcard key. The key may contain '?' and '*', but need - * not do so. In general, the most specific searches will - * be fastest. - */ - virtual std::list< value_type > find( const std::string& key ) const ; - - /** - * Remove all values associated with key's that match the given - * key. The key may have wildcards '?' and '*', and follow - * the same semantics as find(). Be sure to deallocate the - * values if necessary before calling erase(), this method will - * not deallocate the items stored in this structure. - * The number of elements erased is returned. - */ - virtual size_type erase( const std::string& key ) ; - - /** - * Produce output about for each node in the trie in the - * following format: - * - * This method is used for statistical analysis. - */ - virtual void dumpDebug( std::ostream& ) const ; - - /** - * Send the key of each node at the given level to the - * output stream. Also send the total number of values - * under each subtree at those nodes. - */ - virtual void levelDebug( std::ostream&, size_t searchLevel ) - const ; - - /** - * Return all keys that have at least as many tokens as - * minLength. - */ - virtual std::list< std::string > findMinLength( size_t minLength ) - const ; -protected: - - /** - * Recursive helper method to the public levelDebug() - */ - virtual void levelDebug( std::ostream&, size_t currentLevel, - size_t searchLevel, - const MTrie< data_type >* ) const ; - - /** - * Return the total number of values under the given node - */ - virtual size_t value_size( const MTrie< data_type >* ) const ; - - /** - * Recursive helper method to the public findMinLength() - */ - virtual void findMinLength( size_t minLength, - std::list< std::string >& retMe, - const MTrie< data_type >* ) const ; - - /** - * Recursive find method that handles all the hard work - * matching across multiple levels. - */ - virtual void find( const MTrie< data_type >*, - const StringTokenizer&, - StringTokenizer::const_reverse_iterator ) - const ; - - /** - * Recursive erase method that handles all the hard work - * matching across multiple levels. - */ - virtual size_type erase( MTrie< data_type >*, - std::list< std::string >&, - const std::string& origKey, - const std::string& key ) ; - - /** - * Convenience method that puts together a list of - * string tokens into a single string. - */ - std::string getBase() const ; - - /** - * Recursive method used only for searching for '*' matched - * strings. - */ - virtual void recursiveFind( const MTrie< data_type >*, - bool blindRecursion = false ) - const ; - - /** - * Recursive method used only for erasing '*' matched - * strings. - */ - virtual size_type recursiveErase( MTrie< data_type >*, - std::list< std::string >& base, - const std::string& key ) ; - - /** - * A recursive method used to output some debugging information. - */ - virtual void recursiveDebug( std::ostream&, - size_t levelNum, - const MTrie< data_type >* ) const ; - - /** - * The number of elements stored in this MTrie - */ - size_type numElements ; - - /** - * The parent node to this node (NULL if root) - */ - MTrie< data_type >* parent ; - - /** - * The string delimiter. - */ - char delimiter ; - - /** - * The type used to store values - */ - typedef std::list< data_type > valuesListType ; - - /** - * An iterator for iterating the valuesList - */ - typedef typename valuesListType::iterator values_iterator ; - - /** - * A const iterator for iterating the valuesList - */ - typedef typename valuesListType::const_iterator const_values_iterator ; - - /** - * The structure used to store values - */ - valuesListType valuesList ; - - /** - * The type used to store pointers to levels in the trie - */ - typedef std::map< std::string, MTrie< _valueT >* > nodesMapType ; - - /** - * An iterator to nodes in the trie - */ - typedef typename nodesMapType::iterator nodes_iterator ; - - /** - * A const iterator to nodes in the trie - */ - typedef typename nodesMapType::const_iterator const_nodes_iterator ; - - /** - * The structure used to store levels in the trie - */ - nodesMapType nodesMap ; - - /** - * This variable is used in find() and erase() to reduce the - * number of arguments passed to the internal recursive methods. - * It stores the current key associated with the node - * being examined. - */ - mutable std::list< std::string > base ; - - /** - * This variable is used in find() and erase() to reduce the - * number of arguments passed to the internal recursive methods. - * It stores the values to be returned from the methods. - */ - mutable std::list< value_type > returnMe ; - - /** - * This variable is used in find() and erase() to reduce the - * number of arguments passed to the internal recursive methods. - * It stores the key being searched for in the overall - * find/erase. - */ - mutable std::string origKey ; - - /** - * The tokens object used in find() and erase(). - */ - StringTokenizer tokens ; - -} ; +template class MTrie { + public: + /** + * Initialize an MTrie. + */ + MTrie(const char delimiter = '.'); + + /** + * Destructor will deallocate all internally allocated + * memory, but will not touch data stored here on behalf + * the client. + */ + virtual ~MTrie(); + + /** + * The type being stored in this structure + */ + typedef _valueT data_type; + + /** + * The key/value pair type + */ + typedef std::pair value_type; + + /** + * The type used to represent the number of elements + * in this MTrie + */ + typedef size_t size_type; + + /** + * Return the current number of elements being stored + * in this MTrie. + */ + inline size_type size() const { return numElements; } + + /** + * Insert a key/value pair. The key must NOT have any + * wildcard characters. + */ + bool insert(const std::string& key, const data_type& value); + + /** + * Return a list of the key/value pairs that match the given + * wildcard key. The key may contain '?' and '*', but need + * not do so. In general, the most specific searches will + * be fastest. + */ + virtual std::list find(const std::string& key) const; + + /** + * Remove all values associated with key's that match the given + * key. The key may have wildcards '?' and '*', and follow + * the same semantics as find(). Be sure to deallocate the + * values if necessary before calling erase(), this method will + * not deallocate the items stored in this structure. + * The number of elements erased is returned. + */ + virtual size_type erase(const std::string& key); + + /** + * Produce output about for each node in the trie in the + * following format: + * + * This method is used for statistical analysis. + */ + virtual void dumpDebug(std::ostream&) const; + + /** + * Send the key of each node at the given level to the + * output stream. Also send the total number of values + * under each subtree at those nodes. + */ + virtual void levelDebug(std::ostream&, size_t searchLevel) const; + + /** + * Return all keys that have at least as many tokens as + * minLength. + */ + virtual std::list findMinLength(size_t minLength) const; + + protected: + /** + * Recursive helper method to the public levelDebug() + */ + virtual void levelDebug(std::ostream&, size_t currentLevel, size_t searchLevel, + const MTrie*) const; + + /** + * Return the total number of values under the given node + */ + virtual size_t value_size(const MTrie*) const; + + /** + * Recursive helper method to the public findMinLength() + */ + virtual void findMinLength(size_t minLength, std::list& retMe, + const MTrie*) const; + + /** + * Recursive find method that handles all the hard work + * matching across multiple levels. + */ + virtual void find(const MTrie*, const StringTokenizer&, + StringTokenizer::const_reverse_iterator) const; + + /** + * Recursive erase method that handles all the hard work + * matching across multiple levels. + */ + virtual size_type erase(MTrie*, std::list&, const std::string& origKey, + const std::string& key); + + /** + * Convenience method that puts together a list of + * string tokens into a single string. + */ + std::string getBase() const; + + /** + * Recursive method used only for searching for '*' matched + * strings. + */ + virtual void recursiveFind(const MTrie*, bool blindRecursion = false) const; + + /** + * Recursive method used only for erasing '*' matched + * strings. + */ + virtual size_type recursiveErase(MTrie*, std::list& base, + const std::string& key); + + /** + * A recursive method used to output some debugging information. + */ + virtual void recursiveDebug(std::ostream&, size_t levelNum, const MTrie*) const; + + /** + * The number of elements stored in this MTrie + */ + size_type numElements; + + /** + * The parent node to this node (NULL if root) + */ + MTrie* parent; + + /** + * The string delimiter. + */ + char delimiter; + + /** + * The type used to store values + */ + typedef std::list valuesListType; + + /** + * An iterator for iterating the valuesList + */ + typedef typename valuesListType::iterator values_iterator; + + /** + * A const iterator for iterating the valuesList + */ + typedef typename valuesListType::const_iterator const_values_iterator; + + /** + * The structure used to store values + */ + valuesListType valuesList; + + /** + * The type used to store pointers to levels in the trie + */ + typedef std::map*> nodesMapType; + + /** + * An iterator to nodes in the trie + */ + typedef typename nodesMapType::iterator nodes_iterator; + + /** + * A const iterator to nodes in the trie + */ + typedef typename nodesMapType::const_iterator const_nodes_iterator; + + /** + * The structure used to store levels in the trie + */ + nodesMapType nodesMap; + + /** + * This variable is used in find() and erase() to reduce the + * number of arguments passed to the internal recursive methods. + * It stores the current key associated with the node + * being examined. + */ + mutable std::list base; + + /** + * This variable is used in find() and erase() to reduce the + * number of arguments passed to the internal recursive methods. + * It stores the values to be returned from the methods. + */ + mutable std::list returnMe; + + /** + * This variable is used in find() and erase() to reduce the + * number of arguments passed to the internal recursive methods. + * It stores the key being searched for in the overall + * find/erase. + */ + mutable std::string origKey; + + /** + * The tokens object used in find() and erase(). + */ + StringTokenizer tokens; +}; // This is a template class, cannot compile, so include the source // inline. #include "MTrie.cc" -#endif // __MTRIE_H +#endif // __MTRIE_H diff --git a/libgnuworld/Signal.cc b/libgnuworld/Signal.cc old mode 100755 new mode 100644 index ccd77e80..54b4b344 --- a/libgnuworld/Signal.cc +++ b/libgnuworld/Signal.cc @@ -21,172 +21,152 @@ * $Id: Signal.cc,v 1.11 2007/09/13 02:00:45 dan_karrels Exp $ */ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include -#include "Signal.h" -#include "ELog.h" +#include "Signal.h" +#include "ELog.h" - -namespace gnuworld -{ -using std::queue ; -using std::cout ; -using std::endl ; +namespace gnuworld { +using std::cout; +using std::endl; +using std::queue; // This will need to be changed to work properly in some code. -//Signal sig ; - -bool Signal::signalError = false ; -int Signal::readFD = -1 ; -int Signal::writeFD = -1 ; - -Signal* Signal::theInstance = 0 ; - -pthread_mutex_t Signal::singletonMutex = PTHREAD_MUTEX_INITIALIZER ; -pthread_mutex_t Signal::pipeMutex = PTHREAD_MUTEX_INITIALIZER ; - -Signal::Signal() -{ -// No need to initialize signalError here since it is only initialized -// directly above, and because this class models the Singleton -// pattern. -if( !openPipes() ) - { - elog << "Signal> Failed to open FIFO pipes" - << endl ; - // Failure to initialize pipes on startup is a critical - // failure. - ::exit( 0 ) ; - } +// Signal sig ; + +bool Signal::signalError = false; +int Signal::readFD = -1; +int Signal::writeFD = -1; + +Signal* Signal::theInstance = 0; + +pthread_mutex_t Signal::singletonMutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t Signal::pipeMutex = PTHREAD_MUTEX_INITIALIZER; + +Signal::Signal() { + // No need to initialize signalError here since it is only initialized + // directly above, and because this class models the Singleton + // pattern. + if (!openPipes()) { + elog << "Signal> Failed to open FIFO pipes" << endl; + // Failure to initialize pipes on startup is a critical + // failure. + ::exit(0); + } // Catch some signals #ifdef SIGINT - ::signal( SIGINT, AddSignal ) ; + ::signal(SIGINT, AddSignal); #endif #ifdef SIGHUP - ::signal( SIGHUP, AddSignal ) ; + ::signal(SIGHUP, AddSignal); #endif #ifdef SIGPIPE - ::signal( SIGPIPE, AddSignal ) ; + ::signal(SIGPIPE, AddSignal); #endif #ifdef SIGTERM - ::signal( SIGTERM, AddSignal ) ; + ::signal(SIGTERM, AddSignal); #endif #ifdef SIGPOLL - ::signal( SIGPOLL, AddSignal ) ; + ::signal(SIGPOLL, AddSignal); #endif #ifdef SIGUSR1 - ::signal( SIGUSR1, AddSignal ) ; + ::signal(SIGUSR1, AddSignal); #endif #ifdef SIGUSR2 - ::signal( SIGUSR2, AddSignal ) ; + ::signal(SIGUSR2, AddSignal); #endif } -Signal::~Signal() -{ -delete theInstance ; theInstance = 0 ; -closePipes() ; -::pthread_mutex_destroy( &singletonMutex ) ; -::pthread_mutex_destroy( &pipeMutex ) ; +Signal::~Signal() { + delete theInstance; + theInstance = 0; + closePipes(); + ::pthread_mutex_destroy(&singletonMutex); + ::pthread_mutex_destroy(&pipeMutex); } -bool Signal::isError() -{ -return ((-1 == readFD) || (-1 == writeFD) || signalError) ; -} +bool Signal::isError() { return ((-1 == readFD) || (-1 == writeFD) || signalError); } -void Signal::closePipes() -{ -::pthread_mutex_lock( &pipeMutex ) ; -::close( readFD ) ; -::close( writeFD ) ; -::pthread_mutex_unlock( &pipeMutex ) ; +void Signal::closePipes() { + ::pthread_mutex_lock(&pipeMutex); + ::close(readFD); + ::close(writeFD); + ::pthread_mutex_unlock(&pipeMutex); -signalError = true ; + signalError = true; } -bool Signal::openPipes() -{ -int rwFD[ 2 ] = { 0, 0 } ; - -// Create the pipe -::pthread_mutex_lock( &pipeMutex ) ; -int pipeRet = ::pipe( rwFD ) ; -::pthread_mutex_unlock( &pipeMutex ) ; - -if( pipeRet < 0 ) - { - elog << "Signal::openPipes> pipe() failed: " - << strerror( errno ) - << endl ; - - signalError = true ; - return false ; - } - -// Set the fd's to non-blocking -::pthread_mutex_lock( &pipeMutex ) ; - -for( size_t i = 0 ; i < 2 ; ++i ) - { - // Get current flags - int flags = ::fcntl( rwFD[ i ], F_GETFL ) ; - if( flags < 0 ) - { - ::pthread_mutex_unlock( &pipeMutex ) ; - elog << "Signal::openPipes> Failed to get flags " - << "for pipe fd: " - << strerror( errno ) - << endl ; - - closePipes() ; - return false ; - } - - // Update flags to indicate non-blocking - flags |= O_NONBLOCK ; - - // Set new flags - if( ::fcntl( rwFD[ i ], F_SETFL, flags ) < 0 ) - { - ::pthread_mutex_unlock( &pipeMutex ) ; - elog << "Signal::openPipes> Failed to set flags " - << "on pipe fd: " - << strerror( errno ) - << endl ; - - closePipes() ; - return false ; - } - } // for() - -// All is well -readFD = rwFD[ 0 ] ; -writeFD = rwFD[ 1 ] ; -::pthread_mutex_unlock( &pipeMutex ) ; - -signalError = false ; - -return true ; +bool Signal::openPipes() { + int rwFD[2] = {0, 0}; + + // Create the pipe + ::pthread_mutex_lock(&pipeMutex); + int pipeRet = ::pipe(rwFD); + ::pthread_mutex_unlock(&pipeMutex); + + if (pipeRet < 0) { + elog << "Signal::openPipes> pipe() failed: " << strerror(errno) << endl; + + signalError = true; + return false; + } + + // Set the fd's to non-blocking + ::pthread_mutex_lock(&pipeMutex); + + for (size_t i = 0; i < 2; ++i) { + // Get current flags + int flags = ::fcntl(rwFD[i], F_GETFL); + if (flags < 0) { + ::pthread_mutex_unlock(&pipeMutex); + elog << "Signal::openPipes> Failed to get flags " + << "for pipe fd: " << strerror(errno) << endl; + + closePipes(); + return false; + } + + // Update flags to indicate non-blocking + flags |= O_NONBLOCK; + + // Set new flags + if (::fcntl(rwFD[i], F_SETFL, flags) < 0) { + ::pthread_mutex_unlock(&pipeMutex); + elog << "Signal::openPipes> Failed to set flags " + << "on pipe fd: " << strerror(errno) << endl; + + closePipes(); + return false; + } + } // for() + + // All is well + readFD = rwFD[0]; + writeFD = rwFD[1]; + ::pthread_mutex_unlock(&pipeMutex); + + signalError = false; + + return true; } /** @@ -194,37 +174,33 @@ return true ; * If any error is detected, then signalError will be set to true * and GetSignal() must handle the rest. */ -void Signal::AddSignal( int whichSig ) -{ -errno = 0 ; - -// Attempt to write this signal to the pipe. -if( ::write( writeFD, &whichSig, sizeof( int ) ) < 0 ) - { - // Check for non-blocking type errors. - if( (EINTR != errno) && (EWOULDBLOCK != errno) && - (EINTR != EAGAIN) ) - { - // Critical error occured, readFD no longer valid - signalError = true ; - - // Do not close the pipes here, the readFD may be - // in use. Let getSignal() handle updating the pipes. - - // Do not attempt to create new pipes inside - // of the signal handler. - // The getSignal() below will attempt to reopen - // the pipes if it detects that one is closed. - return ; - } // if( errno ) - } // if( ::read() ) - -// In general, outputting data during a signal handler is a very -// bad idea. -// This is for testing purposes only. -//std::cerr << "Signal::AddSignal> Successfully sent signal: " -// << whichSig -// << endl ; +void Signal::AddSignal(int whichSig) { + errno = 0; + + // Attempt to write this signal to the pipe. + if (::write(writeFD, &whichSig, sizeof(int)) < 0) { + // Check for non-blocking type errors. + if ((EINTR != errno) && (EWOULDBLOCK != errno) && (EINTR != EAGAIN)) { + // Critical error occured, readFD no longer valid + signalError = true; + + // Do not close the pipes here, the readFD may be + // in use. Let getSignal() handle updating the pipes. + + // Do not attempt to create new pipes inside + // of the signal handler. + // The getSignal() below will attempt to reopen + // the pipes if it detects that one is closed. + return; + } // if( errno ) + } // if( ::read() ) + + // In general, outputting data during a signal handler is a very + // bad idea. + // This is for testing purposes only. + // std::cerr << "Signal::AddSignal> Successfully sent signal: " + // << whichSig + // << endl ; } // AddSignal() /** @@ -233,62 +209,50 @@ if( ::write( writeFD, &whichSig, sizeof( int ) ) < 0 ) * for either a new signal or an error state (-1) * - false indicates that no error and no signal are ready */ -bool Signal::getSignal( int& theSignal ) -{ -errno = 0 ; - -// Attempt to read the next signal from the pipe -::pthread_mutex_lock( &pipeMutex ) ; -int readResult = ::read( readFD, &theSignal, sizeof( int ) ) ; -::pthread_mutex_unlock( &pipeMutex ) ; - -if( readResult < 0 ) - { - // Check for non-blocking type errors. - if( (EINTR != errno) && (EWOULDBLOCK != errno) && - (EINTR != EAGAIN) ) - { - // Critical error occured, readFD no longer valid - - // closePipes() will set signalError to true. - closePipes() ; - - // Attempt to re-open the pipes - openPipes() ; - - theSignal = -1 ; - return true ; - } - else - { - // No signal detected - return false ; - } - } - -if( readResult != sizeof( int ) ) - { - elog << "Signal::getSignal> Somehow read " - << readResult - << " bytes, where sizeof(int) is: " - << sizeof( int ) - << endl ; - } - -// Signal detected, read() returned ok -return true ; +bool Signal::getSignal(int& theSignal) { + errno = 0; + + // Attempt to read the next signal from the pipe + ::pthread_mutex_lock(&pipeMutex); + int readResult = ::read(readFD, &theSignal, sizeof(int)); + ::pthread_mutex_unlock(&pipeMutex); + + if (readResult < 0) { + // Check for non-blocking type errors. + if ((EINTR != errno) && (EWOULDBLOCK != errno) && (EINTR != EAGAIN)) { + // Critical error occured, readFD no longer valid + + // closePipes() will set signalError to true. + closePipes(); + + // Attempt to re-open the pipes + openPipes(); + + theSignal = -1; + return true; + } else { + // No signal detected + return false; + } + } + + if (readResult != sizeof(int)) { + elog << "Signal::getSignal> Somehow read " << readResult + << " bytes, where sizeof(int) is: " << sizeof(int) << endl; + } + + // Signal detected, read() returned ok + return true; } -Signal* Signal::getInstance() -{ -::pthread_mutex_lock( &singletonMutex ) ; -if( 0 == theInstance ) - { - theInstance = new Signal ; - } -::pthread_mutex_unlock( &singletonMutex ) ; +Signal* Signal::getInstance() { + ::pthread_mutex_lock(&singletonMutex); + if (0 == theInstance) { + theInstance = new Signal; + } + ::pthread_mutex_unlock(&singletonMutex); -return theInstance ; + return theInstance; } } // namespace gnuworld diff --git a/libgnuworld/Signal.h b/libgnuworld/Signal.h old mode 100755 new mode 100644 index a353aa28..01cb686e --- a/libgnuworld/Signal.h +++ b/libgnuworld/Signal.h @@ -24,10 +24,9 @@ #ifndef __SIGNAL_H #define __SIGNAL_H "$Id: Signal.h,v 1.5 2003/12/17 18:21:36 dan_karrels Exp $" -#include +#include -namespace gnuworld -{ +namespace gnuworld { /** * A class used to safely handle asynchronous (non-realtime) signals. @@ -35,97 +34,94 @@ namespace gnuworld * my thesis) to solve the multiple consumer, single nonblocking * producer p/c problem. */ -class Signal -{ - -protected: - - /** - * This variable is true if there exists an uncoverable error. - */ - static bool signalError ; - - /** - * The FD for the read side of the pipe. - */ - static int readFD ; - - /** - * The FD for the write side of the pipe. - */ - static int writeFD ; - - /** - * A mutex to guard access to the Singleton. - */ - static pthread_mutex_t singletonMutex ; - - /** - * The Singleton instance. - */ - static Signal* theInstance ; - - /** - * This mutex guards from multiple threads performing a get() - */ - static pthread_mutex_t pipeMutex ; - -public: - /** - * Release resources associated with this class. - */ - virtual ~Signal() ; - - /** - * Retrieve the Singleton instance of this class, creating - * it if necessary. - * Once an instance is created, all signals currently - * supported by this class will be remapped to this subsystem. - */ - static Signal* getInstance() ; - - /** - * Add a signal to the signal queue. - * This method is meant to be called *only* from the - * asynchronous signal handler. - */ - static void AddSignal( int whichSig ) ; - - /** - * The semantics of the return statement are a little backwards here: - * - true indicates that the caller should check the value of - * theSignal for either a new signal or an error state (-1) - * - false indicates that no error and no signal are ready - */ - static bool getSignal( int& theSignal ) ; - - /** - * This method will return true if there is a non-recoverable - * error in the signal handler subsystem. - */ - static bool isError() ; - -private: - /** - * Private constructor, make this class a Singleton. - */ - Signal() ; - -protected: - /** - * Convenience method to close the pipes when a critical - * error occurs. In this case, signalError will remain - * set, and both pipes are invalid, no signal delivery - * will occur. - */ - static void closePipes() ; - - /** - * Opens both pipes, and configures in nonblocking mode. - */ - static bool openPipes() ; - -} ; +class Signal { + + protected: + /** + * This variable is true if there exists an uncoverable error. + */ + static bool signalError; + + /** + * The FD for the read side of the pipe. + */ + static int readFD; + + /** + * The FD for the write side of the pipe. + */ + static int writeFD; + + /** + * A mutex to guard access to the Singleton. + */ + static pthread_mutex_t singletonMutex; + + /** + * The Singleton instance. + */ + static Signal* theInstance; + + /** + * This mutex guards from multiple threads performing a get() + */ + static pthread_mutex_t pipeMutex; + + public: + /** + * Release resources associated with this class. + */ + virtual ~Signal(); + + /** + * Retrieve the Singleton instance of this class, creating + * it if necessary. + * Once an instance is created, all signals currently + * supported by this class will be remapped to this subsystem. + */ + static Signal* getInstance(); + + /** + * Add a signal to the signal queue. + * This method is meant to be called *only* from the + * asynchronous signal handler. + */ + static void AddSignal(int whichSig); + + /** + * The semantics of the return statement are a little backwards here: + * - true indicates that the caller should check the value of + * theSignal for either a new signal or an error state (-1) + * - false indicates that no error and no signal are ready + */ + static bool getSignal(int& theSignal); + + /** + * This method will return true if there is a non-recoverable + * error in the signal handler subsystem. + */ + static bool isError(); + + private: + /** + * Private constructor, make this class a Singleton. + */ + Signal(); + + protected: + /** + * Convenience method to close the pipes when a critical + * error occurs. In this case, signalError will remain + * set, and both pipes are invalid, no signal delivery + * will occur. + */ + static void closePipes(); + + /** + * Opens both pipes, and configures in nonblocking mode. + */ + static bool openPipes(); +}; } // namespace gnuworld diff --git a/libgnuworld/StringTokenizer.cc b/libgnuworld/StringTokenizer.cc old mode 100755 new mode 100644 index c409911e..e7f4a19b --- a/libgnuworld/StringTokenizer.cc +++ b/libgnuworld/StringTokenizer.cc @@ -21,17 +21,16 @@ * $Id: StringTokenizer.cc,v 1.7 2005/02/20 15:49:21 dan_karrels Exp $ */ -#include -#include -#include -#include -#include "StringTokenizer.h" +#include +#include +#include +#include +#include "StringTokenizer.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::vector ; +using std::string; +using std::vector; /** * StringTokenizer() @@ -40,14 +39,11 @@ using std::vector ; * delimiter: The specified delimiter by which * we will tokenize the string */ -StringTokenizer::StringTokenizer( const string& buf, char _delimiter ) - : delimiter( _delimiter ) -{ -Tokenize( buf ) ; +StringTokenizer::StringTokenizer(const string& buf, char _delimiter) : delimiter(_delimiter) { + Tokenize(buf); } -StringTokenizer::~StringTokenizer() -{ /* No heap space allocated */ } +StringTokenizer::~StringTokenizer() { /* No heap space allocated */ } /** * getToken() @@ -56,11 +52,10 @@ StringTokenizer::~StringTokenizer() * This method will deliberately drop core in debug * mode if sub is out of range. */ -const string& StringTokenizer::getToken( const size_type& sub ) const -{ -// Dump core -assert( validSubscript( sub ) ) ; -return array[ sub ] ; +const string& StringTokenizer::getToken(const size_type& sub) const { + // Dump core + assert(validSubscript(sub)); + return array[sub]; } /** @@ -72,81 +67,74 @@ return array[ sub ] ; * function calls, and more linear algorithm * complexity (though still not quite linear). */ -void StringTokenizer::Tokenize( const string& buf ) -{ -// Make sure that there is something -// worth tokenizing -if( buf.empty() ) - { - return ; - } - -// addMe is the string which will be added to the vector -// Initialize it to buf.size() empty characters to speed -// up addition of characters onto the string -// This method is only called once for the life of this object, -// so no need for memory of any kind here. -char* addMe = new (std::nothrow) char[ buf.size() + 1 ] ; -assert( addMe != 0 ) ; - -addMe[ 0 ] = 0 ; - -// (addMePtr) is used to walk down the addMe buffer, adding new -// characters to the end. -// (addMePtr) always points to the next location in the addMe ptr -// in which a character may be placed. -char* addMePtr = addMe ; - -// currentPtr is the current character pointer -string::const_iterator currentPtr = buf.begin() ; - -// endPtr is the end of the string, currentPtr is valid on -// [buf.begin(), buf.end()) -string::const_iterator endPtr = buf.end() ; - -// Iterate through the entire string -for( ; currentPtr != endPtr ; ++currentPtr ) - { - - // Is this the delimiter for which we are searching? - if( delimiter == *currentPtr ) - { - // We have reached a delimiter - // Null terminate the token - *addMePtr = 0 ; - - // Is this an empty token? - if( addMe[ 0 ] != 0 ) - { - // Nope, go ahead and add it to the vector - array.push_back( addMe ) ; - - addMePtr = addMe ; - *addMePtr = 0 ; - } - } - - // Otherwise, no delimiter was found...just add this - // character to addMe - else - { - *addMePtr = *currentPtr ; - ++addMePtr ; - } - } - -// Null terminate, if necessary -*addMePtr = 0 ; - -// currentPtr == endPtr -// Make sure to check for last token -if( addMe[ 0 ] != 0 ) - { - array.push_back( addMe ) ; - } - -// This point is always reached, excluding a crash -delete[] addMe ; +void StringTokenizer::Tokenize(const string& buf) { + // Make sure that there is something + // worth tokenizing + if (buf.empty()) { + return; + } + + // addMe is the string which will be added to the vector + // Initialize it to buf.size() empty characters to speed + // up addition of characters onto the string + // This method is only called once for the life of this object, + // so no need for memory of any kind here. + char* addMe = new (std::nothrow) char[buf.size() + 1]; + assert(addMe != 0); + + addMe[0] = 0; + + // (addMePtr) is used to walk down the addMe buffer, adding new + // characters to the end. + // (addMePtr) always points to the next location in the addMe ptr + // in which a character may be placed. + char* addMePtr = addMe; + + // currentPtr is the current character pointer + string::const_iterator currentPtr = buf.begin(); + + // endPtr is the end of the string, currentPtr is valid on + // [buf.begin(), buf.end()) + string::const_iterator endPtr = buf.end(); + + // Iterate through the entire string + for (; currentPtr != endPtr; ++currentPtr) { + + // Is this the delimiter for which we are searching? + if (delimiter == *currentPtr) { + // We have reached a delimiter + // Null terminate the token + *addMePtr = 0; + + // Is this an empty token? + if (addMe[0] != 0) { + // Nope, go ahead and add it to the vector + array.push_back(addMe); + + addMePtr = addMe; + *addMePtr = 0; + } + } + + // Otherwise, no delimiter was found...just add this + // character to addMe + else { + *addMePtr = *currentPtr; + ++addMePtr; + } + } + + // Null terminate, if necessary + *addMePtr = 0; + + // currentPtr == endPtr + // Make sure to check for last token + if (addMe[0] != 0) { + array.push_back(addMe); + } + + // This point is always reached, excluding a crash + delete[] addMe; } /** @@ -154,60 +142,50 @@ delete[] addMe ; * Assemble into a string all tokens starting from index * (start). */ -string StringTokenizer::assemble( const size_type& start, int end ) const -{ +string StringTokenizer::assemble(const size_type& start, int end) const { -// check if the beginning index is valid -if( !validSubscript( start ) ) - { - return string() ; - } + // check if the beginning index is valid + if (!validSubscript(start)) { + return string(); + } -if(end < 0) - { + if (end < 0) { end = size(); - } -else if(!validSubscript(end-1)) - { + } else if (!validSubscript(end - 1)) { return string(); - } + } -// retMe will be returned at the end of the method -string retMe ; -retMe.reserve( totalChars() ) ; + // retMe will be returned at the end of the method + string retMe; + retMe.reserve(totalChars()); -// continue while there are more tokens to concatenate -for( size_type i = start ; i < (size_type)end ; i++ ) - { - // Add this token to the returning string - retMe += array[ i ] ; + // continue while there are more tokens to concatenate + for (size_type i = start; i < (size_type)end; i++) { + // Add this token to the returning string + retMe += array[i]; - // If there is another token, put a delimiter here - if( (i + 1) < (size_type)end ) - { - retMe += delimiter ; - } + // If there is another token, put a delimiter here + if ((i + 1) < (size_type)end) { + retMe += delimiter; + } - } // close for + } // close for -// Return the assembled string -return retMe ; + // Return the assembled string + return retMe; } -StringTokenizer::size_type StringTokenizer::totalChars() const -{ -size_type numChars = 0 ; +StringTokenizer::size_type StringTokenizer::totalChars() const { + size_type numChars = 0; -for( const_iterator currentPtr = begin() ; currentPtr != end() ; - ++currentPtr ) - { - numChars += (*currentPtr).size() ; - } + for (const_iterator currentPtr = begin(); currentPtr != end(); ++currentPtr) { + numChars += (*currentPtr).size(); + } -// Account for delimiters -numChars += size() - 1 ; + // Account for delimiters + numChars += size() - 1; -return numChars ; + return numChars; } } // namespace gnuworld diff --git a/libgnuworld/StringTokenizer.h b/libgnuworld/StringTokenizer.h old mode 100755 new mode 100644 index c390f6ce..388852b8 --- a/libgnuworld/StringTokenizer.h +++ b/libgnuworld/StringTokenizer.h @@ -24,12 +24,11 @@ #ifndef __STRINGTOKENIZER_H #define __STRINGTOKENIZER_H "$Id: StringTokenizer.h,v 1.6 2003/12/29 23:59:36 dan_karrels Exp $" -#include -#include -#include +#include +#include +#include -namespace gnuworld -{ +namespace gnuworld { /** * This class provides a clean mechanism for parsing @@ -39,178 +38,163 @@ namespace gnuworld * The tokens maintained by this class are zero indexed. * This class is immutable. */ -class StringTokenizer -{ - -private: - /** - * This is the type that will be used to store - * the tokens in the StringTokenizer object. - */ - typedef std::vector< std::string > vectorType ; - -public: - - /** - * Constructor receives the string to be - * tokenized, and the delimiter by which - * tokens will be generated. - */ - StringTokenizer( const std::string& = std::string(), char = ' ' ) ; - - /** - * The destructor is a NOOP because no streams have been - * opened, and no memory dynamically explicitly allocated. - */ - virtual ~StringTokenizer() ; - - /** - * This is the type of the variable used for - * representing the size (number of tokens) of - * the StringTokenizer object. - */ - typedef vectorType::size_type size_type ; - - /** - * Retrieve a const reference to a given token, zero-indexed. - * This method will assert(false) if the requested index is - * out of bounds. This is for debugging, and may be conditionally - * compiled at a later time to throw an exception while - * in a production environment. - */ - const std::string& getToken( const size_type& ) const ; - - /** - * This method allows StringTokenizer objects to be used like - * arrays. This method just calls the getToken() method, and - * its semantics are the same. - */ - inline const std::string& operator[]( const size_type& sub ) const - { return getToken( sub ) ; } - - /** - * Return a const reference to the original C++ string before - * tokenization. - * A copy of the original string is *not* kept because, in - * the setting in which this class was designed, getOriginal() - * is never called. This will free up some processing time - * spent copying the original string. - */ - inline const std::string getOriginal() const - { return assemble() ; } - - /** - * Return the number of tokens in this StringTokenizer object. - */ - inline size_type size() const - { return array.size() ; } - - /** - * Return true if the StringTokenizer holds no tokens, - * false otherwise. - * This is equivalent to (size() == 0). - */ - inline bool empty() const - { return array.empty() ; } - - /** - * Determine if the subscript argument is within the - * bounds [0,size()). - * Return true if so, false otherwise. - * This method works also even if the StringTokenizer is empty. - */ - inline bool validSubscript( const size_type& sub ) const - { return (sub < size()) ; } - - /** - * This method builds and returns a C++ string starting at the given - * index, and continuing until the last token, placing the - * appropriate delimiter between each token. - * With no argument supplied, assemble() will return the entire - * original string, delimiters included. - */ - std::string assemble( const size_type& = 0, int = -1 ) const ; - - /** - * The immutable iterator type to use for walking through - * this object's tokens. - */ - typedef vectorType::const_iterator const_iterator ; - - /** - * The immutable reverse iterator type to use for walking through - * this object's tokens, in reverse. - */ - typedef vectorType::const_reverse_iterator const_reverse_iterator ; - - /** - * Retrieve an immutable iterator to the beginning of this - * object's token structure. - */ - inline const_iterator begin() const - { return array.begin() ; } - - /** - * Retrieve an immutable iterator to the end of this object's - * token structure. - */ - inline const_iterator end() const - { return array.end() ; } - - /** - * Retrieve an immutable reverse iterator to the - * reverse beginning of this object's token structure. - */ - inline const_reverse_iterator rbegin() const - { return array.rbegin() ; } - - /** - * Retrieve an immutable reverse iterator to the reverse - * end of this object's token structure. - */ - inline const_reverse_iterator rend() const - { return array.rend() ; } - - /** - * Return the total number of characters for all tokens, - * including the delimiters. - */ - inline size_type totalChars() const ; - - /** - * Convenience method for debugging purposes. - */ - friend std::ostream& operator<<( std::ostream& out, - const StringTokenizer& rhs ) - { - for( size_type i = 0, end = rhs.size() ; i < end ; ++i ) - { - out << rhs.array[ i ] ; - if( i < (rhs.size() - 1) ) - { - out << rhs.delimiter ; - } - } - return out ; - } - -protected: - /** - * Protected method called internally by the constructor once - * at object instantiation to tokenize the given C++ string. - */ - virtual void Tokenize( const std::string& ) ; - - /** - * The delimiter by which the (original) string is tokenized. - */ - char delimiter ; - - /** - * The structure for holding the tokens. - */ - vectorType array ; -} ; +class StringTokenizer { + + private: + /** + * This is the type that will be used to store + * the tokens in the StringTokenizer object. + */ + typedef std::vector vectorType; + + public: + /** + * Constructor receives the string to be + * tokenized, and the delimiter by which + * tokens will be generated. + */ + StringTokenizer(const std::string& = std::string(), char = ' '); + + /** + * The destructor is a NOOP because no streams have been + * opened, and no memory dynamically explicitly allocated. + */ + virtual ~StringTokenizer(); + + /** + * This is the type of the variable used for + * representing the size (number of tokens) of + * the StringTokenizer object. + */ + typedef vectorType::size_type size_type; + + /** + * Retrieve a const reference to a given token, zero-indexed. + * This method will assert(false) if the requested index is + * out of bounds. This is for debugging, and may be conditionally + * compiled at a later time to throw an exception while + * in a production environment. + */ + const std::string& getToken(const size_type&) const; + + /** + * This method allows StringTokenizer objects to be used like + * arrays. This method just calls the getToken() method, and + * its semantics are the same. + */ + inline const std::string& operator[](const size_type& sub) const { return getToken(sub); } + + /** + * Return a const reference to the original C++ string before + * tokenization. + * A copy of the original string is *not* kept because, in + * the setting in which this class was designed, getOriginal() + * is never called. This will free up some processing time + * spent copying the original string. + */ + inline const std::string getOriginal() const { return assemble(); } + + /** + * Return the number of tokens in this StringTokenizer object. + */ + inline size_type size() const { return array.size(); } + + /** + * Return true if the StringTokenizer holds no tokens, + * false otherwise. + * This is equivalent to (size() == 0). + */ + inline bool empty() const { return array.empty(); } + + /** + * Determine if the subscript argument is within the + * bounds [0,size()). + * Return true if so, false otherwise. + * This method works also even if the StringTokenizer is empty. + */ + inline bool validSubscript(const size_type& sub) const { return (sub < size()); } + + /** + * This method builds and returns a C++ string starting at the given + * index, and continuing until the last token, placing the + * appropriate delimiter between each token. + * With no argument supplied, assemble() will return the entire + * original string, delimiters included. + */ + std::string assemble(const size_type& = 0, int = -1) const; + + /** + * The immutable iterator type to use for walking through + * this object's tokens. + */ + typedef vectorType::const_iterator const_iterator; + + /** + * The immutable reverse iterator type to use for walking through + * this object's tokens, in reverse. + */ + typedef vectorType::const_reverse_iterator const_reverse_iterator; + + /** + * Retrieve an immutable iterator to the beginning of this + * object's token structure. + */ + inline const_iterator begin() const { return array.begin(); } + + /** + * Retrieve an immutable iterator to the end of this object's + * token structure. + */ + inline const_iterator end() const { return array.end(); } + + /** + * Retrieve an immutable reverse iterator to the + * reverse beginning of this object's token structure. + */ + inline const_reverse_iterator rbegin() const { return array.rbegin(); } + + /** + * Retrieve an immutable reverse iterator to the reverse + * end of this object's token structure. + */ + inline const_reverse_iterator rend() const { return array.rend(); } + + /** + * Return the total number of characters for all tokens, + * including the delimiters. + */ + inline size_type totalChars() const; + + /** + * Convenience method for debugging purposes. + */ + friend std::ostream& operator<<(std::ostream& out, const StringTokenizer& rhs) { + for (size_type i = 0, end = rhs.size(); i < end; ++i) { + out << rhs.array[i]; + if (i < (rhs.size() - 1)) { + out << rhs.delimiter; + } + } + return out; + } + + protected: + /** + * Protected method called internally by the constructor once + * at object instantiation to tokenize the given C++ string. + */ + virtual void Tokenize(const std::string&); + + /** + * The delimiter by which the (original) string is tokenized. + */ + char delimiter; + + /** + * The structure for holding the tokens. + */ + vectorType array; +}; } // namespace gnuworld diff --git a/libgnuworld/gThread.cc b/libgnuworld/gThread.cc old mode 100755 new mode 100644 index 7d2e37e7..c70dd778 --- a/libgnuworld/gThread.cc +++ b/libgnuworld/gThread.cc @@ -13,204 +13,161 @@ * 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. - * + * * $Id: gThread.cc,v 1.4 2003/06/17 15:13:53 dan_karrels Exp $ */ -#include +#include -#include -#include -#include +#include +#include +#include -#include -#include -#include +#include +#include +#include -#include "gThread.h" -#include "ELog.h" +#include "gThread.h" +#include "ELog.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::cout ; -using std::endl ; +using std::cout; +using std::endl; +using std::string; /** * This function issues the call back to the gThread subclass, and * is executed in a separate thread of execution. */ -void* stub( void* arg ) -{ -assert( arg != 0 ) ; +void* stub(void* arg) { + assert(arg != 0); -gThread* theThread = reinterpret_cast< gThread* >( arg ) ; -theThread->Exec() ; + gThread* theThread = reinterpret_cast(arg); + theThread->Exec(); -return 0 ; + return 0; } -gThread::gThread() -{ -keepRunning = true ; -isShutdownComplete = false ; -threadID = 0 ; - -if( ::pthread_mutex_init( &waitMutex, 0 ) != 0 ) - { - elog << "gThread> Unable to initialize waitMutex: " - << strerror( errno ) - << endl ; - ::exit( -1 ) ; - } +gThread::gThread() { + keepRunning = true; + isShutdownComplete = false; + threadID = 0; + + if (::pthread_mutex_init(&waitMutex, 0) != 0) { + elog << "gThread> Unable to initialize waitMutex: " << strerror(errno) << endl; + ::exit(-1); + } } -gThread::~gThread() -{ -Join() ; -DestroyAllMutexes() ; -// destroy mutexes -if( !isShutdownComplete ) - { - Join() ; - } - -::pthread_mutex_destroy( &waitMutex ) ; +gThread::~gThread() { + Join(); + DestroyAllMutexes(); + // destroy mutexes + if (!isShutdownComplete) { + Join(); + } + + ::pthread_mutex_destroy(&waitMutex); } -bool gThread::CreateMutex( const string& mutexName ) -{ -if( mutexName.empty() ) - { - // Invalid name - return false ; - } - -if( mutexMap.find( mutexName ) != mutexMap.end() ) - { - // Mutex already exists for that name - return false ; - } - -pthread_mutex_t newMutex ; -::pthread_mutex_init( &newMutex, 0 ) ; - -if( !mutexMap.insert( - mutexMapType::value_type( mutexName, newMutex ) ).second ) - { - // Insertion into map failed - ::pthread_mutex_destroy( &newMutex ) ; - - return false ; - } - -// All is well -return true ; +bool gThread::CreateMutex(const string& mutexName) { + if (mutexName.empty()) { + // Invalid name + return false; + } + + if (mutexMap.find(mutexName) != mutexMap.end()) { + // Mutex already exists for that name + return false; + } + + pthread_mutex_t newMutex; + ::pthread_mutex_init(&newMutex, 0); + + if (!mutexMap.insert(mutexMapType::value_type(mutexName, newMutex)).second) { + // Insertion into map failed + ::pthread_mutex_destroy(&newMutex); + + return false; + } + + // All is well + return true; } -bool gThread::DestroyMutex( const string& mutexName ) -{ -mutexIterator mItr = mutexMap.find( mutexName ) ; -if( mItr == mutexMap.end() ) - { - return false ; - } - -bool retMe = true ; -if( ::pthread_mutex_destroy( &(mItr->second) ) != 0 ) - { - elog << "gThread::DestroyMutex> Unable to destroy mutex: " - << mutexName - << " because: " - << strerror( errno ) - << endl ; - retMe = false ; - } - -// Remove it from the map either way -mutexMap.erase( mItr ) ; - -return retMe ; +bool gThread::DestroyMutex(const string& mutexName) { + mutexIterator mItr = mutexMap.find(mutexName); + if (mItr == mutexMap.end()) { + return false; + } + + bool retMe = true; + if (::pthread_mutex_destroy(&(mItr->second)) != 0) { + elog << "gThread::DestroyMutex> Unable to destroy mutex: " << mutexName + << " because: " << strerror(errno) << endl; + retMe = false; + } + + // Remove it from the map either way + mutexMap.erase(mItr); + + return retMe; } -void gThread::DestroyAllMutexes() -{ -for( mutexIterator mItr = mutexMap.begin() ; mItr != mutexMap.end() ; - ++mItr ) - { - if( ::pthread_mutex_destroy( &(mItr->second) ) != 0 ) - { - elog << "gThread::DestroyAllMutexes> " - << "pthread_mutex_destroy() failed: " - << strerror( errno ) - << endl ; - } - } -mutexMap.clear() ; +void gThread::DestroyAllMutexes() { + for (mutexIterator mItr = mutexMap.begin(); mItr != mutexMap.end(); ++mItr) { + if (::pthread_mutex_destroy(&(mItr->second)) != 0) { + elog << "gThread::DestroyAllMutexes> " + << "pthread_mutex_destroy() failed: " << strerror(errno) << endl; + } + } + mutexMap.clear(); } -void gThread::LockMutex( const string& mutexName ) -{ -mutexIterator mItr = mutexMap.find( mutexName ) ; -if( mItr == mutexMap.end() ) - { - elog << "gThread::LockMutex> Unable to locate mutex: " - << mutexName - << endl ; - return ; - } - -::pthread_mutex_lock( &(mItr->second) ) ; +void gThread::LockMutex(const string& mutexName) { + mutexIterator mItr = mutexMap.find(mutexName); + if (mItr == mutexMap.end()) { + elog << "gThread::LockMutex> Unable to locate mutex: " << mutexName << endl; + return; + } + + ::pthread_mutex_lock(&(mItr->second)); } -void gThread::UnLockMutex( const string& mutexName ) -{ -mutexIterator mItr = mutexMap.find( mutexName ) ; -if( mItr == mutexMap.end() ) - { - elog << "gThread::UnLockMutex> Unable to locate mutex: " - << mutexName - << endl ; - return ; - } - -::pthread_mutex_unlock( &(mItr->second) ) ; +void gThread::UnLockMutex(const string& mutexName) { + mutexIterator mItr = mutexMap.find(mutexName); + if (mItr == mutexMap.end()) { + elog << "gThread::UnLockMutex> Unable to locate mutex: " << mutexName << endl; + return; + } + + ::pthread_mutex_unlock(&(mItr->second)); } -bool gThread::Start() -{ -if( ::pthread_create( &threadID, 0, stub, - reinterpret_cast< void* >( this ) ) != 0 ) - { - elog << "gThread::Start> pthread_create() failed: " - << strerror( errno ) - << endl ; - - threadID = 0 ; - return false ; - } -return true ; +bool gThread::Start() { + if (::pthread_create(&threadID, 0, stub, reinterpret_cast(this)) != 0) { + elog << "gThread::Start> pthread_create() failed: " << strerror(errno) << endl; + + threadID = 0; + return false; + } + return true; } -void gThread::Join() -{ -if( isShutdownComplete || (0 == threadID) ) - { - // Not running, or never started - return ; - } - -if( ::pthread_join( threadID, 0 ) != 0 ) - { - elog << "gThread::Join> join() failed: " - << strerror( errno ) - << endl ; - } -isShutdownComplete = true ; +void gThread::Join() { + if (isShutdownComplete || (0 == threadID)) { + // Not running, or never started + return; + } + + if (::pthread_join(threadID, 0) != 0) { + elog << "gThread::Join> join() failed: " << strerror(errno) << endl; + } + isShutdownComplete = true; } } // namespace gnuworld diff --git a/libgnuworld/gThread.h b/libgnuworld/gThread.h old mode 100755 new mode 100644 index 3ef2da08..532a6fa3 --- a/libgnuworld/gThread.h +++ b/libgnuworld/gThread.h @@ -13,25 +13,24 @@ * 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 + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. - * + * * $Id: gThread.h,v 1.5 2003/12/29 23:59:36 dan_karrels Exp $ */ #ifndef __GTHREAD_H #define __GTHREAD_H "$Id: gThread.h,v 1.5 2003/12/29 23:59:36 dan_karrels Exp $" -#include +#include -#include -#include +#include +#include -#include "misc.h" +#include "misc.h" -namespace gnuworld -{ +namespace gnuworld { /** * The base class for creating a thread. @@ -44,134 +43,127 @@ namespace gnuworld * is set to false; this indicates that a Stop() request * has been issued. */ -class gThread -{ - -protected: - /** - * The type used to store mutexes. - */ - typedef std::map< std::string, pthread_mutex_t, noCaseCompare > - mutexMapType ; - - /** - * The iterator type to the mutex map. - */ - typedef mutexMapType::iterator mutexIterator ; - - /** - * The const_iterator type to the mutex map. - */ - typedef mutexMapType::const_iterator constMutexIterator ; - -public: - - /** - * Default constructor. - */ - gThread() ; - - /** - * The destructor will stop the thread, issue a join(), and - * destroy any mutexes. - */ - virtual ~gThread() ; - - /** - * Invoke this method to begin the Exec() method in a new - * thread. - */ - virtual bool Start() ; - - /** - * Return true if this thread is running, false otherwise. - */ - virtual bool isRunning() const - { return (keepRunning && (threadID != 0)) ; } - - /** - * Request that this thread stop processing. This could take - * an arbitrary length of time to fully stop, depending on how - * well the thread subclass follows directions (see above). - */ - virtual void Stop() - { keepRunning = false ; } - - /** - * Issue a pthread_join() on this (already stopped) thread to - * cleanup. - */ - virtual void Join() ; - - /** - * Create a mutex with the given case insensitive name. - * True is returned if successfull, false otherwise. - */ - virtual bool CreateMutex( const std::string& mutexName ) ; - - /** - * Destroy a mutex with the given case insensitive name. - * True is returned if successfull, false otherwise. - */ - virtual bool DestroyMutex( const std::string& mutexName ) ; - - /** - * Destroy all active mutexes. - */ - virtual void DestroyAllMutexes() ; - - /** - * Locks the mutex specified by mutexName. - * This method blocks indefinitely until the lock is obtained. - */ - virtual void LockMutex( const std::string& mutexName ) -; - - /** - * Unlocks the mutex specified by mutexName. - * This method will return immediately. - */ - virtual void UnLockMutex( const std::string& mutexName ) ; - - /** - * This method is invoked in a new thread when the Start() - * method is invoked. Subclasses must overload this method - * to perform the meaningful duty of the thread proper. - * This method must halt when keepRunning is set to false. - */ - virtual void Exec() {} - -protected: - - /** - * The running status of the thread. Subclasses must honor - * the value of this variable. - */ - bool keepRunning ; - - /** - * True if shutdown has completed (keepRunning request has - * been honored), and it is clear to issue a join(), false - * otherwise. - */ - bool isShutdownComplete ; - - /** - * The thread ID for this thread, 0 if not running. - */ - pthread_t threadID ; - - /** - * The container used to store the active mutexes. - */ - mutexMapType mutexMap ; - - /** - * A general purpose mutex on which to wait. - */ - pthread_mutex_t waitMutex ; - -} ; // class gThread +class gThread { + + protected: + /** + * The type used to store mutexes. + */ + typedef std::map mutexMapType; + + /** + * The iterator type to the mutex map. + */ + typedef mutexMapType::iterator mutexIterator; + + /** + * The const_iterator type to the mutex map. + */ + typedef mutexMapType::const_iterator constMutexIterator; + + public: + /** + * Default constructor. + */ + gThread(); + + /** + * The destructor will stop the thread, issue a join(), and + * destroy any mutexes. + */ + virtual ~gThread(); + + /** + * Invoke this method to begin the Exec() method in a new + * thread. + */ + virtual bool Start(); + + /** + * Return true if this thread is running, false otherwise. + */ + virtual bool isRunning() const { return (keepRunning && (threadID != 0)); } + + /** + * Request that this thread stop processing. This could take + * an arbitrary length of time to fully stop, depending on how + * well the thread subclass follows directions (see above). + */ + virtual void Stop() { keepRunning = false; } + + /** + * Issue a pthread_join() on this (already stopped) thread to + * cleanup. + */ + virtual void Join(); + + /** + * Create a mutex with the given case insensitive name. + * True is returned if successfull, false otherwise. + */ + virtual bool CreateMutex(const std::string& mutexName); + + /** + * Destroy a mutex with the given case insensitive name. + * True is returned if successfull, false otherwise. + */ + virtual bool DestroyMutex(const std::string& mutexName); + + /** + * Destroy all active mutexes. + */ + virtual void DestroyAllMutexes(); + + /** + * Locks the mutex specified by mutexName. + * This method blocks indefinitely until the lock is obtained. + */ + virtual void LockMutex(const std::string& mutexName); + + /** + * Unlocks the mutex specified by mutexName. + * This method will return immediately. + */ + virtual void UnLockMutex(const std::string& mutexName); + + /** + * This method is invoked in a new thread when the Start() + * method is invoked. Subclasses must overload this method + * to perform the meaningful duty of the thread proper. + * This method must halt when keepRunning is set to false. + */ + virtual void Exec() {} + + protected: + /** + * The running status of the thread. Subclasses must honor + * the value of this variable. + */ + bool keepRunning; + + /** + * True if shutdown has completed (keepRunning request has + * been honored), and it is clear to issue a join(), false + * otherwise. + */ + bool isShutdownComplete; + + /** + * The thread ID for this thread, 0 if not running. + */ + pthread_t threadID; + + /** + * The container used to store the active mutexes. + */ + mutexMapType mutexMap; + + /** + * A general purpose mutex on which to wait. + */ + pthread_mutex_t waitMutex; + +}; // class gThread } // namespace gnuworld diff --git a/libgnuworld/ircd_chattr.h b/libgnuworld/ircd_chattr.h old mode 100755 new mode 100644 index e7e5161d..db374806 --- a/libgnuworld/ircd_chattr.h +++ b/libgnuworld/ircd_chattr.h @@ -39,38 +39,38 @@ #define INCLUDED_sys_types_h #endif -#include "match_table.h" +#include "match_table.h" /* * Character attribute macros */ -#define NTL_ALNUM 0x0001 /* (NTL_ALPHA | NTL_DIGIT) */ -#define NTL_ALPHA 0x0002 /* (NTL_LOWER | NTL_UPPER) */ -#define NTL_CNTRL 0x0004 /* \000 - \037 == 0x00 - 0x1F */ -#define NTL_DIGIT 0x0008 /* 0123456789 */ -#define NTL_GRAPH 0x0010 /* (NTL_ALNUM | NTL_PUNCT) */ -#define NTL_LOWER 0x0020 /* abcdefghijklmnopqrstuvwxyz{|}~ */ -#define NTL_PRINT 0x0040 /* (NTL_GRAPH | ' ') */ -#define NTL_PUNCT 0x0080 /* !"#$%&'()*+,-./:;<=>?@_` */ -#define NTL_SPACE 0x0100 /* \011\012\013\014\015\040 */ -#define NTL_UPPER 0x0200 /* ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^ */ -#define NTL_IRCCH 0x0400 /* Channel's names charset */ -#define NTL_IRCCL 0x0800 /* Force toLower() in ch-name */ -#define NTL_IRCNK 0x1000 /* Nick names charset, aka isvalid() */ -#define NTL_IRCUI 0x2000 /* UserIDs charset, IRCHN plus tilde */ -#define NTL_IRCHN 0x4000 /* Hostnames charset (weak, RFC 1033) */ -#define NTL_IRCIP 0x8000 /* Numeric IPs charset (DIGIT and .) */ -#define NTL_EOL 0x10000 /* \r\n */ -#define NTL_KTIME 0x20000 /* Valid character for a k:line time */ -#define NTL_CHPFX 0x40000 /* channel prefix char # & + */ +#define NTL_ALNUM 0x0001 /* (NTL_ALPHA | NTL_DIGIT) */ +#define NTL_ALPHA 0x0002 /* (NTL_LOWER | NTL_UPPER) */ +#define NTL_CNTRL 0x0004 /* \000 - \037 == 0x00 - 0x1F */ +#define NTL_DIGIT 0x0008 /* 0123456789 */ +#define NTL_GRAPH 0x0010 /* (NTL_ALNUM | NTL_PUNCT) */ +#define NTL_LOWER 0x0020 /* abcdefghijklmnopqrstuvwxyz{|}~ */ +#define NTL_PRINT 0x0040 /* (NTL_GRAPH | ' ') */ +#define NTL_PUNCT 0x0080 /* !"#$%&'()*+,-./:;<=>?@_` */ +#define NTL_SPACE 0x0100 /* \011\012\013\014\015\040 */ +#define NTL_UPPER 0x0200 /* ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^ */ +#define NTL_IRCCH 0x0400 /* Channel's names charset */ +#define NTL_IRCCL 0x0800 /* Force toLower() in ch-name */ +#define NTL_IRCNK 0x1000 /* Nick names charset, aka isvalid() */ +#define NTL_IRCUI 0x2000 /* UserIDs charset, IRCHN plus tilde */ +#define NTL_IRCHN 0x4000 /* Hostnames charset (weak, RFC 1033) */ +#define NTL_IRCIP 0x8000 /* Numeric IPs charset (DIGIT and .) */ +#define NTL_EOL 0x10000 /* \r\n */ +#define NTL_KTIME 0x20000 /* Valid character for a k:line time */ +#define NTL_CHPFX 0x40000 /* channel prefix char # & + */ /* * Translation macros for channel name case translation - * NOTE: Channel names are supposed to be lower case insensitive for + * NOTE: Channel names are supposed to be lower case insensitive for * ISO 8859-1 character sets. */ -#define ToLower(c) (ToLowerTab_8859_1[(c) - CHAR_MIN]) -#define ToUpper(c) (ToUpperTab_8859_1[(c) - CHAR_MIN]) +#define ToLower(c) (ToLowerTab_8859_1[(c) - CHAR_MIN]) +#define ToUpper(c) (ToUpperTab_8859_1[(c) - CHAR_MIN]) /* * Character classification macros @@ -78,22 +78,22 @@ * ISO 8859-1 character set, unlike the ToUpper and ToLower macros above. * IsUpper and IsLower only apply for comparisons of the US ASCII subset. */ -#define IsAlnum(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_ALNUM) -#define IsAlpha(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_ALPHA) -#define IsDigit(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_DIGIT) -#define IsLower(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_LOWER) -#define IsSpace(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_SPACE) -#define IsUpper(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_UPPER) -#define IsCntrl(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_CNTRL) +#define IsAlnum(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_ALNUM) +#define IsAlpha(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_ALPHA) +#define IsDigit(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_DIGIT) +#define IsLower(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_LOWER) +#define IsSpace(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_SPACE) +#define IsUpper(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_UPPER) +#define IsCntrl(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_CNTRL) -#define IsChannelChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCCH) -#define IsChannelLower(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCCL) +#define IsChannelChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCCH) +#define IsChannelLower(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCCL) #define IsChannelPrefix(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_CHPFX) -#define IsNickChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCNK) -#define IsUserChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCUI) -#define IsHostChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCHN) -#define IsIPChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCIP) -#define IsEol(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_EOL) -#define IsKTimeChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_KTIME) +#define IsNickChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCNK) +#define IsUserChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCUI) +#define IsHostChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCHN) +#define IsIPChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_IRCIP) +#define IsEol(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_EOL) +#define IsKTimeChar(c) (IRCD_CharAttrTab[(c) - CHAR_MIN] & NTL_KTIME) #endif /* INCLUDED_ircd_chattr_h */ diff --git a/libgnuworld/match.cc b/libgnuworld/match.cc old mode 100755 new mode 100644 index ae60954c..d478d1f0 --- a/libgnuworld/match.cc +++ b/libgnuworld/match.cc @@ -19,65 +19,59 @@ * $Id: match.cc,v 1.10 2007/09/13 02:00:45 dan_karrels Exp $ */ -#include -#include -#include -#include "match.h" -#include "misc.h" -#include "StringTokenizer.h" - -namespace gnuworld -{ - -int match( const string& s1, const string& s2 ) -{ - if( s1.empty() || s2.empty() ) - { - return 1 ; - } - - //Handle just two plainAddress! Withouth any nick!user part! - if (!isUserHost(s1) && !isUserHost(s2)) - { - if (match(s1.c_str(), s2.c_str()) == 0) - return 0; - } - - // Address checking, first we try to pass the address from the nick!user part ... - if (isUserHost(s1) && isUserHost(s2)) - { - if (match(extractNick(s1).c_str(), extractNick(s2).c_str())) - return 1; - - if (match(extractUser(s1).c_str(), extractUser(s2).c_str())) - return 1; - /* If passed, we deal only with the hostip part, and because match() handles cidr addresses too - * our matching is complete. - */ - if (match(extractHostIP(s1).c_str(), extractHostIP(s2).c_str()) == 0) - return 0; - } - return 1; +#include +#include +#include +#include "match.h" +#include "misc.h" +#include "StringTokenizer.h" + +namespace gnuworld { + +int match(const string& s1, const string& s2) { + if (s1.empty() || s2.empty()) { + return 1; + } + + // Handle just two plainAddress! Withouth any nick!user part! + if (!isUserHost(s1) && !isUserHost(s2)) { + if (match(s1.c_str(), s2.c_str()) == 0) + return 0; + } + + // Address checking, first we try to pass the address from the nick!user part ... + if (isUserHost(s1) && isUserHost(s2)) { + if (match(extractNick(s1).c_str(), extractNick(s2).c_str())) + return 1; + + if (match(extractUser(s1).c_str(), extractUser(s2).c_str())) + return 1; + /* If passed, we deal only with the hostip part, and because match() handles cidr addresses + * too our matching is complete. + */ + if (match(extractHostIP(s1).c_str(), extractHostIP(s2).c_str()) == 0) + return 0; + } + return 1; } -int match(const string& mask, const iClient* theClient) -{ - if (!isUserHost(mask)) - return 1; +int match(const string& mask, const iClient* theClient) { + if (!isUserHost(mask)) + return 1; - if (match(extractNick(mask).c_str(), theClient->getNickName().c_str())) - return 1; + if (match(extractNick(mask).c_str(), theClient->getNickName().c_str())) + return 1; - if (match(extractUser(mask).c_str(), theClient->getUserName().c_str())) - return 1; + if (match(extractUser(mask).c_str(), theClient->getUserName().c_str())) + return 1; - // But now we match with realhost too - if ((match(extractHostIP(mask), theClient->getRealInsecureHost()) == 0) - || (match(extractHostIP(mask), theClient->getInsecureHost()) == 0) - || (match(extractHostIP(mask), theClient->getNumericIP()) == 0)) - return 0; + // But now we match with realhost too + if ((match(extractHostIP(mask), theClient->getRealInsecureHost()) == 0) || + (match(extractHostIP(mask), theClient->getInsecureHost()) == 0) || + (match(extractHostIP(mask), theClient->getNumericIP()) == 0)) + return 0; - return 1; + return 1; } /* @@ -98,112 +92,104 @@ int match(const string& mask, const iClient* theClient) /****************** Nemesi's match() ***************/ -int match(const char *mask, const char *string) -{ - const char *m = mask, *s = string; - char ch; - const char *bm, *bs; /* Will be reg anyway on a decent CPU/compiler */ - - irc_in_addr ipmask; - irc_in_addr ipstring; - int ipmask_valid; - int ipstring_valid; - unsigned char ipmask_len; - unsigned char ipstring_len; - - /* Checking and parsing any possible ipv4/ipv6 address. */ - ipmask_valid = ipmask_parse(mask, &ipmask, &ipmask_len); - ipstring_valid = ipmask_parse(string, &ipstring, &ipstring_len); - - if ((ipmask_valid) && (ipstring_valid)) - { - if (ipmask_check(&ipstring, &ipmask, ipmask_len)) - return 0; - else - return 1; - } - - m = mask; - - /* Process the "head" of the mask, if any */ - while ((ch = *m++) && (ch != '*')) - switch (ch) - { - case '\\': - if (*m == '?' || *m == '*') - ch = *m++; - /* fall through */ - default: - if (ToLower(*s) != ToLower(ch)) - return 1; - /* fall through */ - case '?': - if (!*s++) - return 1; - }; - if (!ch) - return *s; +int match(const char* mask, const char* string) { + const char *m = mask, *s = string; + char ch; + const char *bm, *bs; /* Will be reg anyway on a decent CPU/compiler */ + + irc_in_addr ipmask; + irc_in_addr ipstring; + int ipmask_valid; + int ipstring_valid; + unsigned char ipmask_len; + unsigned char ipstring_len; + + /* Checking and parsing any possible ipv4/ipv6 address. */ + ipmask_valid = ipmask_parse(mask, &ipmask, &ipmask_len); + ipstring_valid = ipmask_parse(string, &ipstring, &ipstring_len); + + if ((ipmask_valid) && (ipstring_valid)) { + if (ipmask_check(&ipstring, &ipmask, ipmask_len)) + return 0; + else + return 1; + } + + m = mask; + + /* Process the "head" of the mask, if any */ + while ((ch = *m++) && (ch != '*')) + switch (ch) { + case '\\': + if (*m == '?' || *m == '*') + ch = *m++; + /* fall through */ + default: + if (ToLower(*s) != ToLower(ch)) + return 1; + /* fall through */ + case '?': + if (!*s++) + return 1; + }; + if (!ch) + return *s; - /* We got a star: quickly find if/where we match the next char */ + /* We got a star: quickly find if/where we match the next char */ got_star: - bm = m; /* Next try rollback here */ - while ((ch = *m++)) - switch (ch) - { - case '?': - if (!*s++) - return 1; - /* fall through */ - case '*': - bm = m; - continue; /* while */ - case '\\': - if (*m == '?' || *m == '*') - ch = *m++; - /* fall through */ - default: - goto break_while; /* C is structured ? */ - }; + bm = m; /* Next try rollback here */ + while ((ch = *m++)) + switch (ch) { + case '?': + if (!*s++) + return 1; + /* fall through */ + case '*': + bm = m; + continue; /* while */ + case '\\': + if (*m == '?' || *m == '*') + ch = *m++; + /* fall through */ + default: + goto break_while; /* C is structured ? */ + }; break_while: - if (!ch) - return 0; /* mask ends with '*', we got it */ - ch = ToLower(ch); - while (ToLower(*s++) != ch) - if (!*s) - return 1; - bs = s; /* Next try start from here */ - - /* Check the rest of the "chunk" */ - while ((ch = *m++)) - { - switch (ch) - { - case '*': - goto got_star; - case '\\': - if (*m == '?' || *m == '*') - ch = *m++; - /* fall through */ - default: - if (ToLower(*s) != ToLower(ch)) - { - m = bm; - s = bs; - goto got_star; + if (!ch) + return 0; /* mask ends with '*', we got it */ + ch = ToLower(ch); + while (ToLower(*s++) != ch) + if (!*s) + return 1; + bs = s; /* Next try start from here */ + + /* Check the rest of the "chunk" */ + while ((ch = *m++)) { + switch (ch) { + case '*': + goto got_star; + case '\\': + if (*m == '?' || *m == '*') + ch = *m++; + /* fall through */ + default: + if (ToLower(*s) != ToLower(ch)) { + m = bm; + s = bs; + goto got_star; + }; + /* fall through */ + case '?': + if (!*s++) + return 1; }; - /* fall through */ - case '?': - if (!*s++) - return 1; }; - }; - if (*s) - { - m = bm; - s = bs; - goto got_star; - }; - return 0; + if (*s) { + m = bm; + s = bs; + goto got_star; + }; + return 0; } /* ircu's match() function @@ -233,153 +219,147 @@ int match(const char *mask, const char *string) * @param[in] name String to check against \a mask. * @return Zero if \a mask matches \a name, non-zero if no match. */ -int smatch(const char *mask, const char *name) -{ - const char *m = mask, *n = name; - const char *m_tmp = mask, *n_tmp = name; - int star_p; - - for (;;) switch (*m) { - case '\0': - if (!*n) - return 0; - backtrack: - if (m_tmp == mask) - return 1; - m = m_tmp; - n = ++n_tmp; - if (*n == '\0') - return 1; - break; - case '\\': - if ((m[1] == '*') || (m[1] == '?')) - m++; - goto normal_character; - case '*': case '?': - for (star_p = 0; ; m++) { - if (*m == '*') - star_p = 1; - else if (*m == '?') { - if (!*n++) - goto backtrack; - } else break; - } - if (star_p) { - if (!*m) - return 0; - m_tmp = m; - for (n_tmp = n; *n && ToLower(*n) != ToLower(*m); n++) ; - } - /* fall through */ - default: - normal_character: - if (!*n) - return *m != '\0'; - if (ToLower(*m) != ToLower(*n)) - goto backtrack; - m++; - n++; - break; - } +int smatch(const char* mask, const char* name) { + const char *m = mask, *n = name; + const char *m_tmp = mask, *n_tmp = name; + int star_p; + + for (;;) + switch (*m) { + case '\0': + if (!*n) + return 0; + backtrack: + if (m_tmp == mask) + return 1; + m = m_tmp; + n = ++n_tmp; + if (*n == '\0') + return 1; + break; + case '\\': + if ((m[1] == '*') || (m[1] == '?')) + m++; + goto normal_character; + case '*': + case '?': + for (star_p = 0;; m++) { + if (*m == '*') + star_p = 1; + else if (*m == '?') { + if (!*n++) + goto backtrack; + } else + break; + } + if (star_p) { + if (!*m) + return 0; + m_tmp = m; + for (n_tmp = n; *n && ToLower(*n) != ToLower(*m); n++) + ; + } + /* fall through */ + default: + normal_character: + if (!*n) + return *m != '\0'; + if (ToLower(*m) != ToLower(*n)) + goto backtrack; + m++; + n++; + break; + } } /* casematch method, I simply removed all ToLower's ... (Seven) */ -int casematch(const char *mask, const char *string) -{ - const char *m = mask, *s = string; - char ch; - const char *bm, *bs; /* Will be reg anyway on a decent CPU/compiler */ - - m = mask; - - /* Process the "head" of the mask, if any */ - while ((ch = *m++) && (ch != '*')) - switch (ch) - { - case '\\': - if (*m == '?' || *m == '*') - ch = *m++; - /* fall through */ - default: - if ((*s) != (ch)) - return 1; - /* fall through */ - case '?': - if (!*s++) - return 1; - }; - if (!ch) - return *s; +int casematch(const char* mask, const char* string) { + const char *m = mask, *s = string; + char ch; + const char *bm, *bs; /* Will be reg anyway on a decent CPU/compiler */ - /* We got a star: quickly find if/where we match the next char */ + m = mask; + + /* Process the "head" of the mask, if any */ + while ((ch = *m++) && (ch != '*')) + switch (ch) { + case '\\': + if (*m == '?' || *m == '*') + ch = *m++; + /* fall through */ + default: + if ((*s) != (ch)) + return 1; + /* fall through */ + case '?': + if (!*s++) + return 1; + }; + if (!ch) + return *s; + + /* We got a star: quickly find if/where we match the next char */ got_star: - bm = m; /* Next try rollback here */ - while ((ch = *m++)) - switch (ch) - { - case '?': - if (!*s++) - return 1; - /* fall through */ - case '*': - bm = m; - continue; /* while */ - case '\\': - if (*m == '?' || *m == '*') - ch = *m++; - /* fall through */ - default: - goto break_while; /* C is structured ? */ - }; + bm = m; /* Next try rollback here */ + while ((ch = *m++)) + switch (ch) { + case '?': + if (!*s++) + return 1; + /* fall through */ + case '*': + bm = m; + continue; /* while */ + case '\\': + if (*m == '?' || *m == '*') + ch = *m++; + /* fall through */ + default: + goto break_while; /* C is structured ? */ + }; break_while: - if (!ch) - return 0; /* mask ends with '*', we got it */ - //ch = ToLower(ch); - while ((*s++) != ch) - if (!*s) - return 1; - bs = s; /* Next try start from here */ - - /* Check the rest of the "chunk" */ - while ((ch = *m++)) - { - switch (ch) - { - case '*': - goto got_star; - case '\\': - if (*m == '?' || *m == '*') - ch = *m++; - /* fall through */ - default: - if ((*s) != (ch)) - { - m = bm; - s = bs; - goto got_star; + if (!ch) + return 0; /* mask ends with '*', we got it */ + // ch = ToLower(ch); + while ((*s++) != ch) + if (!*s) + return 1; + bs = s; /* Next try start from here */ + + /* Check the rest of the "chunk" */ + while ((ch = *m++)) { + switch (ch) { + case '*': + goto got_star; + case '\\': + if (*m == '?' || *m == '*') + ch = *m++; + /* fall through */ + default: + if ((*s) != (ch)) { + m = bm; + s = bs; + goto got_star; + }; + /* fall through */ + case '?': + if (!*s++) + return 1; }; - /* fall through */ - case '?': - if (!*s++) - return 1; }; - }; - if (*s) - { - m = bm; - s = bs; - goto got_star; - }; - return 0; + if (*s) { + m = bm; + s = bs; + goto got_star; + }; + return 0; } -int casematch( const std::string& s1, const std::string& s2 ) -{ -if( s1.empty() || s2.empty() ) - { - return 1 ; - } -return casematch( s1.c_str(), s2.c_str() ) ; +int casematch(const std::string& s1, const std::string& s2) { + if (s1.empty() || s2.empty()) { + return 1; + } + return casematch(s1.c_str(), s2.c_str()); } /* ircu's mask match */ @@ -421,105 +401,91 @@ return casematch( s1.c_str(), s2.c_str() ) ; * @param[in] new_mask Another wildcard mask. * @return Zero if \a old_mask is a superset of \a new_mask, non-zero otherwise. */ -int mmatch(const char *old_mask, const char *new_mask) -{ - const char *m = old_mask; - const char *n = new_mask; - const char *ma = m; - const char *na = n; - int wild = 0; - int mq = 0, nq = 0; - - while (1) - { - if (*m == '*') - { - while (*m == '*') - m++; - wild = 1; - ma = m; - na = n; - } - - if (!*m) - { - if (!*n) - return 0; - for (m--; (m > old_mask) && (*m == '?'); m--) - ; - if ((*m == '*') && (m > old_mask) && (m[-1] != '\\')) - return 0; - if (!wild) - return 1; - m = ma; - - /* Added to `mmatch' : Because '\?' and '\*' now is one character: */ - if ((*na == '\\') && ((na[1] == '*') || (na[1] == '?'))) - ++na; - - n = ++na; - } - else if (!*n) - { - while (*m == '*') - m++; - return (*m != 0); - } - if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?'))) - { - m++; - mq = 1; - } - else - mq = 0; - - /* Added to `mmatch' : Because '\?' and '\*' now is one character: */ - if ((*n == '\\') && ((n[1] == '*') || (n[1] == '?'))) - { - n++; - nq = 1; - } - else - nq = 0; - -/* - * This `if' has been changed compared to match() to do the following: - * Match when: - * old (m) new (n) boolean expression - * * any (*m == '*' && !mq) || - * ? any except '*' (*m == '?' && !mq && (*n != '*' || nq)) || - * any except * or ? same as m (!((*m == '*' || *m == '?') && !mq) && - * ToLower(*m) == ToLower(*n) && - * !((mq && !nq) || (!mq && nq))) - * - * Here `any' also includes \* and \? ! - * - * After reworking the boolean expressions, we get: - * (Optimized to use boolean short-circuits, with most frequently occurring - * cases upfront (which took 2 hours!)). - */ - if ((*m == '*' && !mq) || - ((!mq || nq) && ToLower(*m) == ToLower(*n)) || - (*m == '?' && !mq && (*n != '*' || nq))) - { - if (*m) - m++; - if (*n) - n++; - } - else - { - if (!wild) - return 1; - m = ma; - - /* Added to `mmatch' : Because '\?' and '\*' now is one character: */ - if ((*na == '\\') && ((na[1] == '*') || (na[1] == '?'))) - ++na; +int mmatch(const char* old_mask, const char* new_mask) { + const char* m = old_mask; + const char* n = new_mask; + const char* ma = m; + const char* na = n; + int wild = 0; + int mq = 0, nq = 0; + + while (1) { + if (*m == '*') { + while (*m == '*') + m++; + wild = 1; + ma = m; + na = n; + } - n = ++na; + if (!*m) { + if (!*n) + return 0; + for (m--; (m > old_mask) && (*m == '?'); m--) + ; + if ((*m == '*') && (m > old_mask) && (m[-1] != '\\')) + return 0; + if (!wild) + return 1; + m = ma; + + /* Added to `mmatch' : Because '\?' and '\*' now is one character: */ + if ((*na == '\\') && ((na[1] == '*') || (na[1] == '?'))) + ++na; + + n = ++na; + } else if (!*n) { + while (*m == '*') + m++; + return (*m != 0); + } + if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?'))) { + m++; + mq = 1; + } else + mq = 0; + + /* Added to `mmatch' : Because '\?' and '\*' now is one character: */ + if ((*n == '\\') && ((n[1] == '*') || (n[1] == '?'))) { + n++; + nq = 1; + } else + nq = 0; + + /* + * This `if' has been changed compared to match() to do the following: + * Match when: + * old (m) new (n) boolean expression + * * any (*m == '*' && !mq) || + * ? any except '*' (*m == '?' && !mq && (*n != '*' || nq)) || + * any except * or ? same as m (!((*m == '*' || *m == '?') && !mq) && + * ToLower(*m) == ToLower(*n) && + * !((mq && !nq) || (!mq && nq))) + * + * Here `any' also includes \* and \? ! + * + * After reworking the boolean expressions, we get: + * (Optimized to use boolean short-circuits, with most frequently occurring + * cases upfront (which took 2 hours!)). + */ + if ((*m == '*' && !mq) || ((!mq || nq) && ToLower(*m) == ToLower(*n)) || + (*m == '?' && !mq && (*n != '*' || nq))) { + if (*m) + m++; + if (*n) + n++; + } else { + if (!wild) + return 1; + m = ma; + + /* Added to `mmatch' : Because '\?' and '\*' now is one character: */ + if ((*na == '\\') && ((na[1] == '*') || (na[1] == '?'))) + ++na; + + n = ++na; + } } - } } /** Test whether an address matches the most significant bits of a mask. @@ -529,19 +495,19 @@ int mmatch(const char *old_mask, const char *new_mask) * @return 0 on mismatch, 1 if bits < 128 and all bits match; -1 if * bits == 128 and all bits match. */ -int ipmask_check(const struct irc_in_addr *addr, const struct irc_in_addr *mask, unsigned char bits) -{ - int k; - - for (k = 0; k < 8; k++) { - if (bits < 16) - return !(htons(addr->in6_16[k] ^ mask->in6_16[k]) >> (16-bits)); - if (addr->in6_16[k] != mask->in6_16[k]) - return 0; - if (!(bits -= 16)) - return 1; - } - return -1; +int ipmask_check(const struct irc_in_addr* addr, const struct irc_in_addr* mask, + unsigned char bits) { + int k; + + for (k = 0; k < 8; k++) { + if (bits < 16) + return !(htons(addr->in6_16[k] ^ mask->in6_16[k]) >> (16 - bits)); + if (addr->in6_16[k] != mask->in6_16[k]) + return 0; + if (!(bits -= 16)) + return 1; + } + return -1; } /* * collapse() @@ -554,47 +520,36 @@ int ipmask_check(const struct irc_in_addr *addr, const struct irc_in_addr *mask, * Note that this new optimized alghoritm can *only* work in place. */ -char *collapse(char *mask) -{ - bool star = false ; - char *m = mask; - char *b; - - if (m) - { - do - { - if ((*m == '*') && ((m[1] == '*') || (m[1] == '?'))) - { - b = m; - do - { - if (*m == '*') - star = true; - else - { - if (star && (*m != '?')) - { - *b++ = '*'; - star = false; +char* collapse(char* mask) { + bool star = false; + char* m = mask; + char* b; + + if (m) { + do { + if ((*m == '*') && ((m[1] == '*') || (m[1] == '?'))) { + b = m; + do { + if (*m == '*') + star = true; + else { + if (star && (*m != '?')) { + *b++ = '*'; + star = false; + }; + *b++ = *m; + if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?'))) + *b++ = *++m; + }; + } while (*m++); + break; + } else { + if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?'))) + m++; }; - *b++ = *m; - if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?'))) - *b++ = *++m; - }; - } - while (*m++); - break; - } - else - { - if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?'))) - m++; - }; - } - while (*m++); - }; - return mask; + } while (*m++); + }; + return mask; } /* @@ -605,21 +560,21 @@ char *collapse(char *mask) * by means of matchcomp() that gets the plain text mask as input and writes * its result in the memory locations addressed by the 3 parameters: * - *cmask will contain the text of the compiled mask - * - *minlen will contain the lenght of the shortest string that can match + * - *minlen will contain the lenght of the shortest string that can match * the mask * - *charset will contain the minimal set of chars needed to match the mask * You can pass NULL as *charset and it will be simply not returned, but you - * MUST pass valid pointers for *minlen and *cmask (wich must be big enough - * to contain the compiled mask text that is in the worst case as long as the - * text of the mask itself in plaintext format) and the return value of - * matchcomp() will be the number of chars actually written there (excluded + * MUST pass valid pointers for *minlen and *cmask (wich must be big enough + * to contain the compiled mask text that is in the worst case as long as the + * text of the mask itself in plaintext format) and the return value of + * matchcomp() will be the number of chars actually written there (excluded * the trailing zero). cmask can be == mask, matchcomp() can work in place. * The {cmask, minlen} couple of values make the real compiled mask and * need to be passed to the functions that use the compiled mask, if you pass * the wrong minlen or something wrong in cmask to one of these expect a * coredump. This means that when you record a compiled mask you must store * *both* these values. - * Once compiled the mask can be used to match a string by means of + * Once compiled the mask can be used to match a string by means of * matchexec(), it can be printed back to human-readable format by means * of sprintmatch() or it can be compared to another compiled mask by means * of mmexec() that will tell if it completely overrides that mask (a lot like @@ -642,7 +597,7 @@ char *collapse(char *mask) * bit is set it means that it contains only wild chars (and you can * match it with strlen(field)>=minlen). * Do these optimizations ONLY when the data you are about to pass to - * matchexec() are *known* to be invalid in advance, using strChattr() + * matchexec() are *known* to be invalid in advance, using strChattr() * or strlen() on the text would be slower than calling matchexec() directly * and let it fail. * Internally a compiled mask contain in the *cmask area the text of @@ -650,14 +605,14 @@ char *collapse(char *mask) * - All characters are forced to lowercase (so that uppercase letters and * specifically the symbols 'A' and 'Z' are reserved for special use) * - All non-escaped stars '*' are replaced by the letter 'Z' - * - All non-escaped question marks '?' are replaced by the letter 'A' + * - All non-escaped question marks '?' are replaced by the letter 'A' * - All escape characters are removed, the wilds escaped by them are * then passed by without the escape since they don't collide anymore - * with the real wilds (encoded as A/Z) + * with the real wilds (encoded as A/Z) * - Finally the part of the mask that follows the last asterisk is * reversed (byte order mirroring) and moved right after the first * asterisk. - * After all this a mask like: Head*CHUNK1*chu\*nK2*ch??k3*TaIl + * After all this a mask like: Head*CHUNK1*chu\*nK2*ch??k3*TaIl * .... becomes: headZliatZchunk1Zchu*nk2ZchAAk3 * This can still be printed on a console, more or less understood by an * human and handled with the usual str*() library functions. @@ -671,98 +626,89 @@ char *collapse(char *mask) * or when you expect to use mmexec() instead of mmatch() 3 times. */ - /* - * matchcomp() - * - * Compiles a mask into a form suitable for using in matchexec(). - */ - -int matchcomp(char *cmask, int *minlen, int *charset, const char *mask) -{ - const char *m = mask; - char *b = cmask; - char *fs = 0; - char *ls = 0; - char *x1, *x2; - int l1, l2, lmin, loop, sign; - bool star = false; - int cnt = 0; - char ch; - int chset = ~0; - int chset2 = (NTL_LOWER | NTL_UPPER); - - if (m) - while ((ch = *m++)) - switch (ch) - { - case '*': - star = true; - break; - case '?': - cnt++; - *b++ = 'A'; - chset2 &= ~NTL_LOWER; - break; - case '\\': - if ((*m == '?') || (*m == '*')) - ch = *m++; - /* fall through */ - default: - if (star) - { - ls = b; - fs = fs ? fs : b; - *b++ = 'Z'; - chset2 &= ~NTL_LOWER; - star = false; - }; - cnt++; - *b = ToLower(ch); - chset &= IRCD_CharAttrTab[*b++ - CHAR_MIN]; - chset2 &= ~NTL_UPPER; - }; - - if (charset) - *charset = (chset | chset2); - - if (star) - { - ls = b; - fs = (fs ? fs : b); - *b++ = 'Z'; - }; - - if (ls) - { - for (x1 = ls + 1, x2 = (b - 1); x1 < x2; x1++, x2--) - { - ch = *x1; - *x1 = *x2; - *x2 = ch; - }; - l1 = (ls - fs); - l2 = (b - ls); - x1 = fs; - while ((lmin = (l1 < l2) ? l1 : l2)) - { - x2 = x1 + l1; - for (loop = 0; loop < lmin; loop++) - { - ch = x1[loop]; - x1[loop] = x2[loop]; - x2[loop] = ch; - }; - x1 += lmin; - sign = l1 - l2; - l1 -= (sign < 0) ? 0 : lmin; - l2 -= (sign > 0) ? 0 : lmin; +/* + * matchcomp() + * + * Compiles a mask into a form suitable for using in matchexec(). + */ + +int matchcomp(char* cmask, int* minlen, int* charset, const char* mask) { + const char* m = mask; + char* b = cmask; + char* fs = 0; + char* ls = 0; + char *x1, *x2; + int l1, l2, lmin, loop, sign; + bool star = false; + int cnt = 0; + char ch; + int chset = ~0; + int chset2 = (NTL_LOWER | NTL_UPPER); + + if (m) + while ((ch = *m++)) + switch (ch) { + case '*': + star = true; + break; + case '?': + cnt++; + *b++ = 'A'; + chset2 &= ~NTL_LOWER; + break; + case '\\': + if ((*m == '?') || (*m == '*')) + ch = *m++; + /* fall through */ + default: + if (star) { + ls = b; + fs = fs ? fs : b; + *b++ = 'Z'; + chset2 &= ~NTL_LOWER; + star = false; + }; + cnt++; + *b = ToLower(ch); + chset &= IRCD_CharAttrTab[*b++ - CHAR_MIN]; + chset2 &= ~NTL_UPPER; + }; + + if (charset) + *charset = (chset | chset2); + + if (star) { + ls = b; + fs = (fs ? fs : b); + *b++ = 'Z'; }; - }; - *b = '\0'; - *minlen = cnt; - return (b - cmask); + if (ls) { + for (x1 = ls + 1, x2 = (b - 1); x1 < x2; x1++, x2--) { + ch = *x1; + *x1 = *x2; + *x2 = ch; + }; + l1 = (ls - fs); + l2 = (b - ls); + x1 = fs; + while ((lmin = (l1 < l2) ? l1 : l2)) { + x2 = x1 + l1; + for (loop = 0; loop < lmin; loop++) { + ch = x1[loop]; + x1[loop] = x2[loop]; + x2[loop] = ch; + }; + x1 += lmin; + sign = l1 - l2; + l1 -= (sign < 0) ? 0 : lmin; + l2 -= (sign > 0) ? 0 : lmin; + }; + }; + *b = '\0'; + *minlen = cnt; + return (b - cmask); } /* @@ -775,71 +721,70 @@ int matchcomp(char *cmask, int *minlen, int *charset, const char *mask) * Note 3: This piece of code is not intended to be nice but efficient. */ -int matchexec(const char *string, const char *cmask, int minlen) -{ - const char *s = string - 1; - const char *b = cmask - 1; - int trash; - const char *bb, *bs; - char ch; +int matchexec(const char* string, const char* cmask, int minlen) { + const char* s = string - 1; + const char* b = cmask - 1; + int trash; + const char *bb, *bs; + char ch; tryhead: - while ((ToLower(*++s) == *++b) && *s) { /* noop */ }; - if (!*s) - return ((*b != '\0') && ((*b++ != 'Z') || (*b != '\0'))); - if (*b != 'Z') - { - if (*b == 'A') - goto tryhead; - return 1; - }; + while ((ToLower(*++s) == *++b) && *s) { /* noop */ + }; + if (!*s) + return ((*b != '\0') && ((*b++ != 'Z') || (*b != '\0'))); + if (*b != 'Z') { + if (*b == 'A') + goto tryhead; + return 1; + }; - bs = s; - while (*++s) { /* noop */ }; + bs = s; + while (*++s) { /* noop */ + }; - if ((trash = (s - string - minlen)) < 0) - return 2; + if ((trash = (s - string - minlen)) < 0) + return 2; trytail: - while ((ToLower(*--s) == *++b) && *b && (ToLower(*--s) == *++b) && *b - && (ToLower(*--s) == *++b) && *b && (ToLower(*--s) == *++b) && *b) { /* noop */ }; - if (*b != 'Z') - { - if (*b == 'A') - goto trytail; - return (*b != '\0'); - }; - - s = --bs; - bb = b; - - while ((ch = *++b)) - { - while ((ToLower(*++s) != ch)) - if (--trash < 0) - return 4; - bs = s; - -trychunk: - while ((ToLower(*++s) == *++b) && *b) { /* noop */ }; - if (!*b) - return 0; - if (*b == 'Z') - { - bs = --s; - bb = b; - continue; + while ((ToLower(*--s) == *++b) && *b && (ToLower(*--s) == *++b) && *b && + (ToLower(*--s) == *++b) && *b && (ToLower(*--s) == *++b) && *b) { /* noop */ + }; + if (*b != 'Z') { + if (*b == 'A') + goto trytail; + return (*b != '\0'); }; - if (*b == 'A') - goto trychunk; - b = bb; - s = bs; - if (--trash < 0) - return 5; - }; + s = --bs; + bb = b; + + while ((ch = *++b)) { + while ((ToLower(*++s) != ch)) + if (--trash < 0) + return 4; + bs = s; + + trychunk: + while ((ToLower(*++s) == *++b) && *b) { /* noop */ + }; + if (!*b) + return 0; + if (*b == 'Z') { + bs = --s; + bb = b; + continue; + }; + if (*b == 'A') + goto trychunk; + + b = bb; + s = bs; + if (--trash < 0) + return 5; + }; - return 0; + return 0; } /* @@ -855,61 +800,57 @@ int matchexec(const char *string, const char *cmask, int minlen) * It returns the number of chars actually written to *mask; */ -int matchdecomp(char *mask, const char *cmask) -{ - char *rtb = mask; - const char *rcm = cmask; - const char *begtail, *endtail; - - if (rtb ==0) - return (-1); - - if (rcm == 0) - return (-2); - - for (; (*rcm != 'Z'); rcm++, rtb++) - { - if ((*rcm == '?') || (*rcm == '*')) - *rtb++ = '\\'; - if (!((*rtb = ((*rcm == 'A') ? '?' : *rcm)))) - return (rtb - mask); - }; - - begtail = rcm++; - *rtb++ = '*'; - - while (*rcm && (*rcm != 'Z')) - rcm++; - - endtail = rcm; - - if (*rcm) - { - while (*++rcm) - switch (*rcm) - { - case 'A': - *rtb++ = '?'; - break; - case 'Z': - *rtb++ = '*'; - break; - case '*': - case '?': - *rtb++ = '\\'; - /* fall through */ - default: - *rtb++ = *rcm; - }; +int matchdecomp(char* mask, const char* cmask) { + char* rtb = mask; + const char* rcm = cmask; + const char *begtail, *endtail; + + if (rtb == 0) + return (-1); + + if (rcm == 0) + return (-2); + + for (; (*rcm != 'Z'); rcm++, rtb++) { + if ((*rcm == '?') || (*rcm == '*')) + *rtb++ = '\\'; + if (!((*rtb = ((*rcm == 'A') ? '?' : *rcm)))) + return (rtb - mask); + }; + + begtail = rcm++; *rtb++ = '*'; - }; - for (rcm = endtail; (--rcm) > begtail; *rtb++ = ((*rcm == 'A') ? '?' : *rcm)) - if ((*rcm == '?') || (*rcm == '*')) - *rtb++ = '\\'; + while (*rcm && (*rcm != 'Z')) + rcm++; + + endtail = rcm; + + if (*rcm) { + while (*++rcm) + switch (*rcm) { + case 'A': + *rtb++ = '?'; + break; + case 'Z': + *rtb++ = '*'; + break; + case '*': + case '?': + *rtb++ = '\\'; + /* fall through */ + default: + *rtb++ = *rcm; + }; + *rtb++ = '*'; + }; + + for (rcm = endtail; (--rcm) > begtail; *rtb++ = ((*rcm == 'A') ? '?' : *rcm)) + if ((*rcm == '?') || (*rcm == '*')) + *rtb++ = '\\'; - *rtb = '\0'; - return (rtb - mask); + *rtb = '\0'; + return (rtb - mask); } /* @@ -918,207 +859,193 @@ int matchdecomp(char *mask, const char *cmask) * a more restrict one (rcm/rminlen), basically what mmatch() does for * non-compiled masks, returns 0 if the override is true (like mmatch()). * "the wider overrides the restrict" means that any string that matches - * the restrict one _will_ also match the wider one, always. - * In this we behave differently from mmatch() because in example we return - * true for " a?*cd overrides a*bcd " for wich the override happens for how + * the restrict one _will_ also match the wider one, always. + * In this we behave differently from mmatch() because in example we return + * true for " a?*cd overrides a*bcd " for wich the override happens for how * we literally defined it, here mmatch() would have returned false. - * The original concepts and the base alghoritm are copied from mmatch() + * The original concepts and the base alghoritm are copied from mmatch() * written by Run (Carlo Wood), this function is written by * Nemesi (Andrea Cocito) */ -int mmexec(const char *wcm, int wminlen, const char *rcm, int rminlen) -{ - const char *w, *r, *br, *bw, *rx, *rz; - int eat, trash; - - /* First of all rm must have enough non-stars to 'contain' wm */ - if ((trash = rminlen - wminlen) < 0) - return 1; - w = wcm; - r = rcm; - eat = 0; - - /* Let's start the game, remember that '*' is mapped to 'Z', '?' - is mapped to 'A' and that head?*??*?chunk*???*tail becomes - headAAAAZliatAAAZchunk for compiled masks */ - - /* Match the head of wm with the head of rm */ - for (; (*r) && (*r != 'Z') && ((*w == *r) || (*w == 'A')); r++, w++) { /* noop */ }; - if (*r == 'Z') - while (*w == 'A') /* Eat extra '?' before '*' in wm if got '*' in rm */ - w++, eat++; - if (*w != 'Z') /* head1.. can't match head2.. */ - return ((*w) || (*r)) ? 1 : 0; /* and head matches only head */ - if (!*++w) - return 0; /* headZ matches head */ - - /* Does rm have any stars in it ? let's check */ - for (rx = r; *r && (*r != 'Z'); r++) { /* noop */ }; - if (!*r) - { - /* rm has no stars and thus isn't a mask but it's just a flat - string: special handling occurs here, note that eat must be 0 here */ - - /* match the tail */ - if (*w != 'Z') - { - for (; r--, (*w) && ((*w == *r) || (*w == 'A')); w++) { /* noop */ }; - if (*w != 'Z') /* headZliat1 fails on head2tail */ - return (*w) ? 1 : 0; /* but headZliat matches headtail */ - } +int mmexec(const char* wcm, int wminlen, const char* rcm, int rminlen) { + const char *w, *r, *br, *bw, *rx, *rz; + int eat, trash; - /* match the chunks */ - while (1) - { /* This loop can't break but only return */ - - for (bw = w++; (*w != *rx); rx++) /* Seek the 1st char of the chunk */ - if (--trash < 0) /* See if we can trash one more char of rm */ - return 1; /* If not we can only fail of course */ - for (r = ++rx, w++; (*w) && ((*w == *r) || (*w == 'A')); r++, w++) { /* noop */ }; - if (!*w) /* Did last loop match the rest of chunk ? */ - return 0; /* ... Yes, end of wm, matched ! */ - if (*w != 'Z') - { /* ... No, hitted non-star */ - w = bw; /* Rollback at beginning of chunk */ - if (--trash < 0) /* Trashed the char where this try started */ - return 1; /* if we can't trash more chars fail */ - } - else - { - rx = r; /* Successfully matched a chunk, move rx */ - } /* and go on with the next one */ - } - } - - /* rm has at least one '*' and thus is a 'real' mask */ - rz = r++; /* rx = unused of head, rz = beg-tail */ - - /* Match the tail of wm (if any) against the tail of rm */ - if (*w != 'Z') - { - for (; (*w) && (*r != 'Z') && ((*w == *r) || (*w == 'A')); w++, r++) { /* noop */ }; - if (*r == 'Z') /* extra '?' before tail are fluff, just flush 'em */ - while (*w == 'A') - w++; - if (*w != 'Z') /* We aren't matching a chunk, can't rollback */ - return (*w) ? 1 : 0; - } - - /* Match the chunks of wm against what remains of the head of rm */ - while (1) - { - bw = w; - for (bw++; (rx < rz) && (*bw != *rx); rx++) /* Seek the first */ - if (--trash < 0) /* waste some trash reserve */ - return 1; - if (!(rx < rz)) /* head finished */ - break; - for (bw++, (br = ++rx); - (br < rz) && (*bw) && ((*bw == *br) || (*bw == 'A')); br++, bw++) { /* noop */ }; - if (!(br < rz)) /* Note that we didn't use any 'eat' char yet, if */ - while (*bw == 'A') /* there were eat-en chars the head would be over */ - bw++, eat++; /* Happens only at end of head, and eat is still 0 */ - if (!*bw) - return 0; - if (*bw != 'Z') - { - eat = 0; - if (!(br < rz)) - { /* If we failed because we got the end of head */ - trash -= (br - rx); /* it makes no sense to rollback, just trash */ - if (--trash < 0) /* all the rest of the head wich isn't long */ - return 1; /* enough for this chunk and go out of this */ - break; /* loop, then we try with the chunks of rm */ - }; - if (--trash < 0) + /* First of all rm must have enough non-stars to 'contain' wm */ + if ((trash = rminlen - wminlen) < 0) return 1; + w = wcm; + r = rcm; + eat = 0; + + /* Let's start the game, remember that '*' is mapped to 'Z', '?' + is mapped to 'A' and that head?*??*?chunk*???*tail becomes + headAAAAZliatAAAZchunk for compiled masks */ + + /* Match the head of wm with the head of rm */ + for (; (*r) && (*r != 'Z') && ((*w == *r) || (*w == 'A')); r++, w++) { /* noop */ + }; + if (*r == 'Z') + while (*w == 'A') /* Eat extra '?' before '*' in wm if got '*' in rm */ + w++, eat++; + if (*w != 'Z') /* head1.. can't match head2.. */ + return ((*w) || (*r)) ? 1 : 0; /* and head matches only head */ + if (!*++w) + return 0; /* headZ matches head */ + + /* Does rm have any stars in it ? let's check */ + for (rx = r; *r && (*r != 'Z'); r++) { /* noop */ + }; + if (!*r) { + /* rm has no stars and thus isn't a mask but it's just a flat + string: special handling occurs here, note that eat must be 0 here */ + + /* match the tail */ + if (*w != 'Z') { + for (; r--, (*w) && ((*w == *r) || (*w == 'A')); w++) { /* noop */ + }; + if (*w != 'Z') /* headZliat1 fails on head2tail */ + return (*w) ? 1 : 0; /* but headZliat matches headtail */ + } + + /* match the chunks */ + while (1) { /* This loop can't break but only return */ + + for (bw = w++; (*w != *rx); rx++) /* Seek the 1st char of the chunk */ + if (--trash < 0) /* See if we can trash one more char of rm */ + return 1; /* If not we can only fail of course */ + for (r = ++rx, w++; (*w) && ((*w == *r) || (*w == 'A')); r++, w++) { /* noop */ + }; + if (!*w) /* Did last loop match the rest of chunk ? */ + return 0; /* ... Yes, end of wm, matched ! */ + if (*w != 'Z') { /* ... No, hitted non-star */ + w = bw; /* Rollback at beginning of chunk */ + if (--trash < 0) /* Trashed the char where this try started */ + return 1; /* if we can't trash more chars fail */ + } else { + rx = r; /* Successfully matched a chunk, move rx */ + } /* and go on with the next one */ + } } - else - { - w = bw; - rx = br; + + /* rm has at least one '*' and thus is a 'real' mask */ + rz = r++; /* rx = unused of head, rz = beg-tail */ + + /* Match the tail of wm (if any) against the tail of rm */ + if (*w != 'Z') { + for (; (*w) && (*r != 'Z') && ((*w == *r) || (*w == 'A')); w++, r++) { /* noop */ + }; + if (*r == 'Z') /* extra '?' before tail are fluff, just flush 'em */ + while (*w == 'A') + w++; + if (*w != 'Z') /* We aren't matching a chunk, can't rollback */ + return (*w) ? 1 : 0; } - } - - /* Match the unused chunks of wm against the chunks of rm */ - rx = r; - for (; *r && (*r != 'Z'); r++) { /* noop */ }; - rz = r; - if (*r++) - { - while (*r) - { - bw = w; - while (eat && *r) /* the '?' we had eated make us skip as many chars */ - if (*r++ != 'Z') /* here, but can't skip stars or trailing zero */ - eat--; - for (bw++; (*r) && (*bw != *r); r++) - if ((*r != 'Z') && (--trash < 0)) - return 1; - if (!*r) - break; - for ((br = ++r), bw++; - (*br) && (*br != 'Z') && ((*bw == *br) || (*bw == 'A')); br++, bw++) { /* noop */ }; - if (*br == 'Z') - while (*bw == 'A') - bw++, eat++; - if (!*bw) - return 0; - if (*bw != 'Z') - { - eat = 0; - if ((!*br) || (*r == 'Z')) - { /* If we hit the end of rm or a star in it */ - trash -= (br - r); /* makes no sense to rollback within this */ - if (trash < 0) /* same chunk of br, skip it all and then */ - return 1; /* either rollback or break this loop if */ - if (!*br) /* it was the end of rm */ + + /* Match the chunks of wm against what remains of the head of rm */ + while (1) { + bw = w; + for (bw++; (rx < rz) && (*bw != *rx); rx++) /* Seek the first */ + if (--trash < 0) /* waste some trash reserve */ + return 1; + if (!(rx < rz)) /* head finished */ break; - r = br; + for (bw++, (br = ++rx); (br < rz) && (*bw) && ((*bw == *br) || (*bw == 'A')); + br++, bw++) { /* noop */ + }; + if (!(br < rz)) /* Note that we didn't use any 'eat' char yet, if */ + while (*bw == 'A') /* there were eat-en chars the head would be over */ + bw++, eat++; /* Happens only at end of head, and eat is still 0 */ + if (!*bw) + return 0; + if (*bw != 'Z') { + eat = 0; + if (!(br < rz)) { /* If we failed because we got the end of head */ + trash -= (br - rx); /* it makes no sense to rollback, just trash */ + if (--trash < 0) /* all the rest of the head wich isn't long */ + return 1; /* enough for this chunk and go out of this */ + break; /* loop, then we try with the chunks of rm */ + }; + if (--trash < 0) + return 1; + } else { + w = bw; + rx = br; } - if (--trash < 0) - return 1; - } - else - { - r = br; - w = bw; - } } - } - - /* match the remaining chunks of wm against what remains of the tail of rm */ - r = rz - eat - 1; /* can't have or 'Z'within the tail, so just move r */ - while (r >= rx) - { - bw = w; - for (bw++; (*bw != *r); r--) - if (--trash < 0) - return 1; - if (!(r >= rx)) - return 1; - for ((br = --r), bw++; - (*bw) && (br >= rx) && ((*bw == *br) || (*bw == 'A')); br--, bw++) { /* noop */ }; - if (!*bw) - return 0; - if (!(br >= rx)) - return 1; - if (*bw != 'Z') - { - if (--trash < 0) - return 1; + + /* Match the unused chunks of wm against the chunks of rm */ + rx = r; + for (; *r && (*r != 'Z'); r++) { /* noop */ + }; + rz = r; + if (*r++) { + while (*r) { + bw = w; + while (eat && *r) /* the '?' we had eated make us skip as many chars */ + if (*r++ != 'Z') /* here, but can't skip stars or trailing zero */ + eat--; + for (bw++; (*r) && (*bw != *r); r++) + if ((*r != 'Z') && (--trash < 0)) + return 1; + if (!*r) + break; + for ((br = ++r), bw++; (*br) && (*br != 'Z') && ((*bw == *br) || (*bw == 'A')); + br++, bw++) { /* noop */ + }; + if (*br == 'Z') + while (*bw == 'A') + bw++, eat++; + if (!*bw) + return 0; + if (*bw != 'Z') { + eat = 0; + if ((!*br) || (*r == 'Z')) { /* If we hit the end of rm or a star in it */ + trash -= (br - r); /* makes no sense to rollback within this */ + if (trash < 0) /* same chunk of br, skip it all and then */ + return 1; /* either rollback or break this loop if */ + if (!*br) /* it was the end of rm */ + break; + r = br; + } + if (--trash < 0) + return 1; + } else { + r = br; + w = bw; + } + } } - else - { - r = br; - w = bw; + + /* match the remaining chunks of wm against what remains of the tail of rm */ + r = rz - eat - 1; /* can't have or 'Z'within the tail, so just move r */ + while (r >= rx) { + bw = w; + for (bw++; (*bw != *r); r--) + if (--trash < 0) + return 1; + if (!(r >= rx)) + return 1; + for ((br = --r), bw++; (*bw) && (br >= rx) && ((*bw == *br) || (*bw == 'A')); + br--, bw++) { /* noop */ + }; + if (!*bw) + return 0; + if (!(br >= rx)) + return 1; + if (*bw != 'Z') { + if (--trash < 0) + return 1; + } else { + r = br; + w = bw; + } } - } - return 1; /* Auch... something left out ? Fail */ + return 1; /* Auch... something left out ? Fail */ } -//int addrMatch(const string& mask, const string& address) +// int addrMatch(const string& mask, const string& address) //{ // // A two step checking, first we try to pass the address from the nick!user part ... // if (isUserHost(mask) && isUserHost(address)) @@ -1126,7 +1053,8 @@ int mmexec(const char *wcm, int wminlen, const char *rcm, int rminlen) // if (match(extractNickUser(mask), extractNickUser(address))) // return 1; // -// /* If passed, we deal only with the hostip part, and because match() handles cidr addresses too +// /* If passed, we deal only with the hostip part, and because match() handles cidr +//addresses too // * our matching is complete. // */ // if (match(extractHostIP(mask), extractHostIP(address)) == 0) @@ -1137,9 +1065,9 @@ int mmexec(const char *wcm, int wminlen, const char *rcm, int rminlen) // return 0; // // return 1; -//} +// } -//int addrMatch(const string& mask, const iClient* theClient) +// int addrMatch(const string& mask, const iClient* theClient) //{ // if (!isUserHost(mask)) // return false; @@ -1154,23 +1082,20 @@ int mmexec(const char *wcm, int wminlen, const char *rcm, int rminlen) // return 0; // // return 1; -//} +// } /* * An attempt to cover as much possible variations of a 'matching all mask' */ -int matchall(const std::string& mask) -{ - for (unsigned int i = 0; i < mask.length(); i++) - { - char c = mask[i]; - if ((c != '*') && (c != '?') && (c != '.') && (c != '!') && (c != '@') && (c != '~')) - return 1; - } - return 0; +int matchall(const std::string& mask) { + for (unsigned int i = 0; i < mask.length(); i++) { + char c = mask[i]; + if ((c != '*') && (c != '?') && (c != '.') && (c != '!') && (c != '@') && (c != '~')) + return 1; + } + return 0; } - /* This function is written to allow cidr matching between two CIDR addresses, * regardless of which one was supplied first. * Exemple: match(10.10.10.0/24, 10.0.0.0/8) wouldn't return a positive match, @@ -1178,36 +1103,32 @@ int matchall(const std::string& mask) * * this function will return a positive match (return 0) for both queries */ -int cidrmatch(const char *mask1, const char *mask2) -{ - StringTokenizer st1(mask1, '/'); - StringTokenizer st2(mask2, '/'); - unsigned char c1, c2; - - if (st1.size() < 2) - c1 = -1; - else - c1 = atoi(st1[1]); - - if (st2.size() < 2) - c2 = -1; - else - c2 = atoi(st2[1]); - - - if (c2 > c1) - return match(mask1, mask2); - else - return match(mask2, mask1); -} +int cidrmatch(const char* mask1, const char* mask2) { + StringTokenizer st1(mask1, '/'); + StringTokenizer st2(mask2, '/'); + unsigned char c1, c2; + + if (st1.size() < 2) + c1 = -1; + else + c1 = atoi(st1[1]); -int cidrmatch(const string& s1, const string& s2) -{ - if (s1.empty() || s2.empty()) - return 1; - - return cidrmatch(s1.c_str(), s2.c_str()); + if (st2.size() < 2) + c2 = -1; + else + c2 = atoi(st2[1]); + + if (c2 > c1) + return match(mask1, mask2); + else + return match(mask2, mask1); } +int cidrmatch(const string& s1, const string& s2) { + if (s1.empty() || s2.empty()) + return 1; + + return cidrmatch(s1.c_str(), s2.c_str()); +} } // namespace gnuworld diff --git a/libgnuworld/match.h b/libgnuworld/match.h old mode 100755 new mode 100644 index 0c850fe0..bc7714cb --- a/libgnuworld/match.h +++ b/libgnuworld/match.h @@ -22,15 +22,14 @@ #ifndef __MATCH_H #define __MATCH_H "$Id: match.h,v 1.4 2003/12/29 23:59:36 dan_karrels Exp $" -#include +#include -#include "match_table.h" -#include "ircd_chattr.h" -#include "Numeric.h" -#include "iClient.h" +#include "match_table.h" +#include "ircd_chattr.h" +#include "Numeric.h" +#include "iClient.h" -namespace gnuworld -{ +namespace gnuworld { using std::string; /* * Prototypes @@ -40,24 +39,25 @@ using std::string; * XXX - match returns 0 if a match is found. Smelly interface * needs to be fixed. --Bleep */ -int match( const string&, const string& ) ; +int match(const string&, const string&); int match(const string&, const iClient*); -int match( const char *ma, const char *na); -int smatch( const char *mask, const char *name ); -int casematch( const char *ma, const char *na); -int casematch( const std::string& s1, const std::string& s2 ); -int mmatch( const char *old_mask, const char *new_mask); -int ipmask_check(const struct irc_in_addr *addr, const struct irc_in_addr *mask, unsigned char bits); +int match(const char* ma, const char* na); +int smatch(const char* mask, const char* name); +int casematch(const char* ma, const char* na); +int casematch(const std::string& s1, const std::string& s2); +int mmatch(const char* old_mask, const char* new_mask); +int ipmask_check(const struct irc_in_addr* addr, const struct irc_in_addr* mask, + unsigned char bits); -char *collapse(char *pattern); +char* collapse(char* pattern); -int matchcomp(char *cmask, int *minlen, int *charset, const char *mask); -int matchexec(const char *string, const char *cmask, int minlen); -int matchdecomp(char *mask, const char *cmask); -int mmexec(const char *wcm, int wminlen, const char *rcm, int rminlen); -//Given mask matches with every mask +int matchcomp(char* cmask, int* minlen, int* charset, const char* mask); +int matchexec(const char* string, const char* cmask, int minlen); +int matchdecomp(char* mask, const char* cmask); +int mmexec(const char* wcm, int wminlen, const char* rcm, int rminlen); +// Given mask matches with every mask int matchall(const std::string&); -int cidrmatch(const char *mask1, const char *mask2); +int cidrmatch(const char* mask1, const char* mask2); int cidrmatch(const string&, const string&); } // namespace gnuworld diff --git a/libgnuworld/match_table.h b/libgnuworld/match_table.h old mode 100755 new mode 100644 index 5ddc62fb..aa570c58 --- a/libgnuworld/match_table.h +++ b/libgnuworld/match_table.h @@ -6,174 +6,1179 @@ */ #include const char ToLowerTab_8859_1[] = { -#if (CHAR_MIN<0) -/* x80-x87 */ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', -/* x88-x8f */ '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', -/* x90-x97 */ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', -/* x98-x9f */ '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f', -/* xa0-xa7 */ '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7', -/* xa8-xaf */ '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf', -/* xb0-xb7 */ '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7', -/* xb8-xbf */ '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf', -/* xc0-xc7 */ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', -/* xc8-xcf */ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', -/* xd0-xd7 */ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xd7', -/* xd8-xdf */ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xdf', -/* xe0-xe7 */ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', -/* xe8-xef */ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', -/* xf0-xf7 */ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7', -/* xf8-xff */ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff' - , +#if (CHAR_MIN < 0) + /* x80-x87 */ '\x80', + '\x81', + '\x82', + '\x83', + '\x84', + '\x85', + '\x86', + '\x87', + /* x88-x8f */ '\x88', + '\x89', + '\x8a', + '\x8b', + '\x8c', + '\x8d', + '\x8e', + '\x8f', + /* x90-x97 */ '\x90', + '\x91', + '\x92', + '\x93', + '\x94', + '\x95', + '\x96', + '\x97', + /* x98-x9f */ '\x98', + '\x99', + '\x9a', + '\x9b', + '\x9c', + '\x9d', + '\x9e', + '\x9f', + /* xa0-xa7 */ '\xa0', + '\xa1', + '\xa2', + '\xa3', + '\xa4', + '\xa5', + '\xa6', + '\xa7', + /* xa8-xaf */ '\xa8', + '\xa9', + '\xaa', + '\xab', + '\xac', + '\xad', + '\xae', + '\xaf', + /* xb0-xb7 */ '\xb0', + '\xb1', + '\xb2', + '\xb3', + '\xb4', + '\xb5', + '\xb6', + '\xb7', + /* xb8-xbf */ '\xb8', + '\xb9', + '\xba', + '\xbb', + '\xbc', + '\xbd', + '\xbe', + '\xbf', + /* xc0-xc7 */ '\xe0', + '\xe1', + '\xe2', + '\xe3', + '\xe4', + '\xe5', + '\xe6', + '\xe7', + /* xc8-xcf */ '\xe8', + '\xe9', + '\xea', + '\xeb', + '\xec', + '\xed', + '\xee', + '\xef', + /* xd0-xd7 */ '\xf0', + '\xf1', + '\xf2', + '\xf3', + '\xf4', + '\xf5', + '\xf6', + '\xd7', + /* xd8-xdf */ '\xf8', + '\xf9', + '\xfa', + '\xfb', + '\xfc', + '\xfd', + '\xfe', + '\xdf', + /* xe0-xe7 */ '\xe0', + '\xe1', + '\xe2', + '\xe3', + '\xe4', + '\xe5', + '\xe6', + '\xe7', + /* xe8-xef */ '\xe8', + '\xe9', + '\xea', + '\xeb', + '\xec', + '\xed', + '\xee', + '\xef', + /* xf0-xf7 */ '\xf0', + '\xf1', + '\xf2', + '\xf3', + '\xf4', + '\xf5', + '\xf6', + '\xf7', + /* xf8-xff */ '\xf8', + '\xf9', + '\xfa', + '\xfb', + '\xfc', + '\xfd', + '\xfe', + '\xff', #endif /* (CHAR_MIN<0) */ -/* x00-x07 */ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', -/* x08-x0f */ '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', -/* x10-x17 */ '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', -/* x18-x1f */ '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', -/* ' '-x27 */ ' ', '!', '"', '#', '$', '%', '&', '\x27', -/* '('-'/' */ '(', ')', '*', '+', ',', '-', '.', '/', -/* '0'-'7' */ '0', '1', '2', '3', '4', '5', '6', '7', -/* '8'-'?' */ '8', '9', ':', ';', '<', '=', '>', '?', -/* '@'-'G' */ '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', -/* 'H'-'O' */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', -/* 'P'-'W' */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', -/* 'X'-'_' */ 'x', 'y', 'z', '{', '|', '}', '~', '_', -/* '`'-'g' */ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', -/* 'h'-'o' */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', -/* 'p'-'w' */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', -/* 'x'-x7f */ 'x', 'y', 'z', '{', '|', '}', '~', '\x7f' -#if (!(CHAR_MIN<0)) - , -/* x80-x87 */ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', -/* x88-x8f */ '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', -/* x90-x97 */ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', -/* x98-x9f */ '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f', -/* xa0-xa7 */ '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7', -/* xa8-xaf */ '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf', -/* xb0-xb7 */ '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7', -/* xb8-xbf */ '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf', -/* xc0-xc7 */ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', -/* xc8-xcf */ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', -/* xd0-xd7 */ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xd7', -/* xd8-xdf */ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xdf', -/* xe0-xe7 */ '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', -/* xe8-xef */ '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef', -/* xf0-xf7 */ '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7', -/* xf8-xff */ '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff' + /* x00-x07 */ '\x00', + '\x01', + '\x02', + '\x03', + '\x04', + '\x05', + '\x06', + '\x07', + /* x08-x0f */ '\x08', + '\x09', + '\x0a', + '\x0b', + '\x0c', + '\x0d', + '\x0e', + '\x0f', + /* x10-x17 */ '\x10', + '\x11', + '\x12', + '\x13', + '\x14', + '\x15', + '\x16', + '\x17', + /* x18-x1f */ '\x18', + '\x19', + '\x1a', + '\x1b', + '\x1c', + '\x1d', + '\x1e', + '\x1f', + /* ' '-x27 */ ' ', + '!', + '"', + '#', + '$', + '%', + '&', + '\x27', + /* '('-'/' */ '(', + ')', + '*', + '+', + ',', + '-', + '.', + '/', + /* '0'-'7' */ '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + /* '8'-'?' */ '8', + '9', + ':', + ';', + '<', + '=', + '>', + '?', + /* '@'-'G' */ '@', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + /* 'H'-'O' */ 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + /* 'P'-'W' */ 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + /* 'X'-'_' */ 'x', + 'y', + 'z', + '{', + '|', + '}', + '~', + '_', + /* '`'-'g' */ '`', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + /* 'h'-'o' */ 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + /* 'p'-'w' */ 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + /* 'x'-x7f */ 'x', + 'y', + 'z', + '{', + '|', + '}', + '~', + '\x7f' +#if (!(CHAR_MIN < 0)) + , + /* x80-x87 */ '\x80', + '\x81', + '\x82', + '\x83', + '\x84', + '\x85', + '\x86', + '\x87', + /* x88-x8f */ '\x88', + '\x89', + '\x8a', + '\x8b', + '\x8c', + '\x8d', + '\x8e', + '\x8f', + /* x90-x97 */ '\x90', + '\x91', + '\x92', + '\x93', + '\x94', + '\x95', + '\x96', + '\x97', + /* x98-x9f */ '\x98', + '\x99', + '\x9a', + '\x9b', + '\x9c', + '\x9d', + '\x9e', + '\x9f', + /* xa0-xa7 */ '\xa0', + '\xa1', + '\xa2', + '\xa3', + '\xa4', + '\xa5', + '\xa6', + '\xa7', + /* xa8-xaf */ '\xa8', + '\xa9', + '\xaa', + '\xab', + '\xac', + '\xad', + '\xae', + '\xaf', + /* xb0-xb7 */ '\xb0', + '\xb1', + '\xb2', + '\xb3', + '\xb4', + '\xb5', + '\xb6', + '\xb7', + /* xb8-xbf */ '\xb8', + '\xb9', + '\xba', + '\xbb', + '\xbc', + '\xbd', + '\xbe', + '\xbf', + /* xc0-xc7 */ '\xe0', + '\xe1', + '\xe2', + '\xe3', + '\xe4', + '\xe5', + '\xe6', + '\xe7', + /* xc8-xcf */ '\xe8', + '\xe9', + '\xea', + '\xeb', + '\xec', + '\xed', + '\xee', + '\xef', + /* xd0-xd7 */ '\xf0', + '\xf1', + '\xf2', + '\xf3', + '\xf4', + '\xf5', + '\xf6', + '\xd7', + /* xd8-xdf */ '\xf8', + '\xf9', + '\xfa', + '\xfb', + '\xfc', + '\xfd', + '\xfe', + '\xdf', + /* xe0-xe7 */ '\xe0', + '\xe1', + '\xe2', + '\xe3', + '\xe4', + '\xe5', + '\xe6', + '\xe7', + /* xe8-xef */ '\xe8', + '\xe9', + '\xea', + '\xeb', + '\xec', + '\xed', + '\xee', + '\xef', + /* xf0-xf7 */ '\xf0', + '\xf1', + '\xf2', + '\xf3', + '\xf4', + '\xf5', + '\xf6', + '\xf7', + /* xf8-xff */ '\xf8', + '\xf9', + '\xfa', + '\xfb', + '\xfc', + '\xfd', + '\xfe', + '\xff' #endif /* (!(CHAR_MIN<0)) */ - }; +}; const char ToUpperTab_8859_1[] = { -#if (CHAR_MIN<0) -/* x80-x87 */ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', -/* x88-x8f */ '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', -/* x90-x97 */ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', -/* x98-x9f */ '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f', -/* xa0-xa7 */ '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7', -/* xa8-xaf */ '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf', -/* xb0-xb7 */ '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7', -/* xb8-xbf */ '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf', -/* xc0-xc7 */ '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', -/* xc8-xcf */ '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', -/* xd0-xd7 */ '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7', -/* xd8-xdf */ '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', -/* xe0-xe7 */ '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', -/* xe8-xef */ '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', -/* xf0-xf7 */ '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xf7', -/* xf8-xff */ '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xff' - , +#if (CHAR_MIN < 0) + /* x80-x87 */ '\x80', + '\x81', + '\x82', + '\x83', + '\x84', + '\x85', + '\x86', + '\x87', + /* x88-x8f */ '\x88', + '\x89', + '\x8a', + '\x8b', + '\x8c', + '\x8d', + '\x8e', + '\x8f', + /* x90-x97 */ '\x90', + '\x91', + '\x92', + '\x93', + '\x94', + '\x95', + '\x96', + '\x97', + /* x98-x9f */ '\x98', + '\x99', + '\x9a', + '\x9b', + '\x9c', + '\x9d', + '\x9e', + '\x9f', + /* xa0-xa7 */ '\xa0', + '\xa1', + '\xa2', + '\xa3', + '\xa4', + '\xa5', + '\xa6', + '\xa7', + /* xa8-xaf */ '\xa8', + '\xa9', + '\xaa', + '\xab', + '\xac', + '\xad', + '\xae', + '\xaf', + /* xb0-xb7 */ '\xb0', + '\xb1', + '\xb2', + '\xb3', + '\xb4', + '\xb5', + '\xb6', + '\xb7', + /* xb8-xbf */ '\xb8', + '\xb9', + '\xba', + '\xbb', + '\xbc', + '\xbd', + '\xbe', + '\xbf', + /* xc0-xc7 */ '\xc0', + '\xc1', + '\xc2', + '\xc3', + '\xc4', + '\xc5', + '\xc6', + '\xc7', + /* xc8-xcf */ '\xc8', + '\xc9', + '\xca', + '\xcb', + '\xcc', + '\xcd', + '\xce', + '\xcf', + /* xd0-xd7 */ '\xd0', + '\xd1', + '\xd2', + '\xd3', + '\xd4', + '\xd5', + '\xd6', + '\xd7', + /* xd8-xdf */ '\xd8', + '\xd9', + '\xda', + '\xdb', + '\xdc', + '\xdd', + '\xde', + '\xdf', + /* xe0-xe7 */ '\xc0', + '\xc1', + '\xc2', + '\xc3', + '\xc4', + '\xc5', + '\xc6', + '\xc7', + /* xe8-xef */ '\xc8', + '\xc9', + '\xca', + '\xcb', + '\xcc', + '\xcd', + '\xce', + '\xcf', + /* xf0-xf7 */ '\xd0', + '\xd1', + '\xd2', + '\xd3', + '\xd4', + '\xd5', + '\xd6', + '\xf7', + /* xf8-xff */ '\xd8', + '\xd9', + '\xda', + '\xdb', + '\xdc', + '\xdd', + '\xde', + '\xff', #endif /* (CHAR_MIN<0) */ -/* x00-x07 */ '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', -/* x08-x0f */ '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', -/* x10-x17 */ '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', -/* x18-x1f */ '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', -/* ' '-x27 */ ' ', '!', '"', '#', '$', '%', '&', '\x27', -/* '('-'/' */ '(', ')', '*', '+', ',', '-', '.', '/', -/* '0'-'7' */ '0', '1', '2', '3', '4', '5', '6', '7', -/* '8'-'?' */ '8', '9', ':', ';', '<', '=', '>', '?', -/* '@'-'G' */ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', -/* 'H'-'O' */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', -/* 'P'-'W' */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', -/* 'X'-'_' */ 'X', 'Y', 'Z', '[', '\x5c', ']', '^', '_', -/* '`'-'g' */ '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', -/* 'h'-'o' */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', -/* 'p'-'w' */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', -/* 'x'-x7f */ 'X', 'Y', 'Z', '[', '\x5c', ']', '^', '\x7f' -#if (!(CHAR_MIN<0)) - , -/* x80-x87 */ '\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87', -/* x88-x8f */ '\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f', -/* x90-x97 */ '\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97', -/* x98-x9f */ '\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f', -/* xa0-xa7 */ '\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7', -/* xa8-xaf */ '\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf', -/* xb0-xb7 */ '\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7', -/* xb8-xbf */ '\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf', -/* xc0-xc7 */ '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', -/* xc8-xcf */ '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', -/* xd0-xd7 */ '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7', -/* xd8-xdf */ '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', -/* xe0-xe7 */ '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', -/* xe8-xef */ '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf', -/* xf0-xf7 */ '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xf7', -/* xf8-xff */ '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xff' + /* x00-x07 */ '\x00', + '\x01', + '\x02', + '\x03', + '\x04', + '\x05', + '\x06', + '\x07', + /* x08-x0f */ '\x08', + '\x09', + '\x0a', + '\x0b', + '\x0c', + '\x0d', + '\x0e', + '\x0f', + /* x10-x17 */ '\x10', + '\x11', + '\x12', + '\x13', + '\x14', + '\x15', + '\x16', + '\x17', + /* x18-x1f */ '\x18', + '\x19', + '\x1a', + '\x1b', + '\x1c', + '\x1d', + '\x1e', + '\x1f', + /* ' '-x27 */ ' ', + '!', + '"', + '#', + '$', + '%', + '&', + '\x27', + /* '('-'/' */ '(', + ')', + '*', + '+', + ',', + '-', + '.', + '/', + /* '0'-'7' */ '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + /* '8'-'?' */ '8', + '9', + ':', + ';', + '<', + '=', + '>', + '?', + /* '@'-'G' */ '@', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + /* 'H'-'O' */ 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + /* 'P'-'W' */ 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + /* 'X'-'_' */ 'X', + 'Y', + 'Z', + '[', + '\x5c', + ']', + '^', + '_', + /* '`'-'g' */ '`', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + /* 'h'-'o' */ 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + /* 'p'-'w' */ 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + /* 'x'-x7f */ 'X', + 'Y', + 'Z', + '[', + '\x5c', + ']', + '^', + '\x7f' +#if (!(CHAR_MIN < 0)) + , + /* x80-x87 */ '\x80', + '\x81', + '\x82', + '\x83', + '\x84', + '\x85', + '\x86', + '\x87', + /* x88-x8f */ '\x88', + '\x89', + '\x8a', + '\x8b', + '\x8c', + '\x8d', + '\x8e', + '\x8f', + /* x90-x97 */ '\x90', + '\x91', + '\x92', + '\x93', + '\x94', + '\x95', + '\x96', + '\x97', + /* x98-x9f */ '\x98', + '\x99', + '\x9a', + '\x9b', + '\x9c', + '\x9d', + '\x9e', + '\x9f', + /* xa0-xa7 */ '\xa0', + '\xa1', + '\xa2', + '\xa3', + '\xa4', + '\xa5', + '\xa6', + '\xa7', + /* xa8-xaf */ '\xa8', + '\xa9', + '\xaa', + '\xab', + '\xac', + '\xad', + '\xae', + '\xaf', + /* xb0-xb7 */ '\xb0', + '\xb1', + '\xb2', + '\xb3', + '\xb4', + '\xb5', + '\xb6', + '\xb7', + /* xb8-xbf */ '\xb8', + '\xb9', + '\xba', + '\xbb', + '\xbc', + '\xbd', + '\xbe', + '\xbf', + /* xc0-xc7 */ '\xc0', + '\xc1', + '\xc2', + '\xc3', + '\xc4', + '\xc5', + '\xc6', + '\xc7', + /* xc8-xcf */ '\xc8', + '\xc9', + '\xca', + '\xcb', + '\xcc', + '\xcd', + '\xce', + '\xcf', + /* xd0-xd7 */ '\xd0', + '\xd1', + '\xd2', + '\xd3', + '\xd4', + '\xd5', + '\xd6', + '\xd7', + /* xd8-xdf */ '\xd8', + '\xd9', + '\xda', + '\xdb', + '\xdc', + '\xdd', + '\xde', + '\xdf', + /* xe0-xe7 */ '\xc0', + '\xc1', + '\xc2', + '\xc3', + '\xc4', + '\xc5', + '\xc6', + '\xc7', + /* xe8-xef */ '\xc8', + '\xc9', + '\xca', + '\xcb', + '\xcc', + '\xcd', + '\xce', + '\xcf', + /* xf0-xf7 */ '\xd0', + '\xd1', + '\xd2', + '\xd3', + '\xd4', + '\xd5', + '\xd6', + '\xf7', + /* xf8-xff */ '\xd8', + '\xd9', + '\xda', + '\xdb', + '\xdc', + '\xdd', + '\xde', + '\xff' #endif /* (!(CHAR_MIN<0)) */ - }; +}; const unsigned int IRCD_CharAttrTab[] = { -#if (CHAR_MIN<0) -/* x80-x87 */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* x88-x8f */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* x90-x97 */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* x98-x9f */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* xa0-xa7 */ 0x0000, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* xa8-xaf */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* xb0-xb7 */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* xb8-xbf */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* xc0-xc7 */ 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, -/* xc8-xcf */ 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, -/* xd0-xd7 */ 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x0400, -/* xd8-xdf */ 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x0400, -/* xe0-xe7 */ 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, -/* xe8-xef */ 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, -/* xf0-xf7 */ 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x0400, -/* xf8-xff */ 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x0400 - , +#if (CHAR_MIN < 0) + /* x80-x87 */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* x88-x8f */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* x90-x97 */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* x98-x9f */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* xa0-xa7 */ 0x0000, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* xa8-xaf */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* xb0-xb7 */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* xb8-xbf */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* xc0-xc7 */ 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + /* xc8-xcf */ 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + /* xd0-xd7 */ 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x0400, + /* xd8-xdf */ 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x0400, + /* xe0-xe7 */ 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + /* xe8-xef */ 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + /* xf0-xf7 */ 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x0400, + /* xf8-xff */ 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x0400, #endif /* (CHAR_MIN<0) */ -/* x00-x07 */ 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0004, -/* x08-x0f */ 0x0404, 0x0504, 0x10504, 0x0504, 0x0504, 0x10504, 0x0404, 0x0404, -/* x10-x17 */ 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, -/* x18-x1f */ 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, 0x0404, -/* ' '-x27 */ 0x20140, 0x04d0, 0x04d0, 0x404d0, 0x04d0, 0x04d0, 0x404d0, 0x24d0, -/* '('-'/' */ 0x04d0, 0x04d0, 0x04d0, 0x404d0, 0x200d0, 0x274d0, 0xe4d0, 0x04d0, -/* '0'-'7' */ 0x2f459, 0x2f459, 0x2f459, 0x2f459, 0x2f459, 0x2f459, 0x2f459, 0x2f459, -/* '8'-'?' */ 0x2f459, 0x2f459, 0x04d0, 0x04d0, 0x04d0, 0x04d0, 0x04d0, 0x04d0, -/* '@'-'G' */ 0x04d0, 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, -/* 'H'-'O' */ 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, -/* 'P'-'W' */ 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, -/* 'X'-'_' */ 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, 0x7653, 0x74d0, -/* '`'-'g' */ 0x34d0, 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, -/* 'h'-'o' */ 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, -/* 'p'-'w' */ 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, -/* 'x'-x7f */ 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, 0x7473, 0x0400 -#if (!(CHAR_MIN<0)) - , -/* x80-x87 */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* x88-x8f */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* x90-x97 */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* x98-x9f */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* xa0-xa7 */ 0x0000, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* xa8-xaf */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* xb0-xb7 */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* xb8-xbf */ 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, -/* xc0-xc7 */ 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, -/* xc8-xcf */ 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, -/* xd0-xd7 */ 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x0400, -/* xd8-xdf */ 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x2c00, 0x0400, -/* xe0-xe7 */ 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, -/* xe8-xef */ 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, -/* xf0-xf7 */ 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x0400, -/* xf8-xff */ 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x2400, 0x0400 + /* x00-x07 */ 0x0404, + 0x0404, + 0x0404, + 0x0404, + 0x0404, + 0x0404, + 0x0404, + 0x0004, + /* x08-x0f */ 0x0404, + 0x0504, + 0x10504, + 0x0504, + 0x0504, + 0x10504, + 0x0404, + 0x0404, + /* x10-x17 */ 0x0404, + 0x0404, + 0x0404, + 0x0404, + 0x0404, + 0x0404, + 0x0404, + 0x0404, + /* x18-x1f */ 0x0404, + 0x0404, + 0x0404, + 0x0404, + 0x0404, + 0x0404, + 0x0404, + 0x0404, + /* ' '-x27 */ 0x20140, + 0x04d0, + 0x04d0, + 0x404d0, + 0x04d0, + 0x04d0, + 0x404d0, + 0x24d0, + /* '('-'/' */ 0x04d0, + 0x04d0, + 0x04d0, + 0x404d0, + 0x200d0, + 0x274d0, + 0xe4d0, + 0x04d0, + /* '0'-'7' */ 0x2f459, + 0x2f459, + 0x2f459, + 0x2f459, + 0x2f459, + 0x2f459, + 0x2f459, + 0x2f459, + /* '8'-'?' */ 0x2f459, + 0x2f459, + 0x04d0, + 0x04d0, + 0x04d0, + 0x04d0, + 0x04d0, + 0x04d0, + /* '@'-'G' */ 0x04d0, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + /* 'H'-'O' */ 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + /* 'P'-'W' */ 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + /* 'X'-'_' */ 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x7653, + 0x74d0, + /* '`'-'g' */ 0x34d0, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + /* 'h'-'o' */ 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + /* 'p'-'w' */ 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + /* 'x'-x7f */ 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x7473, + 0x0400 +#if (!(CHAR_MIN < 0)) + , + /* x80-x87 */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* x88-x8f */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* x90-x97 */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* x98-x9f */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* xa0-xa7 */ 0x0000, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* xa8-xaf */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* xb0-xb7 */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* xb8-xbf */ 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + 0x0400, + /* xc0-xc7 */ 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + /* xc8-xcf */ 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + /* xd0-xd7 */ 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x0400, + /* xd8-xdf */ 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x2c00, + 0x0400, + /* xe0-xe7 */ 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + /* xe8-xef */ 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + /* xf0-xf7 */ 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x0400, + /* xf8-xff */ 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x2400, + 0x0400 #endif /* (!(CHAR_MIN<0)) */ - }; +}; #endif // __MATCH_TABLE_H diff --git a/libgnuworld/md5hash.cc b/libgnuworld/md5hash.cc old mode 100755 new mode 100644 index 15c0f1c0..918cf299 --- a/libgnuworld/md5hash.cc +++ b/libgnuworld/md5hash.cc @@ -4,424 +4,380 @@ * $Modtime: 1/08/97 6:35p $ * * PURPOSE: - * MD5 Message digest class derived from the RSA Data Security, Inc. + * MD5 Message digest class derived from the RSA Data Security, Inc. * MD5 Message-Digest Algorithm as published in RFC 1321, April 1992. - * + * * COPYRIGHT: * Copyright (c) 1995, 1996, 1997 Tree Frog Software, All rights reserved. * This source code and the binaries that result may be freely distributed, * used and modified as long as the above copyright notice remains intact. - * + * * WARRANTY: * The author of md5.cpp (hereafter referred to as "the author") makes no - * warranty of any kind, expressed or implied, including without limitation, + * warranty of any kind, expressed or implied, including without limitation, * any warranties of merchantability and/or fitness for a particular purpose. * The author shall not be liable for any damages, whether direct, indirect, - * special, or consequential arising from a failure of this program to + * special, or consequential arising from a failure of this program to * operate in the manner desired by the user. The author shall not be liable - * for any damage to data or property which may be caused directly or + * for any damage to data or property which may be caused directly or * indirectly by use of the program. * * In no event will the author be liable to the user for any damages, - * including any lost profits, lost savings, or other incidental or - * consequential damages arising out of the use or inability to use the + * including any lost profits, lost savings, or other incidental or + * consequential damages arising out of the use or inability to use the * program, or for any claim by any other party. - * + * * -------------------- MD5 RSA copyright follows: ------------------------- * * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All * rights reserved. - * + * * License to copy and use this software is granted provided that it * is identified as the "RSA Data Security, Inc. MD5 Message-Digest * Algorithm" in all material mentioning or referencing this software * or this function. - * + * * License is also granted to make and use derivative works provided * that such works are identified as "derived from the RSA Data * Security, Inc. MD5 Message-Digest Algorithm" in all material * mentioning or referencing the derived work. - * + * * RSA Data Security, Inc. makes no representations concerning either * the merchantability of this software or the suitability of this * software for any particular purpose. It is provided "as is" * without express or implied warranty of any kind. - * + * * These notices must be retained in any copies of any part of this * documentation and/or software. - * - * So there! + * + * So there! ************************************************************************/ -#include // Needed for ostream and istream. -#include // Needed for memcpy() and memset(). -#include -#include "md5hash.h" +#include // Needed for ostream and istream. +#include // Needed for memcpy() and memset(). +#include +#include "md5hash.h" -namespace gnuworld -{ +namespace gnuworld { // F, G, H and I are basic MD5 functions. -inline uint32_t F( uint32_t xx, uint32_t yy, uint32_t zz ) -{ return (( xx & yy ) | (~xx & zz )); } +inline uint32_t F(uint32_t xx, uint32_t yy, uint32_t zz) { return ((xx & yy) | (~xx & zz)); } -inline uint32_t G( uint32_t xx, uint32_t yy, uint32_t zz ) -{ return (( xx & zz ) | ( yy & ~zz )); } +inline uint32_t G(uint32_t xx, uint32_t yy, uint32_t zz) { return ((xx & zz) | (yy & ~zz)); } -inline uint32_t H( uint32_t xx, uint32_t yy, uint32_t zz ) -{ return xx ^ yy ^ zz; } +inline uint32_t H(uint32_t xx, uint32_t yy, uint32_t zz) { return xx ^ yy ^ zz; } -inline uint32_t I( uint32_t xx, uint32_t yy, uint32_t zz ) -{ return yy ^ ( xx | ~zz ); } +inline uint32_t I(uint32_t xx, uint32_t yy, uint32_t zz) { return yy ^ (xx | ~zz); } // ROTATE_LEFT rotates x left n bits. -inline uint32_t ROTATE_LEFT( uint32_t xx, int32_t nn ) -{ return ( xx << nn ) | ( xx >> (32-nn )); } +inline uint32_t ROTATE_LEFT(uint32_t xx, int32_t nn) { return (xx << nn) | (xx >> (32 - nn)); } // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. // Rotation is separate from addition to prevent recomputation. -inline void -FF(uint32_t &aa, uint32_t bb, uint32_t cc, uint32_t dd, uint32_t xx, int32_t ss, uint32_t ac){ - aa += F( bb, cc, dd ) + xx + ac; - aa = ROTATE_LEFT( aa, ss ); - aa += bb; - return; +inline void FF(uint32_t& aa, uint32_t bb, uint32_t cc, uint32_t dd, uint32_t xx, int32_t ss, + uint32_t ac) { + aa += F(bb, cc, dd) + xx + ac; + aa = ROTATE_LEFT(aa, ss); + aa += bb; + return; } -inline void -GG(uint32_t &aa, uint32_t bb, uint32_t cc, uint32_t dd, uint32_t xx, int32_t ss, uint32_t ac){ - aa += G( bb, cc, dd ) + xx + ac; - aa = ROTATE_LEFT( aa, ss ); - aa += bb; - return; +inline void GG(uint32_t& aa, uint32_t bb, uint32_t cc, uint32_t dd, uint32_t xx, int32_t ss, + uint32_t ac) { + aa += G(bb, cc, dd) + xx + ac; + aa = ROTATE_LEFT(aa, ss); + aa += bb; + return; } -inline void -HH(uint32_t &aa, uint32_t bb, uint32_t cc, uint32_t dd, uint32_t xx, int32_t ss, uint32_t ac){ - aa += H( bb, cc, dd ) + xx + ac; - aa = ROTATE_LEFT( aa, ss ); - aa += bb; - return; +inline void HH(uint32_t& aa, uint32_t bb, uint32_t cc, uint32_t dd, uint32_t xx, int32_t ss, + uint32_t ac) { + aa += H(bb, cc, dd) + xx + ac; + aa = ROTATE_LEFT(aa, ss); + aa += bb; + return; } -inline void -II(uint32_t &aa, uint32_t bb, uint32_t cc, uint32_t dd, uint32_t xx, int32_t ss, uint32_t ac){ - aa += I( bb, cc, dd ) + xx + ac; - aa = ROTATE_LEFT( aa, ss ); - aa += bb; - return; +inline void II(uint32_t& aa, uint32_t bb, uint32_t cc, uint32_t dd, uint32_t xx, int32_t ss, + uint32_t ac) { + aa += I(bb, cc, dd) + xx + ac; + aa = ROTATE_LEFT(aa, ss); + aa += bb; + return; } -md5Digest::md5Digest( void ) -{ - clear(); -} +md5Digest::md5Digest(void) { clear(); } -md5Digest::~md5Digest( void ) -{ - clear(); -} +md5Digest::~md5Digest(void) { clear(); } -void -md5Digest::clear( void ) -{ - memset( m_data, 0, sizeof( m_data )); - return; +void md5Digest::clear(void) { + memset(m_data, 0, sizeof(m_data)); + return; } -unsigned char& -md5Digest::operator[]( size_t ii ) // lvalue operator[]. +unsigned char& md5Digest::operator[](size_t ii) // lvalue operator[]. { - static unsigned char val = 0; - if( ii >= MD5_DIGEST_LENGTH ) { // Note that size_t is unsigned. - val = 0; - return val; // Benign, don't throw an exception. - } - return m_data[ ii ]; + static unsigned char val = 0; + if (ii >= MD5_DIGEST_LENGTH) { // Note that size_t is unsigned. + val = 0; + return val; // Benign, don't throw an exception. + } + return m_data[ii]; } -unsigned char -md5Digest::operator[]( size_t ii ) const // rvalue operator[]. +unsigned char md5Digest::operator[](size_t ii) const // rvalue operator[]. { - if( ii >= MD5_DIGEST_LENGTH ) { // Note that size_t is unsigned. - return 0; // Benign, don't throw an exception. - } - return m_data[ ii ]; + if (ii >= MD5_DIGEST_LENGTH) { // Note that size_t is unsigned. + return 0; // Benign, don't throw an exception. + } + return m_data[ii]; } -int32_t -operator==( const md5Digest &lhs, const md5Digest &rhs ) -{ - int32_t result = 1; // Assume true to begin with. - for( int32_t ii = 0; result && ii < MD5_DIGEST_LENGTH; ii++ ) { - result = lhs.m_data[ii] == rhs.m_data[ii]; - } - return result; +int32_t operator==(const md5Digest& lhs, const md5Digest& rhs) { + int32_t result = 1; // Assume true to begin with. + for (int32_t ii = 0; result && ii < MD5_DIGEST_LENGTH; ii++) { + result = lhs.m_data[ii] == rhs.m_data[ii]; + } + return result; } -int32_t -operator!=( const md5Digest &lhs, const md5Digest &rhs ) -{ - return !( lhs == rhs ); -} +int32_t operator!=(const md5Digest& lhs, const md5Digest& rhs) { return !(lhs == rhs); } -std::istream& -operator>>( std::istream& stream, md5Digest& digest ) -{ - stream.read( reinterpret_cast< char* >( digest.m_data ), - MD5_DIGEST_LENGTH ); -// for( int32_t ii = 0; ii < MD5_DIGEST_LENGTH; ii++ ) { -// stream >> digest.m_data[ii]; -// } - return stream; +std::istream& operator>>(std::istream& stream, md5Digest& digest) { + stream.read(reinterpret_cast(digest.m_data), MD5_DIGEST_LENGTH); + // for( int32_t ii = 0; ii < MD5_DIGEST_LENGTH; ii++ ) { + // stream >> digest.m_data[ii]; + // } + return stream; } -std::ostream& -operator<<( std::ostream& stream, const md5Digest& digest ) -{ - stream.write( reinterpret_cast< const char* >( digest.m_data ), - MD5_DIGEST_LENGTH ); -// for( int32_t ii = 0; ii < MD5_DIGEST_LENGTH; ii++ ) { -// stream << digest.m_data[ii]; -// } - return stream; +std::ostream& operator<<(std::ostream& stream, const md5Digest& digest) { + stream.write(reinterpret_cast(digest.m_data), MD5_DIGEST_LENGTH); + // for( int32_t ii = 0; ii < MD5_DIGEST_LENGTH; ii++ ) { + // stream << digest.m_data[ii]; + // } + return stream; } -md5::md5( void ) -{ - init(); // Set up the initial state values. +md5::md5(void) { + init(); // Set up the initial state values. } -md5::~md5( void ) -{ - clear(); // Wipe the class data clean. +md5::~md5(void) { + clear(); // Wipe the class data clean. } -void -md5::init( void ) -{ // Load magic initialization constants. - m_state[0] = 0x67452301L; // These values are only used here. - m_state[1] = 0xefcdab89L; - m_state[2] = 0x98badcfeL; - m_state[3] = 0x10325476L; - m_count[0] = m_count[1] = 0; - memset( m_buffer, 0, sizeof( m_buffer )); - return; +void md5::init(void) { // Load magic initialization constants. + m_state[0] = 0x67452301L; // These values are only used here. + m_state[1] = 0xefcdab89L; + m_state[2] = 0x98badcfeL; + m_state[3] = 0x10325476L; + m_count[0] = m_count[1] = 0; + memset(m_buffer, 0, sizeof(m_buffer)); + return; } -void -md5::clear( void ) -{ // Zero the data memebers of this class. - m_state[0] = m_state[1] = m_state[2] = m_state[3] = 0; - m_count[0] = m_count[1] = 0; - memset( m_buffer, 0, sizeof( m_buffer )); - return; +void md5::clear(void) { // Zero the data memebers of this class. + m_state[0] = m_state[1] = m_state[2] = m_state[3] = 0; + m_count[0] = m_count[1] = 0; + memset(m_buffer, 0, sizeof(m_buffer)); + return; } -void -md5::update( const unsigned char *input, size_t inputLen ) -{ // MD5 block update operation. Continues an MD5 message-digest - // operation, processing another message block, and updating the - // context. - - // Compute number of bytes mod 64. - size_t index = (size_t)((m_count[0] >> 3) & 0x3F); - - // Update number of bits. - if(( m_count[0] += ((uint32_t)inputLen << 3)) < ((uint32_t)inputLen << 3)) { - m_count[1]++; - } - m_count[1] += ((uint32_t)inputLen >> 29); - - size_t partLen = 64 - index; - - // Transform as many times as possible. - size_t ii = 0; - if( inputLen >= partLen ) { - memcpy( &m_buffer[index], input, partLen); - transform( m_buffer ); - - for( ii = partLen; ii + 63 < inputLen; ii += 64 ) { - transform( &input[ii] ); - } - index = 0; - } - if( inputLen - ii ) { - // Buffer remaining input. - memcpy( &m_buffer[index],&input[ii],inputLen-ii ); - } - return; +void md5::update(const unsigned char* input, + size_t inputLen) { // MD5 block update operation. Continues an MD5 message-digest + // operation, processing another message block, and updating the + // context. + + // Compute number of bytes mod 64. + size_t index = (size_t)((m_count[0] >> 3) & 0x3F); + + // Update number of bits. + if ((m_count[0] += ((uint32_t)inputLen << 3)) < ((uint32_t)inputLen << 3)) { + m_count[1]++; + } + m_count[1] += ((uint32_t)inputLen >> 29); + + size_t partLen = 64 - index; + + // Transform as many times as possible. + size_t ii = 0; + if (inputLen >= partLen) { + memcpy(&m_buffer[index], input, partLen); + transform(m_buffer); + + for (ii = partLen; ii + 63 < inputLen; ii += 64) { + transform(&input[ii]); + } + index = 0; + } + if (inputLen - ii) { + // Buffer remaining input. + memcpy(&m_buffer[index], &input[ii], inputLen - ii); + } + return; } -void -md5::report( md5Digest &digest ) -{ // MD5 finalization. Ends an MD5 message-digest operation, writing the - // the message digest and zeroizing the context. - static unsigned char padding[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - unsigned char bits[8]; - - encode( bits, m_count, 8 ); // Save number of bits - - // Pad out to 56 mod 64. - size_t index = (size_t)((m_count[0] >> 3) & 0x3f); - size_t padLen = (index < 56) ? (56 - index) : (120 - index); - - update( padding, padLen ); - update( bits, 8 ); // Append length (before padding). - - encode( digest ); // Store state in digest. - clear(); // Zero sensitive information. - return; -} +void md5::report( + md5Digest& digest) { // MD5 finalization. Ends an MD5 message-digest operation, writing the + // the message digest and zeroizing the context. + static unsigned char padding[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + unsigned char bits[8]; + + encode(bits, m_count, 8); // Save number of bits -void -md5::transform( const unsigned char block[64] ) -{ // MD5 basic transformation. Transforms state based on block. - const int32_t S11 = 7; - const int32_t S12 = 12; - const int32_t S13 = 17; - const int32_t S14 = 22; - const int32_t S21 = 5; - const int32_t S22 = 9; - const int32_t S23 = 14; - const int32_t S24 = 20; - const int32_t S31 = 4; - const int32_t S32 = 11; - const int32_t S33 = 16; - const int32_t S34 = 23; - const int32_t S41 = 6; - const int32_t S42 = 10; - const int32_t S43 = 15; - const int32_t S44 = 21; - - uint32_t aa = m_state[0], bb = m_state[1], cc = m_state[2], dd = m_state[3]; - uint32_t xx[16]; - - decode( xx, block, 64 ); - - /* Round 1 */ - FF( aa, bb, cc, dd, xx[ 0], S11, 0xd76aa478L); /* 1 */ - FF( dd, aa, bb, cc, xx[ 1], S12, 0xe8c7b756L); /* 2 */ - FF( cc, dd, aa, bb, xx[ 2], S13, 0x242070dbL); /* 3 */ - FF( bb, cc, dd, aa, xx[ 3], S14, 0xc1bdceeeL); /* 4 */ - FF( aa, bb, cc, dd, xx[ 4], S11, 0xf57c0fafL); /* 5 */ - FF( dd, aa, bb, cc, xx[ 5], S12, 0x4787c62aL); /* 6 */ - FF( cc, dd, aa, bb, xx[ 6], S13, 0xa8304613L); /* 7 */ - FF( bb, cc, dd, aa, xx[ 7], S14, 0xfd469501L); /* 8 */ - FF( aa, bb, cc, dd, xx[ 8], S11, 0x698098d8L); /* 9 */ - FF( dd, aa, bb, cc, xx[ 9], S12, 0x8b44f7afL); /* 10 */ - FF( cc, dd, aa, bb, xx[10], S13, 0xffff5bb1L); /* 11 */ - FF( bb, cc, dd, aa, xx[11], S14, 0x895cd7beL); /* 12 */ - FF( aa, bb, cc, dd, xx[12], S11, 0x6b901122L); /* 13 */ - FF( dd, aa, bb, cc, xx[13], S12, 0xfd987193L); /* 14 */ - FF( cc, dd, aa, bb, xx[14], S13, 0xa679438eL); /* 15 */ - FF( bb, cc, dd, aa, xx[15], S14, 0x49b40821L); /* 16 */ - - /* Round 2 */ - GG( aa, bb, cc, dd, xx[ 1], S21, 0xf61e2562L); /* 17 */ - GG( dd, aa, bb, cc, xx[ 6], S22, 0xc040b340L); /* 18 */ - GG( cc, dd, aa, bb, xx[11], S23, 0x265e5a51L); /* 19 */ - GG( bb, cc, dd, aa, xx[ 0], S24, 0xe9b6c7aaL); /* 20 */ - GG( aa, bb, cc, dd, xx[ 5], S21, 0xd62f105dL); /* 21 */ - GG( dd, aa, bb, cc, xx[10], S22, 0x02441453L); /* 22 */ - GG( cc, dd, aa, bb, xx[15], S23, 0xd8a1e681L); /* 23 */ - GG( bb, cc, dd, aa, xx[ 4], S24, 0xe7d3fbc8L); /* 24 */ - GG( aa, bb, cc, dd, xx[ 9], S21, 0x21e1cde6L); /* 25 */ - GG( dd, aa, bb, cc, xx[14], S22, 0xc33707d6L); /* 26 */ - GG( cc, dd, aa, bb, xx[ 3], S23, 0xf4d50d87L); /* 27 */ - GG( bb, cc, dd, aa, xx[ 8], S24, 0x455a14edL); /* 28 */ - GG( aa, bb, cc, dd, xx[13], S21, 0xa9e3e905L); /* 29 */ - GG( dd, aa, bb, cc, xx[ 2], S22, 0xfcefa3f8L); /* 30 */ - GG( cc, dd, aa, bb, xx[ 7], S23, 0x676f02d9L); /* 31 */ - GG( bb, cc, dd, aa, xx[12], S24, 0x8d2a4c8aL); /* 32 */ - - /* Round 3 */ - HH( aa, bb, cc, dd, xx[ 5], S31, 0xfffa3942L); /* 33 */ - HH( dd, aa, bb, cc, xx[ 8], S32, 0x8771f681L); /* 34 */ - HH( cc, dd, aa, bb, xx[11], S33, 0x6d9d6122L); /* 35 */ - HH( bb, cc, dd, aa, xx[14], S34, 0xfde5380cL); /* 36 */ - HH( aa, bb, cc, dd, xx[ 1], S31, 0xa4beea44L); /* 37 */ - HH( dd, aa, bb, cc, xx[ 4], S32, 0x4bdecfa9L); /* 38 */ - HH( cc, dd, aa, bb, xx[ 7], S33, 0xf6bb4b60L); /* 39 */ - HH( bb, cc, dd, aa, xx[10], S34, 0xbebfbc70L); /* 40 */ - HH( aa, bb, cc, dd, xx[13], S31, 0x289b7ec6L); /* 41 */ - HH( dd, aa, bb, cc, xx[ 0], S32, 0xeaa127faL); /* 42 */ - HH( cc, dd, aa, bb, xx[ 3], S33, 0xd4ef3085L); /* 43 */ - HH( bb, cc, dd, aa, xx[ 6], S34, 0x04881d05L); /* 44 */ - HH( aa, bb, cc, dd, xx[ 9], S31, 0xd9d4d039L); /* 45 */ - HH( dd, aa, bb, cc, xx[12], S32, 0xe6db99e5L); /* 46 */ - HH( cc, dd, aa, bb, xx[15], S33, 0x1fa27cf8L); /* 47 */ - HH( bb, cc, dd, aa, xx[ 2], S34, 0xc4ac5665L); /* 48 */ - - /* Round 4 */ - II( aa, bb, cc, dd, xx[ 0], S41, 0xf4292244L); /* 49 */ - II( dd, aa, bb, cc, xx[ 7], S42, 0x432aff97L); /* 50 */ - II( cc, dd, aa, bb, xx[14], S43, 0xab9423a7L); /* 51 */ - II( bb, cc, dd, aa, xx[ 5], S44, 0xfc93a039L); /* 52 */ - II( aa, bb, cc, dd, xx[12], S41, 0x655b59c3L); /* 53 */ - II( dd, aa, bb, cc, xx[ 3], S42, 0x8f0ccc92L); /* 54 */ - II( cc, dd, aa, bb, xx[10], S43, 0xffeff47dL); /* 55 */ - II( bb, cc, dd, aa, xx[ 1], S44, 0x85845dd1L); /* 56 */ - II( aa, bb, cc, dd, xx[ 8], S41, 0x6fa87e4fL); /* 57 */ - II( dd, aa, bb, cc, xx[15], S42, 0xfe2ce6e0L); /* 58 */ - II( cc, dd, aa, bb, xx[ 6], S43, 0xa3014314L); /* 59 */ - II( bb, cc, dd, aa, xx[13], S44, 0x4e0811a1L); /* 60 */ - II( aa, bb, cc, dd, xx[ 4], S41, 0xf7537e82L); /* 61 */ - II( dd, aa, bb, cc, xx[11], S42, 0xbd3af235L); /* 62 */ - II( cc, dd, aa, bb, xx[ 2], S43, 0x2ad7d2bbL); /* 63 */ - II( bb, cc, dd, aa, xx[ 9], S44, 0xeb86d391L); /* 64 */ - - m_state[0] += aa; - m_state[1] += bb; - m_state[2] += cc; - m_state[3] += dd; - - memset((unsigned char*)xx, 0, sizeof (xx)); // Clear sensitive information. - return; + // Pad out to 56 mod 64. + size_t index = (size_t)((m_count[0] >> 3) & 0x3f); + size_t padLen = (index < 56) ? (56 - index) : (120 - index); + + update(padding, padLen); + update(bits, 8); // Append length (before padding). + + encode(digest); // Store state in digest. + clear(); // Zero sensitive information. + return; } -void -md5::encode( unsigned char *output, const uint32_t *input, int32_t len ) -{ // Encodes input (uint32_t) into output (unsigned char). - // Assumes len is a multiple of 4. - int32_t ii, jj; - for( ii = 0, jj = 0; jj < len; ii++, jj += 4 ) { - output[jj] = (unsigned char)( input[ii] & 0xFF ); - output[jj+1] = (unsigned char)(( input[ii] >> 8 ) & 0xFF ); - output[jj+2] = (unsigned char)(( input[ii] >> 16 ) & 0xFF ); - output[jj+3] = (unsigned char)(( input[ii] >> 24 ) & 0xFF ); - } - return; +void md5::transform( + const unsigned char block[64]) { // MD5 basic transformation. Transforms state based on block. + const int32_t S11 = 7; + const int32_t S12 = 12; + const int32_t S13 = 17; + const int32_t S14 = 22; + const int32_t S21 = 5; + const int32_t S22 = 9; + const int32_t S23 = 14; + const int32_t S24 = 20; + const int32_t S31 = 4; + const int32_t S32 = 11; + const int32_t S33 = 16; + const int32_t S34 = 23; + const int32_t S41 = 6; + const int32_t S42 = 10; + const int32_t S43 = 15; + const int32_t S44 = 21; + + uint32_t aa = m_state[0], bb = m_state[1], cc = m_state[2], dd = m_state[3]; + uint32_t xx[16]; + + decode(xx, block, 64); + + /* Round 1 */ + FF(aa, bb, cc, dd, xx[0], S11, 0xd76aa478L); /* 1 */ + FF(dd, aa, bb, cc, xx[1], S12, 0xe8c7b756L); /* 2 */ + FF(cc, dd, aa, bb, xx[2], S13, 0x242070dbL); /* 3 */ + FF(bb, cc, dd, aa, xx[3], S14, 0xc1bdceeeL); /* 4 */ + FF(aa, bb, cc, dd, xx[4], S11, 0xf57c0fafL); /* 5 */ + FF(dd, aa, bb, cc, xx[5], S12, 0x4787c62aL); /* 6 */ + FF(cc, dd, aa, bb, xx[6], S13, 0xa8304613L); /* 7 */ + FF(bb, cc, dd, aa, xx[7], S14, 0xfd469501L); /* 8 */ + FF(aa, bb, cc, dd, xx[8], S11, 0x698098d8L); /* 9 */ + FF(dd, aa, bb, cc, xx[9], S12, 0x8b44f7afL); /* 10 */ + FF(cc, dd, aa, bb, xx[10], S13, 0xffff5bb1L); /* 11 */ + FF(bb, cc, dd, aa, xx[11], S14, 0x895cd7beL); /* 12 */ + FF(aa, bb, cc, dd, xx[12], S11, 0x6b901122L); /* 13 */ + FF(dd, aa, bb, cc, xx[13], S12, 0xfd987193L); /* 14 */ + FF(cc, dd, aa, bb, xx[14], S13, 0xa679438eL); /* 15 */ + FF(bb, cc, dd, aa, xx[15], S14, 0x49b40821L); /* 16 */ + + /* Round 2 */ + GG(aa, bb, cc, dd, xx[1], S21, 0xf61e2562L); /* 17 */ + GG(dd, aa, bb, cc, xx[6], S22, 0xc040b340L); /* 18 */ + GG(cc, dd, aa, bb, xx[11], S23, 0x265e5a51L); /* 19 */ + GG(bb, cc, dd, aa, xx[0], S24, 0xe9b6c7aaL); /* 20 */ + GG(aa, bb, cc, dd, xx[5], S21, 0xd62f105dL); /* 21 */ + GG(dd, aa, bb, cc, xx[10], S22, 0x02441453L); /* 22 */ + GG(cc, dd, aa, bb, xx[15], S23, 0xd8a1e681L); /* 23 */ + GG(bb, cc, dd, aa, xx[4], S24, 0xe7d3fbc8L); /* 24 */ + GG(aa, bb, cc, dd, xx[9], S21, 0x21e1cde6L); /* 25 */ + GG(dd, aa, bb, cc, xx[14], S22, 0xc33707d6L); /* 26 */ + GG(cc, dd, aa, bb, xx[3], S23, 0xf4d50d87L); /* 27 */ + GG(bb, cc, dd, aa, xx[8], S24, 0x455a14edL); /* 28 */ + GG(aa, bb, cc, dd, xx[13], S21, 0xa9e3e905L); /* 29 */ + GG(dd, aa, bb, cc, xx[2], S22, 0xfcefa3f8L); /* 30 */ + GG(cc, dd, aa, bb, xx[7], S23, 0x676f02d9L); /* 31 */ + GG(bb, cc, dd, aa, xx[12], S24, 0x8d2a4c8aL); /* 32 */ + + /* Round 3 */ + HH(aa, bb, cc, dd, xx[5], S31, 0xfffa3942L); /* 33 */ + HH(dd, aa, bb, cc, xx[8], S32, 0x8771f681L); /* 34 */ + HH(cc, dd, aa, bb, xx[11], S33, 0x6d9d6122L); /* 35 */ + HH(bb, cc, dd, aa, xx[14], S34, 0xfde5380cL); /* 36 */ + HH(aa, bb, cc, dd, xx[1], S31, 0xa4beea44L); /* 37 */ + HH(dd, aa, bb, cc, xx[4], S32, 0x4bdecfa9L); /* 38 */ + HH(cc, dd, aa, bb, xx[7], S33, 0xf6bb4b60L); /* 39 */ + HH(bb, cc, dd, aa, xx[10], S34, 0xbebfbc70L); /* 40 */ + HH(aa, bb, cc, dd, xx[13], S31, 0x289b7ec6L); /* 41 */ + HH(dd, aa, bb, cc, xx[0], S32, 0xeaa127faL); /* 42 */ + HH(cc, dd, aa, bb, xx[3], S33, 0xd4ef3085L); /* 43 */ + HH(bb, cc, dd, aa, xx[6], S34, 0x04881d05L); /* 44 */ + HH(aa, bb, cc, dd, xx[9], S31, 0xd9d4d039L); /* 45 */ + HH(dd, aa, bb, cc, xx[12], S32, 0xe6db99e5L); /* 46 */ + HH(cc, dd, aa, bb, xx[15], S33, 0x1fa27cf8L); /* 47 */ + HH(bb, cc, dd, aa, xx[2], S34, 0xc4ac5665L); /* 48 */ + + /* Round 4 */ + II(aa, bb, cc, dd, xx[0], S41, 0xf4292244L); /* 49 */ + II(dd, aa, bb, cc, xx[7], S42, 0x432aff97L); /* 50 */ + II(cc, dd, aa, bb, xx[14], S43, 0xab9423a7L); /* 51 */ + II(bb, cc, dd, aa, xx[5], S44, 0xfc93a039L); /* 52 */ + II(aa, bb, cc, dd, xx[12], S41, 0x655b59c3L); /* 53 */ + II(dd, aa, bb, cc, xx[3], S42, 0x8f0ccc92L); /* 54 */ + II(cc, dd, aa, bb, xx[10], S43, 0xffeff47dL); /* 55 */ + II(bb, cc, dd, aa, xx[1], S44, 0x85845dd1L); /* 56 */ + II(aa, bb, cc, dd, xx[8], S41, 0x6fa87e4fL); /* 57 */ + II(dd, aa, bb, cc, xx[15], S42, 0xfe2ce6e0L); /* 58 */ + II(cc, dd, aa, bb, xx[6], S43, 0xa3014314L); /* 59 */ + II(bb, cc, dd, aa, xx[13], S44, 0x4e0811a1L); /* 60 */ + II(aa, bb, cc, dd, xx[4], S41, 0xf7537e82L); /* 61 */ + II(dd, aa, bb, cc, xx[11], S42, 0xbd3af235L); /* 62 */ + II(cc, dd, aa, bb, xx[2], S43, 0x2ad7d2bbL); /* 63 */ + II(bb, cc, dd, aa, xx[9], S44, 0xeb86d391L); /* 64 */ + + m_state[0] += aa; + m_state[1] += bb; + m_state[2] += cc; + m_state[3] += dd; + + memset((unsigned char*)xx, 0, sizeof(xx)); // Clear sensitive information. + return; } -void -md5::encode( md5Digest &digest ) -{ // Encodes m_state into digest. - int32_t ii, jj; - for( ii = 0, jj = 0; jj < MD5_DIGEST_LENGTH; ii++, jj += 4 ) { - digest.m_data[jj] = (unsigned char)( m_state[ii] & 0xFF ); - digest.m_data[jj+1] = (unsigned char)(( m_state[ii] >> 8 ) & 0xFF ); - digest.m_data[jj+2] = (unsigned char)(( m_state[ii] >> 16 ) & 0xFF ); - digest.m_data[jj+3] = (unsigned char)(( m_state[ii] >> 24 ) & 0xFF ); - } - return; +void md5::encode(unsigned char* output, const uint32_t* input, + int32_t len) { // Encodes input (uint32_t) into output (unsigned char). + // Assumes len is a multiple of 4. + int32_t ii, jj; + for (ii = 0, jj = 0; jj < len; ii++, jj += 4) { + output[jj] = (unsigned char)(input[ii] & 0xFF); + output[jj + 1] = (unsigned char)((input[ii] >> 8) & 0xFF); + output[jj + 2] = (unsigned char)((input[ii] >> 16) & 0xFF); + output[jj + 3] = (unsigned char)((input[ii] >> 24) & 0xFF); + } + return; } -void -md5::decode( uint32_t *output, const unsigned char *input, int32_t len ) -{ // Decodes input (unsigned char) into output (uint32_t). - // Assumes len is a multiple of 4. - int32_t ii, jj; - for( ii = 0, jj = 0; jj < len; ii++, jj += 4 ) { - output[ii] = ((uint32_t)input[jj]) | - (((uint32_t)input[jj+1]) << 8 ) | - (((uint32_t)input[jj+2]) << 16 ) | - (((uint32_t)input[jj+3]) << 24 ); - } - return; +void md5::encode(md5Digest& digest) { // Encodes m_state into digest. + int32_t ii, jj; + for (ii = 0, jj = 0; jj < MD5_DIGEST_LENGTH; ii++, jj += 4) { + digest.m_data[jj] = (unsigned char)(m_state[ii] & 0xFF); + digest.m_data[jj + 1] = (unsigned char)((m_state[ii] >> 8) & 0xFF); + digest.m_data[jj + 2] = (unsigned char)((m_state[ii] >> 16) & 0xFF); + digest.m_data[jj + 3] = (unsigned char)((m_state[ii] >> 24) & 0xFF); + } + return; } +void md5::decode(uint32_t* output, const unsigned char* input, + int32_t len) { // Decodes input (unsigned char) into output (uint32_t). + // Assumes len is a multiple of 4. + int32_t ii, jj; + for (ii = 0, jj = 0; jj < len; ii++, jj += 4) { + output[ii] = ((uint32_t)input[jj]) | (((uint32_t)input[jj + 1]) << 8) | + (((uint32_t)input[jj + 2]) << 16) | (((uint32_t)input[jj + 3]) << 24); + } + return; +} -} // Namespace +} // namespace gnuworld diff --git a/libgnuworld/md5hash.h b/libgnuworld/md5hash.h old mode 100755 new mode 100644 index f7208b22..339d6545 --- a/libgnuworld/md5hash.h +++ b/libgnuworld/md5hash.h @@ -4,36 +4,36 @@ * $Modtime: 1/08/97 6:35p $ * * PURPOSE: - * MD5 Message-Digest class derived from the RSA Data Security, Inc. + * MD5 Message-Digest class derived from the RSA Data Security, Inc. * MD5 Message-Digest Algorithm as published in RFC 1321, April 1992. - * + * * ASSUMES: * size_t as unsigned. * * NOTE: * Currently the md5::update length is limited to unsigned int, which may * be less than unit32_t. - * + * * COPYRIGHT: * Copyright (c) 1995, 1996, 1997 Tree Frog Software, All rights reserved. * This source code and the binaries that result may be freely distributed, * used and modified as long as the above copyright notice remains intact. - * + * * WARRANTY: * The author of md5.h (hereafter referred to as "the author") makes no - * warranty of any kind, expressed or implied, including without limitation, + * warranty of any kind, expressed or implied, including without limitation, * any warranties of merchantability and/or fitness for a particular purpose. * The author shall not be liable for any damages, whether direct, indirect, - * special, or consequential arising from a failure of this program to + * special, or consequential arising from a failure of this program to * operate in the manner desired by the user. The author shall not be liable - * for any damage to data or property which may be caused directly or + * for any damage to data or property which may be caused directly or * indirectly by use of the program. * * In no event will the author be liable to the user for any damages, - * including any lost profits, lost savings, or other incidental or - * consequential damages arising out of the use or inability to use the + * including any lost profits, lost savings, or other incidental or + * consequential damages arising out of the use or inability to use the * program, or for any claim by any other party. - * + * * -------------------- MD5 RSA copyright follows: ------------------------- * * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All @@ -43,70 +43,68 @@ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest * Algorithm" in all material mentioning or referencing this software * or this function. - * + * * License is also granted to make and use derivative works provided * that such works are identified as "derived from the RSA Data * Security, Inc. MD5 Message-Digest Algorithm" in all material * mentioning or referencing the derived work. - * + * * RSA Data Security, Inc. makes no representations concerning either * the merchantability of this software or the suitability of this * software for any particular purpose. It is provided "as is" * without express or implied warranty of any kind. * These notices must be retained in any copies of any part of this * documentation and/or software. - * - * So there! + * + * So there! **********************************************************************/ #ifndef MD5_H #define MD5_H "$Id: md5hash.h,v 1.4 2005/11/16 21:40:37 kewlio Exp $" #include - + #define MD5_DIGEST_LENGTH 16 -namespace gnuworld -{ +namespace gnuworld { -class md5Digest; // Forward declaration. +class md5Digest; // Forward declaration. class md5 { -public: - md5( void ); // Automatically calls md5::init(). - virtual ~md5( void ); // Automatically calls md5::clear(). - void update( const unsigned char *input, size_t length ); // Process data. - void report( md5Digest &digest ); // Used to generate the digest. - void init( void ); // Used for reinitialization. - void clear( void ); // Used to wipe clean interal data. -protected: - uint32_t m_state[4]; // State (ABCD) - uint32_t m_count[2]; // Number of bits, modulo 2^64 (lsb first). - unsigned char m_buffer[64]; // Input buffer. - void transform( const unsigned char block[64] ); - void encode( unsigned char *output, const uint32_t *input, int32_t len ); - void encode( md5Digest &digest ); - void decode( uint32_t *output, const unsigned char *input, int32_t len ); + public: + md5(void); // Automatically calls md5::init(). + virtual ~md5(void); // Automatically calls md5::clear(). + void update(const unsigned char* input, size_t length); // Process data. + void report(md5Digest& digest); // Used to generate the digest. + void init(void); // Used for reinitialization. + void clear(void); // Used to wipe clean interal data. + protected: + uint32_t m_state[4]; // State (ABCD) + uint32_t m_count[2]; // Number of bits, modulo 2^64 (lsb first). + unsigned char m_buffer[64]; // Input buffer. + void transform(const unsigned char block[64]); + void encode(unsigned char* output, const uint32_t* input, int32_t len); + void encode(md5Digest& digest); + void decode(uint32_t* output, const unsigned char* input, int32_t len); }; class md5Digest { - friend class md5 ; -public: - md5Digest( void ); // Automatically calls md5Digest::clear(). - ~md5Digest( void ); // Automatically calls md5Digest::clear(). - unsigned char &operator[]( size_t ii ); // lvalue. - unsigned char operator[]( size_t ii ) const; // rvalue. - void clear( void ); + friend class md5; + + public: + md5Digest(void); // Automatically calls md5Digest::clear(). + ~md5Digest(void); // Automatically calls md5Digest::clear(). + unsigned char& operator[](size_t ii); // lvalue. + unsigned char operator[](size_t ii) const; // rvalue. + void clear(void); -private: - unsigned char m_data[ MD5_DIGEST_LENGTH ]; + private: + unsigned char m_data[MD5_DIGEST_LENGTH]; - friend int32_t operator==( const md5Digest &lhs, const md5Digest &rhs ); - friend int32_t operator!=( const md5Digest &lhs, const md5Digest &rhs ); - friend std::istream& operator>>( std::istream& stream, - md5Digest& digest ); - friend std::ostream& operator<<( std::ostream& stream, - const md5Digest& digest ); -// friend void md5::encode( md5Digest &digest ); + friend int32_t operator==(const md5Digest& lhs, const md5Digest& rhs); + friend int32_t operator!=(const md5Digest& lhs, const md5Digest& rhs); + friend std::istream& operator>>(std::istream& stream, md5Digest& digest); + friend std::ostream& operator<<(std::ostream& stream, const md5Digest& digest); + // friend void md5::encode( md5Digest &digest ); }; } // namespace gnuworld diff --git a/libgnuworld/misc.cc b/libgnuworld/misc.cc index 7dbca1be..e2019ef3 100644 --- a/libgnuworld/misc.cc +++ b/libgnuworld/misc.cc @@ -20,73 +20,68 @@ * $Id: misc.cc,v 1.6 2007/12/27 20:45:15 kewlio Exp $ */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "misc.h" -#include "StringTokenizer.h" -#include "ELog.h" - -namespace gnuworld -{ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "misc.h" +#include "StringTokenizer.h" +#include "ELog.h" + +namespace gnuworld { /** * Create a string and copy into it (Key), but convert to all * lower case. */ -string string_lower( const string& Key ) -{ -// This variable will be the string to be returned -// Make a copy of the original string to speed up -// allocation. -string retMe( Key ) ; - -// Iterate through the new string, converting each character -// to lower case -for( string::size_type i = 0, end = retMe.size() ; i < end ; ++i ) - { - retMe[ i ] = tolower( retMe[ i ] ) ; - } +string string_lower(const string& Key) { + // This variable will be the string to be returned + // Make a copy of the original string to speed up + // allocation. + string retMe(Key); + + // Iterate through the new string, converting each character + // to lower case + for (string::size_type i = 0, end = retMe.size(); i < end; ++i) { + retMe[i] = tolower(retMe[i]); + } -// Return by value the new string (this will create a copy of -// the new string) -return retMe ; + // Return by value the new string (this will create a copy of + // the new string) + return retMe; } /** * Create a string and copy into it (Key), but convert to all * upper case. */ -string string_upper( const string& Key ) -{ +string string_upper(const string& Key) { -// This variable will be the string to be returned -// Make a copy of the original string to speed up -// allocation. -string retMe( Key ) ; + // This variable will be the string to be returned + // Make a copy of the original string to speed up + // allocation. + string retMe(Key); -// Iterate through the new string, converting each character -// to upper case -for( string::size_type i = 0, end = retMe.size() ; i < end ; i++ ) - { - retMe[ i ] = toupper( retMe[ i ] ) ; - } + // Iterate through the new string, converting each character + // to upper case + for (string::size_type i = 0, end = retMe.size(); i < end; i++) { + retMe[i] = toupper(retMe[i]); + } -// Return by value the new string (this will create a copy of -// the new string) -return retMe ; + // Return by value the new string (this will create a copy of + // the new string) + return retMe; } /** @@ -95,12 +90,10 @@ return retMe ; * equivalent method which receives the string by const * reference. */ -void string_tolower( string& Key ) -{ -for( string::size_type i = 0, end = Key.size() ; i < end ; i++ ) - { - Key[ i ] = tolower( Key[ i ] ) ; - } +void string_tolower(string& Key) { + for (string::size_type i = 0, end = Key.size(); i < end; i++) { + Key[i] = tolower(Key[i]); + } } /** @@ -109,529 +102,441 @@ for( string::size_type i = 0, end = Key.size() ; i < end ; i++ ) * equivalent method which receives the string by const * reference. */ -void string_toupper( string& Key ) -{ -for( string::size_type i = 0, end = Key.size() ; i < end ; i++ ) - { - Key[ i ] = toupper( Key[ i ] ) ; - } +void string_toupper(string& Key) { + for (string::size_type i = 0, end = Key.size(); i < end; i++) { + Key[i] = toupper(Key[i]); + } } /** * Return true if this string consists of all numerical * [0,9] characters. * Return false otherwise. */ -bool IsNumeric( const string& s ) -{ -for( string::const_iterator ptr = s.begin(), endPtr = s.end() ; - ptr != endPtr ; ++ptr ) - { - if( !isdigit( *ptr ) ) - { - return false ; - } - } -return true ; +bool IsNumeric(const string& s) { + for (string::const_iterator ptr = s.begin(), endPtr = s.end(); ptr != endPtr; ++ptr) { + if (!isdigit(*ptr)) { + return false; + } + } + return true; } /** * Return true if this string consists of a time specification * [0123456789SsMmHhDd] - it also must begin with a digit. */ -bool IsTimeSpec( const string& s ) -{ - char c; - int count = 0; - - for ( string::const_iterator ptr = s.begin(), endPtr = s.end() ; - ptr != endPtr ; ++ptr ) - { - c = tolower(*ptr); - /* if this is the start, it must be a digit */ - if ((ptr == s.begin()) && (!isdigit(c))) - return false; - /* check for valid characters (digits, smhd) */ - if (!isdigit(c) && c != 's' && c != 'm' && c != 'h' && c != 'd') - return false; - /* keep a count of non-numeric characters */ - if (!isdigit(c)) - count++; - /* maximum of 1 is allowed */ - if (count > 1) - return false; - } - /* if we reach here, this is a valid time specification */ - return true; -} - -int strcasecmp( const string& s1, const string& s2 ) -{ -return ::strcasecmp( s1.c_str(), s2.c_str() ) ; +bool IsTimeSpec(const string& s) { + char c; + int count = 0; + + for (string::const_iterator ptr = s.begin(), endPtr = s.end(); ptr != endPtr; ++ptr) { + c = tolower(*ptr); + /* if this is the start, it must be a digit */ + if ((ptr == s.begin()) && (!isdigit(c))) + return false; + /* check for valid characters (digits, smhd) */ + if (!isdigit(c) && c != 's' && c != 'm' && c != 'h' && c != 'd') + return false; + /* keep a count of non-numeric characters */ + if (!isdigit(c)) + count++; + /* maximum of 1 is allowed */ + if (count > 1) + return false; + } + /* if we reach here, this is a valid time specification */ + return true; } +int strcasecmp(const string& s1, const string& s2) { return ::strcasecmp(s1.c_str(), s2.c_str()); } + /** * Returns the time which is given as # as seconds */ -time_t extractTime( string Length, unsigned int defaultUnits ) -{ -unsigned int Units; - -if (defaultUnits == 0) - Units = 1; -else - Units = defaultUnits; - -if (!strcasecmp(Length.substr(Length.length()-1).c_str(),"d")) - { - Units = (24*3600); - Length.resize(Length.length()-1); - } -else if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"h")) - { +time_t extractTime(string Length, unsigned int defaultUnits) { + unsigned int Units; + + if (defaultUnits == 0) + Units = 1; + else + Units = defaultUnits; + + if (!strcasecmp(Length.substr(Length.length() - 1).c_str(), "d")) { + Units = (24 * 3600); + Length.resize(Length.length() - 1); + } else if (!strcasecmp(Length.substr(Length.length() - 1).c_str(), "h")) { Units = 3600; - Length.resize(Length.length()-1); - } -else if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"m")) - { + Length.resize(Length.length() - 1); + } else if (!strcasecmp(Length.substr(Length.length() - 1).c_str(), "m")) { Units = 60; - Length.resize(Length.length()-1); - } -else if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"s")) - { + Length.resize(Length.length() - 1); + } else if (!strcasecmp(Length.substr(Length.length() - 1).c_str(), "s")) { Units = 1; - Length.resize(Length.length()-1); - } + Length.resize(Length.length() - 1); + } -return atoi(Length.c_str()) * Units; + return atoi(Length.c_str()) * Units; } -int atoi( const std::string& val ) -{ -return ::atoi( val.c_str() ) ; -} +int atoi(const std::string& val) { return ::atoi(val.c_str()); } -string itoa(int n) -{ - string Result; - std::ostringstream convert; - convert << n; - Result = convert.str(); - return Result; +string itoa(int n) { + string Result; + std::ostringstream convert; + convert << n; + Result = convert.str(); + return Result; } -string extractNick(const string& NickUserHostIP) -{ - StringTokenizer st( NickUserHostIP, '!' ) ; +string extractNick(const string& NickUserHostIP) { + StringTokenizer st(NickUserHostIP, '!'); - // Make sure there are exactly two tokens - if( st.size() != 2 ) - return string(""); + // Make sure there are exactly two tokens + if (st.size() != 2) + return string(""); - return st[0]; + return st[0]; } -string extractUser(const string& NickUserHostIP) -{ - string NickUser = extractNickUser(NickUserHostIP); +string extractUser(const string& NickUserHostIP) { + string NickUser = extractNickUser(NickUserHostIP); - StringTokenizer st( NickUser, '!' ) ; + StringTokenizer st(NickUser, '!'); - if( st.size() != 2 ) - return string(""); + if (st.size() != 2) + return string(""); - return st[1]; + return st[1]; } -string extractNickUser(const std::string& NickUserHostIP) -{ - StringTokenizer st( NickUserHostIP, '@' ) ; +string extractNickUser(const std::string& NickUserHostIP) { + StringTokenizer st(NickUserHostIP, '@'); - if( st.size() != 2 ) - return string(""); + if (st.size() != 2) + return string(""); - return st[0]; + return st[0]; } -string extractHostIP(const string& NickUserHostIP) -{ - StringTokenizer st( NickUserHostIP, '@' ) ; +string extractHostIP(const string& NickUserHostIP) { + StringTokenizer st(NickUserHostIP, '@'); - if( st.size() != 2 ) - return string(""); + if (st.size() != 2) + return string(""); - return st[1]; + return st[1]; } -bool validUserMask(const string& userMask) -{ - // Check that a '@' exists - StringTokenizer st( userMask, '@' ) ; +bool validUserMask(const string& userMask) { + // Check that a '@' exists + StringTokenizer st(userMask, '@'); - if (st.size() != 2) - { - return false ; - } + if (st.size() != 2) { + return false; + } - // Check that a '!' exists - StringTokenizer st1( st[0], '!' ) ; - if (st1.size() != 2) - { - return false ; - } + // Check that a '!' exists + StringTokenizer st1(st[0], '!'); + if (st1.size() != 2) { + return false; + } - // Be sure that the hostname is no more than 255 characters - if( st[ 1 ].size() > 255 ) - { - return false ; - } + // Be sure that the hostname is no more than 255 characters + if (st[1].size() > 255) { + return false; + } - // Tests have passed - return true ; + // Tests have passed + return true; } -bool validCIDRLength(const string& address) -{ - string hostip = extractHostIP(address); - irc_in_addr ip; - unsigned char ipmask_len; - if (!ipmask_parse(hostip.c_str(), &ip, &ipmask_len)) - return true; - if ((ipmask_len > 0) && (ipmask_len < 32)) - return false; - else - return true; +bool validCIDRLength(const string& address) { + string hostip = extractHostIP(address); + irc_in_addr ip; + unsigned char ipmask_len; + if (!ipmask_parse(hostip.c_str(), &ip, &ipmask_len)) + return true; + if ((ipmask_len > 0) && (ipmask_len < 32)) + return false; + else + return true; } /* If the address is only a hostip/cidr OR an empty string --> will return unchanged * If any wildcard or '!' or '@' found will complete to valid form */ -string fixAddress(const string& address) -{ - if (address.empty()) - return address; - - bool checksafe = false; - - string fixaddr = address; - - if ((fixaddr[0] == '@') || (fixaddr[0] == '!')) - { - fixaddr = "*" + fixaddr; - checksafe = true; - } - if (fixaddr[fixaddr.size()-1] == '@') - { - fixaddr = fixaddr + "*"; - checksafe = true; - } - - StringTokenizer st( fixaddr, '@' ) ; - if (st.size() < 2) - { - irc_in_addr ip; - unsigned char ipmask_len; - if (!ipmask_parse(address.c_str(), &ip, &ipmask_len)) - return address; - else - fixaddr = "*!*@" + address; - } - - //If a CIDR is specified, help out and calculate the correct address - string fixIpHost = extractHostIP(fixaddr); - if (fixIpHost.find('/') != string::npos) - { - fixToCIDR64(fixIpHost); - fixaddr = extractNickUser(fixaddr) + "@" + fixIpHost; - } - - if (validUserMask(fixaddr)) - { - if (((fixaddr == "*!*@*") || (fixaddr == "*!~*@*")) && (checksafe)) - return address; - return fixaddr; - } - - string nick = extractNick(st[0]); - if (nick.empty()) - { - if ((fixaddr[0] != '*') && (fixaddr[0] != '~')) - fixaddr = "*!*" + fixaddr; - else - fixaddr = "*!" + fixaddr; - checksafe = true; - } - if (((fixaddr == "*!*@*") || (fixaddr == "*!~*@*")) && (checksafe)) - return address; - return fixaddr; -} - -bool isUserHost(const string& address) -{ - std::size_t atpos = address.find('@'); - if (atpos == string::npos) - return false; - return true; -} - -bool isAllWildcard(const string& address, bool checkfordots) -{ - bool allwildcard = true; - for (string::size_type pos = 0; pos < address.size(); pos++) - { - if ((address[pos] == '*') || (address[pos] == '?')) - { - continue; - } - else if ((checkfordots) && (address[pos] == '.')) - { - continue; - } - else - { - allwildcard = false; - break; - } - } - return allwildcard; -} - -unsigned char fixToCIDR64(string& strIP) -{ - irc_in_addr ip; - unsigned char ipmask_len; - if (!ipmask_parse(strIP.c_str(), &ip, &ipmask_len)) - return 0; - - bool IsIPv4 = irc_in_addr_is_ipv4(&ip); - string::size_type pos = strIP.find('/'); - strIP = strIP.substr(0, pos); - - // Re-enable this, if want to force to always /64 - //if ((ipmask_len > 64) && (!IsIPv4)) - // ipmask_len = 64; - - //Instead of the above rule, if we have an ipv6 address, and no '/' present, - //then the address is default truncated to /64 - if (((ipmask_len > 64) && (!IsIPv4)) && (pos == string::npos)) - ipmask_len = 64; - - if (((ipmask_len >= 16) && (!IsIPv4)) || ((ipmask_len >= 96) && (IsIPv4))) - { - strIP = IPCIDRMinIP(ip, ipmask_len); - if (IsIPv4) - { //adjust to 32 bit, if we have a IPv4/32 we don't want to show /32 - if (ipmask_len < 128) - strIP += '/' + itoa(unsigned(ipmask_len) - 96); - } - else - { //also, if ipv6/128, don't show the /128 - if (ipmask_len < 128) - strIP += '/' + itoa(unsigned(ipmask_len)); - } - } - return ipmask_len; -} - -string fixToCIDR64(const string& strIP) -{ - string fixIP = strIP; - fixToCIDR64(fixIP); - return fixIP; -} - -string createBanMask(const string& address) -{ - if (!isUserHost(address)) - return address; - - string nick = extractNick(address); - string ident = extractUser(address); - string hostip = extractHostIP(address); - - if (!nick.empty()) nick = "*!"; - - if ('~' == ident[0]) - ident = "~*"; - - if (hostip.find(':') != string::npos) - hostip = createClass(hostip); - - return nick + ident +'@'+ hostip; -} - -string createClass(const string& address, bool wildcard) -{ - string fixaddr; - bool isUserAddr = isUserHost(address); - if (isUserAddr) - fixaddr = extractHostIP(address); - else - fixaddr = address; - unsigned char ipmask_len; - irc_in_addr ip; - if (ipmask_parse(fixaddr.c_str(), &ip, &ipmask_len)) - { - if (irc_in_addr_is_ipv4(&ip)) - { - if (wildcard) - { - StringTokenizer st24(fixaddr, '.'); - fixaddr = st24[0] + '.'; - fixaddr += st24[1] + '.'; - fixaddr += st24[2] + ".*"; - } - else - fixaddr += "/24"; - if (isUserAddr) - fixaddr = extractNickUser(address) + '@' + fixaddr; - return fixaddr; - } - else - { - fixaddr = fixToCIDR64(fixaddr.c_str()); - if (isUserAddr) - fixaddr = extractNickUser(address) + '@' + fixaddr; - return fixaddr; - } - } - else //host address case - { - StringTokenizer st(fixaddr, '.'); - if (st.size() < 2) - return address; - fixaddr = "*." + st.assemble(1); - if (isUserAddr) - fixaddr = extractNickUser(address) + '@' + fixaddr; - return fixaddr; - } -} - -const string prettyNumber( int number ) -{ -std::stringstream ss ; -try { - ss.imbue( std::locale( "en_US.UTF-8" ) ) ; -} catch( const std::exception& e ) { - ss.imbue( std::locale("") ) ; -} -ss << number ; -return ss.str() ; -} - -const string prettyDuration( int duration ) -{ -if (duration == 0) - return "Never"; - -// Pretty format a 'duration' in seconds to -// x day(s), xx:xx:xx. - -char tmpBuf[ 64 ] = {0}; - -int res = ::time(NULL) - duration, - secs = res % 60, - mins = (res / 60) % 60, - hours = (res / 3600) % 24, - days = (res / 86400) ; - -sprintf(tmpBuf, "%i day%s, %02d:%02d:%02d", - days, - (days == 1 ? "" : "s"), - hours, - mins, - secs ); - -return string( tmpBuf ) ; -} - -const string prettyTime( const time_t& theTime, bool Time ) -{ -std::tm retTime = *std::gmtime( &theTime ) ; - -std::ostringstream oss ; -if( Time ) - oss << std::put_time( &retTime, "%F %H:%M:%S" ) ; -else - oss << std::put_time( &retTime, "%F" ) ; - -return oss.str() ; -} - -int getCurrentGMTHour() -{ - time_t rawtime; - tm * ptm; - - time ( &rawtime ); - ptm = gmtime ( &rawtime ); - - return ptm->tm_hour; -} - -const string TokenStringsParams(const char* format,...) -{ - char buf[ 1024 ] = { 0 } ; - va_list _list ; - - va_start( _list, format ) ; - vsnprintf( buf, 1024, format, _list ) ; - va_end( _list ) ; - return string(buf); +string fixAddress(const string& address) { + if (address.empty()) + return address; + + bool checksafe = false; + + string fixaddr = address; + + if ((fixaddr[0] == '@') || (fixaddr[0] == '!')) { + fixaddr = "*" + fixaddr; + checksafe = true; + } + if (fixaddr[fixaddr.size() - 1] == '@') { + fixaddr = fixaddr + "*"; + checksafe = true; + } + + StringTokenizer st(fixaddr, '@'); + if (st.size() < 2) { + irc_in_addr ip; + unsigned char ipmask_len; + if (!ipmask_parse(address.c_str(), &ip, &ipmask_len)) + return address; + else + fixaddr = "*!*@" + address; + } + + // If a CIDR is specified, help out and calculate the correct address + string fixIpHost = extractHostIP(fixaddr); + if (fixIpHost.find('/') != string::npos) { + fixToCIDR64(fixIpHost); + fixaddr = extractNickUser(fixaddr) + "@" + fixIpHost; + } + + if (validUserMask(fixaddr)) { + if (((fixaddr == "*!*@*") || (fixaddr == "*!~*@*")) && (checksafe)) + return address; + return fixaddr; + } + + string nick = extractNick(st[0]); + if (nick.empty()) { + if ((fixaddr[0] != '*') && (fixaddr[0] != '~')) + fixaddr = "*!*" + fixaddr; + else + fixaddr = "*!" + fixaddr; + checksafe = true; + } + if (((fixaddr == "*!*@*") || (fixaddr == "*!~*@*")) && (checksafe)) + return address; + return fixaddr; +} + +bool isUserHost(const string& address) { + std::size_t atpos = address.find('@'); + if (atpos == string::npos) + return false; + return true; +} + +bool isAllWildcard(const string& address, bool checkfordots) { + bool allwildcard = true; + for (string::size_type pos = 0; pos < address.size(); pos++) { + if ((address[pos] == '*') || (address[pos] == '?')) { + continue; + } else if ((checkfordots) && (address[pos] == '.')) { + continue; + } else { + allwildcard = false; + break; + } + } + return allwildcard; +} + +unsigned char fixToCIDR64(string& strIP) { + irc_in_addr ip; + unsigned char ipmask_len; + if (!ipmask_parse(strIP.c_str(), &ip, &ipmask_len)) + return 0; + + bool IsIPv4 = irc_in_addr_is_ipv4(&ip); + string::size_type pos = strIP.find('/'); + strIP = strIP.substr(0, pos); + + // Re-enable this, if want to force to always /64 + // if ((ipmask_len > 64) && (!IsIPv4)) + // ipmask_len = 64; + + // Instead of the above rule, if we have an ipv6 address, and no '/' present, + // then the address is default truncated to /64 + if (((ipmask_len > 64) && (!IsIPv4)) && (pos == string::npos)) + ipmask_len = 64; + + if (((ipmask_len >= 16) && (!IsIPv4)) || ((ipmask_len >= 96) && (IsIPv4))) { + strIP = IPCIDRMinIP(ip, ipmask_len); + if (IsIPv4) { // adjust to 32 bit, if we have a IPv4/32 we don't want to show /32 + if (ipmask_len < 128) + strIP += '/' + itoa(unsigned(ipmask_len) - 96); + } else { // also, if ipv6/128, don't show the /128 + if (ipmask_len < 128) + strIP += '/' + itoa(unsigned(ipmask_len)); + } + } + return ipmask_len; +} + +string fixToCIDR64(const string& strIP) { + string fixIP = strIP; + fixToCIDR64(fixIP); + return fixIP; +} + +string createBanMask(const string& address) { + if (!isUserHost(address)) + return address; + + string nick = extractNick(address); + string ident = extractUser(address); + string hostip = extractHostIP(address); + + if (!nick.empty()) + nick = "*!"; + + if ('~' == ident[0]) + ident = "~*"; + + if (hostip.find(':') != string::npos) + hostip = createClass(hostip); + + return nick + ident + '@' + hostip; +} + +string createClass(const string& address, bool wildcard) { + string fixaddr; + bool isUserAddr = isUserHost(address); + if (isUserAddr) + fixaddr = extractHostIP(address); + else + fixaddr = address; + unsigned char ipmask_len; + irc_in_addr ip; + if (ipmask_parse(fixaddr.c_str(), &ip, &ipmask_len)) { + if (irc_in_addr_is_ipv4(&ip)) { + if (wildcard) { + StringTokenizer st24(fixaddr, '.'); + fixaddr = st24[0] + '.'; + fixaddr += st24[1] + '.'; + fixaddr += st24[2] + ".*"; + } else + fixaddr += "/24"; + if (isUserAddr) + fixaddr = extractNickUser(address) + '@' + fixaddr; + return fixaddr; + } else { + fixaddr = fixToCIDR64(fixaddr.c_str()); + if (isUserAddr) + fixaddr = extractNickUser(address) + '@' + fixaddr; + return fixaddr; + } + } else // host address case + { + StringTokenizer st(fixaddr, '.'); + if (st.size() < 2) + return address; + fixaddr = "*." + st.assemble(1); + if (isUserAddr) + fixaddr = extractNickUser(address) + '@' + fixaddr; + return fixaddr; + } +} + +const string prettyNumber(int number) { + std::stringstream ss; + try { + ss.imbue(std::locale("en_US.UTF-8")); + } catch (const std::exception& e) { + ss.imbue(std::locale("")); + } + ss << number; + return ss.str(); +} + +const string prettyDuration(int duration) { + if (duration == 0) + return "Never"; + + // Pretty format a 'duration' in seconds to + // x day(s), xx:xx:xx. + + char tmpBuf[64] = {0}; + + int res = ::time(NULL) - duration, secs = res % 60, mins = (res / 60) % 60, + hours = (res / 3600) % 24, days = (res / 86400); + + sprintf(tmpBuf, "%i day%s, %02d:%02d:%02d", days, (days == 1 ? "" : "s"), hours, mins, secs); + + return string(tmpBuf); +} + +const string prettyTime(const time_t& theTime, bool Time) { + std::tm retTime = *std::gmtime(&theTime); + + std::ostringstream oss; + if (Time) + oss << std::put_time(&retTime, "%F %H:%M:%S"); + else + oss << std::put_time(&retTime, "%F"); + + return oss.str(); +} + +int getCurrentGMTHour() { + time_t rawtime; + tm* ptm; + + time(&rawtime); + ptm = gmtime(&rawtime); + + return ptm->tm_hour; +} + +const string TokenStringsParams(const char* format, ...) { + char buf[1024] = {0}; + va_list _list; + + va_start(_list, format); + vsnprintf(buf, 1024, format, _list); + va_end(_list); + return string(buf); } /** * Global method to replace ' with \' in strings for safe placement in * SQL statements. */ -const string escapeSQLChars( const string& theString ) -{ -string retMe ; - -for( string::const_iterator ptr = theString.begin() ; - ptr != theString.end() ; ++ptr ) - { - if( *ptr == '\'' ) - { - //retMe += "\\\047" ; - retMe += "''"; - } -// else if ( *ptr == '\\' ) -// { -// retMe += "\\\134" ; -// } - else - { - retMe += *ptr ; - } - } -return retMe ; +const string escapeSQLChars(const string& theString) { + string retMe; + + for (string::const_iterator ptr = theString.begin(); ptr != theString.end(); ++ptr) { + if (*ptr == '\'') { + // retMe += "\\\047" ; + retMe += "''"; + } + // else if ( *ptr == '\\' ) + // { + // retMe += "\\\134" ; + // } + else { + retMe += *ptr; + } + } + return retMe; } /** * Global method to replace wildcards (* and ?) with % and _ in strings for wildcard * searches in SQL statements. */ -const string searchSQL( const string& theString ) -{ -string retMe ; - -for( string::const_iterator ptr = theString.begin() ; - ptr != theString.end() ; ++ptr ) - { - if( *ptr == '*' ) - { - retMe += "%" ; - } - else if ( *ptr == '?' ) - { - retMe += "_" ; - } - else - { - retMe += *ptr ; - } - } -return retMe ; +const string searchSQL(const string& theString) { + string retMe; + + for (string::const_iterator ptr = theString.begin(); ptr != theString.end(); ++ptr) { + if (*ptr == '*') { + retMe += "%"; + } else if (*ptr == '?') { + retMe += "_"; + } else { + retMe += *ptr; + } + } + return retMe; } /** @@ -640,141 +545,141 @@ return retMe ; * * Example: stripModes("+ntkl key 12", "l") will amend the string to "+ntk key". */ -void stripModes( std::string& tempModes, const std::string& modesToStrip ) -{ -std::istringstream iss( tempModes ) ; -std::string modes ; -iss >> modes ; - -std::vector< std::string > args ; -std::string arg ; -while( iss >> arg ) - args.push_back( arg ) ; - -// Helper set to identify modes with arguments -const std::string modesWithArgs = "lkAU"; - -// Create a map to match each mode with its argument -std::unordered_map< char, std::string > modeArgMap ; -size_t argIndex = 0 ; - -for( char mode : modes ) - { - if( modesWithArgs.find( mode ) != std::string::npos && argIndex < args.size() ) - modeArgMap[mode] = args[argIndex++] ; - } - -// Remove specified modes and their arguments -std::string newModes ; -std::vector< std::string > newArgs ; - -for( char mode : modes ) - { - if( modesToStrip.find( mode ) == std::string::npos ) - { - newModes += mode ; - if( modesWithArgs.find( mode ) != std::string::npos && modeArgMap.find( mode ) != modeArgMap.end() ) - newArgs.push_back( modeArgMap[mode] ) ; - } - } - -std::ostringstream oss ; -oss << newModes ; -for( const auto& a : newArgs ) - oss << " " << a ; - -tempModes = oss.str() ; +void stripModes(std::string& tempModes, const std::string& modesToStrip) { + std::istringstream iss(tempModes); + std::string modes; + iss >> modes; + + std::vector args; + std::string arg; + while (iss >> arg) + args.push_back(arg); + + // Helper set to identify modes with arguments + const std::string modesWithArgs = "lkAU"; + + // Create a map to match each mode with its argument + std::unordered_map modeArgMap; + size_t argIndex = 0; + + for (char mode : modes) { + if (modesWithArgs.find(mode) != std::string::npos && argIndex < args.size()) + modeArgMap[mode] = args[argIndex++]; + } + + // Remove specified modes and their arguments + std::string newModes; + std::vector newArgs; + + for (char mode : modes) { + if (modesToStrip.find(mode) == std::string::npos) { + newModes += mode; + if (modesWithArgs.find(mode) != std::string::npos && + modeArgMap.find(mode) != modeArgMap.end()) + newArgs.push_back(modeArgMap[mode]); + } + } + + std::ostringstream oss; + oss << newModes; + for (const auto& a : newArgs) + oss << " " << a; + + tempModes = oss.str(); } /* Returns the memory usage of gnuworld in KB. */ -size_t getMemoryUsage() -{ -struct rusage usage ; -getrusage( RUSAGE_SELF, &usage ) ; -return usage.ru_maxrss ; +size_t getMemoryUsage() { + struct rusage usage; + getrusage(RUSAGE_SELF, &usage); + return usage.ru_maxrss; } // Converts "12asb23b..." to "12:AS:B2:3B..." -std::string compactToCanonical( const std::string& fingerprint ) -{ -std::string result ; -for( size_t i = 0 ; i < fingerprint.size() ; ++i ) - { - result += std::toupper( fingerprint[ i ] ) ; - if( ( i + 1 ) % 2 == 0 && i + 1 < fingerprint.size() ) - result += ':' ; -} -return result ; +std::string compactToCanonical(const std::string& fingerprint) { + std::string result; + for (size_t i = 0; i < fingerprint.size(); ++i) { + result += std::toupper(fingerprint[i]); + if ((i + 1) % 2 == 0 && i + 1 < fingerprint.size()) + result += ':'; + } + return result; } // Converts "12:AS:B2:3B..." back to "12asb23b..." -std::string canonicalToCompact( const std::string& fingerprint ) -{ -std::string result ; -for( char c : fingerprint ) - if( c != ':' ) - result += std::tolower( c ) ; -return result ; +std::string canonicalToCompact(const std::string& fingerprint) { + std::string result; + for (char c : fingerprint) + if (c != ':') + result += std::tolower(c); + return result; } // SHA-256 fingerprint format: 32-byte hash in uppercase hex, separated by colons -bool isValidSHA256Fingerprint( const std::string& fingerprint ) -{ -const std::regex fingerprintRegex( "^([A-F0-9]{2}:){31}[A-F0-9]{2}$" ) ; +bool isValidSHA256Fingerprint(const std::string& fingerprint) { + const std::regex fingerprintRegex("^([A-F0-9]{2}:){31}[A-F0-9]{2}$"); -if( fingerprint.length() != 95 ) - return false ; + if (fingerprint.length() != 95) + return false; -return std::regex_match( fingerprint, fingerprintRegex ) ; + return std::regex_match(fingerprint, fingerprintRegex); } /* Returns the CPU time used by gnuworld in seconds. */ double getCPUTime() { -struct rusage usage ; -getrusage( RUSAGE_SELF, &usage ) ; -return usage.ru_utime.tv_sec + usage.ru_utime.tv_usec / 1e6 + - usage.ru_stime.tv_sec + usage.ru_stime.tv_usec / 1e6 ; -} - -std::string escapeJsonString( const std::string& input ) -{ -std::string output ; -output.reserve( input.length() * 2 ) ; - -for( char c : input) - { - switch (c) { - case '"': output += "\\\"" ; break ; - case '\\': output += "\\\\" ; break ; - case '\b': output += "\\b" ; break ; - case '\f': output += "\\f" ; break ; - case '\n': output += "\\n" ; break ; - case '\r': output += "\\r" ; break ; - case '\t': output += "\\t" ; break ; - default: - if( c >= 0 && c < 32 ) - { - output += "\\u" ; - output += std::to_string( static_cast< int >( c ) ) ; - } - else - { - output += c; + struct rusage usage; + getrusage(RUSAGE_SELF, &usage); + return usage.ru_utime.tv_sec + usage.ru_utime.tv_usec / 1e6 + usage.ru_stime.tv_sec + + usage.ru_stime.tv_usec / 1e6; +} + +std::string escapeJsonString(const std::string& input) { + std::string output; + output.reserve(input.length() * 2); + + for (char c : input) { + switch (c) { + case '"': + output += "\\\""; + break; + case '\\': + output += "\\\\"; + break; + case '\b': + output += "\\b"; + break; + case '\f': + output += "\\f"; + break; + case '\n': + output += "\\n"; + break; + case '\r': + output += "\\r"; + break; + case '\t': + output += "\\t"; + break; + default: + if (c >= 0 && c < 32) { + output += "\\u"; + output += std::to_string(static_cast(c)); + } else { + output += c; + } + break; } - break ; } - } -return output ; + return output; } -std::string getCurrentTimestamp() -{ -auto now = std::time( nullptr ) ; -auto tm = *std::gmtime( &now ) ; +std::string getCurrentTimestamp() { + auto now = std::time(nullptr); + auto tm = *std::gmtime(&now); -std::ostringstream oss ; -oss << std::put_time( &tm, "%Y-%m-%dT%H:%M:%SZ" ) ; -return oss.str() ; + std::ostringstream oss; + oss << std::put_time(&tm, "%Y-%m-%dT%H:%M:%SZ"); + return oss.str(); } } // namespace gnuworld diff --git a/libgnuworld/misc.h b/libgnuworld/misc.h old mode 100755 new mode 100644 index 6a18c2c4..cad0c4f2 --- a/libgnuworld/misc.h +++ b/libgnuworld/misc.h @@ -25,128 +25,117 @@ #ifndef __MISC_H #define __MISC_H "$Id: misc.h,v 1.9 2007/12/27 20:45:15 kewlio Exp $" -#include -#include -#include +#include +#include +#include -#include -#include -#include +#include +#include +#include -#include "match.h" +#include "match.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; /** * Return 0 if the two strings are equivalent, according to * case insensitive searches. * Otherwise, it returns the comparison between * s1 and s2. */ -int strcasecmp( const string&, const string& ) ; +int strcasecmp(const string&, const string&); /** * Case insensitive comparison struct for use by STL structures/algorithms. */ -struct noCaseCompare -{ -inline bool operator()( const string& lhs, const string& rhs ) const - { - return (strcasecmp( lhs, rhs ) < 0) ; - } -} ; +struct noCaseCompare { + inline bool operator()(const string& lhs, const string& rhs) const { + return (strcasecmp(lhs, rhs) < 0); + } +}; /** * A case insensitive binary predicate comparator for two * string's. */ -struct eqstr -{ -inline bool operator()( const string& s1, const string& s2 ) const - { - return (0 == strcasecmp( s1, s2 )) ; - } -} ; +struct eqstr { + inline bool operator()(const string& s1, const string& s2) const { + return (0 == strcasecmp(s1, s2)); + } +}; /** * A hashing operator for the system hash tables. * This is not used for now, since hash_map has been removed * from gnuworld completely. */ -struct eHash -{ -inline size_t operator()( const string& s ) const - { - if( s.empty() ) - { - return 0 ; - } - - size_t __h = 0 ; - for ( const char* ptr = s.c_str() ; *ptr ; ++ptr ) - { - __h = (5 * __h) + tolower( *ptr ) ; - } - return __h ; - } -} ; +struct eHash { + inline size_t operator()(const string& s) const { + if (s.empty()) { + return 0; + } + + size_t __h = 0; + for (const char* ptr = s.c_str(); *ptr; ++ptr) { + __h = (5 * __h) + tolower(*ptr); + } + return __h; + } +}; /** * A functor suitable for using in STL style containers which provides * wildcard matching routine. */ -struct Match -{ -inline bool operator()( const string& lhs, const string& rhs ) const - { - return (match( lhs, rhs ) < 0) ; - } -} ; +struct Match { + inline bool operator()(const string& lhs, const string& rhs) const { + return (match(lhs, rhs) < 0); + } +}; /** * Return a copy of a given C++ string, whose characters * are all lower case. */ -string string_lower( const string& ) ; +string string_lower(const string&); /** * Return a copy of a given C++ string, whose * characters are all upper case. */ -string string_upper( const string& ) ; +string string_upper(const string&); /** * Convert all characters of a given C++ string to * lower case. */ -void string_tolower( string& ) ; +void string_tolower(string&); /** * Convert all characters of a given C++ string to * upper case. */ -void string_toupper( string& ) ; +void string_toupper(string&); /** * Examine a given C++ string and return true if it contains * a time specification, return false otherwise. */ -bool IsTimeSpec( const string& ) ; +bool IsTimeSpec(const string&); /** * Examine a given C++ string and return true if it contains * all numeric characters, return false otherwise. */ -bool IsNumeric( const string& ) ; +bool IsNumeric(const string&); /** * Returns the time which is given as # as seconds */ -time_t extractTime( string Length, unsigned int defaultUnits ) ; +time_t extractTime(string Length, unsigned int defaultUnits); -int atoi( const string& ) ; +int atoi(const string&); /* itoa: convert n to characters in s */ string itoa(int n); @@ -154,36 +143,36 @@ string itoa(int n); /** * Extract the parts of a *valid* nick!user@hostip address */ -string extractNick( const string& ) ; +string extractNick(const string&); -string extractUser( const string& ) ; +string extractUser(const string&); -string extractNickUser( const string& ) ; +string extractNickUser(const string&); -string extractHostIP( const string& ) ; +string extractHostIP(const string&); // Check for valid hostmask. -bool validUserMask(const string& ); +bool validUserMask(const string&); -bool validCIDRLength(const string& ); +bool validCIDRLength(const string&); -string fixAddress( const string& ); +string fixAddress(const string&); -//Check if we have !at least! a *@hostip format -bool isUserHost( const string& ); +// Check if we have !at least! a *@hostip format +bool isUserHost(const string&); bool isAllWildcard(const string&, bool checkfordots = false); /* Truncate a > /64 IPv6 address to a /64 cidr address * or creates a between /32 - /64 valid cidr address */ -unsigned char fixToCIDR64(string& ); +unsigned char fixToCIDR64(string&); -//Same as above, just returns the fixed address. Easier to use many times -string fixToCIDR64(const string& ); +// Same as above, just returns the fixed address. Easier to use many times +string fixToCIDR64(const string&); -//Constructs a 'generally valid' banmask for a [nick!]user@hostip address -string createBanMask(const string& ); +// Constructs a 'generally valid' banmask for a [nick!]user@hostip address +string createBanMask(const string&); /* Create a 24/64 cidr address (optionally wildcarded) * for an IPv4 or IPv6 address, or for a hostname @@ -192,30 +181,35 @@ string createBanMask(const string& ); string createClass(const string&, bool wildcard = false); /* Formats a timestamp into a "X Days, XX:XX:XX" from 'Now'. */ -const string prettyDuration( int ) ; +const string prettyDuration(int); /* Comma separates thousands for a number (e.g. 1000 to 1,000) */ -const string prettyNumber( int ) ; +const string prettyNumber(int); /* Formats a timestamp into %F %H:%M:%S */ -const std::string prettyTime( const std::time_t&, bool = true ) ; +const std::string prettyTime(const std::time_t&, bool = true); /* Returns the number of milliseconds having lapsed from the startTime, * provided as an argument. */ -template < typename Clock = std::chrono::high_resolution_clock, typename Duration = std::chrono::milliseconds > -long long elapsedMs( const typename Clock::time_point& startTime ) -{ return std::chrono::duration_cast< Duration >( Clock::now() - startTime ).count() ; } +template +long long elapsedMs(const typename Clock::time_point& startTime) { + return std::chrono::duration_cast(Clock::now() - startTime).count(); +} /* Returns the current timepoint. */ -template < typename Clock = std::chrono::high_resolution_clock > -typename Clock::time_point currentTimePoint() -{ return Clock::now() ; } +template +typename Clock::time_point currentTimePoint() { + return Clock::now(); +} /* Converts a timepoint into a time_t epoch timestamp. */ -template < typename Clock = std::chrono::high_resolution_clock, typename Duration = std::chrono::seconds > -time_t timePointToEpoch( const typename Clock::time_point& timePoint ) -{ return std::chrono::duration_cast< Duration >( timePoint.time_since_epoch() ).count() ; } +template +time_t timePointToEpoch(const typename Clock::time_point& timePoint) { + return std::chrono::duration_cast(timePoint.time_since_epoch()).count(); +} int getCurrentGMTHour(); /* returns the current hour in GMT (00-23) */ @@ -226,13 +220,13 @@ const string TokenStringsParams(const char*, ...); * Global method to replace ' with \' in strings for safe placement in * SQL statements. */ -const std::string escapeSQLChars( const std::string& ) ; +const std::string escapeSQLChars(const std::string&); /** * Global method to replace wildcards (* and ?) with % and _ in strings for wildcard * searches in SQL statements. */ -const std::string searchSQL( const std::string& ) ; +const std::string searchSQL(const std::string&); /** * Takes as the first arugment a reference to a string containing modes (and args if any), @@ -240,30 +234,29 @@ const std::string searchSQL( const std::string& ) ; * * Example: stripModes("+ntkl key 12", "l") will amend the string to "+ntk key". */ -void stripModes( std::string& , const std::string& ) ; +void stripModes(std::string&, const std::string&); /* Returns the memory usage of gnuworld in KB. */ -size_t getMemoryUsage() ; +size_t getMemoryUsage(); -std::string compactToCanonical( const std::string& ) ; +std::string compactToCanonical(const std::string&); // Converts "12:AS:B2:3B..." back to "12asb23b..." -std::string canonicalToCompact( const std::string& ) ; +std::string canonicalToCompact(const std::string&); -bool isValidSHA256Fingerprint( const std::string& ) ; +bool isValidSHA256Fingerprint(const std::string&); /* Returns the CPU time used by gnuworld in seconds. */ -double getCPUTime() ; +double getCPUTime(); /* Masks a string for logging purposes. Typically used for passwords. */ -inline std::string mask( const std::string& s ) - { return std::string( s.size(), '*' ) ; } +inline std::string mask(const std::string& s) { return std::string(s.size(), '*'); } /* Escape a string for JSON logging. */ -std::string escapeJsonString( const std::string& input ) ; +std::string escapeJsonString(const std::string& input); /* Returns current UTC timestamp in ISO 8601 format. */ -std::string getCurrentTimestamp() ; +std::string getCurrentTimestamp(); } // namespace gnuworld diff --git a/libgnuworld/threadworker.cc b/libgnuworld/threadworker.cc index 5d3fb373..23b54f89 100644 --- a/libgnuworld/threadworker.cc +++ b/libgnuworld/threadworker.cc @@ -23,53 +23,41 @@ #include "threadworker.h" #include "misc.h" -namespace gnuworld -{ +namespace gnuworld { -ThreadWorker::ThreadWorker( ) : stop( false ) -{ -worker = std::thread( &ThreadWorker::run, this ) ; -} - -ThreadWorker::~ThreadWorker() -{ - { - std::lock_guard lock( mutex ) ; - stop = true ; - } -cv.notify_one() ; -if( worker.joinable() ) - worker.join() ; -} +ThreadWorker::ThreadWorker() : stop(false) { worker = std::thread(&ThreadWorker::run, this); } -void ThreadWorker::run() -{ -while( true ) - { - std::function< void() > job ; +ThreadWorker::~ThreadWorker() { { - std::unique_lock lock( mutex ) ; - cv.wait( lock, [&] { return stop || !jobs.empty() ; } ) ; - if( stop && jobs.empty() ) - return ; - job = std::move( jobs.front() ) ; - jobs.pop() ; + std::lock_guard lock(mutex); + stop = true; } + cv.notify_one(); + if (worker.joinable()) + worker.join(); +} - try - { - // elog << "Starting job execution" << endl ; - job() ; - } - catch( const std::exception& e ) - { - elog << "Exception in job execution: " << e.what() << std::endl ; - } - catch( ... ) - { - elog << "Unknown exception in job execution" << std::endl ; +void ThreadWorker::run() { + while (true) { + std::function job; + { + std::unique_lock lock(mutex); + cv.wait(lock, [&] { return stop || !jobs.empty(); }); + if (stop && jobs.empty()) + return; + job = std::move(jobs.front()); + jobs.pop(); + } + + try { + // elog << "Starting job execution" << endl ; + job(); + } catch (const std::exception& e) { + elog << "Exception in job execution: " << e.what() << std::endl; + } catch (...) { + elog << "Unknown exception in job execution" << std::endl; + } } - } } } // namespace gnuworld diff --git a/libgnuworld/threadworker.h b/libgnuworld/threadworker.h index 740d5fd5..f278e8cf 100644 --- a/libgnuworld/threadworker.h +++ b/libgnuworld/threadworker.h @@ -28,43 +28,39 @@ #include #include -namespace gnuworld -{ +namespace gnuworld { class ThreadWorker { -private: - std::queue< std::function< void() > > jobs ; - mutable std::mutex mutex ; - std::condition_variable cv ; - std::thread worker ; - bool stop ; + private: + std::queue> jobs; + mutable std::mutex mutex; + std::condition_variable cv; + std::thread worker; + bool stop; - void run() ; + void run(); -public: - ThreadWorker() ; - ~ThreadWorker() ; + public: + ThreadWorker(); + ~ThreadWorker(); - template< typename Callable > - void submitJob( Callable&& task ) { - { - std::lock_guard< std::mutex > lock( mutex ) ; - jobs.emplace( std::forward< Callable >( task ) ) ; + template void submitJob(Callable&& task) { + { + std::lock_guard lock(mutex); + jobs.emplace(std::forward(task)); + } + cv.notify_one(); } - cv.notify_one() ; - } - bool hasPendingJobs() const - { - std::lock_guard< std::mutex > lock( mutex ) ; - return !jobs.empty() ; + bool hasPendingJobs() const { + std::lock_guard lock(mutex); + return !jobs.empty(); } - size_t getPendingJobCount() const - { - std::lock_guard< std::mutex > lock( mutex ) ; - return jobs.size() ; + size_t getPendingJobCount() const { + std::lock_guard lock(mutex); + return jobs.size(); } -} ; +}; } // namespace gnuworld diff --git a/libgnuworld/xparameters.h b/libgnuworld/xparameters.h old mode 100755 new mode 100644 index d4fb9415..5033d0e2 --- a/libgnuworld/xparameters.h +++ b/libgnuworld/xparameters.h @@ -23,15 +23,14 @@ #ifndef __XPARAMETERS_H #define __XPARAMETERS_H "$Id: xparameters.h,v 1.4 2003/12/29 23:59:36 dan_karrels Exp $" -#include -#include +#include +#include -#include +#include -#include "ELog.h" +#include "ELog.h" -namespace gnuworld -{ +namespace gnuworld { /** * This class is similar to StringTokenizer, except that it accepts @@ -41,180 +40,167 @@ namespace gnuworld * at zero. * This class is mutable. */ -class xParameters -{ - -private: - /** - * The structure type for storing the tokens internally. - */ - typedef std::vector< char* > vectorType ; - -public: - - /** - * The variable type used to represent this class's - * size (number of tokens in the object). - */ - typedef vectorType::size_type size_type ; - - /** - * Construct an xParameters object. - */ - xParameters() {} - - /** - * Destroy an xParameters object. - * No streams have been opened, and no memory explicitly - * dynamically allocated, so this method is a NOOP. - */ - ~xParameters() {} - - /** - * This type is used to perform a read only iteration - * of this objects array of strings. - */ - typedef vectorType::const_iterator const_iterator ; - - /** - * Return a const_iterator to the beginning of the array - * of strings. - */ - inline const_iterator begin() const - { return myVector.begin() ; } - - /** - * Return a const_iterator to the end of the array - * of strings. - */ - inline const_iterator end() const - { return myVector.end() ; } - - /** - * Insert a pointer to a character array (token) into the - * xParameters instance. - */ - inline xParameters& operator<<( char* Parameter ) - { myVector.push_back( Parameter ) ; return *this ; } - - /** - * Return a pointer to a mutable character array token. - * The tokens are indexed beginning at zero. - * This method will assert false if the requested index - * is out of bounds, according to validSubscript. - */ - inline char* operator[]( const size_type& pos ) const - { assert( validSubscript( pos ) ) ; return myVector[ pos ] ; } - - /** - * Set a particular element to a new value, NULL is - * permitted. - */ - void setValue( const size_t pos, char* newVal ) - { assert( validSubscript( pos ) ) ; myVector[ pos ] = newVal ; } - - /** - * Remove all tokens, if any, from this xParameters object. - */ - inline void Clear() - { myVector.clear() ; } - - /** - * Return the number of tokens held in this xParameters object. - */ - inline size_type Count() const - { return myVector.size() ; } - - /** - * Return the number of tokens held in this xParameters object. - */ - inline size_type size() const - { return myVector.size() ; } - - /** - * Return true if there exist no tokens represented by this - * class. - */ - inline bool empty() const - { return myVector.empty() ; } - - /** - * Return true if the given variable (i) is a valid index - * into the table of tokens. - * Return false otherwise. - */ - inline bool validSubscript( const size_type& i ) const - { return (i < myVector.size()) ; } - - /** - * Return a string containing all tokens beginning - * with the zero based index beginIndex. A ' ' will - * be placed between token in the string returned. - */ - inline std::string assemble( const size_type& beginIndex ) const - { - assert( validSubscript( beginIndex ) ) ; - if( myVector.empty() ) - { - return std::string() ; - } - std::string retMe( "" ) ; - for( vectorType::size_type i = beginIndex ; - i < myVector.size() ; ++i ) - { - retMe += myVector[ i ] ; - if( (i + 1) < myVector.size() ) - { - retMe += ' ' ; - } - } - return retMe ; - } - - /** - * A simple operator to output an xParameters object to - * an ELog stream. - */ - friend ELog& operator<<( ELog& out, const xParameters& param ) - { - // Iterate through to each element - for( size_type i = 0 ; i < param.size() ; ++i ) - { - // Place this element into the ELog stream - out << param[ i ] ; - - // If there is at least one more token left, - // place a space character into the stream - if( (i + 1) < param.size() ) - { - out << ' ' ; - } - } - // Return the ELog stream so that it may be used - // for further pipelining of output - return out ; - } - -protected: - - /** - * Disable copy constructing. - * This method is declared, but NOT defined. - */ - xParameters( const xParameters& ) ; - - /** - * Disable default assignment. - * This method is declared but NOT defined. - */ - xParameters operator=( const xParameters& ) ; - - /** - * This is the structure used to store tokens internally. - */ - vectorType myVector ; - -} ; +class xParameters { + + private: + /** + * The structure type for storing the tokens internally. + */ + typedef std::vector vectorType; + + public: + /** + * The variable type used to represent this class's + * size (number of tokens in the object). + */ + typedef vectorType::size_type size_type; + + /** + * Construct an xParameters object. + */ + xParameters() {} + + /** + * Destroy an xParameters object. + * No streams have been opened, and no memory explicitly + * dynamically allocated, so this method is a NOOP. + */ + ~xParameters() {} + + /** + * This type is used to perform a read only iteration + * of this objects array of strings. + */ + typedef vectorType::const_iterator const_iterator; + + /** + * Return a const_iterator to the beginning of the array + * of strings. + */ + inline const_iterator begin() const { return myVector.begin(); } + + /** + * Return a const_iterator to the end of the array + * of strings. + */ + inline const_iterator end() const { return myVector.end(); } + + /** + * Insert a pointer to a character array (token) into the + * xParameters instance. + */ + inline xParameters& operator<<(char* Parameter) { + myVector.push_back(Parameter); + return *this; + } + + /** + * Return a pointer to a mutable character array token. + * The tokens are indexed beginning at zero. + * This method will assert false if the requested index + * is out of bounds, according to validSubscript. + */ + inline char* operator[](const size_type& pos) const { + assert(validSubscript(pos)); + return myVector[pos]; + } + + /** + * Set a particular element to a new value, NULL is + * permitted. + */ + void setValue(const size_t pos, char* newVal) { + assert(validSubscript(pos)); + myVector[pos] = newVal; + } + + /** + * Remove all tokens, if any, from this xParameters object. + */ + inline void Clear() { myVector.clear(); } + + /** + * Return the number of tokens held in this xParameters object. + */ + inline size_type Count() const { return myVector.size(); } + + /** + * Return the number of tokens held in this xParameters object. + */ + inline size_type size() const { return myVector.size(); } + + /** + * Return true if there exist no tokens represented by this + * class. + */ + inline bool empty() const { return myVector.empty(); } + + /** + * Return true if the given variable (i) is a valid index + * into the table of tokens. + * Return false otherwise. + */ + inline bool validSubscript(const size_type& i) const { return (i < myVector.size()); } + + /** + * Return a string containing all tokens beginning + * with the zero based index beginIndex. A ' ' will + * be placed between token in the string returned. + */ + inline std::string assemble(const size_type& beginIndex) const { + assert(validSubscript(beginIndex)); + if (myVector.empty()) { + return std::string(); + } + std::string retMe(""); + for (vectorType::size_type i = beginIndex; i < myVector.size(); ++i) { + retMe += myVector[i]; + if ((i + 1) < myVector.size()) { + retMe += ' '; + } + } + return retMe; + } + + /** + * A simple operator to output an xParameters object to + * an ELog stream. + */ + friend ELog& operator<<(ELog& out, const xParameters& param) { + // Iterate through to each element + for (size_type i = 0; i < param.size(); ++i) { + // Place this element into the ELog stream + out << param[i]; + + // If there is at least one more token left, + // place a space character into the stream + if ((i + 1) < param.size()) { + out << ' '; + } + } + // Return the ELog stream so that it may be used + // for further pipelining of output + return out; + } + + protected: + /** + * Disable copy constructing. + * This method is declared, but NOT defined. + */ + xParameters(const xParameters&); + + /** + * Disable default assignment. + * This method is declared but NOT defined. + */ + xParameters operator=(const xParameters&); + + /** + * This is the structure used to store tokens internally. + */ + vectorType myVector; +}; } // namespace gnuworld diff --git a/libircu/msg_AC.cc b/libircu/msg_AC.cc old mode 100755 new mode 100644 index 2dbb4fb8..bf26c052 --- a/libircu/msg_AC.cc +++ b/libircu/msg_AC.cc @@ -19,20 +19,19 @@ * "$Id: msg_AC.cc,v 1.9 2005/03/25 03:07:29 dan_karrels Exp $" */ -#include -#include +#include +#include -#include "gnuworld_config.h" -#include "ServerCommandHandler.h" -#include "server.h" -#include "xparameters.h" -#include "Channel.h" -#include "Network.h" -#include "iClient.h" -#include "ELog.h" +#include "gnuworld_config.h" +#include "ServerCommandHandler.h" +#include "server.h" +#include "xparameters.h" +#include "Channel.h" +#include "Network.h" +#include "iClient.h" +#include "ELog.h" -namespace gnuworld -{ +namespace gnuworld { CREATE_HANDLER(msg_AC) @@ -43,76 +42,69 @@ CREATE_HANDLER(msg_AC) * AXAAA AC BQrTd Hidden 1694970265 1024 * Note: ACCOUNT_ID and ACCOUNT_FLAGS are optional */ -bool msg_AC::Execute( const xParameters& Param ) -{ -if( Param.size() < 3 ) - { - elog << "msg_AC> Invalid number of parameters" - << std::endl ; - return false ; - } +bool msg_AC::Execute(const xParameters& Param) { + if (Param.size() < 3) { + elog << "msg_AC> Invalid number of parameters" << std::endl; + return false; + } -// Find the target user -iClient* theClient = Network->findClient( Param[ 1 ] ) ; -if( !theClient ) - { - elog << "msg_AC> Unable to find target client: " - << Param[ 1 ] - << std::endl ; - return false; - } + // Find the target user + iClient* theClient = Network->findClient(Param[1]); + if (!theClient) { + elog << "msg_AC> Unable to find target client: " << Param[1] << std::endl; + return false; + } -std::string account( Param[2] ); -unsigned int account_id = 0; -iClient::flagType account_flags = 0; + std::string account(Param[2]); + unsigned int account_id = 0; + iClient::flagType account_flags = 0; -/* If we have an account, does it have an id? */ -if( ! account.empty() ) { - std::string::size_type pos = account.find(':'); - if( ! ( pos == std::string::npos ) ) { - /* We have an account id */ - if ( pos == ( account.length() - 1 ) ) { - /* Bizarre - colon but no following account id */ - elog << "msg_N> Invalid account format: " - << account - << std::endl; - } else { - std::string account_id_s = account; - account_id_s.erase(0, pos + 1); - account.erase(pos); + /* If we have an account, does it have an id? */ + if (!account.empty()) { + std::string::size_type pos = account.find(':'); + if (!(pos == std::string::npos)) { + /* We have an account id */ + if (pos == (account.length() - 1)) { + /* Bizarre - colon but no following account id */ + elog << "msg_N> Invalid account format: " << account << std::endl; + } else { + std::string account_id_s = account; + account_id_s.erase(0, pos + 1); + account.erase(pos); - account_id = atoi(account_id_s.c_str()); - } - } - if (Param.size() > 3) { - std::string account_id_s = Param[3]; - if (!account_id_s.empty()) { - account_id = atoi(account_id_s); - } - } - if (Param.size() > 4) { - std::string account_flags_s = Param[4]; - if (!account_flags_s.empty()) { - account_flags = atoi(account_flags_s); - } - } -} + account_id = atoi(account_id_s.c_str()); + } + } + if (Param.size() > 3) { + std::string account_id_s = Param[3]; + if (!account_id_s.empty()) { + account_id = atoi(account_id_s); + } + } + if (Param.size() > 4) { + std::string account_flags_s = Param[4]; + if (!account_flags_s.empty()) { + account_flags = atoi(account_flags_s); + } + } + } -// Is this a change of flags or a new login? -bool alreadyAuthed = false ; -if( theClient->isModeR() ) - alreadyAuthed = true ; + // Is this a change of flags or a new login? + bool alreadyAuthed = false; + if (theClient->isModeR()) + alreadyAuthed = true; -// Update user information -theClient->setAccount( account ) ; -theClient->setAccountID( account_id ) ; -theClient->setAccountFlags( account_flags ) ; + // Update user information + theClient->setAccount(account); + theClient->setAccountID(account_id); + theClient->setAccountFlags(account_flags); -// Post event to listening clients -theServer->PostEvent( alreadyAuthed ? EVT_ACCOUNT_FLAGS : EVT_ACCOUNT, static_cast< void* >( theClient ) ) ; + // Post event to listening clients + theServer->PostEvent(alreadyAuthed ? EVT_ACCOUNT_FLAGS : EVT_ACCOUNT, + static_cast(theClient)); -// Return success -return true; + // Return success + return true; } } // namespace gnuworld diff --git a/libircu/msg_AD.cc b/libircu/msg_AD.cc index 372ffaf5..0dcecd76 100644 --- a/libircu/msg_AD.cc +++ b/libircu/msg_AD.cc @@ -20,19 +20,15 @@ * $Id: msg_AD.cc,v 1.4 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include "gnuworld_config.h" -#include "server.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { CREATE_HANDLER(msg_AD) -bool msg_AD::Execute( const xParameters& ) -{ -return true ; -} +bool msg_AD::Execute(const xParameters&) { return true; } } // namespace gnuworld diff --git a/libircu/msg_B.cc b/libircu/msg_B.cc index 2360152b..20b8bc6f 100644 --- a/libircu/msg_B.cc +++ b/libircu/msg_B.cc @@ -21,54 +21,47 @@ * $Id: msg_B.cc,v 1.12 2008/04/16 20:29:37 danielaustin Exp $ */ -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "gnuworld_config.h" -#include "server.h" -#include "xparameters.h" -#include "StringTokenizer.h" -#include "ELog.h" -#include "Channel.h" -#include "ChannelUser.h" -#include "Network.h" -#include "iClient.h" -#include "ServerCommandHandler.h" - - -namespace gnuworld -{ -using std::pair ; -using std::make_pair ; -using std::string ; -using std::vector ; -using std::endl ; - -class msg_B : public ServerCommandHandler -{ -public: - msg_B( xServer* theServer ) - : ServerCommandHandler( theServer ) - {} - virtual ~msg_B() - {} - - virtual bool Execute( const xParameters& ) ; - -protected: - void parseBurstUsers( Channel*, const string& ) ; - void parseBurstBans( Channel*, const string& ) ; - -} ; +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "gnuworld_config.h" +#include "server.h" +#include "xparameters.h" +#include "StringTokenizer.h" +#include "ELog.h" +#include "Channel.h" +#include "ChannelUser.h" +#include "Network.h" +#include "iClient.h" +#include "ServerCommandHandler.h" + +namespace gnuworld { +using std::endl; +using std::make_pair; +using std::pair; +using std::string; +using std::vector; + +class msg_B : public ServerCommandHandler { + public: + msg_B(xServer* theServer) : ServerCommandHandler(theServer) {} + virtual ~msg_B() {} + + virtual bool Execute(const xParameters&); + + protected: + void parseBurstUsers(Channel*, const string&); + void parseBurstBans(Channel*, const string&); +}; CREATE_LOADER(msg_B) @@ -103,219 +96,174 @@ CREATE_LOADER(msg_B) // B : // Ck B #test 1128024142 +tnAU apass upass BBAAA:999 // -bool msg_B::Execute( const xParameters& Param ) -{ -// Make sure there are at least four arguments supplied: -// servernumeric #channel time_stamp arguments -if( Param.size() < 3 ) - { - elog << "msg_B> Invalid number of arguments: " - << Param - << endl ; - return false ; - } - -// Attempt to find the channel in the network channel table -Channel* theChan = Network->findChannel( Param[ 1 ] ) ; - -// Was the channel found? -if( NULL == theChan ) - { - // The channel does not yet exist, go ahead and create it. - theChan = new (std::nothrow) - Channel( Param[ 1 ], atoi( Param[ 2 ] ) ) ; - assert( theChan != 0 ) ; - - // Add the new Channel to the network channel table - if( !Network->addChannel( theChan ) ) - { - // The addition of this channel failed, *shrug* - elog << "msg_B> Failed to add channel: " - << Param[ 1 ] - << endl ; - - // Prevent a memory leak by deleting the channel - delete theChan ; theChan = 0 ; - - // Return error - return false ; - } - } // if( NULL == theChan ) -else - { - // The channel was already found. - // Make sure the timestamp is accurate, this is an oddity imho. - time_t newCreationTime = - static_cast< time_t >( ::atoi( Param[ 2 ] ) ) ; - - // Is the old TS greater than the new TS? - if( theChan->getCreationTime() > newCreationTime ) - { - // Nope, update the timestamp - theChan->setCreationTime( newCreationTime ) ; - theChan->removeAllModes() ; - theChan->removeAllBans() ; - } - } - -if( 3 == Param.size() ) - { - // Zombie in channel. - // If the user is dezombified, the client will be shown - // to issue a "J", and the channel will be created anyway. - // Only difference is the timestamp difference. - return true ; - } - -// Parse out the channel state -xParameters::size_type whichToken = 3 ; - -// Channel modes will always be the first thing to follow if it's in the burst -if( '+' == Param[ whichToken ][ 0 ] ) - { - // channel modes - const char* currentPtr = Param[ whichToken ] ; - - // Skip over the '+' - ++currentPtr ; - - xServer::modeVectorType modeVector ; - - for( ; currentPtr && *currentPtr ; ++currentPtr ) - { - switch( *currentPtr ) - { - case 't': - modeVector.push_back( make_pair( - true, Channel::MODE_T ) ) ; - break ; - case 'n': - modeVector.push_back( make_pair( - true, Channel::MODE_N ) ) ; - break ; - case 'm': - modeVector.push_back( make_pair( - true, Channel::MODE_M ) ) ; - break ; - case 'p': - modeVector.push_back( make_pair( - true, Channel::MODE_P ) ) ; - break ; - case 's': - modeVector.push_back( make_pair( - true, Channel::MODE_S ) ) ; - break ; - case 'i': - modeVector.push_back( make_pair( - true, Channel::MODE_I ) ) ; - break ; - case 'r': - modeVector.push_back( make_pair( - true, Channel::MODE_R ) ) ; - break ; - case 'R': - modeVector.push_back( make_pair( - true, Channel::MODE_REG ) ) ; - break ; - case 'D': - modeVector.push_back( make_pair( - true, Channel::MODE_D ) ) ; - break ; - case 'c': - modeVector.push_back( make_pair( - true, Channel::MODE_C ) ) ; - break ; - case 'C': - modeVector.push_back( make_pair( - true, Channel::MODE_CTCP ) ) ; - break ; - case 'u': - modeVector.push_back( make_pair( - true, Channel::MODE_PART ) ) ; - break ; - case 'M': - modeVector.push_back( make_pair( - true, Channel::MODE_MNOREG ) ) ; - break ; - case 'Z': - modeVector.push_back( make_pair( - true, Channel::MODE_Z ) ) ; - break ; - case 'l': - theServer->OnChannelModeL( theChan, true, - 0, - ::atoi( Param[ whichToken + 1 ] ) ) ; - whichToken++ ; - break ; - case 'k': - theServer->OnChannelModeK( theChan, true, - 0, - Param[ whichToken + 1 ] ) ; - whichToken++ ; - break ; - case 'A': - theServer->OnChannelModeA( theChan, true, - 0, - Param[ whichToken + 1 ] ) ; - whichToken++ ; - break ; - case 'U': - theServer->OnChannelModeU( theChan, true, - 0, - Param[ whichToken + 1 ] ) ; - whichToken++ ; - break ; - default: - break ; - } // switch - - } // for( currentPtr != endPtr ) - - if( !modeVector.empty() ) - { - theServer->OnChannelMode( theChan, 0, modeVector ) ; - } - - // Skip over the modes token - // whichToken either points to the modes token if no +l/+k - // was specified, or it points to the last +l/+k argument; - // skip over this token no matter which. - whichToken++ ; - - } // if( '+' == Param[ whichToken ][ 0 ] - -// Have we reached the end of this burst command? -if( whichToken >= Param.size() ) - { - return true ; - } - -// Parse the remaining tokens -for( ; whichToken < Param.size() ; ++whichToken ) - { - // Bans will always be the last thing burst, so no users - // will be burst afterwards. This is useful because xParameters - // will only delimit tokens by ':', so the ban string is guaranteed - // to be caught. - if( '~' == Param[ whichToken ][ 0 ] ) - { - // Channel ban exceptions - // Be sure to skip over the '%' - //parseBurstExcepts( theChan, Param[ whichToken ] + 1 ) ; - } - else if( '%' == Param[ whichToken ][ 0 ] ) - { - // Channel bans - // Be sure to skip over the '%' - parseBurstBans( theChan, Param[ whichToken ] + 1 ) ; - } - else - { - // Userlist - parseBurstUsers( theChan, Param[ whichToken ] ) ; - } - } -return true ; +bool msg_B::Execute(const xParameters& Param) { + // Make sure there are at least four arguments supplied: + // servernumeric #channel time_stamp arguments + if (Param.size() < 3) { + elog << "msg_B> Invalid number of arguments: " << Param << endl; + return false; + } + + // Attempt to find the channel in the network channel table + Channel* theChan = Network->findChannel(Param[1]); + + // Was the channel found? + if (NULL == theChan) { + // The channel does not yet exist, go ahead and create it. + theChan = new (std::nothrow) Channel(Param[1], atoi(Param[2])); + assert(theChan != 0); + + // Add the new Channel to the network channel table + if (!Network->addChannel(theChan)) { + // The addition of this channel failed, *shrug* + elog << "msg_B> Failed to add channel: " << Param[1] << endl; + + // Prevent a memory leak by deleting the channel + delete theChan; + theChan = 0; + + // Return error + return false; + } + } // if( NULL == theChan ) + else { + // The channel was already found. + // Make sure the timestamp is accurate, this is an oddity imho. + time_t newCreationTime = static_cast(::atoi(Param[2])); + + // Is the old TS greater than the new TS? + if (theChan->getCreationTime() > newCreationTime) { + // Nope, update the timestamp + theChan->setCreationTime(newCreationTime); + theChan->removeAllModes(); + theChan->removeAllBans(); + } + } + + if (3 == Param.size()) { + // Zombie in channel. + // If the user is dezombified, the client will be shown + // to issue a "J", and the channel will be created anyway. + // Only difference is the timestamp difference. + return true; + } + + // Parse out the channel state + xParameters::size_type whichToken = 3; + + // Channel modes will always be the first thing to follow if it's in the burst + if ('+' == Param[whichToken][0]) { + // channel modes + const char* currentPtr = Param[whichToken]; + + // Skip over the '+' + ++currentPtr; + + xServer::modeVectorType modeVector; + + for (; currentPtr && *currentPtr; ++currentPtr) { + switch (*currentPtr) { + case 't': + modeVector.push_back(make_pair(true, Channel::MODE_T)); + break; + case 'n': + modeVector.push_back(make_pair(true, Channel::MODE_N)); + break; + case 'm': + modeVector.push_back(make_pair(true, Channel::MODE_M)); + break; + case 'p': + modeVector.push_back(make_pair(true, Channel::MODE_P)); + break; + case 's': + modeVector.push_back(make_pair(true, Channel::MODE_S)); + break; + case 'i': + modeVector.push_back(make_pair(true, Channel::MODE_I)); + break; + case 'r': + modeVector.push_back(make_pair(true, Channel::MODE_R)); + break; + case 'R': + modeVector.push_back(make_pair(true, Channel::MODE_REG)); + break; + case 'D': + modeVector.push_back(make_pair(true, Channel::MODE_D)); + break; + case 'c': + modeVector.push_back(make_pair(true, Channel::MODE_C)); + break; + case 'C': + modeVector.push_back(make_pair(true, Channel::MODE_CTCP)); + break; + case 'u': + modeVector.push_back(make_pair(true, Channel::MODE_PART)); + break; + case 'M': + modeVector.push_back(make_pair(true, Channel::MODE_MNOREG)); + break; + case 'Z': + modeVector.push_back(make_pair(true, Channel::MODE_Z)); + break; + case 'l': + theServer->OnChannelModeL(theChan, true, 0, ::atoi(Param[whichToken + 1])); + whichToken++; + break; + case 'k': + theServer->OnChannelModeK(theChan, true, 0, Param[whichToken + 1]); + whichToken++; + break; + case 'A': + theServer->OnChannelModeA(theChan, true, 0, Param[whichToken + 1]); + whichToken++; + break; + case 'U': + theServer->OnChannelModeU(theChan, true, 0, Param[whichToken + 1]); + whichToken++; + break; + default: + break; + } // switch + + } // for( currentPtr != endPtr ) + + if (!modeVector.empty()) { + theServer->OnChannelMode(theChan, 0, modeVector); + } + + // Skip over the modes token + // whichToken either points to the modes token if no +l/+k + // was specified, or it points to the last +l/+k argument; + // skip over this token no matter which. + whichToken++; + + } // if( '+' == Param[ whichToken ][ 0 ] + + // Have we reached the end of this burst command? + if (whichToken >= Param.size()) { + return true; + } + + // Parse the remaining tokens + for (; whichToken < Param.size(); ++whichToken) { + // Bans will always be the last thing burst, so no users + // will be burst afterwards. This is useful because xParameters + // will only delimit tokens by ':', so the ban string is guaranteed + // to be caught. + if ('~' == Param[whichToken][0]) { + // Channel ban exceptions + // Be sure to skip over the '%' + // parseBurstExcepts( theChan, Param[ whichToken ] + 1 ) ; + } else if ('%' == Param[whichToken][0]) { + // Channel bans + // Be sure to skip over the '%' + parseBurstBans(theChan, Param[whichToken] + 1); + } else { + // Userlist + parseBurstUsers(theChan, Param[whichToken]); + } + } + return true; } // dA1,jBN:ov,C3K:v,jGZ:o,CkU @@ -324,232 +272,191 @@ return true ; // mode state. // Mode states will always be in the order ov, v, o if present // at all. -void msg_B::parseBurstUsers( Channel* theChan, const string& theUsers ) -{ -// This is a protected method, so the method arguments are -// guaranteed to be valid -string chanName = theChan->getName(); // Added for fixing crash when Channel gets destroyed in the result of PostChannelEvent() below -//elog << "msg_B::parseBurstUsers> Channel: " << theChan->getName() -// << ", users: " << theUsers << endl ; -// Parse out users and their modes -StringTokenizer st( theUsers, ',' ) ; - -// Used to track op/voice/opvoice mode state switches. -// 1 = op, 2 = voice, 3 = opvoice. -unsigned short int mode_state = 0; - -typedef xServer::opVectorType opVectorType ; -typedef xServer::voiceVectorType voiceVectorType ; - -opVectorType opVector ; -voiceVectorType voiceVector ; - -for( StringTokenizer::const_iterator ptr = st.begin() ; ptr != st.end() ; - ++ptr ) - { - // Each token is of the form: - // abc or abc:modes - string::size_type pos = (*ptr).find_first_of( ':' ) ; - - // Find the client in the client table - iClient* theClient = Network->findClient( (*ptr).substr( 0, pos ) ) ; - - // Was the search successful? - if( NULL == theClient ) - { - // Nope, no such user - // Log the error - elog << "msg_B::parseBurstUsers> (" - << theChan->getName() << ")" - << ": Unable to find client: " - << (*ptr).substr( 0, pos ) - << endl ; - - // Skip this user - continue ; - } - -// elog << "msg_B::parseBurstUsers> Adding user " -// << theClient->getNickName() -// << "(" << theClient->getCharYYXXX() << ") to channel " -// << theChan->getName() << endl ; - - // Add this channel to the user's channel structure. - if( !theClient->addChannel( theChan ) ) - { - elog << "msg_B::parseBurstUsers> Failed to add " - << "channel " - << *theChan - << " to iClient " - << *theClient - << endl ; - - // Non-fatal error - continue ; - } - - // Create a ChannelUser object to represent this user's presence - // in this channel - ChannelUser* chanUser = - new (std::nothrow) ChannelUser( theClient ) ; - assert( chanUser != 0 ) ; - - // Add this user to the channel's database. - if( !theChan->addUser( chanUser ) ) - { - // The addition failed - elog << "msg_B::parseBurstUsers> Unable to add user " - << theClient->getNickName() - << " to channel " - << theChan->getName() - << endl ; - - // Prevent a memory leak by deallocating the unused - // ChannelUser object - delete chanUser ; chanUser = 0 ; - - // Remove the channel info from the client - theClient->removeChannel( theChan ) ; - - continue ; - } - - // Notify the services clients that a user has - // joined the channel - theServer->PostChannelEvent( EVT_BURST, theChan, - static_cast< void* >( theClient ), - static_cast< void* >( chanUser ) ) ; - - // Check if the Channel and User both exist after PostChannelEvent() - // Has to be done to prevent a crash for cases where PostChannelEvent() results in kicking the burst user right in the middle of this function. - // If the user was alone in the channel, the channel is destroyed and referenced later, causing a segmentation fault. - Channel* tmpChan = Network->findChannel( chanName ); - if (tmpChan == 0) - continue; - if (tmpChan->findUser(theClient) == 0) - continue; - - // Is there a ':' in this client's info? - if( string::npos == pos ) - { - // no ':' in this string, add the user with the current - // MODE state. - switch( mode_state ) - { - case 1: - opVector.push_back( - opVectorType::value_type( - true, chanUser ) ) ; - break; - case 2: - voiceVector.push_back( - voiceVectorType::value_type( - true, chanUser ) ) ; - break; - case 3: - opVector.push_back( - opVectorType::value_type( - true, chanUser ) ) ; - voiceVector.push_back( - voiceVectorType::value_type( - true, chanUser ) ) ; - break; - } - - // mode_state still 0, not opped or voiced. - continue ; - } - - // Otherwise, user modes have been specified. - for( pos++ ; pos < (*ptr).size() ; ++pos ) - { - switch( (*ptr)[ pos ] ) - { - case 'o': - opVector.push_back( - opVectorType::value_type( - true, chanUser ) ) ; - mode_state = 1; - break ; - case 'v': - // Does the user already - // have mode 'o'? - if( 1 == mode_state ) - { - // User has 'o' mode already - opVector.push_back( - opVectorType::value_type( - true, chanUser ) ) ; - } - voiceVector.push_back( - voiceVectorType::value_type( - true, chanUser ) ) ; - mode_state = (mode_state == 1) ? 3 : 2; - break ; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - /* This is an oplevel, which we are not (currently) interested in. - * However, we also don't want it to cause an error! - */ - break; - default: - elog << "msg_B::parseBurstUsers> " - << "Unknown mode: " - << (*ptr)[ pos ] << endl ; - break ; - } // switch - } // for() - - } // while( ptr != st.end() ) - -// Commit the user modes to the internal tables, and notify -// all listening clients -if( !opVector.empty() ) - { - theServer->OnChannelModeO( theChan, 0, opVector ) ; - } -if( !voiceVector.empty() ) - { - theServer->OnChannelModeV( theChan, 0, voiceVector ) ; - } +void msg_B::parseBurstUsers(Channel* theChan, const string& theUsers) { + // This is a protected method, so the method arguments are + // guaranteed to be valid + string chanName = theChan->getName(); // Added for fixing crash when Channel gets destroyed in + // the result of PostChannelEvent() below + // elog << "msg_B::parseBurstUsers> Channel: " << theChan->getName() + // << ", users: " << theUsers << endl ; + // Parse out users and their modes + StringTokenizer st(theUsers, ','); + + // Used to track op/voice/opvoice mode state switches. + // 1 = op, 2 = voice, 3 = opvoice. + unsigned short int mode_state = 0; + + typedef xServer::opVectorType opVectorType; + typedef xServer::voiceVectorType voiceVectorType; + + opVectorType opVector; + voiceVectorType voiceVector; + + for (StringTokenizer::const_iterator ptr = st.begin(); ptr != st.end(); ++ptr) { + // Each token is of the form: + // abc or abc:modes + string::size_type pos = (*ptr).find_first_of(':'); + + // Find the client in the client table + iClient* theClient = Network->findClient((*ptr).substr(0, pos)); + + // Was the search successful? + if (NULL == theClient) { + // Nope, no such user + // Log the error + elog << "msg_B::parseBurstUsers> (" << theChan->getName() << ")" + << ": Unable to find client: " << (*ptr).substr(0, pos) << endl; + + // Skip this user + continue; + } + + // elog << "msg_B::parseBurstUsers> Adding user " + // << theClient->getNickName() + // << "(" << theClient->getCharYYXXX() << ") to channel " + // << theChan->getName() << endl ; + + // Add this channel to the user's channel structure. + if (!theClient->addChannel(theChan)) { + elog << "msg_B::parseBurstUsers> Failed to add " + << "channel " << *theChan << " to iClient " << *theClient << endl; + + // Non-fatal error + continue; + } + + // Create a ChannelUser object to represent this user's presence + // in this channel + ChannelUser* chanUser = new (std::nothrow) ChannelUser(theClient); + assert(chanUser != 0); + + // Add this user to the channel's database. + if (!theChan->addUser(chanUser)) { + // The addition failed + elog << "msg_B::parseBurstUsers> Unable to add user " << theClient->getNickName() + << " to channel " << theChan->getName() << endl; + + // Prevent a memory leak by deallocating the unused + // ChannelUser object + delete chanUser; + chanUser = 0; + + // Remove the channel info from the client + theClient->removeChannel(theChan); + + continue; + } + + // Notify the services clients that a user has + // joined the channel + theServer->PostChannelEvent(EVT_BURST, theChan, static_cast(theClient), + static_cast(chanUser)); + + // Check if the Channel and User both exist after PostChannelEvent() + // Has to be done to prevent a crash for cases where PostChannelEvent() results in kicking + // the burst user right in the middle of this function. If the user was alone in the + // channel, the channel is destroyed and referenced later, causing a segmentation fault. + Channel* tmpChan = Network->findChannel(chanName); + if (tmpChan == 0) + continue; + if (tmpChan->findUser(theClient) == 0) + continue; + + // Is there a ':' in this client's info? + if (string::npos == pos) { + // no ':' in this string, add the user with the current + // MODE state. + switch (mode_state) { + case 1: + opVector.push_back(opVectorType::value_type(true, chanUser)); + break; + case 2: + voiceVector.push_back(voiceVectorType::value_type(true, chanUser)); + break; + case 3: + opVector.push_back(opVectorType::value_type(true, chanUser)); + voiceVector.push_back(voiceVectorType::value_type(true, chanUser)); + break; + } + + // mode_state still 0, not opped or voiced. + continue; + } + + // Otherwise, user modes have been specified. + for (pos++; pos < (*ptr).size(); ++pos) { + switch ((*ptr)[pos]) { + case 'o': + opVector.push_back(opVectorType::value_type(true, chanUser)); + mode_state = 1; + break; + case 'v': + // Does the user already + // have mode 'o'? + if (1 == mode_state) { + // User has 'o' mode already + opVector.push_back(opVectorType::value_type(true, chanUser)); + } + voiceVector.push_back(voiceVectorType::value_type(true, chanUser)); + mode_state = (mode_state == 1) ? 3 : 2; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* This is an oplevel, which we are not (currently) interested in. + * However, we also don't want it to cause an error! + */ + break; + default: + elog << "msg_B::parseBurstUsers> " + << "Unknown mode: " << (*ptr)[pos] << endl; + break; + } // switch + } // for() + + } // while( ptr != st.end() ) + + // Commit the user modes to the internal tables, and notify + // all listening clients + if (!opVector.empty()) { + theServer->OnChannelModeO(theChan, 0, opVector); + } + if (!voiceVector.empty()) { + theServer->OnChannelModeV(theChan, 0, voiceVector); + } } -void msg_B::parseBurstBans( Channel* theChan, const string& theBans ) -{ -// This is a protected method, so the method arguments are -// guaranteed to be valid - -//elog << "msg_B::parseBurstBans> Found bans for channel " -// << theChan->getName() -// << ": " -// << theBans -// << endl ; - -// Tokenize the ban string -StringTokenizer st( theBans ) ; - -typedef xServer::banVectorType banVectorType ; -banVectorType banVector( st.size() ) ; - -// Move through each token and add the ban -for( StringTokenizer::size_type i = 0 ; i < st.size() ; ++i ) - { - banVector.push_back( - banVectorType::value_type( true, st[ i ] ) ) ; - } - -if( !banVector.empty() ) - { - theServer->OnChannelModeB( theChan, 0, banVector ) ; - } +void msg_B::parseBurstBans(Channel* theChan, const string& theBans) { + // This is a protected method, so the method arguments are + // guaranteed to be valid + + // elog << "msg_B::parseBurstBans> Found bans for channel " + // << theChan->getName() + // << ": " + // << theBans + // << endl ; + + // Tokenize the ban string + StringTokenizer st(theBans); + + typedef xServer::banVectorType banVectorType; + banVectorType banVector(st.size()); + + // Move through each token and add the ban + for (StringTokenizer::size_type i = 0; i < st.size(); ++i) { + banVector.push_back(banVectorType::value_type(true, st[i])); + } + + if (!banVector.empty()) { + theServer->OnChannelModeB(theChan, 0, banVector); + } } } // namespace gnuworld diff --git a/libircu/msg_C.cc b/libircu/msg_C.cc index b5d54e2e..2460a6b0 100644 --- a/libircu/msg_C.cc +++ b/libircu/msg_C.cc @@ -21,31 +21,29 @@ * $Id: msg_C.cc,v 1.10 2007/03/16 15:31:28 mrbean_ Exp $ */ -#include -#include -#include - -#include - -#include "gnuworld_config.h" -#include "server.h" -#include "Network.h" -#include "events.h" - -#include "ELog.h" -#include "StringTokenizer.h" -#include "xparameters.h" -#include "iClient.h" -#include "Channel.h" -#include "ChannelUser.h" -#include "ServerCommandHandler.h" - - -namespace gnuworld -{ -using std::pair ; -using std::string ; -using std::endl ; +#include +#include +#include + +#include + +#include "gnuworld_config.h" +#include "server.h" +#include "Network.h" +#include "events.h" + +#include "ELog.h" +#include "StringTokenizer.h" +#include "xparameters.h" +#include "iClient.h" +#include "Channel.h" +#include "ChannelUser.h" +#include "ServerCommandHandler.h" + +namespace gnuworld { +using std::endl; +using std::pair; +using std::string; CREATE_HANDLER(msg_C) @@ -54,196 +52,158 @@ CREATE_HANDLER(msg_C) * UAA C #xfactor 957134023 * zBP C #OaXaCa,#UruApan,#skatos 957207634 */ -bool msg_C::Execute( const xParameters& Param ) -{ - -// Verify that there exist sufficient arguments to successfully -// handle this command -// client_numeric #channel[,#channel2,...] timestamp -if( Param.size() < 3 ) - { - // Insufficient arguments provided - elog << "msg_C> Invalid number of parameters" - << endl ; - - // Return error - return false ; - } - -// Find the client in question. -iClient* theClient = Network->findClient( Param[ 0 ] ) ; - -// Did we find the client? -if( NULL == theClient ) - { - // Nope, log the error - elog << "msg_C> (" - << Param[ 1 ] - << ") Unable to find client: " - << Param[ 0 ] - << endl ; - - // Return error - return false ; - } - -// Grab the creation time. -time_t creationTime = - static_cast< time_t >( atoi( Param[ Param.size() - 1 ] ) ) ; - -iServer* nickUplink = 0; -char serverYY[3]; -strncpy(serverYY, Param[0], 2); -serverYY[2] = '\0'; -nickUplink = Network->findServer(serverYY); -if (!nickUplink->isBursting()) - { - // Set the server's lag time - time_t lag = 0; - if (::time(0) > creationTime) - lag = ::time(0) - creationTime; - else - lag = 0; - nickUplink->setLag(lag); - } - -// Tokenize based on ','. Multiple channels may be put into the -// same C(REATE) command. -StringTokenizer st( Param[ 1 ], ',' ) ; - -for( StringTokenizer::const_iterator ptr = st.begin() ; ptr != st.end() ; - ++ptr ) - { - - // Is this a modeless channel? - if( '+' == (*ptr)[ 0 ] ) - { - // Modeless channel, ignore it - continue ; - } - - // Find the channel in question. - Channel* theChan = Network->findChannel( *ptr ) ; - - // Did we find the channel? - if( NULL == theChan ) - { - // Channel doesn't exist..this transmutes to a create - theChan = new (std::nothrow) - Channel( *ptr, creationTime ) ; - assert( theChan != 0 ) ; - - // Add this channel to the network channel table - if( !Network->addChannel( theChan ) ) - { - // Addition failed, log the error - elog << "msg_C> Failed to add channel: " - << *theChan - << endl ; - - // Prevent memory leaks by removing the unused - // channel - delete theChan ; theChan = 0 ; - - // continue to next one *shrug* - continue ; - } - } - - ChannelUser* theUser = 0 ; - if( theClient->findChannel( theChan ) ) - { - // The client knows about this channel already - // Verify that the channel knows about the user. - theUser = theChan->findUser( theClient ) ; - if( 0 == theUser ) - { - // The client knows of the channel, but not - // the other way around. - // theUser will be created and added to the - // channel membership table below. - elog << "msg_C> Half-way membership found " - << " for client " - << *theClient - << ", in channel " - << *theChan - << endl ; - } - else - { - // User is already in the channel, probably lag or - // a non-authoritative kick -// theUser->removeZombie() ; - } - } - else - { - // Add this channel to the client's channel structure. - if( !theClient->addChannel( theChan ) ) - { - elog << "msg_C> Unable to add channel " - << *theChan - << " to iClient " - << *theClient - << endl ; - - continue ; - } - } - - // The client now knows about the channel, build the second - // half of the channel<->user association, if necessary. - if( 0 == theUser ) - { - // Create a new ChannelUser to represent this iClient's - // membership in this channel. - theUser = new (std::nothrow) ChannelUser( theClient ) ; - assert( theUser != 0 ) ; - - // Add the ChannelUser to the Channel's information - if( !theChan->addUser( theUser ) ) - { - // Addition failed, log the error - // This should never happen. - elog << "msg_C> Unable to add user " - << theUser->getNickName() - << " to channel " - << theChan->getName() - << endl ; - - // Prevent a memory leak by deallocating the - // unused ChannelUser structure - delete theUser ; theUser = 0 ; - - // Remove the channel information from the client - theClient->removeChannel( theChan ) ; - - // Continue to next channel - continue ; - } - } - - int creationTime = atoi ( Param [ 2 ] ); - // The user who created the channel is automatically +o - if(creationTime == theChan->getCreationTime() ) - { - theUser->setModeO(); - } - if(creationTime < theChan->getCreationTime() ) - { - //Need to clean all the channel modes and op the user who created the channel - theChan->removeAllModes(); - theUser->setModeO() ; - theChan->setCreationTime(creationTime); - } - - // Notify all listening xClients of this event - theServer->PostChannelEvent( EVT_CREATE, theChan, - static_cast< void* >( theClient ) ) ; - - } // for() - -return true ; +bool msg_C::Execute(const xParameters& Param) { + + // Verify that there exist sufficient arguments to successfully + // handle this command + // client_numeric #channel[,#channel2,...] timestamp + if (Param.size() < 3) { + // Insufficient arguments provided + elog << "msg_C> Invalid number of parameters" << endl; + + // Return error + return false; + } + + // Find the client in question. + iClient* theClient = Network->findClient(Param[0]); + + // Did we find the client? + if (NULL == theClient) { + // Nope, log the error + elog << "msg_C> (" << Param[1] << ") Unable to find client: " << Param[0] << endl; + + // Return error + return false; + } + + // Grab the creation time. + time_t creationTime = static_cast(atoi(Param[Param.size() - 1])); + + iServer* nickUplink = 0; + char serverYY[3]; + strncpy(serverYY, Param[0], 2); + serverYY[2] = '\0'; + nickUplink = Network->findServer(serverYY); + if (!nickUplink->isBursting()) { + // Set the server's lag time + time_t lag = 0; + if (::time(0) > creationTime) + lag = ::time(0) - creationTime; + else + lag = 0; + nickUplink->setLag(lag); + } + + // Tokenize based on ','. Multiple channels may be put into the + // same C(REATE) command. + StringTokenizer st(Param[1], ','); + + for (StringTokenizer::const_iterator ptr = st.begin(); ptr != st.end(); ++ptr) { + + // Is this a modeless channel? + if ('+' == (*ptr)[0]) { + // Modeless channel, ignore it + continue; + } + + // Find the channel in question. + Channel* theChan = Network->findChannel(*ptr); + + // Did we find the channel? + if (NULL == theChan) { + // Channel doesn't exist..this transmutes to a create + theChan = new (std::nothrow) Channel(*ptr, creationTime); + assert(theChan != 0); + + // Add this channel to the network channel table + if (!Network->addChannel(theChan)) { + // Addition failed, log the error + elog << "msg_C> Failed to add channel: " << *theChan << endl; + + // Prevent memory leaks by removing the unused + // channel + delete theChan; + theChan = 0; + + // continue to next one *shrug* + continue; + } + } + + ChannelUser* theUser = 0; + if (theClient->findChannel(theChan)) { + // The client knows about this channel already + // Verify that the channel knows about the user. + theUser = theChan->findUser(theClient); + if (0 == theUser) { + // The client knows of the channel, but not + // the other way around. + // theUser will be created and added to the + // channel membership table below. + elog << "msg_C> Half-way membership found " + << " for client " << *theClient << ", in channel " << *theChan << endl; + } else { + // User is already in the channel, probably lag or + // a non-authoritative kick + // theUser->removeZombie() ; + } + } else { + // Add this channel to the client's channel structure. + if (!theClient->addChannel(theChan)) { + elog << "msg_C> Unable to add channel " << *theChan << " to iClient " << *theClient + << endl; + + continue; + } + } + + // The client now knows about the channel, build the second + // half of the channel<->user association, if necessary. + if (0 == theUser) { + // Create a new ChannelUser to represent this iClient's + // membership in this channel. + theUser = new (std::nothrow) ChannelUser(theClient); + assert(theUser != 0); + + // Add the ChannelUser to the Channel's information + if (!theChan->addUser(theUser)) { + // Addition failed, log the error + // This should never happen. + elog << "msg_C> Unable to add user " << theUser->getNickName() << " to channel " + << theChan->getName() << endl; + + // Prevent a memory leak by deallocating the + // unused ChannelUser structure + delete theUser; + theUser = 0; + + // Remove the channel information from the client + theClient->removeChannel(theChan); + + // Continue to next channel + continue; + } + } + + int creationTime = atoi(Param[2]); + // The user who created the channel is automatically +o + if (creationTime == theChan->getCreationTime()) { + theUser->setModeO(); + } + if (creationTime < theChan->getCreationTime()) { + // Need to clean all the channel modes and op the user who created the channel + theChan->removeAllModes(); + theUser->setModeO(); + theChan->setCreationTime(creationTime); + } + + // Notify all listening xClients of this event + theServer->PostChannelEvent(EVT_CREATE, theChan, static_cast(theClient)); + + } // for() + + return true; } } // namespace gnuworld diff --git a/libircu/msg_CF.cc b/libircu/msg_CF.cc old mode 100755 new mode 100644 index aa2cc091..ca57da21 --- a/libircu/msg_CF.cc +++ b/libircu/msg_CF.cc @@ -18,75 +18,63 @@ * */ - #include - #include - - #include "gnuworld_config.h" - #include "ServerCommandHandler.h" - #include "server.h" - #include "xparameters.h" - #include "Channel.h" - #include "Network.h" - #include "iClient.h" - #include "ELog.h" - - namespace gnuworld - { - - CREATE_HANDLER(msg_CF) - - /** - * CONFIGURATION message handler. - * - * This message is used to propagate network configuration - * source CF : - */ - bool msg_CF::Execute( const xParameters& Param ) - { - if( Param.size() < 3 ) - { - elog << "msg_CF> Invalid number of parameters" - << std::endl ; - return false ; - } - - iServer* sourceServer = Network->findServer( Param[ 0 ] ) ; - if( NULL == sourceServer ) - { - elog << "msg_CF> Unable to find source server: " - << Param[ 0 ] << std::endl ; - return false ; - } +#include +#include -time_t timestamp = atoi( Param[ 1 ] ) ; -std::string key( Param[ 2 ] ) ; -std::string value( Param.assemble( 3 ) ) ; +#include "gnuworld_config.h" +#include "ServerCommandHandler.h" +#include "server.h" +#include "xparameters.h" +#include "Channel.h" +#include "Network.h" +#include "iClient.h" +#include "ELog.h" -auto netConf = Network->findNetConf( key ) ; -if( netConf && netConf->second > timestamp ) - { - // This should never happen. - elog << "msg_CF> Netconf variable already exists and is newer: " - << key - << " (timestamp on file: " << netConf->second << ", timestamp on network: " << timestamp << ")" - << std::endl ; - return false ; +namespace gnuworld { + +CREATE_HANDLER(msg_CF) + +/** + * CONFIGURATION message handler. + * + * This message is used to propagate network configuration + * source CF : + */ +bool msg_CF::Execute(const xParameters& Param) { + if (Param.size() < 3) { + elog << "msg_CF> Invalid number of parameters" << std::endl; + return false; + } + + iServer* sourceServer = Network->findServer(Param[0]); + if (NULL == sourceServer) { + elog << "msg_CF> Unable to find source server: " << Param[0] << std::endl; + return false; } - - Network->addNetConf( key, value, timestamp ) ; - elog << "msg_CF> Adding netconf variable: " - << key - << " (value: " << value << ")" - << " (timestamp: " << timestamp << ")" - << std::endl ; + time_t timestamp = atoi(Param[1]); + std::string key(Param[2]); + std::string value(Param.assemble(3)); + + auto netConf = Network->findNetConf(key); + if (netConf && netConf->second > timestamp) { + // This should never happen. + elog << "msg_CF> Netconf variable already exists and is newer: " << key + << " (timestamp on file: " << netConf->second + << ", timestamp on network: " << timestamp << ")" << std::endl; + return false; + } + + Network->addNetConf(key, value, timestamp); + + elog << "msg_CF> Adding netconf variable: " << key << " (value: " << value << ")" + << " (timestamp: " << timestamp << ")" << std::endl; + + // Post event to listening clients + theServer->PostEvent(EVT_NETCONF, static_cast(sourceServer), static_cast(&key)); + + // Return success + return true; +} - // Post event to listening clients - theServer->PostEvent( EVT_NETCONF, static_cast< void* >( sourceServer ), - static_cast< void* >( &key ) ) ; - - // Return success - return true ; - } - - } // namespace gnuworld +} // namespace gnuworld diff --git a/libircu/msg_CM.cc b/libircu/msg_CM.cc index 92d4c83e..45090685 100644 --- a/libircu/msg_CM.cc +++ b/libircu/msg_CM.cc @@ -20,25 +20,24 @@ * $Id: msg_CM.cc,v 1.11 2008/04/16 20:29:37 danielaustin Exp $ */ -#include -#include -#include +#include +#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "Channel.h" -#include "ChannelUser.h" -#include "Network.h" -#include "iClient.h" -#include "xparameters.h" -#include "ELog.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "Channel.h" +#include "ChannelUser.h" +#include "Network.h" +#include "iClient.h" +#include "xparameters.h" +#include "ELog.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ -using std::pair ; -using std::make_pair ; -using std::endl ; +namespace gnuworld { +using std::endl; +using std::make_pair; +using std::pair; CREATE_HANDLER(msg_CM) @@ -48,250 +47,210 @@ CREATE_HANDLER(msg_CM) * The above message would remove all ops, bans, and voice modes * from channel #channel. */ -bool msg_CM::Execute( const xParameters& Param ) -{ -if( Param.size() < 3 ) - { - elog << "msg_CM> Invalid number of parameters" - << endl ; - return false ; - } +bool msg_CM::Execute(const xParameters& Param) { + if (Param.size() < 3) { + elog << "msg_CM> Invalid number of parameters" << endl; + return false; + } -Channel* tmpChan = Network->findChannel( Param[ 1 ] ) ; -if( !tmpChan ) - { - // Log Error. - elog << "msg_CM> Unable to locate channel: " - << Param[ 1 ] - << endl ; - return false ; - } + Channel* tmpChan = Network->findChannel(Param[1]); + if (!tmpChan) { + // Log Error. + elog << "msg_CM> Unable to locate channel: " << Param[1] << endl; + return false; + } -/* - * First, determine what we are going to clear. - */ -std::string Modes = Param[ 2 ] ; + /* + * First, determine what we are going to clear. + */ + std::string Modes = Param[2]; -// These three variables will be set to true if we are to clear either -// the ops, voice, or bans, respectively -bool clearOps = false ; -bool clearVoice = false ; -bool clearBans = false ; + // These three variables will be set to true if we are to clear either + // the ops, voice, or bans, respectively + bool clearOps = false; + bool clearVoice = false; + bool clearBans = false; -// Go ahead and post the server mode event -iServer* serverSource = 0 ; + // Go ahead and post the server mode event + iServer* serverSource = 0; -if( NULL != strchr( Param[ 0 ], '.' ) ) -{ - // Server, by name - serverSource = Network->findServerName( Param[ 0 ] ) ; -} else if( strlen( Param[ 0 ] ) < 3 ) -{ - // 1 or 2 char numeric, server - serverSource = Network->findServer( Param[ 0 ] ) ; -} + if (NULL != strchr(Param[0], '.')) { + // Server, by name + serverSource = Network->findServerName(Param[0]); + } else if (strlen(Param[0]) < 3) { + // 1 or 2 char numeric, server + serverSource = Network->findServer(Param[0]); + } -if (serverSource != 0) - theServer->PostChannelEvent( EVT_SERVERMODE, tmpChan, - static_cast< void* >( serverSource ) ); + if (serverSource != 0) + theServer->PostChannelEvent(EVT_SERVERMODE, tmpChan, static_cast(serverSource)); -xServer::modeVectorType modeVector ; + xServer::modeVectorType modeVector; -for( std::string::size_type i = 0 ; i < Modes.size() ; i++ ) - { - switch( Modes[ i ] ) - { - case 'o': - clearOps = true ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_CHANOPS" -// << endl; - break ; - case 'v': - clearVoice = true ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_VOICED" -// << endl; - break ; - case 's': - modeVector.push_back( make_pair( - false, Channel::MODE_S ) ) ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_SECRET" -// << endl; - break ; - case 'r': - modeVector.push_back( make_pair( - false, Channel::MODE_R ) ) ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_REGISTER" -// << endl; - break ; - // Do not remove mode R (Channel::MODE_REG) - case 'D': - modeVector.push_back( make_pair( - false, Channel::MODE_D ) ) ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_MODED" -// << endl; - break ; - case 'c': - modeVector.push_back(make_pair( - false, Channel::MODE_C)); - // elog << tmpChan->getName() - // << "msg_CM> Doing CLEAR_MODE_C" - // << endl; - break; - case 'C': - modeVector.push_back(make_pair( - false, Channel::MODE_CTCP)); - // elog << tmpChan->getName() - // << "msg_CM> Doing CLEAR_MODE_CTCP" - // << endl; - break; - case 'm': - modeVector.push_back( make_pair( - false, Channel::MODE_M ) ) ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_MODERATED" -// << endl; - break ; - case 't': - modeVector.push_back( make_pair( - false, Channel::MODE_T ) ) ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_TOPICLIMIT" -// << endl; - break ; - case 'i': - modeVector.push_back( make_pair( - false, Channel::MODE_I ) ) ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_INVITEONLY" -// << endl; - break ; - case 'n': - modeVector.push_back( make_pair( - false, Channel::MODE_N ) ) ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_NOPRIVMSGS" -// << endl; - break ; - case 'p': - modeVector.push_back( make_pair( - false, Channel::MODE_P ) ) ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_NOPRIVMSGS" -// << endl; - break ; - case 'u': - modeVector.push_back( make_pair( - false, Channel::MODE_PART ) ) ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_PART" -// << endl; - break ; - case 'M': - modeVector.push_back( make_pair( - false, Channel::MODE_MNOREG ) ) ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_MNOREG" -// << endl; - break ; - case 'Z': - modeVector.push_back( make_pair( - false, Channel::MODE_Z ) ) ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_Z" -// << endl; - break ; - case 'k': - theServer->OnChannelModeK( tmpChan, false, 0, - std::string() ) ; - tmpChan->setKey( std::string() ); -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_KEY" -// << endl; - break ; - case 'b': - clearBans = true ; - tmpChan->removeAllBans(); -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_BANS" -// << endl; - break ; - case 'l': - theServer->OnChannelModeL( tmpChan, false, 0, 0 ) ; -// elog << tmpChan->getName() -// << "msg_CM> Doing CLEAR_LIMIT" -// << endl; - break ; - default: - // Unknown mode - elog << "msg_CM> Unknown mode: " - << Modes[ i ] - << endl ; - break ; - } // switch - } // for + for (std::string::size_type i = 0; i < Modes.size(); i++) { + switch (Modes[i]) { + case 'o': + clearOps = true; + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_CHANOPS" + // << endl; + break; + case 'v': + clearVoice = true; + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_VOICED" + // << endl; + break; + case 's': + modeVector.push_back(make_pair(false, Channel::MODE_S)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_SECRET" + // << endl; + break; + case 'r': + modeVector.push_back(make_pair(false, Channel::MODE_R)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_REGISTER" + // << endl; + break; + // Do not remove mode R (Channel::MODE_REG) + case 'D': + modeVector.push_back(make_pair(false, Channel::MODE_D)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_MODED" + // << endl; + break; + case 'c': + modeVector.push_back(make_pair(false, Channel::MODE_C)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_MODE_C" + // << endl; + break; + case 'C': + modeVector.push_back(make_pair(false, Channel::MODE_CTCP)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_MODE_CTCP" + // << endl; + break; + case 'm': + modeVector.push_back(make_pair(false, Channel::MODE_M)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_MODERATED" + // << endl; + break; + case 't': + modeVector.push_back(make_pair(false, Channel::MODE_T)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_TOPICLIMIT" + // << endl; + break; + case 'i': + modeVector.push_back(make_pair(false, Channel::MODE_I)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_INVITEONLY" + // << endl; + break; + case 'n': + modeVector.push_back(make_pair(false, Channel::MODE_N)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_NOPRIVMSGS" + // << endl; + break; + case 'p': + modeVector.push_back(make_pair(false, Channel::MODE_P)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_NOPRIVMSGS" + // << endl; + break; + case 'u': + modeVector.push_back(make_pair(false, Channel::MODE_PART)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_PART" + // << endl; + break; + case 'M': + modeVector.push_back(make_pair(false, Channel::MODE_MNOREG)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_MNOREG" + // << endl; + break; + case 'Z': + modeVector.push_back(make_pair(false, Channel::MODE_Z)); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_Z" + // << endl; + break; + case 'k': + theServer->OnChannelModeK(tmpChan, false, 0, std::string()); + tmpChan->setKey(std::string()); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_KEY" + // << endl; + break; + case 'b': + clearBans = true; + tmpChan->removeAllBans(); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_BANS" + // << endl; + break; + case 'l': + theServer->OnChannelModeL(tmpChan, false, 0, 0); + // elog << tmpChan->getName() + // << "msg_CM> Doing CLEAR_LIMIT" + // << endl; + break; + default: + // Unknown mode + elog << "msg_CM> Unknown mode: " << Modes[i] << endl; + break; + } // switch + } // for -if( !modeVector.empty() ) - { - theServer->OnChannelMode( tmpChan, 0, modeVector ) ; - } + if (!modeVector.empty()) { + theServer->OnChannelMode(tmpChan, 0, modeVector); + } -if( clearOps || clearVoice ) - { - /* - * Lets loop over everyone in the channel and either deop - * or devoice them. - */ - xServer::opVectorType opVector ; - xServer::voiceVectorType voiceVector ; + if (clearOps || clearVoice) { + /* + * Lets loop over everyone in the channel and either deop + * or devoice them. + */ + xServer::opVectorType opVector; + xServer::voiceVectorType voiceVector; - for( Channel::const_userIterator ptr = tmpChan->userList_begin(); - ptr != tmpChan->userList_end() ; ++ptr ) - { - if( clearOps && ptr->second->isModeO() ) - { - ptr->second->removeModeO(); - opVector.push_back( pair< bool, ChannelUser* > - ( false, ptr->second ) ) ; - } - if( clearVoice && ptr->second->isModeV() ) - { - ptr->second->removeModeV(); - voiceVector.push_back( pair< bool, ChannelUser* > - ( false, ptr->second ) ) ; - } - } + for (Channel::const_userIterator ptr = tmpChan->userList_begin(); + ptr != tmpChan->userList_end(); ++ptr) { + if (clearOps && ptr->second->isModeO()) { + ptr->second->removeModeO(); + opVector.push_back(pair(false, ptr->second)); + } + if (clearVoice && ptr->second->isModeV()) { + ptr->second->removeModeV(); + voiceVector.push_back(pair(false, ptr->second)); + } + } - if( !voiceVector.empty() ) - { - theServer->OnChannelModeV( tmpChan, 0, voiceVector ) ; - } - if( !opVector.empty() ) - { - theServer->OnChannelModeO( tmpChan, 0, opVector ) ; - } - } // if( clearOps || clearVoice ) + if (!voiceVector.empty()) { + theServer->OnChannelModeV(tmpChan, 0, voiceVector); + } + if (!opVector.empty()) { + theServer->OnChannelModeO(tmpChan, 0, opVector); + } + } // if( clearOps || clearVoice ) -if( clearBans ) - { - xServer::banVectorType banVector ; + if (clearBans) { + xServer::banVectorType banVector; - for( Channel::banIterator ptr = tmpChan->banList_begin(), - endPtr = tmpChan->banList_end() ; - ptr != endPtr ; ++ptr ) - { - banVector.push_back( pair< bool, std::string > - ( false, *ptr ) ) ; - } + for (Channel::banIterator ptr = tmpChan->banList_begin(), endPtr = tmpChan->banList_end(); + ptr != endPtr; ++ptr) { + banVector.push_back(pair(false, *ptr)); + } - theServer->OnChannelModeB( tmpChan, 0, banVector ) ; - } // if( clearBans ) + theServer->OnChannelModeB(tmpChan, 0, banVector); + } // if( clearBans ) -return true ; + return true; } } // namespace gnuworld diff --git a/libircu/msg_D.cc b/libircu/msg_D.cc index 9a82c6bf..61c028f7 100644 --- a/libircu/msg_D.cc +++ b/libircu/msg_D.cc @@ -20,25 +20,24 @@ * $Id: msg_D.cc,v 1.5 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include -#include - -#include - -#include "gnuworld_config.h" -#include "server.h" -#include "iClient.h" -#include "iServer.h" -#include "events.h" -#include "Network.h" -#include "ELog.h" -#include "StringTokenizer.h" -#include "ServerCommandHandler.h" - -namespace gnuworld -{ -using std::string ; -using std::endl ; +#include +#include + +#include + +#include "gnuworld_config.h" +#include "server.h" +#include "iClient.h" +#include "iServer.h" +#include "events.h" +#include "Network.h" +#include "ELog.h" +#include "StringTokenizer.h" +#include "ServerCommandHandler.h" + +namespace gnuworld { +using std::endl; +using std::string; CREATE_HANDLER(msg_D) @@ -49,107 +48,81 @@ CREATE_HANDLER(msg_D) * G D r[l :NewYork-R.NY.US.Undernet.Org!NewYork-R.NY.US.Undernet.org ... * The source of the kill could be a server or a client. */ -bool msg_D::Execute( const xParameters& Param ) -{ -if( Param.size() < 3 ) - { - elog << "msg_D> Invalid number of parameters" - << endl ; - return false ; - } - -if( (Param[ 1 ][ 0 ] == theServer->getCharYY()[ 0 ]) && - (Param[ 1 ][ 1 ] == theServer->getCharYY()[ 1 ]) ) - { - // See if the client being killed is one of my own. - xClient* myClient = Network->findLocalClient( Param[ 1 ] ) ; - - // Is the user being killed on this server? - if( NULL != myClient ) - { - // doh, yes it is :( - myClient->OnKill() ; - - // Don't detach the client until it requests so. - // TODO: Work on this system. - - // Note that the client is still attached to the - // server. - return true ; - } - else - { - // It's a client on my server, but not an xClient. - // This is ok, the normal client kill handling code - // (for iClient) will handle removing fake clients. - // Allow it continue instead of returning. - } - } - -// Otherwise, it's a non-local client. -iClient* source = 0 ; -iServer* serverSource = 0 ; - -if( strchr( Param[ 0 ], '.' ) != NULL ) - { - // Server, by name - serverSource = Network->findServerName( Param[ 0 ] ) ; - } -else if( strlen( Param[ 0 ] ) >= 3 ) - { - // Client, by numeric - source = Network->findClient( Param[ 0 ] ) ; - } -else - { - // Server, by numeric - serverSource = Network->findServer( Param[ 0 ] ) ; - } - -if( (NULL == serverSource) && (NULL == source) ) - { - elog << "msg_D> Unable to find source: " - << Param[ 0 ] - << endl ; - return false ; - } - -// Find and remove the client that was just killed. -// xNetwork::removeClient will remove user<->channel associations -iClient* target = Network->removeClient( Param[ 1 ] ) ; - -// Make sure we have valid pointers to both source -// and target. -if( NULL == target ) - { - elog << "msg_D> Unable to find target client: " - << Param[ 1 ] - << endl ; - return false ; - } - -// Notify all listeners of the EVT_KILL event. -string reason( Param[ 2 ] ) ; - -if( source != NULL ) - { - theServer->PostEvent( EVT_KILL, - static_cast< void* >( source ), - static_cast< void* >( target ), - static_cast< void* >( &reason ) ) ; - } -else - { - theServer->PostEvent( EVT_KILL, - static_cast< void* >( serverSource ), - static_cast< void* >( target ), - static_cast< void* >( &reason ) ) ; - } - -// Deallocate the memory associated with this iClient. -delete target ; - -return true ; +bool msg_D::Execute(const xParameters& Param) { + if (Param.size() < 3) { + elog << "msg_D> Invalid number of parameters" << endl; + return false; + } + + if ((Param[1][0] == theServer->getCharYY()[0]) && (Param[1][1] == theServer->getCharYY()[1])) { + // See if the client being killed is one of my own. + xClient* myClient = Network->findLocalClient(Param[1]); + + // Is the user being killed on this server? + if (NULL != myClient) { + // doh, yes it is :( + myClient->OnKill(); + + // Don't detach the client until it requests so. + // TODO: Work on this system. + + // Note that the client is still attached to the + // server. + return true; + } else { + // It's a client on my server, but not an xClient. + // This is ok, the normal client kill handling code + // (for iClient) will handle removing fake clients. + // Allow it continue instead of returning. + } + } + + // Otherwise, it's a non-local client. + iClient* source = 0; + iServer* serverSource = 0; + + if (strchr(Param[0], '.') != NULL) { + // Server, by name + serverSource = Network->findServerName(Param[0]); + } else if (strlen(Param[0]) >= 3) { + // Client, by numeric + source = Network->findClient(Param[0]); + } else { + // Server, by numeric + serverSource = Network->findServer(Param[0]); + } + + if ((NULL == serverSource) && (NULL == source)) { + elog << "msg_D> Unable to find source: " << Param[0] << endl; + return false; + } + + // Find and remove the client that was just killed. + // xNetwork::removeClient will remove user<->channel associations + iClient* target = Network->removeClient(Param[1]); + + // Make sure we have valid pointers to both source + // and target. + if (NULL == target) { + elog << "msg_D> Unable to find target client: " << Param[1] << endl; + return false; + } + + // Notify all listeners of the EVT_KILL event. + string reason(Param[2]); + + if (source != NULL) { + theServer->PostEvent(EVT_KILL, static_cast(source), static_cast(target), + static_cast(&reason)); + } else { + theServer->PostEvent(EVT_KILL, static_cast(serverSource), static_cast(target), + static_cast(&reason)); + } + + // Deallocate the memory associated with this iClient. + delete target; + + return true; } } // namespace gnuworld diff --git a/libircu/msg_DS.cc b/libircu/msg_DS.cc index b37baf16..694f8683 100644 --- a/libircu/msg_DS.cc +++ b/libircu/msg_DS.cc @@ -20,22 +20,20 @@ * $Id: msg_DS.cc,v 1.4 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include "gnuworld_config.h" -#include "server.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { CREATE_HANDLER(msg_DS) // DeSynch handler? // 0 DS :HACK: JavaDude MODE #irc.core.com +smtink lamers [957881646] -bool msg_DS::Execute( const xParameters& ) -{ -// TODO -return true ; +bool msg_DS::Execute(const xParameters&) { + // TODO + return true; } } // namespace gnuworld diff --git a/libircu/msg_EA.cc b/libircu/msg_EA.cc index e8059472..d86d095e 100644 --- a/libircu/msg_EA.cc +++ b/libircu/msg_EA.cc @@ -20,24 +20,23 @@ * $Id: msg_EA.cc,v 1.5 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include -#include +#include +#include -#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "Network.h" -#include "events.h" -#include "ELog.h" -#include "iServer.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "Network.h" +#include "events.h" +#include "ELog.h" +#include "iServer.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::endl ; +using std::endl; +using std::string; CREATE_HANDLER(msg_EA) @@ -45,31 +44,25 @@ CREATE_HANDLER(msg_EA) // Q: Remote server numeric // EA: End Of Burst Acknowledge // Our uplink server has acknowledged our EB -bool msg_EA::Execute( const xParameters& Param ) -{ -if( !strcmp( Param[ 0 ], theServer->getUplinkCharYY().c_str() ) ) - { - // My uplink! :) - // Reset EOB just to be sure - theServer->setBursting( false ) ; // ACKNOWLEDGE! :) - } +bool msg_EA::Execute(const xParameters& Param) { + if (!strcmp(Param[0], theServer->getUplinkCharYY().c_str())) { + // My uplink! :) + // Reset EOB just to be sure + theServer->setBursting(false); // ACKNOWLEDGE! :) + } -//if( !theServer->isBursting() ) -// { - iServer* burstServer = Network->findServer( Param[ 0 ] ) ; - if( NULL == burstServer ) - { - elog << "msg_EA> Unable to find server: " - << Param[ 0 ] - << endl ; - return false ; - } + // if( !theServer->isBursting() ) + // { + iServer* burstServer = Network->findServer(Param[0]); + if (NULL == burstServer) { + elog << "msg_EA> Unable to find server: " << Param[0] << endl; + return false; + } - theServer->PostEvent( EVT_BURST_ACK, - static_cast< void* >( burstServer ) ); -// } + theServer->PostEvent(EVT_BURST_ACK, static_cast(burstServer)); + // } -return true ; + return true; } } // namespace gnuworld diff --git a/libircu/msg_EB.cc b/libircu/msg_EB.cc index 12b13008..6ef40b31 100644 --- a/libircu/msg_EB.cc +++ b/libircu/msg_EB.cc @@ -20,121 +20,103 @@ * $Id: msg_EB.cc,v 1.10 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include -#include +#include +#include -#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "iServer.h" -#include "events.h" -#include "Network.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "iServer.h" +#include "events.h" +#include "Network.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ -using std::clog ; -using std::endl ; +namespace gnuworld { +using std::clog; +using std::endl; CREATE_HANDLER(msg_EB) // Q EB // Q: Remote server numeric // EB: End Of Burst -bool msg_EB::Execute( const xParameters& params ) -{ -if( !strcmp( params[ 0 ], theServer->getUplinkCharYY().c_str() ) ) - { -// elog << "msg_EB> sendEA: " -// << theServer->getSendEA() -// << endl ; - - // It's my uplink - if( theServer->getSendEA() && theServer->getSendEB() ) - { - theServer->setBurstEnd( ::time( 0 ) ) ; - - // Our uplink is done bursting - // This is done here instead of down below the if/else - // structure because some of the methods called here - // may depend or use the Uplink's isBursting() method - theServer->getUplink()->stopBursting() ; - } - - // Signal that all Write()'s should write to the - // normal output buffer - theServer->setUseHoldBuffer( false ) ; - - // Burst our clients - theServer->BurstClients() ; - - // Burst our channels - theServer->BurstChannels() ; - - // Only need EB to be sent to turn off bursting, since after - // EB no bursts can be sent - if( theServer->getSendEB() ) - { - // We are no longer bursting - theServer->setBursting( false ) ; - } - - // Called PostEvent() here to notify all attached clients - // that we are no longer bursting. This will ensure - // that all end of burst items are written to the - // burstOutputBuffer before the burst if officially - // completed (as seen by the network) - theServer->PostEvent( EVT_BURST_CMPLT, - static_cast< void* >( theServer->getUplink() ) ) ; - - if( theServer->isVerbose() ) - { - clog << "*** Completed net burst" - << endl ; - } - - elog << "*** Completed net burst" - << endl ; - - if( theServer->getSendEB() ) - { - // Send our EB - theServer->Write( "%s EB\n", theServer->getCharYY().c_str() ) ; - } - - if( theServer->getSendEA() ) - { - // Acknowledge their end of burst - theServer->Write( "%s EA\n", theServer->getCharYY().c_str() ) ; - } - - // Is the burstOutputBuffer empty? - theServer->WriteBurstBuffer() ; - - theServer->PostEvent( EVT_EA_SENT, - static_cast< void* >( theServer->getUplink() ) ) ; - } -else - { - /* Its another server that has just completed its net.burst. */ - iServer* targetServer = Network->findServer( params[ 0 ] ) ; - if( NULL == targetServer ) - { - elog << "msg_EB> Unable to find server: " - << params[ 0 ] - << endl ; - return -1 ; - } - - targetServer->stopBursting() ; - theServer->PostEvent( EVT_BURST_CMPLT, - static_cast< void* >( targetServer ) ) ; - } - -return true ; +bool msg_EB::Execute(const xParameters& params) { + if (!strcmp(params[0], theServer->getUplinkCharYY().c_str())) { + // elog << "msg_EB> sendEA: " + // << theServer->getSendEA() + // << endl ; + + // It's my uplink + if (theServer->getSendEA() && theServer->getSendEB()) { + theServer->setBurstEnd(::time(0)); + + // Our uplink is done bursting + // This is done here instead of down below the if/else + // structure because some of the methods called here + // may depend or use the Uplink's isBursting() method + theServer->getUplink()->stopBursting(); + } + + // Signal that all Write()'s should write to the + // normal output buffer + theServer->setUseHoldBuffer(false); + + // Burst our clients + theServer->BurstClients(); + + // Burst our channels + theServer->BurstChannels(); + + // Only need EB to be sent to turn off bursting, since after + // EB no bursts can be sent + if (theServer->getSendEB()) { + // We are no longer bursting + theServer->setBursting(false); + } + + // Called PostEvent() here to notify all attached clients + // that we are no longer bursting. This will ensure + // that all end of burst items are written to the + // burstOutputBuffer before the burst if officially + // completed (as seen by the network) + theServer->PostEvent(EVT_BURST_CMPLT, static_cast(theServer->getUplink())); + + if (theServer->isVerbose()) { + clog << "*** Completed net burst" << endl; + } + + elog << "*** Completed net burst" << endl; + + if (theServer->getSendEB()) { + // Send our EB + theServer->Write("%s EB\n", theServer->getCharYY().c_str()); + } + + if (theServer->getSendEA()) { + // Acknowledge their end of burst + theServer->Write("%s EA\n", theServer->getCharYY().c_str()); + } + + // Is the burstOutputBuffer empty? + theServer->WriteBurstBuffer(); + + theServer->PostEvent(EVT_EA_SENT, static_cast(theServer->getUplink())); + } else { + /* Its another server that has just completed its net.burst. */ + iServer* targetServer = Network->findServer(params[0]); + if (NULL == targetServer) { + elog << "msg_EB> Unable to find server: " << params[0] << endl; + return -1; + } + + targetServer->stopBursting(); + theServer->PostEvent(EVT_BURST_CMPLT, static_cast(targetServer)); + } + + return true; } } // namespace gnuworld diff --git a/libircu/msg_G.cc b/libircu/msg_G.cc index b946e93c..5696bb7c 100644 --- a/libircu/msg_G.cc +++ b/libircu/msg_G.cc @@ -20,28 +20,27 @@ * $Id: msg_G.cc,v 1.8 2009/07/25 18:12:34 hidden1 Exp $ */ -#include +#include -#include -#include -#include +#include +#include +#include -#include -#include -#include +#include +#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "xparameters.h" -#include "ELog.h" -#include "ServerCommandHandler.h" -#include "StringTokenizer.h" +#include "gnuworld_config.h" +#include "server.h" +#include "xparameters.h" +#include "ELog.h" +#include "ServerCommandHandler.h" +#include "StringTokenizer.h" -namespace gnuworld -{ -using std::string ; -using std::endl ; -using std::stringstream ; +namespace gnuworld { +using std::endl; +using std::string; +using std::stringstream; CREATE_HANDLER(msg_G) @@ -62,116 +61,103 @@ CREATE_HANDLER(msg_G) // Z ! // Z ! // The format of = . -// -bool msg_G::Execute( const xParameters& params ) -{ -if( params.size() < 2 ) - { - elog << "msg_G> Invalid number of parameters" - << endl ; - return false ; - } - -string s( theServer->getCharYY() ) ; -s += " Z " ; - -if( 2 == params.size() ) - { - // Old style ping - s += params[ 0 ] ; - - if( params.size() >= static_cast< xParameters::size_type >( 1 ) ) - { - s += " :" ; - s += params[ 1 ] ; - } - } -else - { - // New style ping - // This little algorithm is purposely verbose - // MJ !1026249984.71811 test.gnuworld.org 1026249984.71811 - // Z ! -// elog << "msg_G> New style ping" -// << endl ; - - s += theServer->getCharYY(); - s += " " ; - // Target server - //s += params[ 0 ] ; - //s += " " ; - - // Remote TS, including the '!' - s += params[ 1 ] ; - s += " " ; - string tStr = params[ 1 ]; - s += tStr.substr(1,string::npos) ; - s += " " ; - -// double remoteTSDouble = ::atof( params[ 1 ] + 1 ) ; - -// elog << "remoteTSDouble: " -// << ((int) remoteTSDouble) -// << "." -// << (remoteTSDouble - (int) remoteTSDouble) -// << endl ; - - timeval now = { 0, 0 } ; - if( ::gettimeofday( &now, 0 ) < 0 ) - { - elog << "msg_G> gettimeofday() failed: " - << strerror( errno ) - << endl ; - return false ; - } - - - StringTokenizer st(params[1] + 1, '.'); - if (st.size() != 2) { - elog << "msg_G> Error in Remote TS" << endl; - return false; - } - int tsDiff = (now.tv_sec - atoi(st[0])) * 1000 + (now.tv_usec - atoi(st[1])) / 1000; - //elog << "msg_G> tsDiff = " << tsDiff << endl; - - stringstream theStream ; - theStream << now.tv_sec - << "." - << now.tv_usec ; - - string localTSString = theStream.str(); - // Obtain localTS as double val - double localTSDouble = 0.0 ; - theStream >> localTSDouble ; - -// elog << "msg_G> localTSString: " -// << localTSString -// << endl ; - - //double tsDiffDouble = localTSDouble - remoteTSDouble ; - //double tsDiffD = 1000 * (localTSDouble - remoteTSDouble); - //int tsDiff = static_cast(tsDiffD); - -// elog << "msg_G> tsDiffDouble: " -// << tsDiffDouble -// << endl ; - - stringstream stream2 ; - stream2 << tsDiff ; - -// elog << "msg_G> stream2: " -// << stream2.str() -// << endl ; - - // Difference TS - s += stream2.str() + " " ; - - // Local TS - s += localTSString ; - } - -//elog << "msg_G> Message: " << s << endl; -return theServer->Write( s ) ; +// +bool msg_G::Execute(const xParameters& params) { + if (params.size() < 2) { + elog << "msg_G> Invalid number of parameters" << endl; + return false; + } + + string s(theServer->getCharYY()); + s += " Z "; + + if (2 == params.size()) { + // Old style ping + s += params[0]; + + if (params.size() >= static_cast(1)) { + s += " :"; + s += params[1]; + } + } else { + // New style ping + // This little algorithm is purposely verbose + // MJ !1026249984.71811 test.gnuworld.org 1026249984.71811 + // Z ! + // elog << "msg_G> New style ping" + // << endl ; + + s += theServer->getCharYY(); + s += " "; + // Target server + // s += params[ 0 ] ; + // s += " " ; + + // Remote TS, including the '!' + s += params[1]; + s += " "; + string tStr = params[1]; + s += tStr.substr(1, string::npos); + s += " "; + + // double remoteTSDouble = ::atof( params[ 1 ] + 1 ) ; + + // elog << "remoteTSDouble: " + // << ((int) remoteTSDouble) + // << "." + // << (remoteTSDouble - (int) remoteTSDouble) + // << endl ; + + timeval now = {0, 0}; + if (::gettimeofday(&now, 0) < 0) { + elog << "msg_G> gettimeofday() failed: " << strerror(errno) << endl; + return false; + } + + StringTokenizer st(params[1] + 1, '.'); + if (st.size() != 2) { + elog << "msg_G> Error in Remote TS" << endl; + return false; + } + int tsDiff = (now.tv_sec - atoi(st[0])) * 1000 + (now.tv_usec - atoi(st[1])) / 1000; + // elog << "msg_G> tsDiff = " << tsDiff << endl; + + stringstream theStream; + theStream << now.tv_sec << "." << now.tv_usec; + + string localTSString = theStream.str(); + // Obtain localTS as double val + double localTSDouble = 0.0; + theStream >> localTSDouble; + + // elog << "msg_G> localTSString: " + // << localTSString + // << endl ; + + // double tsDiffDouble = localTSDouble - remoteTSDouble ; + // double tsDiffD = 1000 * (localTSDouble - remoteTSDouble); + // int tsDiff = static_cast(tsDiffD); + + // elog << "msg_G> tsDiffDouble: " + // << tsDiffDouble + // << endl ; + + stringstream stream2; + stream2 << tsDiff; + + // elog << "msg_G> stream2: " + // << stream2.str() + // << endl ; + + // Difference TS + s += stream2.str() + " "; + + // Local TS + s += localTSString; + } + + // elog << "msg_G> Message: " << s << endl; + return theServer->Write(s); } } // namespace gnuworld diff --git a/libircu/msg_GL.cc b/libircu/msg_GL.cc index 19cd28dc..b3df82f7 100644 --- a/libircu/msg_GL.cc +++ b/libircu/msg_GL.cc @@ -20,22 +20,21 @@ * $Id: msg_GL.cc,v 1.9 2009/08/01 08:32:21 mrbean_ Exp $ */ -#include -#include +#include +#include -#include +#include -#include "gnuworld_config.h" -#include "ServerCommandHandler.h" -#include "server.h" -#include "events.h" -#include "Gline.h" -#include "ELog.h" -#include "xparameters.h" +#include "gnuworld_config.h" +#include "ServerCommandHandler.h" +#include "server.h" +#include "events.h" +#include "Gline.h" +#include "ELog.h" +#include "xparameters.h" -namespace gnuworld -{ -using std::endl ; +namespace gnuworld { +using std::endl; CREATE_HANDLER(msg_GL) @@ -45,70 +44,54 @@ CREATE_HANDLER(msg_GL) * (On Mon May 1 22:40:23 2000 GMT from SE5 for 180 seconds: remgline * test.. [0]) */ -bool msg_GL::Execute( const xParameters& Params ) -{ -if( '-' == Params[ 2 ][ 0 ] ) - { - // Removing a gline - if( Params.size() < 3 ) - { - elog << "msg_GL> Invalid number of arguments" - << endl ; - return false ; - } - - xServer::glineIterator gItr = theServer->findGlineIterator( - Params[ 2 ] + 1 ) ; - if( gItr == theServer->glines_end() ) - { - // Unable to find the gline to be removed *shrug* - return true ; - } - - // Let the modules know that it has been removed - theServer->PostEvent( EVT_REMGLINE, - static_cast< void* >( gItr->second ) ) ; - - // Clean up memory - delete gItr->second ; - theServer->eraseGline( gItr ) ; - - return true ; - } - -// Else, adding a gline -if( Params.size() < 5 ) - { - elog << "msg_GL> Invalid number of arguments" - << endl ; - return false ; - } - -Gline* newGline = new (std::nothrow) Gline( - Params[ 0 ], - Params[ 2 ] + 1, - Params[ Params.size() - 1 ], - atoi( Params[ 3 ] ), - atoi( Params[ 4 ] )) ; -assert( newGline != 0 ) ; - -// Temporary variable -{ - xServer::glineIterator gItr = theServer->findGlineIterator( - newGline->getUserHost() ) ; - if( gItr != theServer->glines_end() ) - { - // This gline is already present - delete gItr->second ; - theServer->eraseGline( gItr ) ; - } -} - -theServer->addGline( newGline ) ; -theServer->PostEvent( EVT_GLINE, - static_cast< void* >( newGline ) ) ; - -return true ; +bool msg_GL::Execute(const xParameters& Params) { + if ('-' == Params[2][0]) { + // Removing a gline + if (Params.size() < 3) { + elog << "msg_GL> Invalid number of arguments" << endl; + return false; + } + + xServer::glineIterator gItr = theServer->findGlineIterator(Params[2] + 1); + if (gItr == theServer->glines_end()) { + // Unable to find the gline to be removed *shrug* + return true; + } + + // Let the modules know that it has been removed + theServer->PostEvent(EVT_REMGLINE, static_cast(gItr->second)); + + // Clean up memory + delete gItr->second; + theServer->eraseGline(gItr); + + return true; + } + + // Else, adding a gline + if (Params.size() < 5) { + elog << "msg_GL> Invalid number of arguments" << endl; + return false; + } + + Gline* newGline = new (std::nothrow) Gline(Params[0], Params[2] + 1, Params[Params.size() - 1], + atoi(Params[3]), atoi(Params[4])); + assert(newGline != 0); + + // Temporary variable + { + xServer::glineIterator gItr = theServer->findGlineIterator(newGline->getUserHost()); + if (gItr != theServer->glines_end()) { + // This gline is already present + delete gItr->second; + theServer->eraseGline(gItr); + } + } + + theServer->addGline(newGline); + theServer->PostEvent(EVT_GLINE, static_cast(newGline)); + + return true; } } // namespace gnuworld diff --git a/libircu/msg_I.cc b/libircu/msg_I.cc index 850fa934..1e3bd1f3 100644 --- a/libircu/msg_I.cc +++ b/libircu/msg_I.cc @@ -20,74 +20,54 @@ * $Id: msg_I.cc,v 1.7 2007/04/18 10:23:39 kewlio Exp $ */ -#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "xparameters.h" -#include "Channel.h" -#include "iClient.h" -#include "ELog.h" -#include "client.h" -#include "Network.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "xparameters.h" +#include "Channel.h" +#include "iClient.h" +#include "ELog.h" +#include "client.h" +#include "Network.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ -using std::endl ; +namespace gnuworld { +using std::endl; CREATE_HANDLER(msg_I) // ABAHo I X :#lksdlkj (non-ts) // ABAHo I X :#lksdlkj 1234567890 (ts) -bool msg_I::Execute( const xParameters& Param ) -{ -if (( Param.size() < 3 ) || ( Param.size() > 4)) - { - elog << "msg_I> Invalid number of arguments (" - << Param.size() - << ")" - << endl ; - int i; - for (i = 0; i < (int)Param.size(); i++) - elog << "msg_I> arg" - << i - << " = '" - << Param[i] - << "'" - << endl ; - return false ; - } +bool msg_I::Execute(const xParameters& Param) { + if ((Param.size() < 3) || (Param.size() > 4)) { + elog << "msg_I> Invalid number of arguments (" << Param.size() << ")" << endl; + int i; + for (i = 0; i < (int)Param.size(); i++) + elog << "msg_I> arg" << i << " = '" << Param[i] << "'" << endl; + return false; + } -iClient* srcClient = Network->findClient( Param[ 0 ] ) ; -if( NULL == srcClient ) - { - elog << "msg_I> Unable to find source client: " - << Param[ 0 ] - << endl ; - return false ; - } + iClient* srcClient = Network->findClient(Param[0]); + if (NULL == srcClient) { + elog << "msg_I> Unable to find source client: " << Param[0] << endl; + return false; + } -xClient* destClient = Network->findLocalNick( Param[ 1 ] ) ; -if( NULL == destClient ) - { - elog << "msg_I> Unable to find destination client: " - << Param[ 1 ] - << endl ; - return false ; - } + xClient* destClient = Network->findLocalNick(Param[1]); + if (NULL == destClient) { + elog << "msg_I> Unable to find destination client: " << Param[1] << endl; + return false; + } -Channel* theChan = Network->findChannel( Param[ 2 ] ) ; -if( NULL == theChan ) - { - elog << "msg_I> Unable to find channel: " - << Param[ 2 ] - << endl ; - return false ; - } + Channel* theChan = Network->findChannel(Param[2]); + if (NULL == theChan) { + elog << "msg_I> Unable to find channel: " << Param[2] << endl; + return false; + } -destClient->OnInvite( srcClient, theChan ) ; -return true ; + destClient->OnInvite(srcClient, theChan); + return true; } } // namespace gnuworld diff --git a/libircu/msg_J.cc b/libircu/msg_J.cc index 7eb64d3e..0f5f42fc 100644 --- a/libircu/msg_J.cc +++ b/libircu/msg_J.cc @@ -20,42 +20,37 @@ * $Id: msg_J.cc,v 1.10 2007/04/18 11:00:20 kewlio Exp $ */ -#include -#include -#include - -#include - -#include "gnuworld_config.h" -#include "server.h" -#include "iClient.h" -#include "Channel.h" -#include "ChannelUser.h" -#include "events.h" -#include "Network.h" -#include "ELog.h" -#include "StringTokenizer.h" -#include "ServerCommandHandler.h" - -namespace gnuworld -{ -using std::string ; -using std::endl ; - -class msg_J : public ServerCommandHandler -{ -public: - msg_J( xServer* theServer ) - : ServerCommandHandler( theServer ) - {} - virtual ~msg_J() - {} - - virtual bool Execute( const xParameters& ) ; - -protected: - void userPartAllChannels( iClient* ) ; -} ; +#include +#include +#include + +#include + +#include "gnuworld_config.h" +#include "server.h" +#include "iClient.h" +#include "Channel.h" +#include "ChannelUser.h" +#include "events.h" +#include "Network.h" +#include "ELog.h" +#include "StringTokenizer.h" +#include "ServerCommandHandler.h" + +namespace gnuworld { +using std::endl; +using std::string; + +class msg_J : public ServerCommandHandler { + public: + msg_J(xServer* theServer) : ServerCommandHandler(theServer) {} + virtual ~msg_J() {} + + virtual bool Execute(const xParameters&); + + protected: + void userPartAllChannels(iClient*); +}; CREATE_LOADER(msg_J) @@ -66,305 +61,267 @@ CREATE_LOADER(msg_J) * OAT J #coder-com,#blah 1234567890 * OAT J 0 */ -bool msg_J::Execute( const xParameters& Param ) -{ -// Verify that sufficient arguments have been provided -// client_numeric #channel[,#channel2,...] -if( Param.size() < 2 ) - { - // Insufficient arguments provided, log the error - elog << "msg_J> Invalid number of arguments" - << endl ; - - int i; - for (i = 0; i < (int)Param.size(); i++) - elog << "msg_J> arg" - << i - << " = '" - << Param[i] - << "'" - << endl ; - - // Return error - return false ; - } - -/* a join to '0' may not have a timestamp, but all others should */ -if ((Param[1][0]!='0') && Param.size() < 3) -{ - elog << "msg_J> Invalid number of arguments" - << endl ; - // Return error - return false; +bool msg_J::Execute(const xParameters& Param) { + // Verify that sufficient arguments have been provided + // client_numeric #channel[,#channel2,...] + if (Param.size() < 2) { + // Insufficient arguments provided, log the error + elog << "msg_J> Invalid number of arguments" << endl; + + int i; + for (i = 0; i < (int)Param.size(); i++) + elog << "msg_J> arg" << i << " = '" << Param[i] << "'" << endl; + + // Return error + return false; + } + + /* a join to '0' may not have a timestamp, but all others should */ + if ((Param[1][0] != '0') && Param.size() < 3) { + elog << "msg_J> Invalid number of arguments" << endl; + // Return error + return false; + } + + // Find the client in question. + iClient* Target = Network->findClient(Param[0]); + + // Did we find the client? + if (NULL == Target) { + // Nope, log the error + elog << "msg_J> (" << Param[1] << ") Unable to find user: " << Param[0] << endl; + + // Return error + return false; + } + + // Tokenize by ',', as the client may join more than one + // channel at once. + StringTokenizer st(Param[1], ','); + time_t joinTs = 0; + if (Param.size() < 3) + joinTs = ::time(NULL); + else + joinTs = atoi(Param[2]); + for (StringTokenizer::size_type i = 0; i < st.size(); i++) { + // Is it a modeless channel? + if ('+' == st[i][0]) { + // Don't care about modeless channels + continue; + } + + // Is the user parting all channels? + if ('0' == st[i][0]) { + // Yup, call userPartAllChannels which will update + // the user's information and notify listening + // services clients of the parts + userPartAllChannels(Target); + + // continue to next channel + continue; + } + + // Attempt to allocate a ChannelUser structure for this + // user<->channel association + ChannelUser* theUser = new (std::nothrow) ChannelUser(Target); + assert(theUser != 0); + + // This variable represents which event actually occurs + channelEventType whichEvent = EVT_JOIN; + + // On a JOIN command, the channel should already exist. + Channel* theChan = Network->findChannel(st[i]); + + // Does the channel already exist? + if (NULL == theChan) { + // Nope, this transmutes to a CREATE + // Create a new Channel to represent this + // network channel + theChan = new (std::nothrow) Channel(st[i], ::time(0)); + assert(theChan != 0); + + // Add the channel to the network tables + if (!Network->addChannel(theChan)) { + // Addition to network tables failed + // Log the error + elog << "msg_J> Unable to add channel: " << theChan->getName() << endl; + + // Prevent memory leaks by deallocating the + // Channel and ChannelUser objects + delete theChan; + theChan = 0; + delete theUser; + theUser = 0; + + // Continue to next channel + continue; + } + + // Since this is equivalent to a CREATE, set the user + // as operator. + theUser->setModeO(); + + // Update the event type + whichEvent = EVT_CREATE; + + } // if( NULL == theChan ) + /* + else if( theChan->findUser( Target ) != 0 ) + { + // The user is already in the channel...check for + // zombie state + ChannelUser* oldUser = theChan->findUser( Target ) ; + if( oldUser->getMode( ChannelUser::ZOMBIE ) ) + { + // The user was in the zombie state + // Remove the zombie state, and continue + // to the next channel + oldUser->removeMode( ChannelUser::ZOMBIE ) ; + + // elog << "msg_J> Removed zombie: " + // << *oldUser + // << " on channel " + // << theChan->getName() + // << endl ; + } + else + { + // User was found in channel, no reason apparent + // This message can happen a lot due + // to lag....it's not too important tho it + // bugs me so. + // elog << "msg_J> Unexpectedly found " + // << "user " + // << *Target + // << " in channel " + // << theChan->getName() + // << endl ; + } + + // In either case, there is no need to add the newly + // created ChannelUser to the channel, because it + // is already there. + delete theUser ; theUser = 0 ; + + // Continue, nothing more to do here + continue ; + } + */ + else if (joinTs < theChan->getCreationTime()) { + // The time of join is earlier than the creation time of the channel + // Need to clear all the modes of the channel + theChan->removeAllModes(); + // Now reset the channel creation time to the join ts + theChan->setCreationTime(joinTs); + } + // Add a new ChannelUser representing this client to this + // channel's user structure. + if (!theChan->addUser(theUser)) { + // Addition of this ChannelUser to the Channel failed + // Log the error + elog << "msg_J> Unable to add user " << theUser->getNickName() + << " to channel: " << theChan->getName() << endl; + + // Prevent memory leaks by deallocating the unused + // ChannelUser object + delete theUser; + theUser = 0; + + if (EVT_CREATE == whichEvent) { + // The channel did not exist before + // this message, so go ahead and + // remove it + Network->removeChannel(theChan->getName()); + + // Do some cleanup + delete theChan; + theChan = 0; + } + + // Continue to next channel + continue; + } + + // Add this channel to this client's channel structure. + if (!Target->addChannel(theChan)) { + elog << "msg_J> Unable to add channel " << *theChan << " to iClient " << *Target + << endl; + + // Remove the ChannelUser from this channel, and + // deallocate the ChannelUser to prevent memory + // leaks + theChan->removeUser(theUser); + delete theUser; + theUser = 0; + + // Did we just create the channel? + if (EVT_CREATE == whichEvent) { + // Yup, remove the channel from the network + // data structures + Network->removeChannel(theChan->getName()); + + // Prevent memory leaks by deallocating + // the channel + delete theChan; + theChan = 0; + } + + // Continue on with the next channel + continue; + } + + // Post the event to the clients listening for events on this + // channel, if any. + theServer->PostChannelEvent(whichEvent, theChan, static_cast(Target), + static_cast(theUser)); + + // TODO: Update event posting so that CREATE is also + // passed the client who created the channel + + } // for() + + return true; } -// Find the client in question. -iClient* Target = Network->findClient( Param[ 0 ] ) ; - -// Did we find the client? -if( NULL == Target ) - { - // Nope, log the error - elog << "msg_J> (" - << Param[ 1 ] - << ") Unable to find user: " - << Param[ 0 ] - << endl ; - - // Return error - return false ; - } - -// Tokenize by ',', as the client may join more than one -// channel at once. -StringTokenizer st( Param[ 1 ], ',' ) ; -time_t joinTs = 0; -if (Param.size() < 3) - joinTs = ::time(NULL); -else - joinTs = atoi( Param [ 2 ] ); -for( StringTokenizer::size_type i = 0 ; i < st.size() ; i++ ) - { - // Is it a modeless channel? - if( '+' == st[ i ][ 0 ] ) - { - // Don't care about modeless channels - continue ; - } - - // Is the user parting all channels? - if( '0' == st[ i ][ 0 ] ) - { - // Yup, call userPartAllChannels which will update - // the user's information and notify listening - // services clients of the parts - userPartAllChannels( Target ) ; - - // continue to next channel - continue ; - } - - // Attempt to allocate a ChannelUser structure for this - // user<->channel association - ChannelUser* theUser = - new (std::nothrow) ChannelUser( Target ) ; - assert( theUser != 0 ) ; - - // This variable represents which event actually occurs - channelEventType whichEvent = EVT_JOIN ; - - // On a JOIN command, the channel should already exist. - Channel* theChan = Network->findChannel( st[ i ] ) ; - - // Does the channel already exist? - if( NULL == theChan ) - { - // Nope, this transmutes to a CREATE - // Create a new Channel to represent this - // network channel - theChan = new (std::nothrow) - Channel( st[ i ], ::time( 0 ) ) ; - assert( theChan != 0 ) ; - - // Add the channel to the network tables - if( !Network->addChannel( theChan ) ) - { - // Addition to network tables failed - // Log the error - elog << "msg_J> Unable to add channel: " - << theChan->getName() - << endl ; - - // Prevent memory leaks by deallocating the - // Channel and ChannelUser objects - delete theChan ; theChan = 0 ; - delete theUser ; theUser = 0 ; - - // Continue to next channel - continue ; - } - - // Since this is equivalent to a CREATE, set the user - // as operator. - theUser->setModeO() ; - - // Update the event type - whichEvent = EVT_CREATE ; - - } // if( NULL == theChan ) -/* - else if( theChan->findUser( Target ) != 0 ) - { - // The user is already in the channel...check for - // zombie state - ChannelUser* oldUser = theChan->findUser( Target ) ; - if( oldUser->getMode( ChannelUser::ZOMBIE ) ) - { - // The user was in the zombie state - // Remove the zombie state, and continue - // to the next channel - oldUser->removeMode( ChannelUser::ZOMBIE ) ; - -// elog << "msg_J> Removed zombie: " -// << *oldUser -// << " on channel " -// << theChan->getName() -// << endl ; - } - else - { - // User was found in channel, no reason apparent - // This message can happen a lot due - // to lag....it's not too important tho it - // bugs me so. -// elog << "msg_J> Unexpectedly found " -// << "user " -// << *Target -// << " in channel " -// << theChan->getName() -// << endl ; - } - - // In either case, there is no need to add the newly - // created ChannelUser to the channel, because it - // is already there. - delete theUser ; theUser = 0 ; - - // Continue, nothing more to do here - continue ; - } -*/ - else if( joinTs < theChan->getCreationTime() ) - { - //The time of join is earlier than the creation time of the channel - //Need to clear all the modes of the channel - theChan->removeAllModes(); - //Now reset the channel creation time to the join ts - theChan->setCreationTime(joinTs); - } - // Add a new ChannelUser representing this client to this - // channel's user structure. - if( !theChan->addUser( theUser ) ) - { - // Addition of this ChannelUser to the Channel failed - // Log the error - elog << "msg_J> Unable to add user " - << theUser->getNickName() - << " to channel: " - << theChan->getName() - << endl ; - - // Prevent memory leaks by deallocating the unused - // ChannelUser object - delete theUser ; theUser = 0 ; - - if( EVT_CREATE == whichEvent ) - { - // The channel did not exist before - // this message, so go ahead and - // remove it - Network->removeChannel( theChan->getName() ) ; - - // Do some cleanup - delete theChan ; theChan = 0 ; - } - - // Continue to next channel - continue ; - } - - // Add this channel to this client's channel structure. - if( !Target->addChannel( theChan ) ) - { - elog << "msg_J> Unable to add channel " - << *theChan - << " to iClient " - << *Target - << endl ; - - // Remove the ChannelUser from this channel, and - // deallocate the ChannelUser to prevent memory - // leaks - theChan->removeUser( theUser ) ; - delete theUser ; theUser = 0 ; - - // Did we just create the channel? - if( EVT_CREATE == whichEvent ) - { - // Yup, remove the channel from the network - // data structures - Network->removeChannel( theChan->getName() ) ; - - // Prevent memory leaks by deallocating - // the channel - delete theChan ; theChan = 0 ; - } - - // Continue on with the next channel - continue ; - } - - // Post the event to the clients listening for events on this - // channel, if any. - theServer->PostChannelEvent( whichEvent, theChan, - static_cast< void* >( Target ), - static_cast< void* >( theUser ) ) ; - - // TODO: Update event posting so that CREATE is also - // passed the client who created the channel - - } // for() - -return true ; -} - -void msg_J::userPartAllChannels( iClient* theClient ) -{ -// Artifact, user is parting all channels -for( iClient::channelIterator ptr = theClient->channels_begin(), - endPtr = theClient->channels_end() ; ptr != endPtr ; ) - { - - // Remove this ChannelUser from the Channel's internal - // structure. - // Deallocate the ChannelUser - ChannelUser* theChanUser = (*ptr)->removeUser( theClient ) ; - if( NULL == theChanUser ) - { - elog << "msg_J::userPartAllChannels> Unable to " - << "remove iClient " - << *theClient - << " from channel " - << *(*ptr) - << endl ; - } - delete theChanUser ; theChanUser = 0 ; - - // BUG: This iClient has inconsistent state because - // no channels have been removed from its internal - // structure until the end of this method. - - // Post this event to all listeners - theServer->PostChannelEvent( EVT_PART, - *ptr, - static_cast< void* >( theClient ) ) ; // iClient* - - // Is the channel empty of all network and services - // clients? - if( (*ptr)->empty() ) - { - // TODO: Post event - - // Yup, remove the channel from the network channel - // table - delete Network->removeChannel( (*ptr++)->getName() ) ; - } - else - ptr++ ; - } - -// Just to be sure -theClient->clearChannels() ; +void msg_J::userPartAllChannels(iClient* theClient) { + // Artifact, user is parting all channels + for (iClient::channelIterator ptr = theClient->channels_begin(), + endPtr = theClient->channels_end(); + ptr != endPtr;) { + + // Remove this ChannelUser from the Channel's internal + // structure. + // Deallocate the ChannelUser + ChannelUser* theChanUser = (*ptr)->removeUser(theClient); + if (NULL == theChanUser) { + elog << "msg_J::userPartAllChannels> Unable to " + << "remove iClient " << *theClient << " from channel " << *(*ptr) << endl; + } + delete theChanUser; + theChanUser = 0; + + // BUG: This iClient has inconsistent state because + // no channels have been removed from its internal + // structure until the end of this method. + + // Post this event to all listeners + theServer->PostChannelEvent(EVT_PART, *ptr, + static_cast(theClient)); // iClient* + + // Is the channel empty of all network and services + // clients? + if ((*ptr)->empty()) { + // TODO: Post event + + // Yup, remove the channel from the network channel + // table + delete Network->removeChannel((*ptr++)->getName()); + } else + ptr++; + } + + // Just to be sure + theClient->clearChannels(); } // userPartAllChannels() diff --git a/libircu/msg_JU.cc b/libircu/msg_JU.cc index da6c842c..ba3d5994 100644 --- a/libircu/msg_JU.cc +++ b/libircu/msg_JU.cc @@ -20,16 +20,15 @@ * $Id: msg_JU.cc,v 1.9 2010/09/20 17:36:25 denspike Exp $ */ -#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "Network.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "Network.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { using std::endl; CREATE_HANDLER(msg_JU) @@ -37,81 +36,63 @@ CREATE_HANDLER(msg_JU) /** * JUPE message handler. */ -bool msg_JU::Execute( const xParameters& Param) -{ +bool msg_JU::Execute(const xParameters& Param) { -if (Param.size() < 6) - { - elog << "msg_JU: Invalid number of arguments" - << endl; - return false; - } -if(Param[2][0] == '+') - { - /* - * A new jupe is interduced, need to create an iServer for it - * and notify all the modules - */ - std::string Reason = Param.assemble(5); - std::string SName = Param[2]; - SName = SName.substr(1); - std::string CTime = Param[4]; - unsigned int intYY = 0; - char temp[3]; - temp[2] = '\0'; - if (!Network->allocateServerNumeric(intYY)) - { - elog << "msg_JU> Error while allocating server numeric!" - << endl; - return false; - } - const char* temp2 = inttobase64(temp,intYY,2); - - if (Reason[0] == ':') - { - Reason = Reason.substr(1); - }; - iServer* jupeServer = new (std::nothrow) iServer( - base64toint(Param[0]), - temp2, - SName, - atoi(CTime.c_str()), - Reason - ); - assert (jupeServer != 0); - jupeServer->setJupe(); - if (!Network->addServer(jupeServer)) - { - elog << "msg_JU> error while adding new server :(" << endl; - return false; - } - theServer->PostEvent(EVT_NETJOIN, //TODO add EVT_JUPE - static_cast< void* >(jupeServer), - NULL); + if (Param.size() < 6) { + elog << "msg_JU: Invalid number of arguments" << endl; + return false; + } + if (Param[2][0] == '+') { + /* + * A new jupe is interduced, need to create an iServer for it + * and notify all the modules + */ + std::string Reason = Param.assemble(5); + std::string SName = Param[2]; + SName = SName.substr(1); + std::string CTime = Param[4]; + unsigned int intYY = 0; + char temp[3]; + temp[2] = '\0'; + if (!Network->allocateServerNumeric(intYY)) { + elog << "msg_JU> Error while allocating server numeric!" << endl; + return false; + } + const char* temp2 = inttobase64(temp, intYY, 2); - } -else - { // its a removal.. - std::string SName = Param[2]; - SName = SName.substr(1); - iServer* jupeServer = Network->findServerName(SName); - if(!jupeServer) - { - elog << "msg_JU> Cant find server for removal" << endl; - return false; - } - if(jupeServer->getCharYY() == theServer->getCharYY()) - { - elog << "msg_JU> Let's not even try to remove ourself" << endl; - return false; - } - // BUG: Nothing here? - if(!Network->removeServer(jupeServer->getIntYY(),true)) - {} - } + if (Reason[0] == ':') { + Reason = Reason.substr(1); + }; + iServer* jupeServer = new (std::nothrow) + iServer(base64toint(Param[0]), temp2, SName, atoi(CTime.c_str()), Reason); + assert(jupeServer != 0); + jupeServer->setJupe(); + if (!Network->addServer(jupeServer)) { + elog << "msg_JU> error while adding new server :(" << endl; + return false; + } + theServer->PostEvent(EVT_NETJOIN, // TODO add EVT_JUPE + static_cast(jupeServer), NULL); -// TODO -return false ; + } else { // its a removal.. + std::string SName = Param[2]; + SName = SName.substr(1); + iServer* jupeServer = Network->findServerName(SName); + if (!jupeServer) { + elog << "msg_JU> Cant find server for removal" << endl; + return false; + } + if (jupeServer->getCharYY() == theServer->getCharYY()) { + elog << "msg_JU> Let's not even try to remove ourself" << endl; + return false; + } + // BUG: Nothing here? + if (!Network->removeServer(jupeServer->getIntYY(), true)) { + } + } + + // TODO + return false; } } // namespace gnuworld diff --git a/libircu/msg_K.cc b/libircu/msg_K.cc index 7cf65884..d1f82f4f 100644 --- a/libircu/msg_K.cc +++ b/libircu/msg_K.cc @@ -20,28 +20,27 @@ * $Id: msg_K.cc,v 1.5 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include -#include -#include +#include +#include +#include -#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "iClient.h" -#include "Channel.h" -#include "ChannelUser.h" -#include "events.h" -#include "Network.h" -#include "ELog.h" -#include "StringTokenizer.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "iClient.h" +#include "Channel.h" +#include "ChannelUser.h" +#include "events.h" +#include "Network.h" +#include "ELog.h" +#include "StringTokenizer.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::endl ; +using std::endl; +using std::string; CREATE_HANDLER(msg_K) @@ -68,172 +67,144 @@ CREATE_HANDLER(msg_K) // or bounce them back to the sender, thus invalidating // the command sent. // -bool msg_K::Execute( const xParameters& Param ) -{ -// Verify that there are at least three arguments provided -// client_source_numeric #channel client_target_numeric -if( Param.size() < 3 ) - { - // Invalid number of arguments - elog << "msg_K> Invalid number of arguments" - << endl ; - - // Return error - return false ; - } - -// Is this a modeless channel? -// Can there even be kicks on modeless channels? -if( '+' == Param[ 1 ][ 0 ] ) - { - // Don't care about modeless channels - return true ; - } - -// Find the source client -// The source can still be a server, so the srcClient here -// may be NULL -iClient* srcClient = Network->findClient( Param[ 0 ] ) ; - -// Find the target client -iClient* destClient = Network->findClient( Param[ 2 ] ) ; - -// Did we find the target client? -if( NULL == destClient ) - { - // Nope, log the error - elog << "msg_K> (" - << Param[ 1 ] - << ") Unable to find target client: " - << Param[ 2 ] - << endl ; - - // Return error - return false ; - } - -// Find the channel in question. -Channel* theChan = Network->findChannel( Param[ 1 ] ) ; - -// Did we find the channel? -if( NULL == theChan ) - { - // Nope, log the error - elog << "msg_K> Unable to find channel: " - << Param[ 1 ] - << endl ; - - // Return error - return false ; - } - -ChannelUser* destChanUser = theChan->findUser( destClient ) ; -if( NULL == destChanUser ) - { -// This is commented out due to lag kicks happening quite a bit -// on production networks, especially in channels with fasting -// banning bots. -// elog << "msg_K> Unable to find target ChannelUser " -// << "for channel " -// << theChan->getName() -// << ", iClient: " -// << *destClient -// << endl ; - - // Return error - return false ; - } - -// On a network with more than 2 servers, the chances are greater -// that the two clients will be on different servers...thus, -// initialize localKick to false here. -bool localKick = false ; - -// Check to see if the source and destination user are -// on the same server. -if( srcClient != 0 ) - { - if( srcClient->getIntYY() == destClient->getIntYY() ) - { - // Local kick - localKick = true ; - } - } - -if( localKick ) - { - // Only remove the ChannelUser from the channel if this - // is a local kick...otherwise, the kick is unauthoritative - theChan->removeUser( destClient ) ; - - // Deallocate the ChannelUser - delete destChanUser ; destChanUser = 0 ; - - // Remove the channel information from the client's internal - // channel structure - if( !destClient->removeChannel( theChan ) ) - { - elog << "msg_K> Unable to remove channel " - << theChan->getName() - << " from the iClient " - << *destClient - << endl ; - } - } -else - { - // Check if the kick wasnt issued by a server , - // if it does, then its authoritative -// if((srcClient == 0) && (Network->findServer(Param[0]))) -// { - theChan->removeUser( destClient ) ; - - // Deallocate the ChannelUser - delete destChanUser ; destChanUser = 0 ; - - // Remove the channel information from the client's internal - // channel structure - if( !destClient->removeChannel( theChan ) ) - { - elog << "msg_K> Unable to remove channel " - << theChan->getName() - << " from the iClient " - << *destClient - << endl ; - } - -// } -// else -// { - // The kick is unauthoritative, the destination client - // is now in the zombie state -// destChanUser->setZombie() ; - - // elog << "msg_K> Adding zombie for user " - // << *destChanUser - // << " on channel " - // << theChan->getName() - // << endl ; -// } - } - -// Post the channel kick event -theServer->PostChannelKick( theChan, - srcClient, - destClient, - (Param.size() >= 4) ? Param[ 3 ] : string(), - localKick ) ; - -// Any users or services clients left in the channel? -if( theChan->empty() ) - { - // Nope, remove the channel - delete Network->removeChannel( theChan->getName() ) ; - - // TODO: Post event - } - -return true ; +bool msg_K::Execute(const xParameters& Param) { + // Verify that there are at least three arguments provided + // client_source_numeric #channel client_target_numeric + if (Param.size() < 3) { + // Invalid number of arguments + elog << "msg_K> Invalid number of arguments" << endl; + + // Return error + return false; + } + + // Is this a modeless channel? + // Can there even be kicks on modeless channels? + if ('+' == Param[1][0]) { + // Don't care about modeless channels + return true; + } + + // Find the source client + // The source can still be a server, so the srcClient here + // may be NULL + iClient* srcClient = Network->findClient(Param[0]); + + // Find the target client + iClient* destClient = Network->findClient(Param[2]); + + // Did we find the target client? + if (NULL == destClient) { + // Nope, log the error + elog << "msg_K> (" << Param[1] << ") Unable to find target client: " << Param[2] << endl; + + // Return error + return false; + } + + // Find the channel in question. + Channel* theChan = Network->findChannel(Param[1]); + + // Did we find the channel? + if (NULL == theChan) { + // Nope, log the error + elog << "msg_K> Unable to find channel: " << Param[1] << endl; + + // Return error + return false; + } + + ChannelUser* destChanUser = theChan->findUser(destClient); + if (NULL == destChanUser) { + // This is commented out due to lag kicks happening quite a bit + // on production networks, especially in channels with fasting + // banning bots. + // elog << "msg_K> Unable to find target ChannelUser " + // << "for channel " + // << theChan->getName() + // << ", iClient: " + // << *destClient + // << endl ; + + // Return error + return false; + } + + // On a network with more than 2 servers, the chances are greater + // that the two clients will be on different servers...thus, + // initialize localKick to false here. + bool localKick = false; + + // Check to see if the source and destination user are + // on the same server. + if (srcClient != 0) { + if (srcClient->getIntYY() == destClient->getIntYY()) { + // Local kick + localKick = true; + } + } + + if (localKick) { + // Only remove the ChannelUser from the channel if this + // is a local kick...otherwise, the kick is unauthoritative + theChan->removeUser(destClient); + + // Deallocate the ChannelUser + delete destChanUser; + destChanUser = 0; + + // Remove the channel information from the client's internal + // channel structure + if (!destClient->removeChannel(theChan)) { + elog << "msg_K> Unable to remove channel " << theChan->getName() << " from the iClient " + << *destClient << endl; + } + } else { + // Check if the kick wasnt issued by a server , + // if it does, then its authoritative + // if((srcClient == 0) && (Network->findServer(Param[0]))) + // { + theChan->removeUser(destClient); + + // Deallocate the ChannelUser + delete destChanUser; + destChanUser = 0; + + // Remove the channel information from the client's internal + // channel structure + if (!destClient->removeChannel(theChan)) { + elog << "msg_K> Unable to remove channel " << theChan->getName() << " from the iClient " + << *destClient << endl; + } + + // } + // else + // { + // The kick is unauthoritative, the destination client + // is now in the zombie state + // destChanUser->setZombie() ; + + // elog << "msg_K> Adding zombie for user " + // << *destChanUser + // << " on channel " + // << theChan->getName() + // << endl ; + // } + } + + // Post the channel kick event + theServer->PostChannelKick(theChan, srcClient, destClient, + (Param.size() >= 4) ? Param[3] : string(), localKick); + + // Any users or services clients left in the channel? + if (theChan->empty()) { + // Nope, remove the channel + delete Network->removeChannel(theChan->getName()); + + // TODO: Post event + } + + return true; } } // namespace gnuworld diff --git a/libircu/msg_L.cc b/libircu/msg_L.cc index 88250cbf..5a759664 100644 --- a/libircu/msg_L.cc +++ b/libircu/msg_L.cc @@ -20,26 +20,25 @@ * $Id: msg_L.cc,v 1.5 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include -#include - -#include "gnuworld_config.h" -#include "server.h" -#include "iClient.h" -#include "Channel.h" -#include "ChannelUser.h" -#include "Network.h" -#include "ELog.h" -#include "StringTokenizer.h" -#include "events.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" - -namespace gnuworld -{ - -using std::string ; -using std::endl ; +#include +#include + +#include "gnuworld_config.h" +#include "server.h" +#include "iClient.h" +#include "Channel.h" +#include "ChannelUser.h" +#include "Network.h" +#include "ELog.h" +#include "StringTokenizer.h" +#include "events.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" + +namespace gnuworld { + +using std::endl; +using std::string; CREATE_HANDLER(msg_L) @@ -47,128 +46,111 @@ CREATE_HANDLER(msg_L) * Someone has just left a channel. * AABBB L #channel */ -bool msg_L::Execute( const xParameters& Param ) -{ -// Verify that there are at least 2 arguments: -// client_numeric #channel -if( Param.size() < 2 ) - { - elog << "msg_L> Invalid number of arguments" - << endl ; - return false ; - } - -// Find the client in question -iClient* theClient = Network->findClient( Param[ 0 ] ) ; - -// Was the client found? -if( NULL == theClient ) - { - // Nope, no matching client found - - // Log the error - elog << "msg_L> (" - << Param[ 1 ] - << "): Unable to find client: " - << Param[ 0 ] - << endl ; - - // Return error - return false ; - } - -// Tokenize the channel string -// Be sure to take into account the channel parting message -// This first line will first tokenize the string containing the -// names of the channel(s) being parted and the part message (if any) -// by ' ' (space). The first token of this StringTokenizer (the channel -// name(s)) will then be tokenized by ':' to separate out the channel -// name(s) from the part message (if any). - -// This first partString StringTokenizer will tokenize out the string -// into two tokens (by space): chan1[,chan2,...] :part message -StringTokenizer partString( Param[ 1 ] ) ; -string partMsg; -if (Param.size() > 2) - partMsg = string(Param[ 2 ]); - -// This tokenizer will separate out the invidividual channel names -StringTokenizer st( partString[ 0 ], ',' ) ; - -// Iterate through all channels that this user is parting -for( StringTokenizer::size_type i = 0 ; i < st.size() ; ++i ) - { - - // Is this a modeless channel? - if( '+' == st[ i ][ 0 ] ) - { - // Ignore modeless channels - continue ; - } - - // Get the channel that was just parted. - Channel* theChan = Network->findChannel( st[ i ] ) ; - - // Was the channel found? - if( NULL == theChan ) - { - // Channel not found, log the error - elog << "msg_L> Unable to find channel: " - << st[ i ] - << endl ; - - // Continue on to the next channel - continue ; - } - - // Remove client<->channel associations - - // Remove and deallocate the ChannelUser instance from this - // channel's ChannelUser structure. - ChannelUser* theChanUser = theChan->removeUser( theClient ) ; - if( NULL == theChanUser ) - { - // This can happen if the user is a zombie - // Since atm GNUWorld ignores zombies, just ignore - // this message. - continue ; - -// elog << "msg_L> Unable to remove " -// << *theClient -// << " from channel: " -// << *theChan -// << endl ; - } - delete theChanUser ; theChanUser = 0 ; - - // Remove this channel from this client's channel structure. - if( !theClient->removeChannel( theChan ) ) - { - elog << "msg_L> Unable to remove iClient " - << *theClient - << " from channel " - << *theChan - << endl ; - } - - //elog << "msg_L> " << theClient << " Part " << theChan->getName() << " (" << partMsg << ")" << endl; - // Post the event to the clients listening for events on this - // channel, if any. - theServer->PostChannelEvent( EVT_PART, theChan, - static_cast< void* >( theClient ), static_cast< string* >( &partMsg )) ; - - // Is the channel now empty, and no services clients are - // on the channel? - if( theChan->empty() ) - { - // No users in the channel, remove it. - delete Network->removeChannel( theChan->getName() ) ; - - // TODO: Post event - } - } // for - -return true ; +bool msg_L::Execute(const xParameters& Param) { + // Verify that there are at least 2 arguments: + // client_numeric #channel + if (Param.size() < 2) { + elog << "msg_L> Invalid number of arguments" << endl; + return false; + } + + // Find the client in question + iClient* theClient = Network->findClient(Param[0]); + + // Was the client found? + if (NULL == theClient) { + // Nope, no matching client found + + // Log the error + elog << "msg_L> (" << Param[1] << "): Unable to find client: " << Param[0] << endl; + + // Return error + return false; + } + + // Tokenize the channel string + // Be sure to take into account the channel parting message + // This first line will first tokenize the string containing the + // names of the channel(s) being parted and the part message (if any) + // by ' ' (space). The first token of this StringTokenizer (the channel + // name(s)) will then be tokenized by ':' to separate out the channel + // name(s) from the part message (if any). + + // This first partString StringTokenizer will tokenize out the string + // into two tokens (by space): chan1[,chan2,...] :part message + StringTokenizer partString(Param[1]); + string partMsg; + if (Param.size() > 2) + partMsg = string(Param[2]); + + // This tokenizer will separate out the invidividual channel names + StringTokenizer st(partString[0], ','); + + // Iterate through all channels that this user is parting + for (StringTokenizer::size_type i = 0; i < st.size(); ++i) { + + // Is this a modeless channel? + if ('+' == st[i][0]) { + // Ignore modeless channels + continue; + } + + // Get the channel that was just parted. + Channel* theChan = Network->findChannel(st[i]); + + // Was the channel found? + if (NULL == theChan) { + // Channel not found, log the error + elog << "msg_L> Unable to find channel: " << st[i] << endl; + + // Continue on to the next channel + continue; + } + + // Remove client<->channel associations + + // Remove and deallocate the ChannelUser instance from this + // channel's ChannelUser structure. + ChannelUser* theChanUser = theChan->removeUser(theClient); + if (NULL == theChanUser) { + // This can happen if the user is a zombie + // Since atm GNUWorld ignores zombies, just ignore + // this message. + continue; + + // elog << "msg_L> Unable to remove " + // << *theClient + // << " from channel: " + // << *theChan + // << endl ; + } + delete theChanUser; + theChanUser = 0; + + // Remove this channel from this client's channel structure. + if (!theClient->removeChannel(theChan)) { + elog << "msg_L> Unable to remove iClient " << *theClient << " from channel " << *theChan + << endl; + } + + // elog << "msg_L> " << theClient << " Part " << theChan->getName() << " (" << partMsg << + // ")" << endl; + // Post the event to the clients listening for events on this + // channel, if any. + theServer->PostChannelEvent(EVT_PART, theChan, static_cast(theClient), + static_cast(&partMsg)); + + // Is the channel now empty, and no services clients are + // on the channel? + if (theChan->empty()) { + // No users in the channel, remove it. + delete Network->removeChannel(theChan->getName()); + + // TODO: Post event + } + } // for + + return true; } } // namespace gnuworld diff --git a/libircu/msg_M.cc b/libircu/msg_M.cc index a4ab6488..1ddfb330 100644 --- a/libircu/msg_M.cc +++ b/libircu/msg_M.cc @@ -20,49 +20,43 @@ * $Id: msg_M.cc,v 1.14 2008/04/16 20:29:37 danielaustin Exp $ */ -#include -#include -#include -#include -#include - -#include "gnuworld_config.h" -#include "misc.h" -#include "events.h" - -#include "server.h" -#include "iClient.h" -#include "Channel.h" -#include "ChannelUser.h" -#include "Network.h" -#include "ELog.h" -#include "StringTokenizer.h" -#include "ServerCommandHandler.h" - -namespace gnuworld -{ - -using std::pair ; -using std::make_pair ; -using std::string ; -using std::vector ; -using std::endl ; - -class msg_M : public ServerCommandHandler -{ -public: - msg_M( xServer* theServer ) - : ServerCommandHandler( theServer ) - {} - virtual ~msg_M() - {} - - virtual bool Execute( const xParameters& ) ; - -protected: - bool onUserModeChange( const xParameters& ) ; - -} ; +#include +#include +#include +#include +#include + +#include "gnuworld_config.h" +#include "misc.h" +#include "events.h" + +#include "server.h" +#include "iClient.h" +#include "Channel.h" +#include "ChannelUser.h" +#include "Network.h" +#include "ELog.h" +#include "StringTokenizer.h" +#include "ServerCommandHandler.h" + +namespace gnuworld { + +using std::endl; +using std::make_pair; +using std::pair; +using std::string; +using std::vector; + +class msg_M : public ServerCommandHandler { + public: + msg_M(xServer* theServer) : ServerCommandHandler(theServer) {} + virtual ~msg_M() {} + + virtual bool Execute(const xParameters&); + + protected: + bool onUserModeChange(const xParameters&); +}; CREATE_LOADER(msg_M) @@ -72,463 +66,383 @@ CREATE_LOADER(msg_M) // // i M #3dx +o eAA // J[K M DEMET_33 :+i -bool msg_M::Execute( const xParameters& Param ) -{ -if( Param.size() < 3 ) - { - elog << "msg_M> Invalid number of arguments" - << endl ; - return false ; - } - -// This source stuff really isn't used here, but it's here for -// debugging and validation. -iServer* serverSource = 0 ; -iClient* clientSource = 0 ; - -// Note that the order of this if/else if/else is important -if( NULL != strchr( Param[ 0 ], '.' ) ) - { - // Server, by name - serverSource = Network->findServerName( Param[ 0 ] ) ; - } -else if( strlen( Param[ 0 ] ) >= 3 ) - { - // Client numeric - clientSource = Network->findClient( Param[ 0 ] ) ; - } -else - { - // 1 or 2 char numeric, server - serverSource = Network->findServer( Param[ 0 ] ) ; - } - -if( (NULL == clientSource) && (NULL == serverSource) ) - { - elog << "msg_M> Unable to find source: " - << Param[ 0 ] - << endl ; - return false ; - } - -// Is it a user mode change? -if( '#' != Param[ 1 ][ 0 ] ) - { - // Yup, process the user's mode change(s) - return onUserModeChange( Param ) ; - } - -// Find the channel in question -Channel* theChan = Network->findChannel( Param[ 1 ] ) ; -if( NULL == theChan ) - { - elog << "msg_M> Unable to find channel: " - << Param[ 1 ] - << endl ; - return false ; - } - -if( serverSource != 0 ) -{ -// elog << "msg_M (" -// << theChan->getName() -// << ") server " -// << serverSource->getName() -// << " performed a mode" -// << end1; - theServer->PostChannelEvent( EVT_SERVERMODE, theChan, - static_cast< void* >( serverSource ) ) ; -} - -/* XXX OPMODE FAILS HERE */ -/* Hidden: But doesn't anymore */ -// Find the ChannelUser of the source client -// It is possible that the ChannelUser will be NULL, in the -// case that a server is setting the mode(s) -ChannelUser* theUser = 0 ; -if( clientSource != 0 ) - { - theUser = theChan->findUser( clientSource ) ; - if( NULL == theUser ) - { -// elog << "msg_M> (" -// << theChan->getName() -// << ") Unable to find channel user: " -// << clientSource->getCharYYXXX() -// << endl ; - /* 2022-02-21: Hidden: Commenting line below to allow OPMODE to be used - return false ; - */ - } - } - -bool polarity = true ; -xParameters::size_type argPos = 3 ; - -xServer::opVectorType opVector ; -xServer::voiceVectorType voiceVector ; -xServer::banVectorType banVector ; -xServer::modeVectorType modeVector ; - -for( const char* modePtr = Param[ 2 ] ; *modePtr ; ++modePtr ) - { - switch( *modePtr ) - { - case '+': - polarity = true ; - break ; - case '-': - polarity = false ; - break ; - case 't': - modeVector.push_back( - make_pair( polarity, Channel::MODE_T ) ) ; - break ; - case 'n': - modeVector.push_back( - make_pair( polarity, Channel::MODE_N ) ) ; - break ; - case 's': - modeVector.push_back( - make_pair( polarity, Channel::MODE_S ) ) ; - break ; - case 'p': - modeVector.push_back( - make_pair( polarity, Channel::MODE_P ) ) ; - break ; - case 'm': - modeVector.push_back( - make_pair( polarity, Channel::MODE_M ) ) ; - break ; - case 'i': - modeVector.push_back( - make_pair( polarity, Channel::MODE_I ) ) ; - break ; - case 'r': - modeVector.push_back( - make_pair( polarity, Channel::MODE_R ) ) ; - break ; - case 'R': - modeVector.push_back( - make_pair( polarity, Channel::MODE_REG ) ) ; - break ; - case 'D': - modeVector.push_back( - make_pair( polarity, Channel::MODE_D ) ) ; - break; - case 'c': - modeVector.push_back( - make_pair(polarity, Channel::MODE_C)); - break; - case 'C': - modeVector.push_back( - make_pair(polarity, Channel::MODE_CTCP)); - break; - case 'u': - modeVector.push_back( - make_pair(polarity, Channel::MODE_PART)); - break; - case 'M': - modeVector.push_back( - make_pair(polarity, Channel::MODE_MNOREG)); - break; - case 'Z': - modeVector.push_back( - make_pair(polarity, Channel::MODE_Z)); - break; - // Channel mode l only has an argument if - // it is being added, but not removed - case 'l': - if( polarity && (argPos >= Param.size()) ) - { - elog << "msg_M> Invalid " - << "format for message: missing " - << "argument to mode +l" - << " in channel " - << *theChan - << endl ; - continue ; - } - - theServer->OnChannelModeL( theChan, - polarity, theUser, - polarity ? atoi( Param[ argPos++ ] ) - : 0 ) ; - break ; - - // Channel mode k always has an argument - case 'k': - if( argPos >= Param.size() ) - { - elog << "msg_M> Invalid " - << "format for message: missing " - << "argument for mode 'k'" - << " in channel " - << *theChan - << endl ; - continue ; - } - - theServer->OnChannelModeK( theChan, - polarity, theUser, - Param[ argPos++ ] ) ; - break ; - case 'o': - { - if( argPos >= Param.size() ) - { - elog << "msg_M> Invalid " - << "format for message: missing " - << "argument for mode 'o'" - << " in channel " - << *theChan - << endl ; - continue ; - } - - iClient* targetClient = Network->findClient( - Param[ argPos++ ] ) ; - if( NULL == targetClient ) - { -// elog << "msg_M> Unable to " -// << "find op target client: " -// << Param[ argPos - 1 ] -// << " in channel " -// << *theChan -// << endl ; - break ; - } - ChannelUser* targetUser = theChan->findUser( - targetClient ) ; - if( NULL == targetUser ) - { -// elog << "msg_M> Unable to " -// << "find op target user: " -// << Param[ argPos - 1 ] -// << " in channel " -// << *theChan -// << endl ; - break ; - } - opVector.push_back( - pair< bool, ChannelUser* >( - polarity, targetUser ) ) ; - - // If the op mode is +o, remove the ZOMBIE - // state from this user. -// if( polarity && targetUser->isZombie() ) -// { -// targetUser->removeZombie() ; -// elog << "msg_M> Removing " -// << "zombie" -// << endl ; -// } - break ; - } - case 'v': - { - if( argPos >= Param.size() ) - { - elog << "msg_M> Invalid " - << "format for message: missing " - << "argument for mode 'v'" - << " in channel " - << *theChan - << endl ; - continue ; - } - - iClient* targetClient = Network->findClient( - Param[ argPos++ ] ) ; - if( NULL == targetClient ) - { -// elog << "msg_M> Unable to " -// << "find voice target client: " -// << Param[ argPos - 1 ] -// << " in channel " -// << *theChan -// << endl ; - break ; - } - ChannelUser* targetUser = theChan->findUser( - targetClient ) ; - if( NULL == targetUser ) - { -// elog << "msg_M> Unable to " -// << "find voice target user: " -// << Param[ argPos - 1 ] -// << " in channel " -// << *theChan -// << endl ; - break ; - } - voiceVector.push_back( - pair< bool, ChannelUser* >( - polarity, targetUser ) ) ; - break ; - } - case 'b': - { - if( argPos >= Param.size() ) - { - elog << "msg_M> Invalid " - << "format for message: missing " - << "argument for mode 'b'" - << " in channel " - << *theChan - << endl ; - continue ; - } - - const char* targetBan = Param[ argPos++ ] ; - banVector.push_back( - pair< bool, string >( - polarity, string( targetBan ) ) ) ; - break ; - } - - } // switch() - } // for() - -if (argPos < Param.size()) - { - // Last argument is creation time - // Update creation timestamp if older - time_t newCreationTime = - static_cast< time_t >( ::atoi( Param[ argPos++ ] ) ) ; - - // Is the old TS greater than the new TS? - if( theChan->getCreationTime() > newCreationTime ) - { - // Nope, update the timestamp - theChan->setCreationTime( newCreationTime ) ; - } - } - -if( !modeVector.empty() ) - { - theServer->OnChannelMode( theChan, theUser, modeVector ) ; - } -if( !opVector.empty() ) - { - theServer->OnChannelModeO( theChan, theUser, opVector ) ; - } -if( !voiceVector.empty() ) - { - theServer->OnChannelModeV( theChan, theUser, voiceVector ) ; - } -if( !banVector.empty() ) - { - theServer->OnChannelModeB( theChan, theUser, banVector ) ; - } - -return true ; +bool msg_M::Execute(const xParameters& Param) { + if (Param.size() < 3) { + elog << "msg_M> Invalid number of arguments" << endl; + return false; + } + + // This source stuff really isn't used here, but it's here for + // debugging and validation. + iServer* serverSource = 0; + iClient* clientSource = 0; + + // Note that the order of this if/else if/else is important + if (NULL != strchr(Param[0], '.')) { + // Server, by name + serverSource = Network->findServerName(Param[0]); + } else if (strlen(Param[0]) >= 3) { + // Client numeric + clientSource = Network->findClient(Param[0]); + } else { + // 1 or 2 char numeric, server + serverSource = Network->findServer(Param[0]); + } + + if ((NULL == clientSource) && (NULL == serverSource)) { + elog << "msg_M> Unable to find source: " << Param[0] << endl; + return false; + } + + // Is it a user mode change? + if ('#' != Param[1][0]) { + // Yup, process the user's mode change(s) + return onUserModeChange(Param); + } + + // Find the channel in question + Channel* theChan = Network->findChannel(Param[1]); + if (NULL == theChan) { + elog << "msg_M> Unable to find channel: " << Param[1] << endl; + return false; + } + + if (serverSource != 0) { + // elog << "msg_M (" + // << theChan->getName() + // << ") server " + // << serverSource->getName() + // << " performed a mode" + // << end1; + theServer->PostChannelEvent(EVT_SERVERMODE, theChan, static_cast(serverSource)); + } + + /* XXX OPMODE FAILS HERE */ + /* Hidden: But doesn't anymore */ + // Find the ChannelUser of the source client + // It is possible that the ChannelUser will be NULL, in the + // case that a server is setting the mode(s) + ChannelUser* theUser = 0; + if (clientSource != 0) { + theUser = theChan->findUser(clientSource); + if (NULL == theUser) { + // elog << "msg_M> (" + // << theChan->getName() + // << ") Unable to find channel user: " + // << clientSource->getCharYYXXX() + // << endl ; + /* 2022-02-21: Hidden: Commenting line below to allow OPMODE to be used + return false ; + */ + } + } + + bool polarity = true; + xParameters::size_type argPos = 3; + + xServer::opVectorType opVector; + xServer::voiceVectorType voiceVector; + xServer::banVectorType banVector; + xServer::modeVectorType modeVector; + + for (const char* modePtr = Param[2]; *modePtr; ++modePtr) { + switch (*modePtr) { + case '+': + polarity = true; + break; + case '-': + polarity = false; + break; + case 't': + modeVector.push_back(make_pair(polarity, Channel::MODE_T)); + break; + case 'n': + modeVector.push_back(make_pair(polarity, Channel::MODE_N)); + break; + case 's': + modeVector.push_back(make_pair(polarity, Channel::MODE_S)); + break; + case 'p': + modeVector.push_back(make_pair(polarity, Channel::MODE_P)); + break; + case 'm': + modeVector.push_back(make_pair(polarity, Channel::MODE_M)); + break; + case 'i': + modeVector.push_back(make_pair(polarity, Channel::MODE_I)); + break; + case 'r': + modeVector.push_back(make_pair(polarity, Channel::MODE_R)); + break; + case 'R': + modeVector.push_back(make_pair(polarity, Channel::MODE_REG)); + break; + case 'D': + modeVector.push_back(make_pair(polarity, Channel::MODE_D)); + break; + case 'c': + modeVector.push_back(make_pair(polarity, Channel::MODE_C)); + break; + case 'C': + modeVector.push_back(make_pair(polarity, Channel::MODE_CTCP)); + break; + case 'u': + modeVector.push_back(make_pair(polarity, Channel::MODE_PART)); + break; + case 'M': + modeVector.push_back(make_pair(polarity, Channel::MODE_MNOREG)); + break; + case 'Z': + modeVector.push_back(make_pair(polarity, Channel::MODE_Z)); + break; + // Channel mode l only has an argument if + // it is being added, but not removed + case 'l': + if (polarity && (argPos >= Param.size())) { + elog << "msg_M> Invalid " + << "format for message: missing " + << "argument to mode +l" + << " in channel " << *theChan << endl; + continue; + } + + theServer->OnChannelModeL(theChan, polarity, theUser, + polarity ? atoi(Param[argPos++]) : 0); + break; + + // Channel mode k always has an argument + case 'k': + if (argPos >= Param.size()) { + elog << "msg_M> Invalid " + << "format for message: missing " + << "argument for mode 'k'" + << " in channel " << *theChan << endl; + continue; + } + + theServer->OnChannelModeK(theChan, polarity, theUser, Param[argPos++]); + break; + case 'o': { + if (argPos >= Param.size()) { + elog << "msg_M> Invalid " + << "format for message: missing " + << "argument for mode 'o'" + << " in channel " << *theChan << endl; + continue; + } + + iClient* targetClient = Network->findClient(Param[argPos++]); + if (NULL == targetClient) { + // elog << "msg_M> Unable to " + // << "find op target client: " + // << Param[ argPos - 1 ] + // << " in channel " + // << *theChan + // << endl ; + break; + } + ChannelUser* targetUser = theChan->findUser(targetClient); + if (NULL == targetUser) { + // elog << "msg_M> Unable to " + // << "find op target user: " + // << Param[ argPos - 1 ] + // << " in channel " + // << *theChan + // << endl ; + break; + } + opVector.push_back(pair(polarity, targetUser)); + + // If the op mode is +o, remove the ZOMBIE + // state from this user. + // if( polarity && targetUser->isZombie() ) + // { + // targetUser->removeZombie() ; + // elog << "msg_M> Removing " + // << "zombie" + // << endl ; + // } + break; + } + case 'v': { + if (argPos >= Param.size()) { + elog << "msg_M> Invalid " + << "format for message: missing " + << "argument for mode 'v'" + << " in channel " << *theChan << endl; + continue; + } + + iClient* targetClient = Network->findClient(Param[argPos++]); + if (NULL == targetClient) { + // elog << "msg_M> Unable to " + // << "find voice target client: " + // << Param[ argPos - 1 ] + // << " in channel " + // << *theChan + // << endl ; + break; + } + ChannelUser* targetUser = theChan->findUser(targetClient); + if (NULL == targetUser) { + // elog << "msg_M> Unable to " + // << "find voice target user: " + // << Param[ argPos - 1 ] + // << " in channel " + // << *theChan + // << endl ; + break; + } + voiceVector.push_back(pair(polarity, targetUser)); + break; + } + case 'b': { + if (argPos >= Param.size()) { + elog << "msg_M> Invalid " + << "format for message: missing " + << "argument for mode 'b'" + << " in channel " << *theChan << endl; + continue; + } + + const char* targetBan = Param[argPos++]; + banVector.push_back(pair(polarity, string(targetBan))); + break; + } + + } // switch() + } // for() + + if (argPos < Param.size()) { + // Last argument is creation time + // Update creation timestamp if older + time_t newCreationTime = static_cast(::atoi(Param[argPos++])); + + // Is the old TS greater than the new TS? + if (theChan->getCreationTime() > newCreationTime) { + // Nope, update the timestamp + theChan->setCreationTime(newCreationTime); + } + } + + if (!modeVector.empty()) { + theServer->OnChannelMode(theChan, theUser, modeVector); + } + if (!opVector.empty()) { + theServer->OnChannelModeO(theChan, theUser, opVector); + } + if (!voiceVector.empty()) { + theServer->OnChannelModeV(theChan, theUser, voiceVector); + } + if (!banVector.empty()) { + theServer->OnChannelModeB(theChan, theUser, banVector); + } + + return true; } // OAD M ripper_ :+owg -bool msg_M::onUserModeChange( const xParameters& Param ) -{ -// Since users aren't allowed to change modes for anyone other than -// themselves, there is no need to lookup the second user argument -// For some reason, when a user changes his/her/its modes, it still -// specifies the second argument to be nickname instaed of numeric. -iClient* theClient = Network->findClient( Param[ 0 ] ) ; -if( NULL == theClient ) - { - elog << "msg_M::OnUserModeChange> Unable to find target " - << "client: " - << Param[ 1 ] - << endl ; - return false ; - } - -if( theClient->getNickName() != Param[ 1 ] ) - { - elog << "msg_M::OnUserModeChange> User trying to change " - << "mode for someone other than itself: " - << *theClient - << ", nickname: " - << Param[ 1 ] - << endl ; - return false ; - } - -// It's important that the mode '+' be default -bool plus = true ; - -for( const char* modePtr = Param[ 2 ] ; *modePtr ; ++modePtr ) - { - switch( *modePtr ) - { - case '+': - plus = true ; - break; - case '-': - plus = false ; - break; - case 'i': - if( plus ) theClient->setModeI() ; - else theClient->removeModeI() ; - break ; - case 'k': - if( plus ) theClient->setModeK() ; - else theClient->removeModeK() ; - break ; - case 'd': - if( plus ) theClient->setModeD() ; - else theClient->removeModeD() ; - break ; - case 'w': - if( plus ) theClient->setModeW() ; - else theClient->removeModeW() ; - break ; - case 'x': - if( plus ) theClient->setModeX() ; - else theClient->removeModeX() ; - break ; - case 'r': - if( plus ) theClient->setModeR() ; - else theClient->removeModeR() ; - break ; - case 'g': - if( plus ) theClient->setModeG() ; - else theClient->removeModeG() ; - break ; - case 'o': - if( plus ) - { - theClient->setModeO() ; - theServer->PostEvent( EVT_OPER, - static_cast< void* >( theClient ) ) ; - } - else - { -// elog << "msg_M::onUserModeChange> " -// << "Caught -o for user: " -// << *theClient -// << endl ; - theClient->removeModeO() ; - } - break ; - case 'n': - case 'I': - case 'h': - case 'X': - case 'R': - case 'f': - // Unsupported but used on networks that - // GNUWorld runs on. - // TODO? - break ; - default: - elog << "msg_M::onUserModeChange> " - << "Unknown mode: " - << *modePtr - << endl ; - break ; - } // close switch - } // close for -return true ; +bool msg_M::onUserModeChange(const xParameters& Param) { + // Since users aren't allowed to change modes for anyone other than + // themselves, there is no need to lookup the second user argument + // For some reason, when a user changes his/her/its modes, it still + // specifies the second argument to be nickname instaed of numeric. + iClient* theClient = Network->findClient(Param[0]); + if (NULL == theClient) { + elog << "msg_M::OnUserModeChange> Unable to find target " + << "client: " << Param[1] << endl; + return false; + } + + if (theClient->getNickName() != Param[1]) { + elog << "msg_M::OnUserModeChange> User trying to change " + << "mode for someone other than itself: " << *theClient << ", nickname: " << Param[1] + << endl; + return false; + } + + // It's important that the mode '+' be default + bool plus = true; + + for (const char* modePtr = Param[2]; *modePtr; ++modePtr) { + switch (*modePtr) { + case '+': + plus = true; + break; + case '-': + plus = false; + break; + case 'i': + if (plus) + theClient->setModeI(); + else + theClient->removeModeI(); + break; + case 'k': + if (plus) + theClient->setModeK(); + else + theClient->removeModeK(); + break; + case 'd': + if (plus) + theClient->setModeD(); + else + theClient->removeModeD(); + break; + case 'w': + if (plus) + theClient->setModeW(); + else + theClient->removeModeW(); + break; + case 'x': + if (plus) + theClient->setModeX(); + else + theClient->removeModeX(); + break; + case 'r': + if (plus) + theClient->setModeR(); + else + theClient->removeModeR(); + break; + case 'g': + if (plus) + theClient->setModeG(); + else + theClient->removeModeG(); + break; + case 'o': + if (plus) { + theClient->setModeO(); + theServer->PostEvent(EVT_OPER, static_cast(theClient)); + } else { + // elog << "msg_M::onUserModeChange> " + // << "Caught -o for user: " + // << *theClient + // << endl ; + theClient->removeModeO(); + } + break; + case 'n': + case 'I': + case 'h': + case 'X': + case 'R': + case 'f': + // Unsupported but used on networks that + // GNUWorld runs on. + // TODO? + break; + default: + elog << "msg_M::onUserModeChange> " + << "Unknown mode: " << *modePtr << endl; + break; + } // close switch + } // close for + return true; } } // namespace gnuworld diff --git a/libircu/msg_M351.cc b/libircu/msg_M351.cc index b406fe63..a844b23a 100644 --- a/libircu/msg_M351.cc +++ b/libircu/msg_M351.cc @@ -20,65 +20,53 @@ * $Id: msg_M351.cc,v 1.4 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include -#include +#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "Network.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "Network.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { -using std::endl ; -using std::string ; +using std::endl; +using std::string; CREATE_HANDLER(msg_M351) -bool msg_M351::Execute( const xParameters& Param ) -{ -if( Param.empty() ) - { - elog << "msg_M351> Invalid number of " - << "arguments" - << endl ; - return false ; - } +bool msg_M351::Execute(const xParameters& Param) { + if (Param.empty()) { + elog << "msg_M351> Invalid number of " + << "arguments" << endl; + return false; + } -xClient* theClient = Network->findLocalClient( Param[ 1 ] ) ; -if( NULL == theClient ) - { - elog << "msg_M351> Unable to find nick: " - << Param[ 1 ] - << endl ; - return false ; - } + xClient* theClient = Network->findLocalClient(Param[1]); + if (NULL == theClient) { + elog << "msg_M351> Unable to find nick: " << Param[1] << endl; + return false; + } -iServer* tmpServer = Network->findServer(Param[0]); -if( NULL == tmpServer ) - { - elog << "msg_M351> Unable to find server: " - << Param[ 0 ] - << endl ; - return false ; - } + iServer* tmpServer = Network->findServer(Param[0]); + if (NULL == tmpServer) { + elog << "msg_M351> Unable to find server: " << Param[0] << endl; + return false; + } -string tMessage = string( tmpServer->getCharYY() ) + " 351 " ; -for( xParameters::size_type i = 2 ; i < Param.size() ; ++i ) - { - tMessage += Param[ i ] ; - if( (i + 1) < Param.size() ) - { - tMessage += " " ; - } - } + string tMessage = string(tmpServer->getCharYY()) + " 351 "; + for (xParameters::size_type i = 2; i < Param.size(); ++i) { + tMessage += Param[i]; + if ((i + 1) < Param.size()) { + tMessage += " "; + } + } -theClient->OnServerMessage( tmpServer, tMessage ); + theClient->OnServerMessage(tmpServer, tMessage); -return true ; + return true; } } // namespace gnuworld diff --git a/libircu/msg_M391.cc b/libircu/msg_M391.cc index 2d5db51d..0066373c 100644 --- a/libircu/msg_M391.cc +++ b/libircu/msg_M391.cc @@ -20,65 +20,53 @@ * $Id: msg_M391.cc,v 1.1 2009/07/25 18:12:34 hidden1 Exp $ */ -#include -#include +#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "Network.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "Network.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { -using std::endl ; -using std::string ; +using std::endl; +using std::string; CREATE_HANDLER(msg_M391) -bool msg_M391::Execute( const xParameters& Param ) -{ -if( Param.empty() ) - { - elog << "msg_M391> Invalid number of " - << "arguments" - << endl ; - return false ; - } +bool msg_M391::Execute(const xParameters& Param) { + if (Param.empty()) { + elog << "msg_M391> Invalid number of " + << "arguments" << endl; + return false; + } -xClient* theClient = Network->findLocalClient( Param[ 1 ] ) ; -if( NULL == theClient ) - { - elog << "msg_M391> Unable to find nick: " - << Param[ 1 ] - << endl ; - return false ; - } + xClient* theClient = Network->findLocalClient(Param[1]); + if (NULL == theClient) { + elog << "msg_M391> Unable to find nick: " << Param[1] << endl; + return false; + } -iServer* tmpServer = Network->findServer(Param[0]); -if( NULL == tmpServer ) - { - elog << "msg_M391> Unable to find server: " - << Param[ 0 ] - << endl ; - return false ; - } + iServer* tmpServer = Network->findServer(Param[0]); + if (NULL == tmpServer) { + elog << "msg_M391> Unable to find server: " << Param[0] << endl; + return false; + } -string tMessage = string( tmpServer->getCharYY() ) + " 391 " ; -for( xParameters::size_type i = 2 ; i < Param.size() ; ++i ) - { - tMessage += Param[ i ] ; - if( (i + 1) < Param.size() ) - { - tMessage += " " ; - } - } + string tMessage = string(tmpServer->getCharYY()) + " 391 "; + for (xParameters::size_type i = 2; i < Param.size(); ++i) { + tMessage += Param[i]; + if ((i + 1) < Param.size()) { + tMessage += " "; + } + } -theClient->OnServerMessage( tmpServer, tMessage ); + theClient->OnServerMessage(tmpServer, tMessage); -return true ; + return true; } } // namespace gnuworld diff --git a/libircu/msg_N.cc b/libircu/msg_N.cc index cd0ba7bb..609fa176 100644 --- a/libircu/msg_N.cc +++ b/libircu/msg_N.cc @@ -20,28 +20,27 @@ * $Id: msg_N.cc,v 1.11 2005/11/30 19:37:34 kewlio Exp $ */ -#include -#include -#include +#include +#include +#include -#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "iClient.h" -#include "events.h" -#include "ip.h" -#include "Network.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" -#include "StringTokenizer.h" +#include "gnuworld_config.h" +#include "server.h" +#include "iClient.h" +#include "events.h" +#include "ip.h" +#include "Network.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" +#include "StringTokenizer.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::endl ; +using std::endl; +using std::string; CREATE_HANDLER(msg_N) @@ -85,208 +84,181 @@ CREATE_HANDLER(msg_N) * AFAAA - numnick * :Generic Client - description */ -bool msg_N::Execute( const xParameters& params ) -{ -if( params.size() < 3 ) - { - // Error - elog << "msg_N> Invalid format: " - << params - << endl ; - return false ; - } +bool msg_N::Execute(const xParameters& params) { + if (params.size() < 3) { + // Error + elog << "msg_N> Invalid format: " << params << endl; + return false; + } -iServer* nickUplink = 0; -if (3 == params.size()) - { - char serverYY[3]; - strncpy(serverYY, params[0], 2); - serverYY[2] = '\0'; - nickUplink = Network->findServer(serverYY); - } -else - nickUplink = Network->findServer(params[0]); + iServer* nickUplink = 0; + if (3 == params.size()) { + char serverYY[3]; + strncpy(serverYY, params[0], 2); + serverYY[2] = '\0'; + nickUplink = Network->findServer(serverYY); + } else + nickUplink = Network->findServer(params[0]); -if (!nickUplink->isBursting()) - { - // Set the server's lag time - time_t nick_ts = atoi(params[2]); - time_t lag = 0; - if (::time(0) > nick_ts) - lag = ::time(0) - nick_ts; - else - lag = 0; - nickUplink->setLag(lag); - } + if (!nickUplink->isBursting()) { + // Set the server's lag time + time_t nick_ts = atoi(params[2]); + time_t lag = 0; + if (::time(0) > nick_ts) + lag = ::time(0) - nick_ts; + else + lag = 0; + nickUplink->setLag(lag); + } -// AUAAB N Gte- 949527071 -if( 3 == params.size() ) - { - // User changing nick -// elog << "msg_N> Rehashing nickname: " -// << params -// << endl ; + // AUAAB N Gte- 949527071 + if (3 == params.size()) { + // User changing nick + // elog << "msg_N> Rehashing nickname: " + // << params + // << endl ; - Network->rehashNick( params[ 0 ], params[ 1 ], atoi( params[ 2 ] ) ) ; - return true ; - } + Network->rehashNick(params[0], params[1], atoi(params[2])); + return true; + } -// Else, it's the network giving us a new client. -if( NULL == nickUplink ) - { - elog << "msg_N> Unable to find server: " - << params[ 0 ] - << endl ; - return false ; - } + // Else, it's the network giving us a new client. + if (NULL == nickUplink) { + elog << "msg_N> Unable to find server: " << params[0] << endl; + return false; + } -// Default arguments, assuming -// no modes set. -const char* modes = "+" ; + // Default arguments, assuming + // no modes set. + const char* modes = "+"; -/* - * 1) - * 2) - * 3) - * 4) - * 5) - * 6) [<+modes>] - * 7+) [] - * -3 - * -2 - * -1 + * 2) + * 3) + * 4) + * 5) + * 6) [<+modes>] + * 7+) [] + * -3 + * -2 + * -1 > account_id) ) - { - elog << "msg_N> Invalid account id: " - << st[ 1 ] - << endl ; - // non-fatal error - } - } // if( 2 <= st.size() ) - if( 3 == st.size() ) - { - // flags present - std::stringstream ss ; - ss << st[ 2 ] ; - if( !(ss >> account_flags) ) - { - elog << "msg_N> Invalid account flags: " - << st[ 2 ] - << endl ; - // non-fatal error - } - } // if( 3 == st.size() ) - } // if( !account.empty() ) + if (!account.empty()) { + StringTokenizer st(account, ':'); + account = st[0]; + if (2 <= st.size()) { + // id present + std::stringstream ss; + ss << st[1]; + if (!(ss >> account_id)) { + elog << "msg_N> Invalid account id: " << st[1] << endl; + // non-fatal error + } + } // if( 2 <= st.size() ) + if (3 == st.size()) { + // flags present + std::stringstream ss; + ss << st[2]; + if (!(ss >> account_flags)) { + elog << "msg_N> Invalid account flags: " << st[2] << endl; + // non-fatal error + } + } // if( 3 == st.size() ) + } // if( !account.empty() ) -/* Set the fingerprint to empty if it is empty. */ -if( tlsFingerprint == "_" ) - tlsFingerprint.clear() ; + /* Set the fingerprint to empty if it is empty. */ + if (tlsFingerprint == "_") + tlsFingerprint.clear(); -/* - * -3 - * -2 - * -1 + * -2 + * -1 getIntYY(), - yyxxx, // numeric - params[ 1 ], // nickname - params[ 4 ], // username - host, // base64 encoded ip - params[ 5 ], // insecureHost - params[ 5 ], // realInsecureHost - modes, // modes (default: +) - account, // account - account_id, // account id - account_flags, // account flags - tlsFingerprint, // TLS fingerprint - sethost, // asuka sethost - fakehost, // srvx fakehost - description, // real name / infoline - atoi( params[ 3 ] ) // nick timestamp - ) ; -assert( newClient != 0 ) ; + iClient* newClient = new (std::nothrow) iClient(nickUplink->getIntYY(), + yyxxx, // numeric + params[1], // nickname + params[4], // username + host, // base64 encoded ip + params[5], // insecureHost + params[5], // realInsecureHost + modes, // modes (default: +) + account, // account + account_id, // account id + account_flags, // account flags + tlsFingerprint, // TLS fingerprint + sethost, // asuka sethost + fakehost, // srvx fakehost + description, // real name / infoline + atoi(params[3]) // nick timestamp + ); + assert(newClient != 0); -if( !Network->addClient( newClient ) ) - { - elog << "msg_N> Failed to add client: " - << *newClient - << ", user already exists? " - << (Network->findClient( newClient->getCharYYXXX() ) ? - "yes" : "no") - << endl ; - delete newClient ; newClient = 0 ; - return false ; - } + if (!Network->addClient(newClient)) { + elog << "msg_N> Failed to add client: " << *newClient << ", user already exists? " + << (Network->findClient(newClient->getCharYYXXX()) ? "yes" : "no") << endl; + delete newClient; + newClient = 0; + return false; + } -//elog << "msg_N> Added user: " -// << *newClient -// << endl ; + // elog << "msg_N> Added user: " + // << *newClient + // << endl ; -theServer->PostEvent( EVT_NICK, static_cast< void* >( newClient ) ) ; + theServer->PostEvent(EVT_NICK, static_cast(newClient)); -return true ; + return true; } } // namespace gnuworld diff --git a/libircu/msg_NOOP.cc b/libircu/msg_NOOP.cc index 8e9740df..e61b0cf1 100644 --- a/libircu/msg_NOOP.cc +++ b/libircu/msg_NOOP.cc @@ -20,19 +20,15 @@ * $Id: msg_NOOP.cc,v 1.5 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include "gnuworld_config.h" -#include "server.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { CREATE_HANDLER(msg_NOOP) -bool msg_NOOP::Execute( const xParameters& ) -{ -return true ; -} +bool msg_NOOP::Execute(const xParameters&) { return true; } } // namespace gnuworld diff --git a/libircu/msg_O.cc b/libircu/msg_O.cc index e488d2a2..754c5a01 100644 --- a/libircu/msg_O.cc +++ b/libircu/msg_O.cc @@ -20,78 +20,59 @@ * $Id: msg_O.cc,v 1.10 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include -#include +#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "Network.h" -#include "iClient.h" -#include "client.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" -#include "StringTokenizer.h" +#include "gnuworld_config.h" +#include "server.h" +#include "Network.h" +#include "iClient.h" +#include "client.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" +#include "StringTokenizer.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::endl ; +using std::endl; +using std::string; CREATE_HANDLER(msg_O) -void channelNotice( iClient* srcClient, - Channel* theChan, - const string& message ) -{ -for( Channel::userIterator userItr = theChan->userList_begin() ; - userItr != theChan->userList_end() ; ++userItr ) - { - unsigned int intYYXXX = userItr->second->getIntYYXXX() ; - - xClient* servicesClient = Network->findLocalClient( intYYXXX ) ; - if( servicesClient != 0 - && servicesClient->isOnChannel( theChan ) - && !servicesClient->getMode( iClient::MODE_DEAF ) ) - { - // xClient, invoke OnChannelNotice() - servicesClient->OnChannelNotice( srcClient, - theChan, - message ) ; - continue ; - } - - // Not an xClient, check if it's a fake client - iClient* targetClient = Network->findFakeClient( - userItr->second->getClient() ) ; - if( 0 == targetClient ) - { - // Nope - continue ; - } - - // Fake client - // Get its owner, use a different variable name here - // just for readability. - xClient* ownerClient = Network->findFakeClientOwner( - targetClient ) ; - if( 0 == ownerClient ) - { - elog << "msg_O::channelNotice> Unable to " - << "find owner of client: " - << *targetClient - << ", in channel: " - << *theChan - << endl ; - continue ; - } - - ownerClient->OnFakeChannelNotice( srcClient, - targetClient, - theChan, - message ) ; - } // for() +void channelNotice(iClient* srcClient, Channel* theChan, const string& message) { + for (Channel::userIterator userItr = theChan->userList_begin(); + userItr != theChan->userList_end(); ++userItr) { + unsigned int intYYXXX = userItr->second->getIntYYXXX(); + + xClient* servicesClient = Network->findLocalClient(intYYXXX); + if (servicesClient != 0 && servicesClient->isOnChannel(theChan) && + !servicesClient->getMode(iClient::MODE_DEAF)) { + // xClient, invoke OnChannelNotice() + servicesClient->OnChannelNotice(srcClient, theChan, message); + continue; + } + + // Not an xClient, check if it's a fake client + iClient* targetClient = Network->findFakeClient(userItr->second->getClient()); + if (0 == targetClient) { + // Nope + continue; + } + + // Fake client + // Get its owner, use a different variable name here + // just for readability. + xClient* ownerClient = Network->findFakeClientOwner(targetClient); + if (0 == ownerClient) { + elog << "msg_O::channelNotice> Unable to " + << "find owner of client: " << *targetClient << ", in channel: " << *theChan + << endl; + continue; + } + + ownerClient->OnFakeChannelNotice(srcClient, targetClient, theChan, message); + } // for() } /** @@ -106,173 +87,124 @@ for( Channel::userIterator userItr = theChan->userList_begin() ; * QAE O AAPAA :translate xaa * abcDE O #chanName :testing 12 3 */ -bool msg_O::Execute( const xParameters& Param ) -{ -if( Param.size() < 3 ) - { - elog << "msg_O> Invalid number of arguments" - << endl ; - return false ; - } - -Channel* theChan = 0 ; -if( '#' == Param[ 1 ][ 0 ] ) - { - // Channel notice - theChan = Network->findChannel( Param[ 1 ] ) ; - if( 0 == theChan ) - { - elog << "msg_O> Unable to locate channel: " - << Param[ 1 ] - << endl ; - return false ; - } - } - -if( '+' == Param[ 1 ][ 0 ] ) - { - // Chances of receiving a local channel are slim to - // none anyway - // *shrug* - return true ; - } - -iClient* srcClient = Network->findClient( Param[ 0 ] ) ; -if( 0 == srcClient ) - { - elog << "msg_O> Unable to find source client: " - << Param[ 0 ] - << endl ; - return false ; - } - -// abcDE O FGhij :hi, how are you? -bool secure = false ; -xClient* targetClient = 0 ; -iClient* fakeTarget = 0 ; - -if( (0 == theChan) && (strchr( Param[ 1 ], '@' ) != 0) ) - { - // nick@host.name specified, secure message - secure = true ; - - StringTokenizer st( Param[ 1 ], '@' ) ; - targetClient = Network->findLocalNick( st[ 0 ] ) ; - if( 0 == targetClient ) - { - fakeTarget = Network->findFakeNick( st[ 0 ] ) ; - if( 0 == fakeTarget ) - { - elog << "msg_O> Received notice for unknown " - << "client: " - << Param[ 1 ] - << ", nick: " - << st[ 0 ] - << endl ; - return true ; - } - } - // Found the target xClient - } -else if( (0 == theChan) && - (Param[ 1 ][ 0 ] == theServer->getCharYY()[ 0 ]) && - (Param[ 1 ][ 1 ] == theServer->getCharYY()[ 1 ]) ) - { -// elog << "msg_O> Notice for local client: " -// << Param[ 1 ] -// << endl ; - - // Normal notice to an xClient - targetClient = Network->findLocalClient( Param[ 1 ] ) ; - if( 0 == targetClient ) - { - // Not an xClient, is it a fake client? - fakeTarget = Network->findFakeClient( Param[ 1 ] ) ; - if( 0 == fakeTarget ) - { - elog << "msg_O> Unable to find local client: " - << Param[ 1 ] - << endl ; - return true ; - } - } - } -else if( 0 == theChan ) - { - // TODO - elog << "msg_O> Unknown target: " - << Param[ 1 ] - << endl ; - - // May be a message to a juped client on a juped server, - // ignore it. - return true ; - } -else - { - // theChan != 0 - // It's a channel message, this is not a problem for - // the case in which there is an xClient in the channel. - // However, it becomes a bit more complicated if there are - // one or more fake clients (possibly in addition to the - // xClient) in the channel. - } - -xClient* ownerClient = 0 ; -if( fakeTarget != 0 ) - { - // The target is a fake client, let's find its owner - ownerClient = Network->findFakeClientOwner( fakeTarget ) ; - if( 0 == ownerClient ) - { - elog << "msg_O> Fake client without owner: " - << *fakeTarget - << endl ; - return true ; - } - } - -string message( Param[ 2 ] ) ; - -if( theChan != 0 ) - { -// elog << "msg_O> Channel message from: " -// << *srcClient -// << ", message: " -// << message -// << ", on channel: " -// << *theChan -// << endl ; - - channelNotice( srcClient, - theChan, - message ) ; - } -else - { -// elog << "msg_O> Private message from: " -// << *srcClient -// << ", message: " -// << message -// << endl ; - - if( fakeTarget != 0 ) - { - ownerClient->OnFakePrivateNotice( - srcClient, - fakeTarget, - message, - secure ) ; - } - else - { - targetClient->OnPrivateNotice( srcClient, - message, - secure ) ; - } // else() - } // else( theChan != 0 ) - -return true ; +bool msg_O::Execute(const xParameters& Param) { + if (Param.size() < 3) { + elog << "msg_O> Invalid number of arguments" << endl; + return false; + } + + Channel* theChan = 0; + if ('#' == Param[1][0]) { + // Channel notice + theChan = Network->findChannel(Param[1]); + if (0 == theChan) { + elog << "msg_O> Unable to locate channel: " << Param[1] << endl; + return false; + } + } + + if ('+' == Param[1][0]) { + // Chances of receiving a local channel are slim to + // none anyway + // *shrug* + return true; + } + + iClient* srcClient = Network->findClient(Param[0]); + if (0 == srcClient) { + elog << "msg_O> Unable to find source client: " << Param[0] << endl; + return false; + } + + // abcDE O FGhij :hi, how are you? + bool secure = false; + xClient* targetClient = 0; + iClient* fakeTarget = 0; + + if ((0 == theChan) && (strchr(Param[1], '@') != 0)) { + // nick@host.name specified, secure message + secure = true; + + StringTokenizer st(Param[1], '@'); + targetClient = Network->findLocalNick(st[0]); + if (0 == targetClient) { + fakeTarget = Network->findFakeNick(st[0]); + if (0 == fakeTarget) { + elog << "msg_O> Received notice for unknown " + << "client: " << Param[1] << ", nick: " << st[0] << endl; + return true; + } + } + // Found the target xClient + } else if ((0 == theChan) && (Param[1][0] == theServer->getCharYY()[0]) && + (Param[1][1] == theServer->getCharYY()[1])) { + // elog << "msg_O> Notice for local client: " + // << Param[ 1 ] + // << endl ; + + // Normal notice to an xClient + targetClient = Network->findLocalClient(Param[1]); + if (0 == targetClient) { + // Not an xClient, is it a fake client? + fakeTarget = Network->findFakeClient(Param[1]); + if (0 == fakeTarget) { + elog << "msg_O> Unable to find local client: " << Param[1] << endl; + return true; + } + } + } else if (0 == theChan) { + // TODO + elog << "msg_O> Unknown target: " << Param[1] << endl; + + // May be a message to a juped client on a juped server, + // ignore it. + return true; + } else { + // theChan != 0 + // It's a channel message, this is not a problem for + // the case in which there is an xClient in the channel. + // However, it becomes a bit more complicated if there are + // one or more fake clients (possibly in addition to the + // xClient) in the channel. + } + + xClient* ownerClient = 0; + if (fakeTarget != 0) { + // The target is a fake client, let's find its owner + ownerClient = Network->findFakeClientOwner(fakeTarget); + if (0 == ownerClient) { + elog << "msg_O> Fake client without owner: " << *fakeTarget << endl; + return true; + } + } + + string message(Param[2]); + + if (theChan != 0) { + // elog << "msg_O> Channel message from: " + // << *srcClient + // << ", message: " + // << message + // << ", on channel: " + // << *theChan + // << endl ; + + channelNotice(srcClient, theChan, message); + } else { + // elog << "msg_O> Private message from: " + // << *srcClient + // << ", message: " + // << message + // << endl ; + + if (fakeTarget != 0) { + ownerClient->OnFakePrivateNotice(srcClient, fakeTarget, message, secure); + } else { + targetClient->OnPrivateNotice(srcClient, message, secure); + } // else() + } // else( theChan != 0 ) + + return true; } // msg_O } // namespace gnuworld diff --git a/libircu/msg_P.cc b/libircu/msg_P.cc index f9f26dc3..55cfa842 100644 --- a/libircu/msg_P.cc +++ b/libircu/msg_P.cc @@ -20,134 +20,95 @@ * $Id: msg_P.cc,v 1.15 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include -#include +#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "Network.h" -#include "iClient.h" -#include "client.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" -#include "StringTokenizer.h" +#include "gnuworld_config.h" +#include "server.h" +#include "Network.h" +#include "iClient.h" +#include "client.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" +#include "StringTokenizer.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::endl ; +using std::endl; +using std::string; CREATE_HANDLER(msg_P) -void channelCTCP( iClient* srcClient, - Channel* theChan, - const string& command, - const string& message ) -{ -for( Channel::userIterator userItr = theChan->userList_begin() ; - userItr != theChan->userList_end() ; ++userItr ) - { - unsigned int intYYXXX = userItr->second->getIntYYXXX() ; - - xClient* servicesClient = Network->findLocalClient( intYYXXX ) ; - if( servicesClient != 0 - && servicesClient->isOnChannel( theChan ) - && !servicesClient->getMode( iClient::MODE_DEAF ) ) - { - // xClient, invoke OnChannelMessage() - servicesClient->OnChannelCTCP( srcClient, - theChan, - command, - message ) ; - continue ; - } - - // Not an xClient, check if it's a fake client - iClient* targetClient = Network->findFakeClient( - userItr->second->getClient() ) ; - if( 0 == targetClient ) - { - // Nope - continue ; - } - - // Fake client - // Get its owner, use a different variable name here - // just for readability. - xClient* ownerClient = Network->findFakeClientOwner( - targetClient ) ; - if( 0 == ownerClient ) - { - elog << "msg_P::channelMessage> Unable to " - << "find owner of client: " - << *targetClient - << ", in channel: " - << *theChan - << endl ; - continue ; - } - - ownerClient->OnFakeChannelCTCP( srcClient, - targetClient, - theChan, - command, - message ) ; - } // for() +void channelCTCP(iClient* srcClient, Channel* theChan, const string& command, + const string& message) { + for (Channel::userIterator userItr = theChan->userList_begin(); + userItr != theChan->userList_end(); ++userItr) { + unsigned int intYYXXX = userItr->second->getIntYYXXX(); + + xClient* servicesClient = Network->findLocalClient(intYYXXX); + if (servicesClient != 0 && servicesClient->isOnChannel(theChan) && + !servicesClient->getMode(iClient::MODE_DEAF)) { + // xClient, invoke OnChannelMessage() + servicesClient->OnChannelCTCP(srcClient, theChan, command, message); + continue; + } + + // Not an xClient, check if it's a fake client + iClient* targetClient = Network->findFakeClient(userItr->second->getClient()); + if (0 == targetClient) { + // Nope + continue; + } + + // Fake client + // Get its owner, use a different variable name here + // just for readability. + xClient* ownerClient = Network->findFakeClientOwner(targetClient); + if (0 == ownerClient) { + elog << "msg_P::channelMessage> Unable to " + << "find owner of client: " << *targetClient << ", in channel: " << *theChan + << endl; + continue; + } + + ownerClient->OnFakeChannelCTCP(srcClient, targetClient, theChan, command, message); + } // for() } -void channelMessage( iClient* srcClient, - Channel* theChan, - const string& message ) -{ -for( Channel::userIterator userItr = theChan->userList_begin() ; - userItr != theChan->userList_end() ; ++userItr ) - { - unsigned int intYYXXX = userItr->second->getIntYYXXX() ; - - xClient* servicesClient = Network->findLocalClient( intYYXXX ) ; - if( servicesClient != 0 - && servicesClient->isOnChannel( theChan ) - && !servicesClient->getMode( iClient::MODE_DEAF ) ) - { - // xClient, invoke OnChannelMessage() - servicesClient->OnChannelMessage( srcClient, - theChan, - message ) ; - continue ; - } - - // Not an xClient, check if it's a fake client - iClient* targetClient = Network->findFakeClient( - userItr->second->getClient() ) ; - if( 0 == targetClient ) - { - // Nope - continue ; - } - - // Fake client - // Get its owner, use a different variable name here - // just for readability. - xClient* ownerClient = Network->findFakeClientOwner( - targetClient ) ; - if( 0 == ownerClient ) - { - elog << "msg_P::channelMessage> Unable to " - << "find owner of client: " - << *targetClient - << ", in channel: " - << *theChan - << endl ; - continue ; - } - - ownerClient->OnFakeChannelMessage( srcClient, - targetClient, - theChan, - message ) ; - } // for() +void channelMessage(iClient* srcClient, Channel* theChan, const string& message) { + for (Channel::userIterator userItr = theChan->userList_begin(); + userItr != theChan->userList_end(); ++userItr) { + unsigned int intYYXXX = userItr->second->getIntYYXXX(); + + xClient* servicesClient = Network->findLocalClient(intYYXXX); + if (servicesClient != 0 && servicesClient->isOnChannel(theChan) && + !servicesClient->getMode(iClient::MODE_DEAF)) { + // xClient, invoke OnChannelMessage() + servicesClient->OnChannelMessage(srcClient, theChan, message); + continue; + } + + // Not an xClient, check if it's a fake client + iClient* targetClient = Network->findFakeClient(userItr->second->getClient()); + if (0 == targetClient) { + // Nope + continue; + } + + // Fake client + // Get its owner, use a different variable name here + // just for readability. + xClient* ownerClient = Network->findFakeClientOwner(targetClient); + if (0 == ownerClient) { + elog << "msg_P::channelMessage> Unable to " + << "find owner of client: " << *targetClient << ", in channel: " << *theChan + << endl; + continue; + } + + ownerClient->OnFakeChannelMessage(srcClient, targetClient, theChan, message); + } // for() } /** @@ -162,276 +123,201 @@ for( Channel::userIterator userItr = theChan->userList_begin() ; * QAE P AAPAA :translate xaa * abcDE P #chanName :testing 12 3 */ -bool msg_P::Execute( const xParameters& Param ) -{ -if( Param.size() < 3 ) - { - elog << "msg_P> Invalid number of arguments" - << endl ; - return false ; - } - -Channel* theChan = 0 ; -if( '#' == Param[ 1 ][ 0 ] ) - { - // Channel message - theChan = Network->findChannel( Param[ 1 ] ) ; - if( 0 == theChan ) - { - elog << "msg_P> Unable to locate channel: " - << Param[ 1 ] - << endl ; - return false ; - } - } - -if( '+' == Param[ 1 ][ 0 ] ) - { - // Chances of receiving a local channel are slim to - // none anyway - // *shrug* - return true ; - } - -iClient* srcClient = Network->findClient( Param[ 0 ] ) ; -if( 0 == srcClient ) - { - elog << "msg_P> Unable to find source client: " - << Param[ 0 ] - << endl ; - return false ; - } - -// abcDE P FGhij :hi, how are you? -bool secure = false ; -xClient* targetClient = 0 ; -iClient* fakeTarget = 0 ; - -if( (0 == theChan) && (strchr( Param[ 1 ], '@' ) != 0) ) - { - // nick@host.name specified, secure message - secure = true ; - - StringTokenizer st( Param[ 1 ], '@' ) ; - targetClient = Network->findLocalNick( st[ 0 ] ) ; - if( 0 == targetClient ) - { - fakeTarget = Network->findFakeNick( st[ 0 ] ) ; - if( 0 == fakeTarget ) - { -// elog << "msg_P> Looking for control nick: " -// << st[ 0 ] -// << endl ; - bool controlNick = - theServer->findControlNick( st[ 0 ] ) ; - if( controlNick ) - { - theServer->ControlCommand( srcClient, - Param[ 2 ] ) ; - // All done - return true ; - } - - // !controlNick - elog << "msg_P> Received message for " - << "unknown client: " - << Param[ 1 ] - << ", nick: " - << st[ 0 ] - << endl ; - return true ; - } - } - // Found the target xClient - } -else if( (0 == theChan) && - (Param[ 1 ][ 0 ] == theServer->getCharYY()[ 0 ]) && - (Param[ 1 ][ 1 ] == theServer->getCharYY()[ 1 ]) ) - { -// elog << "msg_P> Message for local client: " -// << Param[ 1 ] -// << endl ; - - // Normal message to an xClient - targetClient = Network->findLocalClient( Param[ 1 ] ) ; - if( 0 == targetClient ) - { - // Not an xClient, is it a fake client? - fakeTarget = Network->findFakeClient( Param[ 1 ] ) ; - if( 0 == fakeTarget ) - { - elog << "msg_P> Unable to find local client: " - << Param[ 1 ] - << endl ; - return true ; - } - } - } -else if( 0 == theChan ) - { - // TODO - elog << "msg_P> Unknown target: " - << Param[ 1 ] - << endl ; - - // May be a message to a juped client on a juped server, - // ignore it. - return true ; - } -else - { - // theChan != 0 - // It's a channel message, this is not a problem for - // the case in which there is an xClient in the channel. - // However, it becomes a bit more complicated if there are - // one or more fake clients (possibly in addition to the - // xClient) in the channel. - } - -xClient* ownerClient = 0 ; -if( fakeTarget != 0 ) - { - // The target is a fake client, let's find its owner - ownerClient = Network->findFakeClientOwner( fakeTarget ) ; - if( 0 == ownerClient ) - { - elog << "msg_P> Fake client without owner: " - << *fakeTarget - << endl ; - return true ; - } - } - -bool CTCP = (Param[ 2 ][ 0 ] == 1) ? true : false ; - -// Prepare a message string to pass to the client which is -// void of any CTCP control chars -// CTCP messages begin and end with '\1' -// In the case of CTCP, it is of the form: -// abcDE P EFghi :\1ctcp_command\1 message -// abcDE P EFghi :\1PING 123456789\1 -// Note that Param[ 2 ] is \1PING 123456789\1 message - -string message( Param[ 2 ] ) ; -string command ; - -if( CTCP ) - { - // CTCP, remove the control chars from the command. - // Tokenize by the CTCP delimiter, \1 - StringTokenizer st( Param[ 2 ], '\1' ) ; - - // Make sure there is at least one token - if( st.empty() ) - { - elog << "msg_P> Found empty tokenizer for CTCP, from: " - << Param[ 2 ] - << endl ; - return false ; - } - - // The CTCP command is now everything that was surrounded - // by the two \1's, or the first token of st, st[ 0 ] - command = st[ 0 ] ; - - // If there was an optional message after the CTCP command, - // st.size() will be greater than 1. - if( st.size() > 1 ) - { - message = st.assemble( 2 ) ; - } - else - { - // No message, clear it - message = "" ; - } - } - -if( CTCP ) - { - if( theChan != 0 ) - { -// elog << "msg_P> Found channel ctcp, command from: " -// << *srcClient -// << ", command: " -// << command -// << ", message: " -// << message -// << ", on channel: " -// << *theChan -// << endl ; - - channelCTCP( srcClient, theChan, command, message ) ; - } - else - { -// elog << "msg_P> Found privmsg CTCP, command from: " -// << *srcClient -// << ", command: " -// << command -// << ", message: " -// << message -// << endl ; - - if( fakeTarget != 0 ) - { - ownerClient->OnFakeCTCP( srcClient, - fakeTarget, - command, - message, - secure ) ; - } - else - { - targetClient->OnCTCP( srcClient, - command, - message, - secure ) ; - } - } - } -else - { - if( theChan != 0 ) - { -// elog << "msg_P> Channel message from: " -// << *srcClient -// << ", message: " -// << message -// << ", on channel: " -// << *theChan -// << endl ; - - channelMessage( srcClient, - theChan, - message ) ; - } - else - { -// elog << "msg_P> Private message from: " -// << *srcClient -// << ", message: " -// << message -// << endl ; - - if( fakeTarget != 0 ) - { - ownerClient->OnFakePrivateMessage( - srcClient, - fakeTarget, - message, - secure ) ; - } - else - { - targetClient->OnPrivateMessage( srcClient, - message, - secure ) ; - } // else() - } // else( theChan != 0 ) - } // else( CTCP ) - -return true ; +bool msg_P::Execute(const xParameters& Param) { + if (Param.size() < 3) { + elog << "msg_P> Invalid number of arguments" << endl; + return false; + } + + Channel* theChan = 0; + if ('#' == Param[1][0]) { + // Channel message + theChan = Network->findChannel(Param[1]); + if (0 == theChan) { + elog << "msg_P> Unable to locate channel: " << Param[1] << endl; + return false; + } + } + + if ('+' == Param[1][0]) { + // Chances of receiving a local channel are slim to + // none anyway + // *shrug* + return true; + } + + iClient* srcClient = Network->findClient(Param[0]); + if (0 == srcClient) { + elog << "msg_P> Unable to find source client: " << Param[0] << endl; + return false; + } + + // abcDE P FGhij :hi, how are you? + bool secure = false; + xClient* targetClient = 0; + iClient* fakeTarget = 0; + + if ((0 == theChan) && (strchr(Param[1], '@') != 0)) { + // nick@host.name specified, secure message + secure = true; + + StringTokenizer st(Param[1], '@'); + targetClient = Network->findLocalNick(st[0]); + if (0 == targetClient) { + fakeTarget = Network->findFakeNick(st[0]); + if (0 == fakeTarget) { + // elog << "msg_P> Looking for control nick: " + // << st[ 0 ] + // << endl ; + bool controlNick = theServer->findControlNick(st[0]); + if (controlNick) { + theServer->ControlCommand(srcClient, Param[2]); + // All done + return true; + } + + // !controlNick + elog << "msg_P> Received message for " + << "unknown client: " << Param[1] << ", nick: " << st[0] << endl; + return true; + } + } + // Found the target xClient + } else if ((0 == theChan) && (Param[1][0] == theServer->getCharYY()[0]) && + (Param[1][1] == theServer->getCharYY()[1])) { + // elog << "msg_P> Message for local client: " + // << Param[ 1 ] + // << endl ; + + // Normal message to an xClient + targetClient = Network->findLocalClient(Param[1]); + if (0 == targetClient) { + // Not an xClient, is it a fake client? + fakeTarget = Network->findFakeClient(Param[1]); + if (0 == fakeTarget) { + elog << "msg_P> Unable to find local client: " << Param[1] << endl; + return true; + } + } + } else if (0 == theChan) { + // TODO + elog << "msg_P> Unknown target: " << Param[1] << endl; + + // May be a message to a juped client on a juped server, + // ignore it. + return true; + } else { + // theChan != 0 + // It's a channel message, this is not a problem for + // the case in which there is an xClient in the channel. + // However, it becomes a bit more complicated if there are + // one or more fake clients (possibly in addition to the + // xClient) in the channel. + } + + xClient* ownerClient = 0; + if (fakeTarget != 0) { + // The target is a fake client, let's find its owner + ownerClient = Network->findFakeClientOwner(fakeTarget); + if (0 == ownerClient) { + elog << "msg_P> Fake client without owner: " << *fakeTarget << endl; + return true; + } + } + + bool CTCP = (Param[2][0] == 1) ? true : false; + + // Prepare a message string to pass to the client which is + // void of any CTCP control chars + // CTCP messages begin and end with '\1' + // In the case of CTCP, it is of the form: + // abcDE P EFghi :\1ctcp_command\1 message + // abcDE P EFghi :\1PING 123456789\1 + // Note that Param[ 2 ] is \1PING 123456789\1 message + + string message(Param[2]); + string command; + + if (CTCP) { + // CTCP, remove the control chars from the command. + // Tokenize by the CTCP delimiter, \1 + StringTokenizer st(Param[2], '\1'); + + // Make sure there is at least one token + if (st.empty()) { + elog << "msg_P> Found empty tokenizer for CTCP, from: " << Param[2] << endl; + return false; + } + + // The CTCP command is now everything that was surrounded + // by the two \1's, or the first token of st, st[ 0 ] + command = st[0]; + + // If there was an optional message after the CTCP command, + // st.size() will be greater than 1. + if (st.size() > 1) { + message = st.assemble(2); + } else { + // No message, clear it + message = ""; + } + } + + if (CTCP) { + if (theChan != 0) { + // elog << "msg_P> Found channel ctcp, command from: " + // << *srcClient + // << ", command: " + // << command + // << ", message: " + // << message + // << ", on channel: " + // << *theChan + // << endl ; + + channelCTCP(srcClient, theChan, command, message); + } else { + // elog << "msg_P> Found privmsg CTCP, command from: " + // << *srcClient + // << ", command: " + // << command + // << ", message: " + // << message + // << endl ; + + if (fakeTarget != 0) { + ownerClient->OnFakeCTCP(srcClient, fakeTarget, command, message, secure); + } else { + targetClient->OnCTCP(srcClient, command, message, secure); + } + } + } else { + if (theChan != 0) { + // elog << "msg_P> Channel message from: " + // << *srcClient + // << ", message: " + // << message + // << ", on channel: " + // << *theChan + // << endl ; + + channelMessage(srcClient, theChan, message); + } else { + // elog << "msg_P> Private message from: " + // << *srcClient + // << ", message: " + // << message + // << endl ; + + if (fakeTarget != 0) { + ownerClient->OnFakePrivateMessage(srcClient, fakeTarget, message, secure); + } else { + targetClient->OnPrivateMessage(srcClient, message, secure); + } // else() + } // else( theChan != 0 ) + } // else( CTCP ) + + return true; } // msg_P } // namespace gnuworld diff --git a/libircu/msg_PA.cc b/libircu/msg_PA.cc index d5c231a9..0c9ecda4 100644 --- a/libircu/msg_PA.cc +++ b/libircu/msg_PA.cc @@ -20,21 +20,19 @@ * $Id: msg_PA.cc,v 1.4 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include "server.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "server.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { CREATE_HANDLER(msg_PA) -bool msg_PA::Execute( const xParameters& ) -{ -theServer->setBursting( true ) ; -theServer->setUseHoldBuffer( true ) ; +bool msg_PA::Execute(const xParameters&) { + theServer->setBursting(true); + theServer->setUseHoldBuffer(true); -return true ; + return true; } } // namespace gnuworld diff --git a/libircu/msg_Q.cc b/libircu/msg_Q.cc index 6264c6c4..5651872d 100644 --- a/libircu/msg_Q.cc +++ b/libircu/msg_Q.cc @@ -20,20 +20,19 @@ * $Id: msg_Q.cc,v 1.4 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include +#include -#include "server.h" -#include "events.h" -#include "Network.h" -#include "iClient.h" -#include "Network.h" -#include "ELog.h" -#include "ServerCommandHandler.h" +#include "server.h" +#include "events.h" +#include "Network.h" +#include "iClient.h" +#include "Network.h" +#include "ELog.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { -using std::endl ; +using std::endl; CREATE_HANDLER(msg_Q) @@ -41,32 +40,26 @@ CREATE_HANDLER(msg_Q) * A client has quit. * QAE Q :Signed off */ -bool msg_Q::Execute( const xParameters& Param ) -{ +bool msg_Q::Execute(const xParameters& Param) { -if( Param.size() < 1 ) - { - elog << "msg_Q> Invalid number of parameters" - << endl ; - return false ; - } + if (Param.size() < 1) { + elog << "msg_Q> Invalid number of parameters" << endl; + return false; + } -// xNetwork::removeClient will remove user<->channel associations -iClient* theClient = Network->removeClient( Param[ 0 ] ) ; -if( NULL == theClient ) - { - elog << "msg_Q> Unable to find client: " - << Param[ 0 ] - << endl ; - return false ; - } + // xNetwork::removeClient will remove user<->channel associations + iClient* theClient = Network->removeClient(Param[0]); + if (NULL == theClient) { + elog << "msg_Q> Unable to find client: " << Param[0] << endl; + return false; + } -theServer->PostEvent( EVT_QUIT, static_cast< void* >( theClient ) ) ; + theServer->PostEvent(EVT_QUIT, static_cast(theClient)); -// xNetwork::removeClient() will remove channel->user associations. -delete theClient ; + // xNetwork::removeClient() will remove channel->user associations. + delete theClient; -return true ; + return true; } } // namespace gnuworld diff --git a/libircu/msg_R.cc b/libircu/msg_R.cc index 67442d04..708b9f4e 100644 --- a/libircu/msg_R.cc +++ b/libircu/msg_R.cc @@ -20,21 +20,17 @@ * $Id: msg_R.cc,v 1.4 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include "server.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "server.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { CREATE_HANDLER(msg_R) // STATS // kAB R O :AI // -bool msg_R::Execute( const xParameters& ) -{ -return false ; -} +bool msg_R::Execute(const xParameters&) { return false; } } // namespace gnuworld diff --git a/libircu/msg_RI.cc b/libircu/msg_RI.cc index f02d42bb..d9f01c34 100644 --- a/libircu/msg_RI.cc +++ b/libircu/msg_RI.cc @@ -18,26 +18,25 @@ * USA. */ -#include -#include +#include +#include -#include -#include +#include +#include -#include "server.h" -#include "iServer.h" -#include "iClient.h" -#include "events.h" -#include "Network.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "server.h" +#include "iServer.h" +#include "iClient.h" +#include "events.h" +#include "Network.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { -using std::endl ; -using std::stringstream ; +using std::endl; +using std::stringstream; CREATE_HANDLER(msg_RI) @@ -55,55 +54,40 @@ CREATE_HANDLER(msg_RI) * params: AB Az ABAAA 1085753348 87482 */ -bool msg_RI::Execute( const xParameters& params ) -{ +bool msg_RI::Execute(const xParameters& params) { -//return true; + // return true; -if( params.size() < 5 ) { - elog << "msg_RI> Invalid number of arguments." - << endl; - return false; -} + if (params.size() < 5) { + elog << "msg_RI> Invalid number of arguments." << endl; + return false; + } -if( params[1] != theServer->getCharYY() ) { - elog << "msg_RI> Got RPING destined for someone else." - << endl; - return false; -} + if (params[1] != theServer->getCharYY()) { + elog << "msg_RI> Got RPING destined for someone else." << endl; + return false; + } -iServer *remoteServer = Network->findServer(params[0]); -iClient *remoteClient = Network->findClient(params[2]); + iServer* remoteServer = Network->findServer(params[0]); + iClient* remoteClient = Network->findClient(params[2]); -if( !remoteServer || !remoteClient ) { - elog << "msg_RI> Got RPING from non-existant client/server." - << endl; - return false; -} + if (!remoteServer || !remoteClient) { + elog << "msg_RI> Got RPING from non-existant client/server." << endl; + return false; + } -/* Construct our reply */ -stringstream reply; -reply << theServer->getCharYY() - << " RO " - << remoteServer->getName() - << " " - << remoteClient->getCharYYXXX() - << " " - << params[3] - << " " - << params[4] - ; - -if( params.size() > 5 ) { - reply << " :" - << params.assemble(5) - ; -} + /* Construct our reply */ + stringstream reply; + reply << theServer->getCharYY() << " RO " << remoteServer->getName() << " " + << remoteClient->getCharYYXXX() << " " << params[3] << " " << params[4]; -theServer->Write(reply); + if (params.size() > 5) { + reply << " :" << params.assemble(5); + } -return true; + theServer->Write(reply); + return true; } } // namespace gnuworld diff --git a/libircu/msg_RO.cc b/libircu/msg_RO.cc index 9149d75f..6b9b638f 100644 --- a/libircu/msg_RO.cc +++ b/libircu/msg_RO.cc @@ -20,65 +20,53 @@ * $Id: msg_RO.cc,v 1.1 2009/07/25 18:12:34 hidden1 Exp $ */ -#include -#include +#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "Network.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "Network.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { -using std::endl ; -using std::string ; +using std::endl; +using std::string; CREATE_HANDLER(msg_RO) -bool msg_RO::Execute( const xParameters& Param ) -{ -if( Param.empty() ) - { - elog << "msg_RO> Invalid number of " - << "arguments" - << endl ; - return false ; - } +bool msg_RO::Execute(const xParameters& Param) { + if (Param.empty()) { + elog << "msg_RO> Invalid number of " + << "arguments" << endl; + return false; + } -xClient* theClient = Network->findLocalClient( Param[ 2 ] ) ; -if( NULL == theClient ) - { - elog << "msg_RO> Unable to find nick: " - << Param[ 1 ] - << endl ; - return false ; - } + xClient* theClient = Network->findLocalClient(Param[2]); + if (NULL == theClient) { + elog << "msg_RO> Unable to find nick: " << Param[1] << endl; + return false; + } -iServer* tmpServer = Network->findServer(Param[0]); -if( NULL == tmpServer ) - { - elog << "msg_RO> Unable to find server: " - << Param[ 0 ] - << endl ; - return false ; - } + iServer* tmpServer = Network->findServer(Param[0]); + if (NULL == tmpServer) { + elog << "msg_RO> Unable to find server: " << Param[0] << endl; + return false; + } -string tMessage = string( tmpServer->getCharYY() ) + " RO " + theServer->getCharYY() + " "; -for( xParameters::size_type i = 2 ; i < Param.size() ; ++i ) - { - tMessage += Param[ i ] ; - if( (i + 1) < Param.size() ) - { - tMessage += " " ; - } - } + string tMessage = string(tmpServer->getCharYY()) + " RO " + theServer->getCharYY() + " "; + for (xParameters::size_type i = 2; i < Param.size(); ++i) { + tMessage += Param[i]; + if ((i + 1) < Param.size()) { + tMessage += " "; + } + } -theClient->OnServerMessage( tmpServer, tMessage ); + theClient->OnServerMessage(tmpServer, tMessage); -return true ; + return true; } } // namespace gnuworld diff --git a/libircu/msg_S.cc b/libircu/msg_S.cc index 4ef53fea..8be3e52f 100644 --- a/libircu/msg_S.cc +++ b/libircu/msg_S.cc @@ -20,26 +20,25 @@ * $Id: msg_S.cc,v 1.7 2007/05/12 13:20:00 mrbean_ Exp $ */ -#include -#include -#include +#include +#include +#include -#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "events.h" -#include "Network.h" -#include "iServer.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "events.h" +#include "Network.h" +#include "iServer.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::endl ; +using std::endl; +using std::string; CREATE_HANDLER(msg_S) @@ -64,74 +63,61 @@ CREATE_HANDLER(msg_S) * As always, the second token, the command, is not * included in the xParameters passed here. */ -bool msg_S::Execute( const xParameters& params ) -{ -// We need at least 9 tokens -if( params.size() < 9 ) - { - elog << "msg_S> Not enough parameters" - << endl ; - return false ; - } - -int uplinkIntYY = base64toint( params[ 0 ] ) ; -iServer* uplinkServer = Network->findServer( uplinkIntYY ) ; - -if( NULL == uplinkServer ) - { - elog << "msg_S> Unable to find uplink server" - << endl ; - return false ; - } - -const string serverName( params[ 1 ] ) ; -// Don't care about hop count -// Don't care about start time -time_t connectTime = static_cast< time_t >( atoi( params[ 4 ] ) ) ; -// Don't care about version - -int serverIntYY = base64toint( params[ 6 ], 2 ) ; - -// Does the new server's numeric already exist? -if( NULL != Network->findServer( serverIntYY ) ) - { - elog << "msg_S> Server numeric collision, numeric: " - << params[ 6 ] - << ", old name: " - << Network->findServer( serverIntYY )->getName() - << ", new name: " - << serverName - << endl ; - delete Network->removeServer( serverIntYY ) ; - } - -// Dun really care about the server description -iServer* newServer = new (std::nothrow) iServer( uplinkIntYY, - params[ 6 ], // yxx - serverName, - connectTime ) ; -assert( newServer != 0 ) ; - -// params[ 5 ] is either "P10", or "J10". The J10 means -// that the server is bursting -if( 'J' == params[ 5 ][ 0 ] ) - { - newServer->setBursting( true ) ; - } - -// Set any appropriate server flags -newServer->setFlags( params[ 7 ] ) ; - -Network->addServer( newServer ) ; -//elog << "msg_S> Added server: " -// << *newServer -// << endl ; - -theServer->PostEvent( EVT_NETJOIN, - static_cast< void* >( newServer ), - static_cast< void* >( uplinkServer ) ) ; - -return true ; +bool msg_S::Execute(const xParameters& params) { + // We need at least 9 tokens + if (params.size() < 9) { + elog << "msg_S> Not enough parameters" << endl; + return false; + } + + int uplinkIntYY = base64toint(params[0]); + iServer* uplinkServer = Network->findServer(uplinkIntYY); + + if (NULL == uplinkServer) { + elog << "msg_S> Unable to find uplink server" << endl; + return false; + } + + const string serverName(params[1]); + // Don't care about hop count + // Don't care about start time + time_t connectTime = static_cast(atoi(params[4])); + // Don't care about version + + int serverIntYY = base64toint(params[6], 2); + + // Does the new server's numeric already exist? + if (NULL != Network->findServer(serverIntYY)) { + elog << "msg_S> Server numeric collision, numeric: " << params[6] + << ", old name: " << Network->findServer(serverIntYY)->getName() + << ", new name: " << serverName << endl; + delete Network->removeServer(serverIntYY); + } + + // Dun really care about the server description + iServer* newServer = new (std::nothrow) iServer(uplinkIntYY, + params[6], // yxx + serverName, connectTime); + assert(newServer != 0); + + // params[ 5 ] is either "P10", or "J10". The J10 means + // that the server is bursting + if ('J' == params[5][0]) { + newServer->setBursting(true); + } + + // Set any appropriate server flags + newServer->setFlags(params[7]); + + Network->addServer(newServer); + // elog << "msg_S> Added server: " + // << *newServer + // << endl ; + + theServer->PostEvent(EVT_NETJOIN, static_cast(newServer), + static_cast(uplinkServer)); + + return true; } } // namespace gnuworld diff --git a/libircu/msg_SQ.cc b/libircu/msg_SQ.cc index fc5385e7..bcc69ba9 100644 --- a/libircu/msg_SQ.cc +++ b/libircu/msg_SQ.cc @@ -20,25 +20,24 @@ * $Id: msg_SQ.cc,v 1.8 2007/04/27 19:30:43 mrbean_ Exp $ */ -#include -#include +#include +#include -#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "events.h" -#include "Network.h" -#include "iServer.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "events.h" +#include "Network.h" +#include "iServer.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::endl ; +using std::endl; +using std::string; CREATE_HANDLER(msg_SQ) @@ -55,66 +54,51 @@ CREATE_HANDLER(msg_SQ) * 0 SQ Asheville-R.NC.US.KrushNet.Org 0 :Ping timeout * Az SQ Seattle-R.WA.US.KrushNet.Org 0 :Ping timeout */ -bool msg_SQ::Execute( const xParameters& Param ) -{ - -if( Param.size() < 2 ) - { - elog << "msg_SQ> Invalid number of parameters" - << endl ; - return false ; - } - -iServer* squitServer = 0 ; -if( strchr( Param[ 1 ], '.' ) != NULL ) - { - // Full server name specified - squitServer = Network->findServerName( Param[ 1 ] ) ; - } -else - { - // Numeric - squitServer = Network->findServer( Param[ 1 ] ) ; - } - -if( NULL == squitServer ) - { - elog << "msg_SQ> Unable to find server: " - << Param[ 1 ] - << endl ; - return false ; - } - -if( squitServer->getIntYY() == theServer->getUplinkIntYY() ) - { - elog << "msg_SQ> Ive been delinked!!" - << endl ; - - // It's my uplink, we have been squit...those bastards! - theServer->Shutdown() ; - return true ; - } -else - { -// elog << "msg_SQ> " << squitServer->getName() -// << " has been squit" -// << endl ; - - string source( Param[ 0 ] ) ; - string reason( Param[ 3 ] ) ; - squitServer->setBursting(false); //If the server was in bursting state, its not anymore :) - theServer->PostEvent( EVT_NETBREAK, - static_cast< void* >( squitServer ), - static_cast< void* >( &source ), - static_cast< void* >( &reason ) ) ; - - // Otherwise, it's just some server. - // xNetwork::OnSplit() will deallocate all servers - // which are split - Network->OnSplit( squitServer->getIntYY() ) ; - } - -return true ; +bool msg_SQ::Execute(const xParameters& Param) { + + if (Param.size() < 2) { + elog << "msg_SQ> Invalid number of parameters" << endl; + return false; + } + + iServer* squitServer = 0; + if (strchr(Param[1], '.') != NULL) { + // Full server name specified + squitServer = Network->findServerName(Param[1]); + } else { + // Numeric + squitServer = Network->findServer(Param[1]); + } + + if (NULL == squitServer) { + elog << "msg_SQ> Unable to find server: " << Param[1] << endl; + return false; + } + + if (squitServer->getIntYY() == theServer->getUplinkIntYY()) { + elog << "msg_SQ> Ive been delinked!!" << endl; + + // It's my uplink, we have been squit...those bastards! + theServer->Shutdown(); + return true; + } else { + // elog << "msg_SQ> " << squitServer->getName() + // << " has been squit" + // << endl ; + + string source(Param[0]); + string reason(Param[3]); + squitServer->setBursting(false); // If the server was in bursting state, its not anymore :) + theServer->PostEvent(EVT_NETBREAK, static_cast(squitServer), + static_cast(&source), static_cast(&reason)); + + // Otherwise, it's just some server. + // xNetwork::OnSplit() will deallocate all servers + // which are split + Network->OnSplit(squitServer->getIntYY()); + } + + return true; } } // namespace gnuworld diff --git a/libircu/msg_Server.cc b/libircu/msg_Server.cc index aa76447b..5b1d3f71 100644 --- a/libircu/msg_Server.cc +++ b/libircu/msg_Server.cc @@ -20,25 +20,24 @@ * $Id: msg_Server.cc,v 1.7 2006/12/22 06:41:41 kewlio Exp $ */ -#include -#include +#include +#include -#include -#include +#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "events.h" -#include "Network.h" -#include "iServer.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "events.h" +#include "Network.h" +#include "iServer.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { -using std::endl ; +using std::endl; CREATE_HANDLER(msg_Server) @@ -59,87 +58,76 @@ CREATE_HANDLER(msg_Server) * * Remember that the "SERVER" parameter is removed. */ -bool msg_Server::Execute( const xParameters& Param ) -{ -theServer->setBurstEnd( 0 ) ; -theServer->setBurstStart( ::time( 0 ) ) ; - -// Check the hopcount -// 1: It's our uplink -if( Param[ 1 ][ 0 ] == '1' ) - { - -// elog << "msg_Server> Got Uplink: " -// << Param[ 0 ] -// << endl ; - - // It's our uplink - if( Param.size() < 6 ) - { - elog << "msg_Server> Invalid number of parameters" - << endl ; - return false ; - } - - // Here's the deal: - // We are just connecting to the network - // We have just received the first server command, - // telling us who our uplink server is. - // We need to add our uplink to network tables. - - // Assume 5 character numerics - unsigned int uplinkIntYY = base64toint( Param[ 5 ], 2 ) ; - - // Our uplink has its own numeric as its uplinkIntYY. - iServer* tmpUplink = new (std::nothrow) iServer( - uplinkIntYY, - Param[ 5 ], // yyxxx - Param[ 0 ], // name - atoi( Param[ 3 ] ) ) ; // connect time - assert( tmpUplink != 0 ) ; - - // Check for P10 versus J10, J10 means the server is - // bursting. - if( 'J' == Param[ 4 ][ 0 ] ) - { - tmpUplink->setBursting( true ) ; - } - - // Set any appropriate server flags - tmpUplink->setFlags( Param[ 6 ] ) ; - - theServer->setUplink( tmpUplink ) ; - - // Find this server (me) - iServer* me = Network->findServer( theServer->getIntYY() ) ; - if( NULL == me ) - { - elog << "msg_Server> Unable to find myself " - << " (" - << theServer->getIntYY() - << ")" - << endl ; - ::exit( 0 ) ; - } - - // Now that I know my uplink, I can set its numeric - // in my own iServer info - me->setUplinkIntYY( uplinkIntYY ) ; - - // We now have a pointer to our own uplink - // Add it to the tables - // We maintain a local pointer just for speed reasons - Network->addServer( theServer->getUplink() ) ; - -// elog << "msg_Server> Added server: " -// << *(theServer->getUplink()) -// << endl ; - } - -// Not posting message here because this method is only called once -// using tokenized commands - when the xServer connects -return true ; +bool msg_Server::Execute(const xParameters& Param) { + theServer->setBurstEnd(0); + theServer->setBurstStart(::time(0)); + + // Check the hopcount + // 1: It's our uplink + if (Param[1][0] == '1') { + + // elog << "msg_Server> Got Uplink: " + // << Param[ 0 ] + // << endl ; + + // It's our uplink + if (Param.size() < 6) { + elog << "msg_Server> Invalid number of parameters" << endl; + return false; + } + + // Here's the deal: + // We are just connecting to the network + // We have just received the first server command, + // telling us who our uplink server is. + // We need to add our uplink to network tables. + + // Assume 5 character numerics + unsigned int uplinkIntYY = base64toint(Param[5], 2); + + // Our uplink has its own numeric as its uplinkIntYY. + iServer* tmpUplink = new (std::nothrow) iServer(uplinkIntYY, + Param[5], // yyxxx + Param[0], // name + atoi(Param[3])); // connect time + assert(tmpUplink != 0); + + // Check for P10 versus J10, J10 means the server is + // bursting. + if ('J' == Param[4][0]) { + tmpUplink->setBursting(true); + } + + // Set any appropriate server flags + tmpUplink->setFlags(Param[6]); + + theServer->setUplink(tmpUplink); + + // Find this server (me) + iServer* me = Network->findServer(theServer->getIntYY()); + if (NULL == me) { + elog << "msg_Server> Unable to find myself " + << " (" << theServer->getIntYY() << ")" << endl; + ::exit(0); + } + + // Now that I know my uplink, I can set its numeric + // in my own iServer info + me->setUplinkIntYY(uplinkIntYY); + + // We now have a pointer to our own uplink + // Add it to the tables + // We maintain a local pointer just for speed reasons + Network->addServer(theServer->getUplink()); + + // elog << "msg_Server> Added server: " + // << *(theServer->getUplink()) + // << endl ; + } + + // Not posting message here because this method is only called once + // using tokenized commands - when the xServer connects + return true; } - } // namespace gnuworld diff --git a/libircu/msg_T.cc b/libircu/msg_T.cc old mode 100755 new mode 100644 index d94644f3..48bdd936 --- a/libircu/msg_T.cc +++ b/libircu/msg_T.cc @@ -20,102 +20,91 @@ * $Id: msg_T.cc,v 1.8 2005/06/20 11:26:33 kewlio Exp $ */ -#include -#include +#include +#include -#include "gnuworld_config.h" -#include "ip.h" -#include "server.h" -#include "xparameters.h" -#include "Network.h" -#include "ELog.h" -#include "Channel.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "ip.h" +#include "server.h" +#include "xparameters.h" +#include "Network.h" +#include "ELog.h" +#include "Channel.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { -using std::endl ; +using std::endl; CREATE_HANDLER(msg_T) // Channel topics currently are not tracked. // kAI T #omniplex :-=[ Washington.DC.US.Krushnet.Org / Luxembourg. // LU.EU.KrushNet.Org Admin Channel ]=- -bool msg_T::Execute( const xParameters& Param ) -{ -if( Param.size() < 3 ) - { - elog << "msg_T> Invalid number of arguments" - << endl ; - return false ; - } +bool msg_T::Execute(const xParameters& Param) { + if (Param.size() < 3) { + elog << "msg_T> Invalid number of arguments" << endl; + return false; + } -Channel* theChan = Network->findChannel( Param[ 1 ] ) ; -if( 0 == theChan ) - { - elog << "msg_T> Unable to locate channel: " - << Param[ 1 ] - << endl; - return false ; - } + Channel* theChan = Network->findChannel(Param[1]); + if (0 == theChan) { + elog << "msg_T> Unable to locate channel: " << Param[1] << endl; + return false; + } -// srcClient may be NULL if a server is setting the topic -iClient* srcClient = Network->findClient( Param[ 0 ] ) ; -std::string newTopic; -bool hasWhoSet = false; + // srcClient may be NULL if a server is setting the topic + iClient* srcClient = Network->findClient(Param[0]); + std::string newTopic; + bool hasWhoSet = false; -if (Param.size() == 6) -{ - /* this is a >.12.19 hub! */ - /* params = numeric, channel, channel creation ts, topic ts, topic nick, topic */ - newTopic = Param[ 5 ]; + if (Param.size() == 6) { + /* this is a >.12.19 hub! */ + /* params = numeric, channel, channel creation ts, topic ts, topic nick, topic */ + newTopic = Param[5]; #ifdef TOPIC_TRACK - theChan->setTopic(Param[5]); - theChan->setTopicTS(atoi(Param[3])); - theChan->setTopicWhoSet(Param[4]); - hasWhoSet = true; + theChan->setTopic(Param[5]); + theChan->setTopicTS(atoi(Param[3])); + theChan->setTopicWhoSet(Param[4]); + hasWhoSet = true; #endif // TOPIC_TRACK -} else if (Param.size() == 5) -{ - /* this is a .12 hub! */ - /* params = numeric, channel, channel creation ts, topic ts, topic */ - newTopic = Param[ 4 ]; + } else if (Param.size() == 5) { + /* this is a .12 hub! */ + /* params = numeric, channel, channel creation ts, topic ts, topic */ + newTopic = Param[4]; #ifdef TOPIC_TRACK - theChan->setTopic(Param[4]); - theChan->setTopicTS(atoi(Param[3])); + theChan->setTopic(Param[4]); + theChan->setTopicTS(atoi(Param[3])); #endif // TOPIC_TRACK -} else { - /* this is a .11 hub! (3 arguments) */ - /* params = numeric, channel, topic */ - newTopic = Param[ 2 ]; + } else { + /* this is a .11 hub! (3 arguments) */ + /* params = numeric, channel, topic */ + newTopic = Param[2]; #ifdef TOPIC_TRACK - theChan->setTopic(Param[2]); - theChan->setTopicTS(::time(NULL)); + theChan->setTopic(Param[2]); + theChan->setTopicTS(::time(NULL)); #endif // TOPIC_TRACK -} + } #ifdef TOPIC_TRACK -/* Even if we have the topic nick (>.12.19) we use srcClient if it was not a burst message */ -if (srcClient == NULL && !hasWhoSet) -{ - theChan->setTopicWhoSet("unknown"); -} else if (srcClient != NULL) { - std::string client_ip; - client_ip = xIP(srcClient->getIP()).GetNumericIP(); - theChan->setTopicWhoSet(srcClient->getNickUserHost() + " [" + client_ip + "]"); -} + /* Even if we have the topic nick (>.12.19) we use srcClient if it was not a burst message */ + if (srcClient == NULL && !hasWhoSet) { + theChan->setTopicWhoSet("unknown"); + } else if (srcClient != NULL) { + std::string client_ip; + client_ip = xIP(srcClient->getIP()).GetNumericIP(); + theChan->setTopicWhoSet(srcClient->getNickUserHost() + " [" + client_ip + "]"); + } #endif // TOPIC_TRACK -// No need to pass the new topic, it has already been stored -// in the theChan -// For bursted topics, srcClient will be NULL but getTopicWhoSet() will have been updated (>.12.19). -theServer->PostChannelEvent( EVT_TOPIC, - theChan, - static_cast< void* >( srcClient ), - static_cast< void* >( &newTopic ) ) ; + // No need to pass the new topic, it has already been stored + // in the theChan + // For bursted topics, srcClient will be NULL but getTopicWhoSet() will have been updated + // (>.12.19). + theServer->PostChannelEvent(EVT_TOPIC, theChan, static_cast(srcClient), + static_cast(&newTopic)); -return true ; + return true; } } // namespace gnuworld diff --git a/libircu/msg_V.cc b/libircu/msg_V.cc index 985167cd..4ea34e69 100644 --- a/libircu/msg_V.cc +++ b/libircu/msg_V.cc @@ -20,18 +20,17 @@ * $Id: msg_V.cc,v 1.7 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "ServerCommandHandler.h" -#include "xparameters.h" +#include "gnuworld_config.h" +#include "server.h" +#include "ServerCommandHandler.h" +#include "xparameters.h" -namespace gnuworld -{ +namespace gnuworld { -using std::endl ; -using std::stringstream ; +using std::endl; +using std::stringstream; CREATE_HANDLER(msg_V) @@ -46,49 +45,41 @@ CREATE_HANDLER(msg_V) * As always, the token itself is missing from our xParameters */ -bool msg_V::Execute( const xParameters& Param ) -{ -/* We should have exactly two parameters - source and destination */ -if( Param.size() != 2) - { - elog << "msg_V> Invalid number of parameters received." - << endl; - return false; - } +bool msg_V::Execute(const xParameters& Param) { + /* We should have exactly two parameters - source and destination */ + if (Param.size() != 2) { + elog << "msg_V> Invalid number of parameters received." << endl; + return false; + } -/* The destination numeric should always match us exactly */ -if(strncmp(Param[1], theServer->getCharYY().c_str(), 2) != 0) - { - elog << "msg_V> Target server is not me!" - << endl; - return false; - } + /* The destination numeric should always match us exactly */ + if (strncmp(Param[1], theServer->getCharYY().c_str(), 2) != 0) { + elog << "msg_V> Target server is not me!" << endl; + return false; + } -/* - * Should we check if the client exists here? - * If the version request got to us, presumably it has to exist - * on the network, even if we don't know about it. - */ + /* + * Should we check if the client exists here? + * If the version request got to us, presumably it has to exist + * on the network, even if we don't know about it. + */ -/* - * Reply looks like: - * A8 351 AyAAA u2.10.11.01. devlink.netgamers.org :B27AeEFfIKMpSU - * - * A8 - Answering server - * 351 - Numeric for version reply - * AyAAA - Target (requester) - * 'the rest' - Reply. - */ -stringstream versionReply; -versionReply << theServer->getCharYY() - << " 351 " - << Param[0] - << " :" __DATE__ " " __TIME__ - << " GNUworld Services Core" ; + /* + * Reply looks like: + * A8 351 AyAAA u2.10.11.01. devlink.netgamers.org :B27AeEFfIKMpSU + * + * A8 - Answering server + * 351 - Numeric for version reply + * AyAAA - Target (requester) + * 'the rest' - Reply. + */ + stringstream versionReply; + versionReply << theServer->getCharYY() << " 351 " << Param[0] << " :" __DATE__ " " __TIME__ + << " GNUworld Services Core"; -theServer->Write(versionReply); + theServer->Write(versionReply); -return true; + return true; } // bool msg_V::Execute() diff --git a/libircu/msg_W.cc b/libircu/msg_W.cc index 43bc0f11..f36a6d17 100644 --- a/libircu/msg_W.cc +++ b/libircu/msg_W.cc @@ -20,60 +20,49 @@ * $Id: msg_W.cc,v 1.5 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "xparameters.h" -#include "ELog.h" -#include "Network.h" -#include "iClient.h" -#include "client.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "xparameters.h" +#include "ELog.h" +#include "Network.h" +#include "iClient.h" +#include "client.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { -using std::endl ; +using std::endl; CREATE_HANDLER(msg_W) // ABAG7 W Az :Gte- -bool msg_W::Execute( const xParameters& Param ) -{ -if( Param.size() != 3 ) - { - elog << "msg_W> Invalid number of parameters" - << endl ; - return false ; - } +bool msg_W::Execute(const xParameters& Param) { + if (Param.size() != 3) { + elog << "msg_W> Invalid number of parameters" << endl; + return false; + } -iClient* sourceClient = Network->findClient( Param[ 0 ] ) ; -if( NULL == sourceClient ) - { - elog << "msg_W> Unable to find source client: " - << Param[ 0 ] - << endl ; - return false ; - } + iClient* sourceClient = Network->findClient(Param[0]); + if (NULL == sourceClient) { + elog << "msg_W> Unable to find source client: " << Param[0] << endl; + return false; + } -iClient* targetClient = Network->findNick( Param[ 2 ] ) ; -if( NULL == targetClient ) - { - elog << "msg_W> Unable to find target client: " - << Param[ 2 ] - << endl ; - return false ; - } + iClient* targetClient = Network->findNick(Param[2]); + if (NULL == targetClient) { + elog << "msg_W> Unable to find target client: " << Param[2] << endl; + return false; + } -// WHOIS must be delivered to all xclients -xNetwork::localClientIterator ptr = Network->localClient_begin() ; -for( ; ptr != Network->localClient_end() ; ++ptr ) - { - ptr->second->OnWhois( sourceClient, targetClient ) ; - } + // WHOIS must be delivered to all xclients + xNetwork::localClientIterator ptr = Network->localClient_begin(); + for (; ptr != Network->localClient_end(); ++ptr) { + ptr->second->OnWhois(sourceClient, targetClient); + } -return true ; + return true; } } // namespace gnuworld diff --git a/libircu/msg_WA.cc b/libircu/msg_WA.cc index f0a33df7..215be9ea 100644 --- a/libircu/msg_WA.cc +++ b/libircu/msg_WA.cc @@ -20,20 +20,16 @@ * $Id: msg_WA.cc,v 1.4 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include "gnuworld_config.h" -#include "server.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { CREATE_HANDLER(msg_WA) // WALLOPS -bool msg_WA::Execute( const xParameters& ) -{ -return false ; -} +bool msg_WA::Execute(const xParameters&) { return false; } } // namespace gnuworld diff --git a/libircu/msg_XQ.cc b/libircu/msg_XQ.cc index 9ffe11f0..8066a207 100644 --- a/libircu/msg_XQ.cc +++ b/libircu/msg_XQ.cc @@ -20,24 +20,23 @@ * $Id: msg_XQ.cc,v 1.1 2010/08/31 21:16:46 denspike Exp $ */ -#include -#include +#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "Network.h" -#include "iClient.h" -#include "client.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" -#include "StringTokenizer.h" +#include "gnuworld_config.h" +#include "server.h" +#include "Network.h" +#include "iClient.h" +#include "client.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" +#include "StringTokenizer.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::endl ; +using std::endl; +using std::string; CREATE_HANDLER(msg_XQ) @@ -49,71 +48,59 @@ CREATE_HANDLER(msg_XQ) * : Our servernumeric * : Token to supply in XR * : Message, can be spaced - * + * * [IN ]: ABAAA XQ Az tokengoeshere :message goes here :) */ -bool msg_XQ::Execute( const xParameters& Param ) -{ -if( Param.size() < 4 ) - { - elog << "msg_XQ> Invalid number of arguments" - << endl ; - return false ; - } - -iServer* serverSource = 0 ; -iClient* clientSource = 0 ; - -if( strlen( Param[ 0 ] ) >= 3 ) - { - clientSource = Network->findClient( Param[ 0 ] ) ; - //This is an oper debugging, treat messages as originated from his server - serverSource = Network->findServer(clientSource->getIntYY()); - } -else - { - serverSource = Network->findServer( Param[ 0 ] ) ; - } - -if( (NULL == clientSource) && (NULL == serverSource) ) - { - elog << "msg_XQ> Unable to find source: " - << Param[ 0 ] - << endl ; - return false ; - } - -if (Network->findServer(Param[ 1 ]) != theServer->getMe()) - { - //Should we do something here? - elog << "msg_XQ> Received XQ not meant for us but for: " - << Param[ 1 ] - << endl ; - return false ; - } - -/* -elog << "msg_XQ> Received, from: " - << Param[ 0 ] << " To: " - << Param[ 1 ] << " Token: " - << Param[ 2 ] << " Message: " - << Param[ 3 ] - << endl; -*/ - -string Routing( Param[2] ); -string Message( Param[3] ); - -theServer->OnXQuery(serverSource, Routing, Message); -//string Routing = Param[2]; -//string Message = Param[3]; -//elog << "STRINGS:: " << Routing << " " << Message << endl; - -//theServer->PostEvent( EVT_XQUERY, -// static_cast< void* >( serverSource ), -// reinterpret_cast< void* > ( &Routing ), reinterpret_cast< void* >( &Message )); - -return true; +bool msg_XQ::Execute(const xParameters& Param) { + if (Param.size() < 4) { + elog << "msg_XQ> Invalid number of arguments" << endl; + return false; + } + + iServer* serverSource = 0; + iClient* clientSource = 0; + + if (strlen(Param[0]) >= 3) { + clientSource = Network->findClient(Param[0]); + // This is an oper debugging, treat messages as originated from his server + serverSource = Network->findServer(clientSource->getIntYY()); + } else { + serverSource = Network->findServer(Param[0]); + } + + if ((NULL == clientSource) && (NULL == serverSource)) { + elog << "msg_XQ> Unable to find source: " << Param[0] << endl; + return false; + } + + if (Network->findServer(Param[1]) != theServer->getMe()) { + // Should we do something here? + elog << "msg_XQ> Received XQ not meant for us but for: " << Param[1] << endl; + return false; + } + + /* + elog << "msg_XQ> Received, from: " + << Param[ 0 ] << " To: " + << Param[ 1 ] << " Token: " + << Param[ 2 ] << " Message: " + << Param[ 3 ] + << endl; + */ + + string Routing(Param[2]); + string Message(Param[3]); + + theServer->OnXQuery(serverSource, Routing, Message); + // string Routing = Param[2]; + // string Message = Param[3]; + // elog << "STRINGS:: " << Routing << " " << Message << endl; + + // theServer->PostEvent( EVT_XQUERY, + // static_cast< void* >( serverSource ), + // reinterpret_cast< void* > ( &Routing ), reinterpret_cast< void* >( &Message )); + + return true; } // msg_XQ } // namespace gnuworld diff --git a/libircu/msg_XR.cc b/libircu/msg_XR.cc index 2fecebd7..d511ec12 100644 --- a/libircu/msg_XR.cc +++ b/libircu/msg_XR.cc @@ -20,24 +20,23 @@ * $Id: msg_XR.cc,v 1.1 2010/08/31 21:16:46 denspike Exp $ */ -#include -#include +#include +#include -#include "gnuworld_config.h" -#include "server.h" -#include "Network.h" -#include "iClient.h" -#include "client.h" -#include "ELog.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" -#include "StringTokenizer.h" +#include "gnuworld_config.h" +#include "server.h" +#include "Network.h" +#include "iClient.h" +#include "client.h" +#include "ELog.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" +#include "StringTokenizer.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::endl ; +using std::endl; +using std::string; CREATE_HANDLER(msg_XR) @@ -49,53 +48,40 @@ CREATE_HANDLER(msg_XR) * : Our servernumeric * : Token to supply in XR * : Message, can be spaced - * + * * [IN ]: AB XR Az tokengoeshere :message goes here :) */ -bool msg_XR::Execute( const xParameters& Param ) -{ -if( Param.size() < 4 ) - { - elog << "msg_XR> Invalid number of arguments" - << endl ; - return false ; - } +bool msg_XR::Execute(const xParameters& Param) { + if (Param.size() < 4) { + elog << "msg_XR> Invalid number of arguments" << endl; + return false; + } -iServer* serverSource = Network->findServer( Param[ 0 ] ) ; + iServer* serverSource = Network->findServer(Param[0]); -if( NULL == serverSource) - { - elog << "msg_XR> Unable to find source: " - << Param[ 0 ] - << endl ; - return false ; - } + if (NULL == serverSource) { + elog << "msg_XR> Unable to find source: " << Param[0] << endl; + return false; + } -if (Network->findServer(Param[ 1 ]) != theServer->getMe()) - { - //Should we do something here? - elog << "msg_XR> Received XQ not meant for us but for: " - << Param[ 1 ] - << endl ; - return false ; - } + if (Network->findServer(Param[1]) != theServer->getMe()) { + // Should we do something here? + elog << "msg_XR> Received XQ not meant for us but for: " << Param[1] << endl; + return false; + } -elog << "msg_XR> Received, from: " - << Param[ 0 ] << " To: " - << Param[ 1 ] << " Token: " - << Param[ 2 ] << " Message: " - << Param[ 3 ] - << endl; + elog << "msg_XR> Received, from: " << Param[0] << " To: " << Param[1] << " Token: " << Param[2] + << " Message: " << Param[3] << endl; -string Routing( Param[2] ); -string Message( Param[3] ); + string Routing(Param[2]); + string Message(Param[3]); -theServer->OnXReply(serverSource, Routing, Message); -//string Routing = Param[2]; -//string Message = Param[3]; -//elog << "STRINGS:: " << Routing << " " << Message << endl; + theServer->OnXReply(serverSource, Routing, Message); + // string Routing = Param[2]; + // string Message = Param[3]; + // elog << "STRINGS:: " << Routing << " " << Message << endl; -return true; + return true; } // msg_XR } // namespace gnuworld diff --git a/libircu/msg_Y.cc b/libircu/msg_Y.cc index 748c8fb4..8e4cd16b 100644 --- a/libircu/msg_Y.cc +++ b/libircu/msg_Y.cc @@ -20,20 +20,15 @@ * $Id: msg_Y.cc,v 1.4 2005/03/25 03:07:29 dan_karrels Exp $ */ -#include "gnuworld_config.h" -#include "server.h" -#include "xparameters.h" -#include "ServerCommandHandler.h" +#include "gnuworld_config.h" +#include "server.h" +#include "xparameters.h" +#include "ServerCommandHandler.h" -namespace gnuworld -{ +namespace gnuworld { CREATE_HANDLER(msg_Y) -bool msg_Y::Execute( const xParameters& ) -{ -return true ; -} - +bool msg_Y::Execute(const xParameters&) { return true; } } // namespace gnuworld diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h index a1679d4a..cdeced0b 100644 --- a/libltdl/ltdl.h +++ b/libltdl/ltdl.h @@ -36,122 +36,100 @@ License along with GNU Libltdl. If not, see . LT_BEGIN_C_DECLS - /* LT_STRLEN can be used safely on NULL pointers. */ -#define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) +#define LT_STRLEN(s) (((s) && (s)[0]) ? strlen(s) : 0) /* --- DYNAMIC MODULE LOADING API --- */ - -typedef struct lt__handle *lt_dlhandle; /* A loaded module. */ +typedef struct lt__handle* lt_dlhandle; /* A loaded module. */ /* Initialisation and finalisation functions for libltdl. */ -LT_SCOPE int lt_dlinit (void); -LT_SCOPE int lt_dlexit (void); +LT_SCOPE int lt_dlinit(void); +LT_SCOPE int lt_dlexit(void); /* Module search path manipulation. */ -LT_SCOPE int lt_dladdsearchdir (const char *search_dir); -LT_SCOPE int lt_dlinsertsearchdir (const char *before, - const char *search_dir); -LT_SCOPE int lt_dlsetsearchpath (const char *search_path); -LT_SCOPE const char *lt_dlgetsearchpath (void); -LT_SCOPE int lt_dlforeachfile ( - const char *search_path, - int (*func) (const char *filename, void *data), - void *data); +LT_SCOPE int lt_dladdsearchdir(const char* search_dir); +LT_SCOPE int lt_dlinsertsearchdir(const char* before, const char* search_dir); +LT_SCOPE int lt_dlsetsearchpath(const char* search_path); +LT_SCOPE const char* lt_dlgetsearchpath(void); +LT_SCOPE int lt_dlforeachfile(const char* search_path, + int (*func)(const char* filename, void* data), void* data); /* User module loading advisors. */ -LT_SCOPE int lt_dladvise_init (lt_dladvise *advise); -LT_SCOPE int lt_dladvise_destroy (lt_dladvise *advise); -LT_SCOPE int lt_dladvise_ext (lt_dladvise *advise); -LT_SCOPE int lt_dladvise_resident (lt_dladvise *advise); -LT_SCOPE int lt_dladvise_local (lt_dladvise *advise); -LT_SCOPE int lt_dladvise_global (lt_dladvise *advise); -LT_SCOPE int lt_dladvise_preload (lt_dladvise *advise); +LT_SCOPE int lt_dladvise_init(lt_dladvise* advise); +LT_SCOPE int lt_dladvise_destroy(lt_dladvise* advise); +LT_SCOPE int lt_dladvise_ext(lt_dladvise* advise); +LT_SCOPE int lt_dladvise_resident(lt_dladvise* advise); +LT_SCOPE int lt_dladvise_local(lt_dladvise* advise); +LT_SCOPE int lt_dladvise_global(lt_dladvise* advise); +LT_SCOPE int lt_dladvise_preload(lt_dladvise* advise); /* Portable libltdl versions of the system dlopen() API. */ -LT_SCOPE lt_dlhandle lt_dlopen (const char *filename); -LT_SCOPE lt_dlhandle lt_dlopenext (const char *filename); -LT_SCOPE lt_dlhandle lt_dlopenadvise (const char *filename, - lt_dladvise advise); -LT_SCOPE void * lt_dlsym (lt_dlhandle handle, const char *name); -LT_SCOPE const char *lt_dlerror (void); -LT_SCOPE int lt_dlclose (lt_dlhandle handle); - - +LT_SCOPE lt_dlhandle lt_dlopen(const char* filename); +LT_SCOPE lt_dlhandle lt_dlopenext(const char* filename); +LT_SCOPE lt_dlhandle lt_dlopenadvise(const char* filename, lt_dladvise advise); +LT_SCOPE void* lt_dlsym(lt_dlhandle handle, const char* name); +LT_SCOPE const char* lt_dlerror(void); +LT_SCOPE int lt_dlclose(lt_dlhandle handle); /* --- PRELOADED MODULE SUPPORT --- */ - /* A preopened symbol. Arrays of this type comprise the exported symbols for a dlpreopened module. */ typedef struct { - const char *name; - void *address; + const char* name; + void* address; } lt_dlsymlist; -typedef int lt_dlpreload_callback_func (lt_dlhandle handle); +typedef int lt_dlpreload_callback_func(lt_dlhandle handle); -LT_SCOPE int lt_dlpreload (const lt_dlsymlist *preloaded); -LT_SCOPE int lt_dlpreload_default (const lt_dlsymlist *preloaded); -LT_SCOPE int lt_dlpreload_open (const char *originator, - lt_dlpreload_callback_func *func); +LT_SCOPE int lt_dlpreload(const lt_dlsymlist* preloaded); +LT_SCOPE int lt_dlpreload_default(const lt_dlsymlist* preloaded); +LT_SCOPE int lt_dlpreload_open(const char* originator, lt_dlpreload_callback_func* func); -#define lt_preloaded_symbols lt__PROGRAM__LTX_preloaded_symbols +#define lt_preloaded_symbols lt__PROGRAM__LTX_preloaded_symbols /* Ensure C linkage. */ extern LT_DLSYM_CONST lt_dlsymlist lt__PROGRAM__LTX_preloaded_symbols[]; -#define LTDL_SET_PRELOADED_SYMBOLS() \ - lt_dlpreload_default(lt_preloaded_symbols) - - +#define LTDL_SET_PRELOADED_SYMBOLS() lt_dlpreload_default(lt_preloaded_symbols) /* --- MODULE INFORMATION --- */ - /* Associating user data with loaded modules. */ -typedef void * lt_dlinterface_id; -typedef int lt_dlhandle_interface (lt_dlhandle handle, const char *id_string); - -LT_SCOPE lt_dlinterface_id lt_dlinterface_register (const char *id_string, - lt_dlhandle_interface *iface); -LT_SCOPE void lt_dlinterface_free (lt_dlinterface_id key); -LT_SCOPE void * lt_dlcaller_set_data (lt_dlinterface_id key, - lt_dlhandle handle, void *data); -LT_SCOPE void * lt_dlcaller_get_data (lt_dlinterface_id key, - lt_dlhandle handle); +typedef void* lt_dlinterface_id; +typedef int lt_dlhandle_interface(lt_dlhandle handle, const char* id_string); +LT_SCOPE lt_dlinterface_id lt_dlinterface_register(const char* id_string, + lt_dlhandle_interface* iface); +LT_SCOPE void lt_dlinterface_free(lt_dlinterface_id key); +LT_SCOPE void* lt_dlcaller_set_data(lt_dlinterface_id key, lt_dlhandle handle, void* data); +LT_SCOPE void* lt_dlcaller_get_data(lt_dlinterface_id key, lt_dlhandle handle); /* Read only information pertaining to a loaded module. */ -typedef struct { - char * filename; /* file name */ - char * name; /* module name */ - int ref_count; /* number of times lt_dlopened minus - number of times lt_dlclosed. */ - unsigned int is_resident:1; /* module can't be unloaded. */ - unsigned int is_symglobal:1; /* module symbols can satisfy - subsequently loaded modules. */ - unsigned int is_symlocal:1; /* module symbols are only available - locally. */ +typedef struct { + char* filename; /* file name */ + char* name; /* module name */ + int ref_count; /* number of times lt_dlopened minus + number of times lt_dlclosed. */ + unsigned int is_resident : 1; /* module can't be unloaded. */ + unsigned int is_symglobal : 1; /* module symbols can satisfy + subsequently loaded modules. */ + unsigned int is_symlocal : 1; /* module symbols are only available + locally. */ } lt_dlinfo; -LT_SCOPE const lt_dlinfo *lt_dlgetinfo (lt_dlhandle handle); - -LT_SCOPE lt_dlhandle lt_dlhandle_iterate (lt_dlinterface_id iface, - lt_dlhandle place); -LT_SCOPE lt_dlhandle lt_dlhandle_fetch (lt_dlinterface_id iface, - const char *module_name); -LT_SCOPE int lt_dlhandle_map (lt_dlinterface_id iface, - int (*func) (lt_dlhandle handle, void *data), - void *data); - +LT_SCOPE const lt_dlinfo* lt_dlgetinfo(lt_dlhandle handle); +LT_SCOPE lt_dlhandle lt_dlhandle_iterate(lt_dlinterface_id iface, lt_dlhandle place); +LT_SCOPE lt_dlhandle lt_dlhandle_fetch(lt_dlinterface_id iface, const char* module_name); +LT_SCOPE int lt_dlhandle_map(lt_dlinterface_id iface, int (*func)(lt_dlhandle handle, void* data), + void* data); /* Deprecated module residency management API. */ -LT_SCOPE int lt_dlmakeresident (lt_dlhandle handle); -LT_SCOPE int lt_dlisresident (lt_dlhandle handle); +LT_SCOPE int lt_dlmakeresident(lt_dlhandle handle); +LT_SCOPE int lt_dlisresident(lt_dlhandle handle); -#define lt_ptr void * +#define lt_ptr void* LT_END_C_DECLS diff --git a/libnotifier/logger.cc b/libnotifier/logger.cc index 6e2db282..8aa0b065 100644 --- a/libnotifier/logger.cc +++ b/libnotifier/logger.cc @@ -24,7 +24,7 @@ #include #ifdef HAVE_FORMAT - #include +#include #endif #include "Channel.h" @@ -33,39 +33,36 @@ #include "logger.h" -namespace gnuworld -{ +namespace gnuworld { -using std::endl ; -using std::string ; +using std::endl; +using std::string; /** * Logger constructor - initializes logging system. * Opens log file based on bot's configuration filename. * Log file path is derived by replacing .conf extension with .log. */ -Logger::Logger( xClient* _bot ) : bot( _bot ) -{ -// Build and save log file path for later use -size_t dotPos = bot->getConfigFileName().find( '.' ) ; -if( dotPos != std::string::npos ) - logFilePath = bot->getConfigFileName().substr( 0, dotPos ) + ".log" ; -else - logFilePath = bot->getConfigFileName() + ".log" ; - -logFile.open( logFilePath, std::ios::app ) ; -if( !logFile.is_open() ) - elog << "Warning: Could not open logfile " << logFilePath << std::endl ; +Logger::Logger(xClient* _bot) : bot(_bot) { + // Build and save log file path for later use + size_t dotPos = bot->getConfigFileName().find('.'); + if (dotPos != std::string::npos) + logFilePath = bot->getConfigFileName().substr(0, dotPos) + ".log"; + else + logFilePath = bot->getConfigFileName() + ".log"; + + logFile.open(logFilePath, std::ios::app); + if (!logFile.is_open()) + elog << "Warning: Could not open logfile " << logFilePath << std::endl; } /** * Logger destructor - ensures proper cleanup. * Closes log file if it was successfully opened. */ -Logger::~Logger() -{ -if( logFile.is_open() ) - logFile.close() ; +Logger::~Logger() { + if (logFile.is_open()) + logFile.close(); } /** @@ -73,23 +70,22 @@ if( logFile.is_open() ) * Creates properly formatted JSON with timestamp, level, function, parameters, and message. * All string values are properly escaped for valid JSON output. */ -void Logger::writeLog( Verbosity v, const std::string& func, const std::string& jsonParams, const std::string& theMessage ) -{ -if( logFile.is_open() ) - { - logFile << "{" - << "\"timestamp\":\"" << getCurrentTimestamp() << "\"," - << "\"level\":\"" << ( v == SQL ? "SQL" : levels[ v ].name ) << "\"" ; - if( !func.empty() ) - logFile << ",\"function\":\"" << escapeJsonString( func ) << "\"" ; - if( !jsonParams.empty() ) - logFile << "," << jsonParams ; - if( !theMessage.empty() ) - logFile << ",\"message\":\"" << escapeJsonString( theMessage ) << "\"" ; - - logFile << "}\n" ; - logFile.flush() ; - } +void Logger::writeLog(Verbosity v, const std::string& func, const std::string& jsonParams, + const std::string& theMessage) { + if (logFile.is_open()) { + logFile << "{" + << "\"timestamp\":\"" << getCurrentTimestamp() << "\"," + << "\"level\":\"" << (v == SQL ? "SQL" : levels[v].name) << "\""; + if (!func.empty()) + logFile << ",\"function\":\"" << escapeJsonString(func) << "\""; + if (!jsonParams.empty()) + logFile << "," << jsonParams; + if (!theMessage.empty()) + logFile << ",\"message\":\"" << escapeJsonString(theMessage) << "\""; + + logFile << "}\n"; + logFile.flush(); + } } /** @@ -100,74 +96,61 @@ if( logFile.is_open() ) * - External notifiers (alerts, webhooks, etc.) * Special handling for SQL logging category. */ -void Logger::writeFunc( Verbosity v, const char* func, const string& jsonParams, const string& theMessage ) -{ +void Logger::writeFunc(Verbosity v, const char* func, const string& jsonParams, + const string& theMessage) { #ifdef USE_THREAD -/* We don't want multiple threads sharing the same logger object to interfer with each other. */ -std::lock_guard< std::mutex > lock( logMutex ) ; + /* We don't want multiple threads sharing the same logger object to interfer with each other. */ + std::lock_guard lock(logMutex); #endif -std::string fmtMessage = ( v == INFO ? "" : parseFunction( func ) + "> " ) + theMessage ; - -/* Is this an SQL log? */ -if( v == SQL ) - { - if( logSQL ) - writeLog( v, parseFunction( func ), jsonParams, theMessage ) ; - - if( consoleSQL && elog.getStream() ) - *(elog.getStream()) << elog.getLocalTime() - << "[" << bot->getNickName() << "] - SQL - " - << theMessage - << endl ; - return ; - } - -/* Write to logfile. */ -if( v <= logVerbosity ) - writeLog( v, parseFunction( func ), jsonParams, theMessage ) ; - -/* Write to console. */ -if( v <= consoleVerbosity && elog.getStream() ) - *(elog.getStream()) << elog.getLocalTime() - << "[" << bot->getNickName() << "] - " - << levels[ v ].prefix << " - " - << fmtMessage - << endl ; - -/* Send notification. */ -for( const auto& [ notifier, logLevel ] : notifiers ) - { - if( v <= logLevel ) - { - notifier->sendMessage( static_cast< int >( v ), fmtMessage ) ; + std::string fmtMessage = (v == INFO ? "" : parseFunction(func) + "> ") + theMessage; + + /* Is this an SQL log? */ + if (v == SQL) { + if (logSQL) + writeLog(v, parseFunction(func), jsonParams, theMessage); + + if (consoleSQL && elog.getStream()) + *(elog.getStream()) << elog.getLocalTime() << "[" << bot->getNickName() + << "] - SQL - " << theMessage << endl; + return; } - } -#ifdef HAVE_FORMAT -if( v <= chanVerbosity && bot->isConnected() && !debugChan.empty() ) - { - /* Try to locate the channel. */ - Channel* theChan = Network->findChannel( debugChan ) ; - if( !theChan ) - { - elog << "[" << bot->getNickName() << "] - WARN - Logger::writeFunc> Unable to locate channel " - << debugChan - << " on network!" - << endl ; + /* Write to logfile. */ + if (v <= logVerbosity) + writeLog(v, parseFunction(func), jsonParams, theMessage); + + /* Write to console. */ + if (v <= consoleVerbosity && elog.getStream()) + *(elog.getStream()) << elog.getLocalTime() << "[" << bot->getNickName() << "] - " + << levels[v].prefix << " - " << fmtMessage << endl; + + /* Send notification. */ + for (const auto& [notifier, logLevel] : notifiers) { + if (v <= logLevel) { + notifier->sendMessage(static_cast(v), fmtMessage); + } } - else - { - std::istringstream stream( fmtMessage ) ; - std::string line ; - - while( std::getline( stream, line ) ) - if( !line.empty() ) - bot->getUplink()->serverNotice( theChan, std::format( "{}[{}] {} {}{}", - getColour( v ), bot->getNickName(), levels[ v ].tag, line, - getColourReset( v ) ) ) ; + +#ifdef HAVE_FORMAT + if (v <= chanVerbosity && bot->isConnected() && !debugChan.empty()) { + /* Try to locate the channel. */ + Channel* theChan = Network->findChannel(debugChan); + if (!theChan) { + elog << "[" << bot->getNickName() + << "] - WARN - Logger::writeFunc> Unable to locate channel " << debugChan + << " on network!" << endl; + } else { + std::istringstream stream(fmtMessage); + std::string line; + + while (std::getline(stream, line)) + if (!line.empty()) + bot->getUplink()->serverNotice( + theChan, std::format("{}[{}] {} {}{}", getColour(v), bot->getNickName(), + levels[v].tag, line, getColourReset(v))); + } } - } #endif } @@ -176,23 +159,21 @@ if( v <= chanVerbosity && bot->isConnected() && !debugChan.empty() ) * Removes template parameters and return types, keeping class::function format. * Handles both C++ member functions and standalone functions. */ -std::string Logger::parseFunction( std::string pretty ) -{ -auto paren = pretty.find( '(' ) ; -if( paren != std::string::npos ) - pretty.erase( paren ) ; - -auto lastColons = pretty.rfind( "::" ) ; -if( lastColons != std::string::npos ) - { - // Find the second-to-last "::" to get class::function - auto secondLastColons = pretty.rfind( "::", lastColons - 1 ) ; - if( secondLastColons != std::string::npos ) - return pretty.substr( secondLastColons + 2 ) ; - else - return pretty ; - } -return pretty ; +std::string Logger::parseFunction(std::string pretty) { + auto paren = pretty.find('('); + if (paren != std::string::npos) + pretty.erase(paren); + + auto lastColons = pretty.rfind("::"); + if (lastColons != std::string::npos) { + // Find the second-to-last "::" to get class::function + auto secondLastColons = pretty.rfind("::", lastColons - 1); + if (secondLastColons != std::string::npos) + return pretty.substr(secondLastColons + 2); + else + return pretty; + } + return pretty; } /** @@ -200,32 +181,30 @@ return pretty ; * Properly formats different data types (strings, numbers, booleans). * Handles JSON escaping and type detection for valid JSON output. */ -std::string Logger::MessageTemplate::buildJsonFromMap() const -{ -if( fields.empty() ) - return "" ; - -std::string result ; -bool first = true ; -for( const auto& [k, v] : fields ) - { - if( !first ) - result += "," ; - - // Determine if value should be quoted - bool isNumeric = !v.empty() && ( std::isdigit( v[ 0 ] ) || - ( v[ 0 ] == '-' && v.length() > 1 && std::isdigit( v[ 1 ] ) ) ) ; - bool isBool = ( v == "true" || v == "false" ) ; - - result += "\"" + escapeJsonString( k ) + "\":" ; - if( isNumeric || isBool ) - result += v ; - else - result += "\"" + escapeJsonString( v ) + "\"" ; - - first = false ; - } -return result ; +std::string Logger::MessageTemplate::buildJsonFromMap() const { + if (fields.empty()) + return ""; + + std::string result; + bool first = true; + for (const auto& [k, v] : fields) { + if (!first) + result += ","; + + // Determine if value should be quoted + bool isNumeric = !v.empty() && (std::isdigit(v[0]) || + (v[0] == '-' && v.length() > 1 && std::isdigit(v[1]))); + bool isBool = (v == "true" || v == "false"); + + result += "\"" + escapeJsonString(k) + "\":"; + if (isNumeric || isBool) + result += v; + else + result += "\"" + escapeJsonString(v) + "\""; + + first = false; + } + return result; } /** @@ -235,35 +214,31 @@ return result ; * 2. Replaces named {field} placeholders with values from .with() calls * Produces clean, readable log messages. */ -std::string Logger::MessageTemplate::format() const -{ -std::string result = template_str ; - -// First, apply format arguments to {} placeholders -if( !format_args.empty() ) - { - size_t arg_index = 0 ; - size_t pos = 0 ; - while( ( pos = result.find( "{}", pos ) ) != std::string::npos && arg_index < format_args.size() ) - { - result.replace( pos, 2, format_args[ arg_index ] ) ; - pos += format_args[ arg_index ].length() ; - arg_index++ ; +std::string Logger::MessageTemplate::format() const { + std::string result = template_str; + + // First, apply format arguments to {} placeholders + if (!format_args.empty()) { + size_t arg_index = 0; + size_t pos = 0; + while ((pos = result.find("{}", pos)) != std::string::npos && + arg_index < format_args.size()) { + result.replace(pos, 2, format_args[arg_index]); + pos += format_args[arg_index].length(); + arg_index++; + } } - } - -// Then, replace named placeholders from .with() fields -for( const auto& [k, v] : fields ) - { - std::string placeholder = "{" + k + "}" ; - size_t pos = result.find( placeholder ) ; - if( pos != std::string::npos ) - { - result.replace( pos, placeholder.length(), v ) ; + + // Then, replace named placeholders from .with() fields + for (const auto& [k, v] : fields) { + std::string placeholder = "{" + k + "}"; + size_t pos = result.find(placeholder); + if (pos != std::string::npos) { + result.replace(pos, placeholder.length(), v); + } } - } -return result ; + return result; } /** @@ -271,20 +246,19 @@ return result ; * Combines human-readable message formatting with structured JSON field logging. * Calls the main logging system with both formatted message and JSON parameters. */ -void Logger::MessageTemplate::logStructured() const -{ -// Early exit if message won't be logged anywhere -if( !logger_instance->shouldLog( level ) ) - return ; +void Logger::MessageTemplate::logStructured() const { + // Early exit if message won't be logged anywhere + if (!logger_instance->shouldLog(level)) + return; -// Create clean message (replace placeholders with actual values) -std::string clean_msg = format() ; + // Create clean message (replace placeholders with actual values) + std::string clean_msg = format(); -// Build JSON fields string -std::string jsonFields = buildJsonFromMap() ; + // Build JSON fields string + std::string jsonFields = buildJsonFromMap(); -// Call the lower-level writeFunc directly -logger_instance->writeFunc( level, func, jsonFields, clean_msg ) ; + // Call the lower-level writeFunc directly + logger_instance->writeFunc(level, func, jsonFields, clean_msg); } /** @@ -293,21 +267,20 @@ logger_instance->writeFunc( level, func, jsonFields, clean_msg ) ; * to ensure the logger writes to the new log file instead of the rotated one. * Thread-safe when USE_THREAD is enabled. */ -void Logger::rotateLogs() -{ +void Logger::rotateLogs() { #ifdef USE_THREAD -std::lock_guard< std::mutex > lock( logMutex ) ; + std::lock_guard lock(logMutex); #endif -// Close existing log file if open -if( logFile.is_open() ) - logFile.close() ; + // Close existing log file if open + if (logFile.is_open()) + logFile.close(); -// Reopen log file using saved path -logFile.open( logFilePath, std::ios::app ) ; -if( !logFile.is_open() ) - { - elog << "Warning: Could not reopen logfile " << logFilePath << " after rotation" << std::endl ; - } + // Reopen log file using saved path + logFile.open(logFilePath, std::ios::app); + if (!logFile.is_open()) { + elog << "Warning: Could not reopen logfile " << logFilePath << " after rotation" + << std::endl; + } } } // namespace gnuworld diff --git a/libnotifier/logger.h b/libnotifier/logger.h index 8665c124..5d2ed4f8 100644 --- a/libnotifier/logger.h +++ b/libnotifier/logger.h @@ -25,10 +25,10 @@ #include #include #ifdef HAVE_FORMAT - #include +#include #endif #ifdef USE_THREAD - #include +#include #endif #include #include @@ -43,30 +43,33 @@ * Usage: LOG(INFO, "User {} connected", username); */ #ifdef HAVE_FORMAT -#define LOG(x, ...) logger->writeFunc(x, __PRETTY_FUNCTION__, "", __VA_ARGS__) +#define LOG(x, ...) logger->writeFunc(x, __PRETTY_FUNCTION__, "", __VA_ARGS__) /** * SQL error logging macro for database-related errors. * Automatically formats SQL error messages from database objects. */ -#define LOGSQL_ERROR(x) logger->writeFunc(ERROR, __PRETTY_FUNCTION__, "", "SQL Error: {}", x->ErrorMessage()) +#define LOGSQL_ERROR(x) \ + logger->writeFunc(ERROR, __PRETTY_FUNCTION__, "", "SQL Error: {}", x->ErrorMessage()) #else -#define LOG(x, ...) do { } while(0) -#define LOGSQL_ERROR(x) elog << "SQL Error: " << x->ErrorMessage() << std::endl ; +#define LOG(x, ...) \ + do { \ + } while (0) +#define LOGSQL_ERROR(x) elog << "SQL Error: " << x->ErrorMessage() << std::endl; #endif /** * Structured logging macro with template support and field extraction. * Allows mixing format arguments with named placeholders and structured fields. - * Usage: LOG_MSG(INFO, "User {} joined {channel}", username).with("channel", chanPtr).logStructured(); + * Usage: LOG_MSG(INFO, "User {} joined {channel}", username).with("channel", + * chanPtr).logStructured(); */ -#define LOG_MSG(level, template_msg, ...) \ +#define LOG_MSG(level, template_msg, ...) \ logger->createMessage(level, __PRETTY_FUNCTION__, template_msg, ##__VA_ARGS__) -namespace gnuworld -{ +namespace gnuworld { -class xClient ; +class xClient; /** * Verbosity levels for logging system. @@ -74,14 +77,14 @@ class xClient ; * SQL is a special category for database query logging. */ enum Verbosity { - TRACE = 6, // Most verbose - detailed execution traces - DEBUG = 5, // Debug information for development - INFO = 4, // General informational messages - WARN = 3, // Warning messages for potential issues - ERROR = 2, // Error messages for failures - FATAL = 1, // Critical errors that may cause shutdown - SQL = 99 // Special category for SQL query logging -} ; + TRACE = 6, // Most verbose - detailed execution traces + DEBUG = 5, // Debug information for development + INFO = 4, // General informational messages + WARN = 3, // Warning messages for potential issues + ERROR = 2, // Error messages for failures + FATAL = 1, // Critical errors that may cause shutdown + SQL = 99 // Special category for SQL query logging +}; /** * Main logging system for GNUWorld services. @@ -89,567 +92,525 @@ enum Verbosity { * and extensible notification systems. Supports both simple text logging * and rich structured logging with custom object handlers. */ -class Logger -{ -private: - xClient* bot = nullptr ; - std::string logFilePath ; - std::string debugChan ; - unsigned short chanVerbosity = 4 ; - unsigned short logVerbosity = 6 ; - unsigned short consoleVerbosity = 6 ; - bool logSQL = false ; - bool consoleSQL = false ; - std::ofstream logFile ; - std::vector< - std::pair< - std::shared_ptr< - notifier >, - unsigned short > > notifiers ; - - /** - * Registry for custom object handlers that modules can register. - * Maps type_index to handler functions for structured logging of custom objects. - */ - std::map< - std::type_index, std::function< - bool( std::map< - std::string, std::string >&, - const std::string&, const void* ) > > customHandlers ; +class Logger { + private: + xClient* bot = nullptr; + std::string logFilePath; + std::string debugChan; + unsigned short chanVerbosity = 4; + unsigned short logVerbosity = 6; + unsigned short consoleVerbosity = 6; + bool logSQL = false; + bool consoleSQL = false; + std::ofstream logFile; + std::vector, unsigned short>> notifiers; + + /** + * Registry for custom object handlers that modules can register. + * Maps type_index to handler functions for structured logging of custom objects. + */ + std::map&, + const std::string&, const void*)>> + customHandlers; #ifdef USE_THREAD - std::mutex logMutex ; + std::mutex logMutex; #endif - /** - * Structure defining display properties for each verbosity level. - * Contains IRC tag, prefix, and full name for each logging level. - */ - struct LevelEntry { - const char* tag ; // Short tag for IRC display - const char* prefix ; // Prefix for log entries - const char* name ; // Full name for JSON logging - } ; - - /** - * Parses __PRETTY_FUNCTION__ to extract readable function names. - * Removes template parameters and keeps class::function format. - */ - std::string parseFunction( std::string ) ; - - /** - * Returns IRC color code for the given verbosity level. - * Used to colorize messages in IRC channels. - */ - std::string getColour( Verbosity v ) - { - switch( v ) - { - case FATAL: - case ERROR: - return "\00304" ; - case WARN: - return "\00307" ; - default: - return "" ; - } + /** + * Structure defining display properties for each verbosity level. + * Contains IRC tag, prefix, and full name for each logging level. + */ + struct LevelEntry { + const char* tag; // Short tag for IRC display + const char* prefix; // Prefix for log entries + const char* name; // Full name for JSON logging + }; + + /** + * Parses __PRETTY_FUNCTION__ to extract readable function names. + * Removes template parameters and keeps class::function format. + */ + std::string parseFunction(std::string); + + /** + * Returns IRC color code for the given verbosity level. + * Used to colorize messages in IRC channels. + */ + std::string getColour(Verbosity v) { + switch (v) { + case FATAL: + case ERROR: + return "\00304"; + case WARN: + return "\00307"; + default: + return ""; + } } - /** - * Returns IRC color reset code for the given verbosity level. - * Resets color formatting after colored messages. - */ - std::string getColourReset( Verbosity v ) - { return getColour( v ).empty() ? "" : "\003" ; } - - /** - * Stream-based logging interface for << operator usage. - * Accumulates messages in a buffer and flushes on std::endl. - * Provides a familiar iostream-style interface for logging. - */ - class LoggerStream - { - public: - /** - * Constructor for LoggerStream. - * Associates the stream with a logger instance and verbosity level. - */ - LoggerStream( Logger& logger, Verbosity v ) - : logger( logger ), verbosity( v ) {} - - /** - * Template operator<< for accumulating log message content. - * Stores all streamed values in an internal buffer. - */ - template< typename T > - LoggerStream& operator<<( const T& value ) - { - messageBuffer << value ; - return *this ; + /** + * Returns IRC color reset code for the given verbosity level. + * Resets color formatting after colored messages. + */ + std::string getColourReset(Verbosity v) { return getColour(v).empty() ? "" : "\003"; } + + /** + * Stream-based logging interface for << operator usage. + * Accumulates messages in a buffer and flushes on std::endl. + * Provides a familiar iostream-style interface for logging. + */ + class LoggerStream { + public: + /** + * Constructor for LoggerStream. + * Associates the stream with a logger instance and verbosity level. + */ + LoggerStream(Logger& logger, Verbosity v) : logger(logger), verbosity(v) {} + + /** + * Template operator<< for accumulating log message content. + * Stores all streamed values in an internal buffer. + */ + template LoggerStream& operator<<(const T& value) { + messageBuffer << value; + return *this; } - /** - * Special operator<< for stream manipulators like std::endl. - * Flushes the accumulated message when std::endl is encountered. - */ - LoggerStream& operator<<( std::ostream& (*fp)( std::ostream& ) ) - { - if( fp == static_cast< std::ostream& (*)( std::ostream& )>( std::endl ) ) - { flush() ; } - return *this ; + /** + * Special operator<< for stream manipulators like std::endl. + * Flushes the accumulated message when std::endl is encountered. + */ + LoggerStream& operator<<(std::ostream& (*fp)(std::ostream&)) { + if (fp == static_cast(std::endl)) { + flush(); + } + return *this; } - private: - Logger& logger ; - Verbosity verbosity ; - std::ostringstream messageBuffer ; - - /** - * Flushes the accumulated message buffer to the logger. - * Clears the buffer after sending the message. - */ - void flush() - { - std::string message = messageBuffer.str() ; - logger.write( verbosity, message ) ; - messageBuffer.str( "" ) ; - messageBuffer.clear() ; + private: + Logger& logger; + Verbosity verbosity; + std::ostringstream messageBuffer; + + /** + * Flushes the accumulated message buffer to the logger. + * Clears the buffer after sending the message. + */ + void flush() { + std::string message = messageBuffer.str(); + logger.write(verbosity, message); + messageBuffer.str(""); + messageBuffer.clear(); } - } ; - -public: - - /** - * Constructor - initializes logger with bot instance. - * Opens log file based on bot's config filename. - */ - Logger( xClient* _bot ) ; - - /** - * Destructor - ensures log file is properly closed. - */ - ~Logger() ; - - /** - * Template-based structured logging class. - * Supports format arguments, named placeholders, and custom object serialization. - * Provides both human-readable messages and machine-parseable JSON output. - */ - class MessageTemplate { - private: - std::string template_str ; // Original template string - std::map< std::string, std::string > fields ; // Key-value pairs for JSON - Verbosity level ; // Log level - const char* func ; // Function name - Logger* logger_instance ; // Logger reference - std::vector< std::string > format_args ; // Positional format arguments - - /** - * Converts format arguments to strings for template replacement. - * Handles different types and ensures proper string conversion. - */ - template< typename T > - std::string formatArgumentToString( T&& arg ) const - { - if constexpr( std::is_same_v< std::decay_t, std::string > ) - return arg ; - else if constexpr( std::is_same_v< std::decay_t, const char* > ) - return std::string( arg ) ; - else - return std::to_string( arg ) ; + }; + + public: + /** + * Constructor - initializes logger with bot instance. + * Opens log file based on bot's config filename. + */ + Logger(xClient* _bot); + + /** + * Destructor - ensures log file is properly closed. + */ + ~Logger(); + + /** + * Template-based structured logging class. + * Supports format arguments, named placeholders, and custom object serialization. + * Provides both human-readable messages and machine-parseable JSON output. + */ + class MessageTemplate { + private: + std::string template_str; // Original template string + std::map fields; // Key-value pairs for JSON + Verbosity level; // Log level + const char* func; // Function name + Logger* logger_instance; // Logger reference + std::vector format_args; // Positional format arguments + + /** + * Converts format arguments to strings for template replacement. + * Handles different types and ensures proper string conversion. + */ + template std::string formatArgumentToString(T&& arg) const { + if constexpr (std::is_same_v, std::string>) + return arg; + else if constexpr (std::is_same_v, const char*>) + return std::string(arg); + else + return std::to_string(arg); } - /** - * Builds JSON string from the fields map. - * Handles proper JSON escaping and type formatting. - */ - std::string buildJsonFromMap() const ; + /** + * Builds JSON string from the fields map. + * Handles proper JSON escaping and type formatting. + */ + std::string buildJsonFromMap() const; + + public: + /** + * Constructor for MessageTemplate with optional format arguments. + * Stores template string and converts format arguments for later use. + */ + template + MessageTemplate(Logger* logger, Verbosity lvl, const char* f, const std::string& tmpl, + FormatArgs&&... args) + : template_str(tmpl), level(lvl), func(f), logger_instance(logger) { + if constexpr (sizeof...(args) > 0) { + // Store format arguments for later formatting + (format_args.push_back(formatArgumentToString(std::forward(args))), + ...); + } + } - public: - /** - * Constructor for MessageTemplate with optional format arguments. - * Stores template string and converts format arguments for later use. - */ - template< typename... FormatArgs > - MessageTemplate( Logger* logger, Verbosity lvl, const char* f, const std::string& tmpl, FormatArgs&&... args ) - : template_str( tmpl ), level( lvl ), func( f ), logger_instance( logger ) - { - if constexpr( sizeof...( args ) > 0 ) - { - // Store format arguments for later formatting - ( format_args.push_back( formatArgumentToString( std::forward( args ) ) ), ... ) ; - } + /** + * Generic with() method for adding structured data fields. + * Attempts custom object handlers first, then falls back to built-in types. + * Supports basic types, IRC objects, and module-registered custom types. + */ + template MessageTemplate& with(const std::string& key, T&& value) { + auto handlerIt = + logger_instance->customHandlers.find(std::type_index(typeid(std::decay_t))); + if (handlerIt != logger_instance->customHandlers.end()) { + if constexpr (std::is_pointer_v>) { + if (handlerIt->second(fields, key, static_cast(value))) + return *this; + } else { + if (handlerIt->second(fields, key, &value)) + return *this; + } + } else if constexpr (std::is_same_v, std::string>) + fields[key] = value; + else if constexpr (std::is_same_v, const char*>) + fields[key] = std::string(value); + else if constexpr (std::is_same_v, bool>) + fields[key] = value ? "true" : "false"; + else if constexpr (std::is_same_v, iClient*>) + return withClient(key, value); + else if constexpr (std::is_same_v, Channel*>) + return withChannel(key, value); + else if constexpr (std::is_same_v, iServer*>) + return withServer(key, value); + else if constexpr (std::is_same_v, ChannelUser*>) + return withChannelUser(key, value); + else if constexpr (std::is_pointer_v>) { + if (value) + fields[key] = "0x" + std::to_string(reinterpret_cast(value)); + else + fields[key] = "nullptr"; + } else + fields[key] = std::to_string(value); + + return *this; } - /** - * Generic with() method for adding structured data fields. - * Attempts custom object handlers first, then falls back to built-in types. - * Supports basic types, IRC objects, and module-registered custom types. - */ - template< typename T > - MessageTemplate& with( const std::string& key, T&& value ) - { - auto handlerIt = logger_instance->customHandlers.find( std::type_index( typeid( std::decay_t ) ) ) ; - if( handlerIt != logger_instance->customHandlers.end() ) - { - if constexpr( std::is_pointer_v< std::decay_t > ) - { - if (handlerIt->second(fields, key, static_cast(value))) - return *this ; + /** + * Specialized handler for iClient* objects. + * Extracts comprehensive client information including nick, host, auth status, etc. + */ + MessageTemplate& withClient(const std::string& prefix, iClient* client) { + if (!client) { + fields[prefix + "_nick"] = "nullptr"; + return *this; } - else - { - if (handlerIt->second(fields, key, &value)) - return *this ; + + fields[prefix + "_nick"] = client->getNickName(); + fields[prefix + "_userhost"] = client->getRealUserHost(); + // fields[ prefix + "_host" ] = client->getInsecureHost() ; + // fields[ prefix + "_realhost" ] = client->getRealInsecureHost() ; + fields[prefix + "_ip"] = xIP(client->getIP()).GetNumericIP(); + fields[prefix + "_numeric"] = client->getCharYYXXX(); + + // Add authentication info if available + if (client->isModeR()) { + fields[prefix + "_account"] = client->getAccount(); + fields[prefix + "_account_id"] = std::to_string(client->getAccountID()); } - } - else if constexpr( std::is_same_v< std::decay_t, std::string > ) - fields[ key ] = value ; - else if constexpr( std::is_same_v< std::decay_t, const char* > ) - fields[ key ] = std::string( value ) ; - else if constexpr( std::is_same_v< std::decay_t, bool > ) - fields[ key ] = value ? "true" : "false" ; - else if constexpr( std::is_same_v< std::decay_t, iClient* > ) - return withClient( key, value ) ; - else if constexpr( std::is_same_v< std::decay_t, Channel* > ) - return withChannel( key, value ) ; - else if constexpr( std::is_same_v< std::decay_t, iServer* > ) - return withServer( key, value ) ; - else if constexpr( std::is_same_v< std::decay_t, ChannelUser* > ) - return withChannelUser( key, value ) ; - else if constexpr( std::is_pointer_v< std::decay_t > ) - { - if( value ) - fields[ key ] = "0x" + std::to_string( reinterpret_cast( value ) ) ; - else - fields[ key ] = "nullptr" ; - } - else - fields[ key ] = std::to_string( value ) ; - - return *this ; - } - /** - * Specialized handler for iClient* objects. - * Extracts comprehensive client information including nick, host, auth status, etc. - */ - MessageTemplate& withClient( const std::string& prefix, iClient* client ) - { - if( !client ) - { - fields[ prefix + "_nick" ] = "nullptr" ; - return *this ; - } - - fields[ prefix + "_nick" ] = client->getNickName() ; - fields[ prefix + "_userhost" ] = client->getRealUserHost() ; - //fields[ prefix + "_host" ] = client->getInsecureHost() ; - //fields[ prefix + "_realhost" ] = client->getRealInsecureHost() ; - fields[ prefix + "_ip" ] = xIP( client->getIP() ).GetNumericIP() ; - fields[ prefix + "_numeric" ] = client->getCharYYXXX() ; - - // Add authentication info if available - if( client->isModeR() ) - { - fields[ prefix + "_account" ] = client->getAccount() ; - fields[ prefix + "_account_id" ] = std::to_string( client->getAccountID() ) ; - } - - fields[ prefix + "_is_oper" ] = client->isOper() ? "true" : "false" ; - //fields[ prefix + "_is_hidden" ] = client->isModeX() ? "true" : "false" ; - - return *this ; + fields[prefix + "_is_oper"] = client->isOper() ? "true" : "false"; + // fields[ prefix + "_is_hidden" ] = client->isModeX() ? "true" : "false" ; + + return *this; } - /** - * Specialized handler for iServer* objects. - * Extracts server information including name, numeric, uplink, and status flags. - */ - MessageTemplate& withServer( const std::string& prefix, iServer* server ) - { - if( !server ) - { - fields[ prefix + "_name" ] = "nullptr" ; - return *this ; - } - - fields[ prefix + "_name" ] = server->getName() ; - fields[ prefix + "_numeric" ] = server->getCharYY() ; - fields[ prefix + "_uplink" ] = server->getUplinkIntYY() ; - - // Add server flags - //fields[ prefix + "_is_service" ] = server->isService() ? "true" : "false" ; - //fields[ prefix + "_is_hub" ] = server->isHub() ? "true" : "false" ; - fields[ prefix + "_is_bursting" ] = server->isBursting() ? "true" : "false" ; - - return *this ; + /** + * Specialized handler for iServer* objects. + * Extracts server information including name, numeric, uplink, and status flags. + */ + MessageTemplate& withServer(const std::string& prefix, iServer* server) { + if (!server) { + fields[prefix + "_name"] = "nullptr"; + return *this; + } + + fields[prefix + "_name"] = server->getName(); + fields[prefix + "_numeric"] = server->getCharYY(); + fields[prefix + "_uplink"] = server->getUplinkIntYY(); + + // Add server flags + // fields[ prefix + "_is_service" ] = server->isService() ? "true" : "false" ; + // fields[ prefix + "_is_hub" ] = server->isHub() ? "true" : "false" ; + fields[prefix + "_is_bursting"] = server->isBursting() ? "true" : "false"; + + return *this; } - /** - * Specialized handler for Channel* objects. - * Extracts channel information including name, creation time, modes, etc. - */ - MessageTemplate& withChannel( const std::string& prefix, Channel* channel ) - { - if( !channel ) - { - fields[ prefix + "_name" ] = "nullptr" ; - return *this ; - } - - fields[ prefix + "_name" ] = channel->getName() ; - //fields[ prefix + "_creation_ts" ] = std::to_string( channel->getCreationTime() ) ; - fields[ prefix + "_modes" ] = channel->getModeString() ; - - return *this ; + /** + * Specialized handler for Channel* objects. + * Extracts channel information including name, creation time, modes, etc. + */ + MessageTemplate& withChannel(const std::string& prefix, Channel* channel) { + if (!channel) { + fields[prefix + "_name"] = "nullptr"; + return *this; + } + + fields[prefix + "_name"] = channel->getName(); + // fields[ prefix + "_creation_ts" ] = std::to_string( channel->getCreationTime() ) ; + fields[prefix + "_modes"] = channel->getModeString(); + + return *this; } - /** - * Specialized handler for ChannelUser* objects. - * Extracts channel-specific user information like op/voice status and modes. - */ - MessageTemplate& withChannelUser( const std::string& prefix, ChannelUser* theUser ) - { - if( !theUser ) - return *this ; + /** + * Specialized handler for ChannelUser* objects. + * Extracts channel-specific user information like op/voice status and modes. + */ + MessageTemplate& withChannelUser(const std::string& prefix, ChannelUser* theUser) { + if (!theUser) + return *this; - fields[ prefix + "_is_op" ] = theUser->getMode( ChannelUser::MODE_O ) ? "true" : "false" ; - fields[ prefix + "_is_voice" ] = theUser->getMode( ChannelUser::MODE_V ) ? "true" : "false" ; - //fields[ prefix + "_channel_modes" ] = theUser->getModeString() ; + fields[prefix + "_is_op"] = theUser->getMode(ChannelUser::MODE_O) ? "true" : "false"; + fields[prefix + "_is_voice"] = theUser->getMode(ChannelUser::MODE_V) ? "true" : "false"; + // fields[ prefix + "_channel_modes" ] = theUser->getModeString() ; - return *this ; + return *this; } - /** - * Replaces both positional {} placeholders and named {field} placeholders. - */ - std::string format() const ; - - /** - * Executes the structured logging operation. - * Sends both formatted message and JSON fields to the logging system. - */ - void logStructured() const ; - } ; - - /** - * Factory method to create a MessageTemplate with no format arguments. - * Used by the LOG_MSG macro for template-based structured logging. - */ - MessageTemplate createMessage( Verbosity level, const char* func, const std::string& templateStr ) - { return MessageTemplate( this, level, func, templateStr ) ; } - - /** - * Template factory method to create a MessageTemplate with format arguments. - * Supports variadic templates for flexible format argument handling. - */ - template< typename... FormatArgs > - MessageTemplate createMessage( Verbosity level, const char* func, const std::string& templateStr, FormatArgs&&... args ) - { return MessageTemplate( this, level, func, templateStr, std::forward( args )... ) ; } - - /** - * Creates a LoggerStream for iostream-style logging. - * Allows usage like: logger.write(INFO) << "Message" << std::endl; - */ - LoggerStream write( Verbosity v ) - { return LoggerStream( *this, v ) ; } - - /** - * Static array defining properties for each verbosity level. - * Contains tag, prefix, and name for consistent level handling. - */ - static constexpr std::array< LevelEntry, 7 > levels { { - {"", "", ""}, // Dummy element at index 0 - {"[F]", "FATAL", "FATAL"}, // FATAL = 1 - {"[E]", "ERROR", "ERROR"}, // ERROR = 2 - {"[W]", "WARN ", "WARNING"}, // WARN = 3 - {"[I]", "INFO ", "INFO"}, // INFO = 4 - {"[D]", "DEBUG", "DEBUG"}, // DEBUG = 5 - {"[T]", "TRACE", "TRACE"} // TRACE = 6 - } } ; - - /** - * Sets the IRC channel name for debug output. - * Messages will be sent to this channel based on chanVerbosity setting. - */ - inline void setChannel( const std::string& channelName ) - { debugChan = channelName ; } - - /** - * Sets the verbosity level for IRC channel output. - * Only messages at or below this level will be sent to the debug channel. - */ - inline void setChanVerbosity( unsigned short level ) - { chanVerbosity = level ; } - - /** - * Sets the verbosity level for log file output. - * Only messages at or below this level will be written to the log file. - */ - inline void setLogVerbosity( unsigned short level ) - { logVerbosity = level ; } - - /** - * Enables or disables SQL query logging. - * When enabled, SQL queries will be logged to the file. - */ - inline void setLogSQL( bool enable ) - { logSQL = enable ; } - - /** - * Sets the verbosity level for console output. - * Only log messages at or below this level will be displayed on the console. - */ - inline void setConsoleVerbosity( unsigned short level ) - { consoleVerbosity = level ; } - - /** - * Enables or disables SQL query logging to the console. - * When enabled, SQL-related log messages will be displayed on the console. - */ - inline void setConsoleSQL( bool enable ) - { consoleSQL = enable ; } - - /** - * Returns the currently configured debug channel name. - */ - inline std::string getChannel() const - { return debugChan ; } - - /** - * Adds a notifier with specific verbosity level. - * Notifiers receive log messages and can send them to external services. - */ - inline void addNotifier( std::shared_ptr< notifier > _notifier, unsigned short _verbosity ) - { notifiers.push_back( std::make_pair( std::move( _notifier ), _verbosity ) ) ; } - - /** - * Adds a notifier with maximum verbosity level (receives all messages). - */ - inline void addNotifier( std::shared_ptr< notifier > _notifier ) - { notifiers.push_back( std::make_pair( std::move( _notifier ), TRACE ) ) ; } - - /** - * Removes a notifier from the notification list. - */ - inline void removeNotifier( std::shared_ptr< notifier > _notifier ) - { - notifiers.erase( - std::remove_if( notifiers.begin(), notifiers.end(), - [&_notifier]( const auto& pair ) { return pair.first == _notifier ; } ), - notifiers.end() ) ; + /** + * Replaces both positional {} placeholders and named {field} placeholders. + */ + std::string format() const; + + /** + * Executes the structured logging operation. + * Sends both formatted message and JSON fields to the logging system. + */ + void logStructured() const; + }; + + /** + * Factory method to create a MessageTemplate with no format arguments. + * Used by the LOG_MSG macro for template-based structured logging. + */ + MessageTemplate createMessage(Verbosity level, const char* func, + const std::string& templateStr) { + return MessageTemplate(this, level, func, templateStr); + } + + /** + * Template factory method to create a MessageTemplate with format arguments. + * Supports variadic templates for flexible format argument handling. + */ + template + MessageTemplate createMessage(Verbosity level, const char* func, const std::string& templateStr, + FormatArgs&&... args) { + return MessageTemplate(this, level, func, templateStr, std::forward(args)...); + } + + /** + * Creates a LoggerStream for iostream-style logging. + * Allows usage like: logger.write(INFO) << "Message" << std::endl; + */ + LoggerStream write(Verbosity v) { return LoggerStream(*this, v); } + + /** + * Static array defining properties for each verbosity level. + * Contains tag, prefix, and name for consistent level handling. + */ + static constexpr std::array levels{{ + {"", "", ""}, // Dummy element at index 0 + {"[F]", "FATAL", "FATAL"}, // FATAL = 1 + {"[E]", "ERROR", "ERROR"}, // ERROR = 2 + {"[W]", "WARN ", "WARNING"}, // WARN = 3 + {"[I]", "INFO ", "INFO"}, // INFO = 4 + {"[D]", "DEBUG", "DEBUG"}, // DEBUG = 5 + {"[T]", "TRACE", "TRACE"} // TRACE = 6 + }}; + + /** + * Sets the IRC channel name for debug output. + * Messages will be sent to this channel based on chanVerbosity setting. + */ + inline void setChannel(const std::string& channelName) { debugChan = channelName; } + + /** + * Sets the verbosity level for IRC channel output. + * Only messages at or below this level will be sent to the debug channel. + */ + inline void setChanVerbosity(unsigned short level) { chanVerbosity = level; } + + /** + * Sets the verbosity level for log file output. + * Only messages at or below this level will be written to the log file. + */ + inline void setLogVerbosity(unsigned short level) { logVerbosity = level; } + + /** + * Enables or disables SQL query logging. + * When enabled, SQL queries will be logged to the file. + */ + inline void setLogSQL(bool enable) { logSQL = enable; } + + /** + * Sets the verbosity level for console output. + * Only log messages at or below this level will be displayed on the console. + */ + inline void setConsoleVerbosity(unsigned short level) { consoleVerbosity = level; } + + /** + * Enables or disables SQL query logging to the console. + * When enabled, SQL-related log messages will be displayed on the console. + */ + inline void setConsoleSQL(bool enable) { consoleSQL = enable; } + + /** + * Returns the currently configured debug channel name. + */ + inline std::string getChannel() const { return debugChan; } + + /** + * Adds a notifier with specific verbosity level. + * Notifiers receive log messages and can send them to external services. + */ + inline void addNotifier(std::shared_ptr _notifier, unsigned short _verbosity) { + notifiers.push_back(std::make_pair(std::move(_notifier), _verbosity)); + } + + /** + * Adds a notifier with maximum verbosity level (receives all messages). + */ + inline void addNotifier(std::shared_ptr _notifier) { + notifiers.push_back(std::make_pair(std::move(_notifier), TRACE)); + } + + /** + * Removes a notifier from the notification list. + */ + inline void removeNotifier(std::shared_ptr _notifier) { + notifiers.erase( + std::remove_if(notifiers.begin(), notifiers.end(), + [&_notifier](const auto& pair) { return pair.first == _notifier; }), + notifiers.end()); } - /** - * Updates the verbosity level for an existing notifier. - */ - inline void updateNotifierVerbosity( std::shared_ptr< notifier > _notifier, unsigned short _verbosity ) - { - for( auto& pair : notifiers ) - { - if( pair.first == _notifier ) - { - pair.second = _verbosity ; - break ; + /** + * Updates the verbosity level for an existing notifier. + */ + inline void updateNotifierVerbosity(std::shared_ptr _notifier, + unsigned short _verbosity) { + for (auto& pair : notifiers) { + if (pair.first == _notifier) { + pair.second = _verbosity; + break; + } } - } } - /** - * Checks if a message should be processed based on verbosity settings. - * Returns true if the message should be logged to any output destination. - */ - inline bool shouldLog( Verbosity v ) const - { - // Special case for SQL logging - if( v == SQL ) - return logSQL ; - - // Check if message meets any output threshold - if( v <= logVerbosity ) - return true ; - - if( v <= chanVerbosity ) - return true ; - - // Check notifiers - for( const auto& [ notifier, logLevel ] : notifiers ) - { - if( v <= logLevel ) - return true ; - } - - return false ; + /** + * Checks if a message should be processed based on verbosity settings. + * Returns true if the message should be logged to any output destination. + */ + inline bool shouldLog(Verbosity v) const { + // Special case for SQL logging + if (v == SQL) + return logSQL; + + // Check if message meets any output threshold + if (v <= logVerbosity) + return true; + + if (v <= chanVerbosity) + return true; + + // Check notifiers + for (const auto& [notifier, logLevel] : notifiers) { + if (v <= logLevel) + return true; + } + + return false; + } + + /** + * Registers a custom object handler for structured logging. + * Allows modules to register handlers for their own object types. + * Handler function receives fields map, key, and object pointer. + */ + template + inline void registerObjectHandler( + std::function&, const std::string&, T*)> handler) { + // Register with the pointer type since that's what with() will look for + customHandlers[std::type_index(typeid(T*))] = + [handler](std::map& fields, const std::string& key, + const void* obj) -> bool { + return handler(fields, key, static_cast(const_cast(obj))); + }; } - /** - * Registers a custom object handler for structured logging. - * Allows modules to register handlers for their own object types. - * Handler function receives fields map, key, and object pointer. - */ - template< typename T > - inline void registerObjectHandler( std::function< bool( std::map< std::string, std::string >&, const std::string&, T* ) > handler ) - { - // Register with the pointer type since that's what with() will look for - customHandlers[ std::type_index( typeid( T* ) ) ] = - [ handler ]( std::map< std::string, std::string >& fields, const std::string& key, const void* obj ) -> bool { - return handler( fields, key, static_cast( const_cast( obj ) ) ) ; - } ; + /** + * Core logging function that handles message distribution. + * Sends messages to log file, IRC channel, and notifiers based on verbosity levels. + */ + void writeFunc(Verbosity, const char*, const std::string&, const std::string&); + + /** + * Helper function for writing JSON-formatted entries to the log file. + * Creates structured log entries with timestamp, level, function, and message. + */ + void writeLog(Verbosity, const std::string&, const std::string&, const std::string&); + + /** + * Simple logging function without function name or JSON parameters. + */ + void write(Verbosity v, const std::string& theMessage) { + writeFunc(v, "", string(), theMessage); } - /** - * Core logging function that handles message distribution. - * Sends messages to log file, IRC channel, and notifiers based on verbosity levels. - */ - void writeFunc( Verbosity, const char*, const std::string&, const std::string& ) ; - - /** - * Helper function for writing JSON-formatted entries to the log file. - * Creates structured log entries with timestamp, level, function, and message. - */ - void writeLog( Verbosity, const std::string&, const std::string&, const std::string& ) ; - - /** - * Simple logging function without function name or JSON parameters. - */ - void write( Verbosity v, const std::string& theMessage ) - { writeFunc( v, "", string(), theMessage ) ; } - - /** - * Template logging function with format string support. - * Provides printf-style formatting for log messages. - */ - template< typename Format, typename... Args > - void write( Verbosity v, const Format& format, Args&&... args ) - { + /** + * Template logging function with format string support. + * Provides printf-style formatting for log messages. + */ + template + void write(Verbosity v, const Format& format, Args&&... args) { #ifdef HAVE_FORMAT - std::string fmtString = std::vformat( format, - std::make_format_args( args... ) ) ; - writeFunc( v, "", string(), fmtString ) ; + std::string fmtString = std::vformat(format, std::make_format_args(args...)); + writeFunc(v, "", string(), fmtString); #endif - } - - /** - * Main logging function with caller function information. - * Called by the LOG macro to provide formatted logging with function context. - * Supports format strings and JSON parameter injection. - */ - template< typename Format, typename... Args > - void writeFunc( Verbosity v, const char* func, const std::string& jsonParams, const Format& format, Args&&... args ) - { + } + + /** + * Main logging function with caller function information. + * Called by the LOG macro to provide formatted logging with function context. + * Supports format strings and JSON parameter injection. + */ + template + void writeFunc(Verbosity v, const char* func, const std::string& jsonParams, + const Format& format, Args&&... args) { #ifdef HAVE_FORMAT - std::string fmtString = std::vformat( format, - std::make_format_args( args... ) ) ; - writeFunc( v, func, jsonParams, fmtString ) ; + std::string fmtString = std::vformat(format, std::make_format_args(args...)); + writeFunc(v, func, jsonParams, fmtString); #endif - } - - /** - * Closes and reopens the log file for external log rotation support. - * Called from xServer::rotateLogs() when a SIGHUP is received. - */ - void rotateLogs() ; -} ; // class Logger + } + + /** + * Closes and reopens the log file for external log rotation support. + * Called from xServer::rotateLogs() when a SIGHUP is received. + */ + void rotateLogs(); +}; // class Logger } // namespace gnuworld diff --git a/libnotifier/notifier.h b/libnotifier/notifier.h index 704041f0..f18d3f89 100644 --- a/libnotifier/notifier.h +++ b/libnotifier/notifier.h @@ -22,18 +22,16 @@ #include -namespace gnuworld -{ +namespace gnuworld { /** * Base class for all notification systems * Provides a common interface for sending messages */ -class notifier -{ -public: - notifier() = default ; - virtual ~notifier() = default ; +class notifier { + public: + notifier() = default; + virtual ~notifier() = default; /** * Send a notification message with verbosity level @@ -41,19 +39,19 @@ class notifier * @param message The message body * @return true if message was sent successfully, false otherwise */ - virtual bool sendMessage( int level, const std::string message ) = 0 ; + virtual bool sendMessage(int level, const std::string message) = 0; /** * Get the number of successful notifications sent * @return Number of successful notifications */ - virtual size_t getSuccessful() const = 0 ; + virtual size_t getSuccessful() const = 0; /** * Get the number of failed notifications * @return Number of failed notifications */ - virtual size_t getErrors() const = 0 ; -} ; + virtual size_t getErrors() const = 0; +}; } // namespace gnuworld \ No newline at end of file diff --git a/libnotifier/prometheus.cc b/libnotifier/prometheus.cc index 6736c1a2..69cdb7c1 100644 --- a/libnotifier/prometheus.cc +++ b/libnotifier/prometheus.cc @@ -28,162 +28,142 @@ #include "threadworker.h" #include "logger.h" -namespace gnuworld -{ +namespace gnuworld { #ifdef HAVE_PROMETHEUS // Real implementation when Prometheus is available -PrometheusClient::PrometheusClient( xClient* _bot, const std::string& ip, unsigned short port ) - : bot{ _bot }, exposer_{ ip + ":" + std::to_string( port ) }, registry_{ std::make_shared< prometheus::Registry >() } -{ - // Register the registry with the exposer to start serving metrics - // The exposer automatically runs in its own thread - exposer_.RegisterCollectable( registry_ ) ; - - // Set startup timestamp - monitoring tools can calculate uptime from this - setGauge( "start_time", static_cast< double >( ::time( nullptr ) ) ) ; - - elog << "*** [PrometheusClient]: Metrics server started on " << ip << ":" << port << std::endl ; - elog << "*** [PrometheusClient]: Metrics available at http://" << ip << ":" << port << "/metrics" << std::endl ; +PrometheusClient::PrometheusClient(xClient* _bot, const std::string& ip, unsigned short port) + : bot{_bot}, exposer_{ip + ":" + std::to_string(port)}, + registry_{std::make_shared()} { + // Register the registry with the exposer to start serving metrics + // The exposer automatically runs in its own thread + exposer_.RegisterCollectable(registry_); + + // Set startup timestamp - monitoring tools can calculate uptime from this + setGauge("start_time", static_cast(::time(nullptr))); + + elog << "*** [PrometheusClient]: Metrics server started on " << ip << ":" << port << std::endl; + elog << "*** [PrometheusClient]: Metrics available at http://" << ip << ":" << port + << "/metrics" << std::endl; } -std::string PrometheusClient::sanitizeMetricName( const std::string& name ) -{ -std::string sanitized = bot->getNickName() + "_" + name ; -std::transform( sanitized.begin(), sanitized.end(), sanitized.begin(), ::tolower ) ; +std::string PrometheusClient::sanitizeMetricName(const std::string& name) { + std::string sanitized = bot->getNickName() + "_" + name; + std::transform(sanitized.begin(), sanitized.end(), sanitized.begin(), ::tolower); -/* Replace invalid characters with underscores. */ -for( auto& c : sanitized ) - if( !std::isalnum(c) && c != '_' && c != ':' ) - c = '_' ; + /* Replace invalid characters with underscores. */ + for (auto& c : sanitized) + if (!std::isalnum(c) && c != '_' && c != ':') + c = '_'; -return sanitized ; + return sanitized; } -void PrometheusClient::incrementCounter( const std::string& counterName ) -{ +void PrometheusClient::incrementCounter(const std::string& counterName) { #ifdef HAVE_PROMETHEUS - std::string sanitizedName = sanitizeMetricName( counterName ) ; - // Check if counter already exists - auto it = counters_.find( sanitizedName ) ; - if( it != counters_.end() ) - { - // Counter exists, increment it - it->second->Increment() ; - } - else - { - // Counter doesn't exist, create it - auto& counterFamily = prometheus::BuildCounter() - .Name( sanitizedName ) - .Help( "Auto-generated counter for " + counterName ) - .Register( *registry_ ) ; - - auto& counter = counterFamily.Add( {} ) ; - counters_[ sanitizedName ] = &counter ; - - // Increment the newly created counter - counter.Increment() ; - - elog << "PrometheusClient: Created new counter '" << sanitizedName << "'" << std::endl ; + std::string sanitizedName = sanitizeMetricName(counterName); + // Check if counter already exists + auto it = counters_.find(sanitizedName); + if (it != counters_.end()) { + // Counter exists, increment it + it->second->Increment(); + } else { + // Counter doesn't exist, create it + auto& counterFamily = prometheus::BuildCounter() + .Name(sanitizedName) + .Help("Auto-generated counter for " + counterName) + .Register(*registry_); + + auto& counter = counterFamily.Add({}); + counters_[sanitizedName] = &counter; + + // Increment the newly created counter + counter.Increment(); + + elog << "PrometheusClient: Created new counter '" << sanitizedName << "'" << std::endl; } #endif } -void PrometheusClient::incrementCounterBy( const std::string& counterName, double value ) -{ - std::string sanitizedName = sanitizeMetricName( counterName ) ; - - // Check if counter already exists - auto it = counters_.find( sanitizedName ) ; - if( it != counters_.end() ) - { - // Counter exists, increment it by value - it->second->Increment( value ) ; - } - else - { - // Counter doesn't exist, create it - auto& counterFamily = prometheus::BuildCounter() - .Name( sanitizedName ) - .Help( "Auto-generated counter for " + counterName ) - .Register( *registry_ ) ; - - auto& counter = counterFamily.Add( {} ) ; - counters_[ sanitizedName ] = &counter ; - - // Increment the newly created counter by value - counter.Increment( value ) ; - - elog << "PrometheusClient: Created new counter '" << sanitizedName << "'" << std::endl ; +void PrometheusClient::incrementCounterBy(const std::string& counterName, double value) { + std::string sanitizedName = sanitizeMetricName(counterName); + + // Check if counter already exists + auto it = counters_.find(sanitizedName); + if (it != counters_.end()) { + // Counter exists, increment it by value + it->second->Increment(value); + } else { + // Counter doesn't exist, create it + auto& counterFamily = prometheus::BuildCounter() + .Name(sanitizedName) + .Help("Auto-generated counter for " + counterName) + .Register(*registry_); + + auto& counter = counterFamily.Add({}); + counters_[sanitizedName] = &counter; + + // Increment the newly created counter by value + counter.Increment(value); + + elog << "PrometheusClient: Created new counter '" << sanitizedName << "'" << std::endl; } } -void PrometheusClient::setGauge( const std::string& gaugeName, double value ) -{ - std::string sanitizedName = sanitizeMetricName( gaugeName ) ; - - // Check if gauge already exists - auto it = gauges_.find( sanitizedName ) ; - if( it != gauges_.end() ) - { - // Gauge exists, set its value - it->second->Set( value ) ; - } - else - { - // Gauge doesn't exist, create it - auto& gaugeFamily = prometheus::BuildGauge() - .Name( sanitizedName ) - .Help( "Auto-generated gauge for " + gaugeName ) - .Register( *registry_ ) ; - - auto& gauge = gaugeFamily.Add( {} ) ; - gauges_[ sanitizedName ] = &gauge ; - - // Set the newly created gauge value - gauge.Set( value ) ; - - elog << "PrometheusClient: Created new gauge '" << sanitizedName << "'" << std::endl ; +void PrometheusClient::setGauge(const std::string& gaugeName, double value) { + std::string sanitizedName = sanitizeMetricName(gaugeName); + + // Check if gauge already exists + auto it = gauges_.find(sanitizedName); + if (it != gauges_.end()) { + // Gauge exists, set its value + it->second->Set(value); + } else { + // Gauge doesn't exist, create it + auto& gaugeFamily = prometheus::BuildGauge() + .Name(sanitizedName) + .Help("Auto-generated gauge for " + gaugeName) + .Register(*registry_); + + auto& gauge = gaugeFamily.Add({}); + gauges_[sanitizedName] = &gauge; + + // Set the newly created gauge value + gauge.Set(value); + + elog << "PrometheusClient: Created new gauge '" << sanitizedName << "'" << std::endl; } } -bool PrometheusClient::sendMessage( int level, const std::string ) -{ - // Use Logger's getLevelName to get consistent level names - std::string levelName = string_lower( Logger::levels[ static_cast< Verbosity >( level ) ].name ) ; - - // Increment counter for this specific log level - incrementCounter( "log_" + levelName + "_total" ) ; - - // Also increment general log counter - incrementCounter( "log_messages_total" ) ; - - ++statSuccessful ; - return true ; +bool PrometheusClient::sendMessage(int level, const std::string) { + // Use Logger's getLevelName to get consistent level names + std::string levelName = string_lower(Logger::levels[static_cast(level)].name); + + // Increment counter for this specific log level + incrementCounter("log_" + levelName + "_total"); + + // Also increment general log counter + incrementCounter("log_messages_total"); + + ++statSuccessful; + return true; } #else // Stub implementation when Prometheus is not available -PrometheusClient::PrometheusClient( xClient* _bot, const std::string&, unsigned short ) - : bot{ _bot } -{ - elog << "PrometheusClient: Prometheus support not compiled in (stub mode)" << std::endl ; +PrometheusClient::PrometheusClient(xClient* _bot, const std::string&, unsigned short) : bot{_bot} { + elog << "PrometheusClient: Prometheus support not compiled in (stub mode)" << std::endl; } -void PrometheusClient::incrementCounter( const std::string& ) -{ } +void PrometheusClient::incrementCounter(const std::string&) {} -void PrometheusClient::incrementCounterBy( const std::string&, double ) -{ } +void PrometheusClient::incrementCounterBy(const std::string&, double) {} -void PrometheusClient::setGauge( const std::string&, double ) -{ } +void PrometheusClient::setGauge(const std::string&, double) {} -bool PrometheusClient::sendMessage( int, const std::string ) -{ return true ; } +bool PrometheusClient::sendMessage(int, const std::string) { return true; } #endif // HAVE_PROMETHEUS diff --git a/libnotifier/prometheus.h b/libnotifier/prometheus.h index 1b75bc65..77dab678 100644 --- a/libnotifier/prometheus.h +++ b/libnotifier/prometheus.h @@ -27,18 +27,17 @@ #include "defs.h" #ifdef HAVE_PROMETHEUS - #include - #include - #include - #include +#include +#include +#include +#include #endif #include "gnuworld_config.h" #include "notifier.h" #include "client.h" -namespace gnuworld -{ +namespace gnuworld { /** * @class PrometheusClient @@ -69,147 +68,143 @@ namespace gnuworld * } * @endcode */ -class PrometheusClient : public notifier -{ - -public: - /** - * @brief Construct a new Prometheus Client - * - * Initializes the Prometheus exposer and registry, starts the HTTP server - * to serve metrics on the specified IP and port. - * - * @param bot Pointer to the xClient instance (for logging and identification) - * @param ip IP address to bind the HTTP server (e.g., "0.0.0.0", "127.0.0.1") - * @param port Port number for the HTTP server (e.g., 9090) - * - * @throws std::runtime_error If the HTTP server cannot bind to the specified address/port - * @throws std::invalid_argument If parameters are invalid - * - * @note The constructor will throw if the port is already in use or if - * the Prometheus library cannot initialize properly - */ - PrometheusClient( xClient* bot, const std::string& ip, unsigned short port ) ; - - /** - * @brief Destroy the Prometheus Client - * - * Automatically stops the HTTP server and cleans up all metrics. - */ - virtual ~PrometheusClient() = default ; - - /** - * @return size_t Count of successful metric updates (counters + gauges) - */ - [[nodiscard]] size_t getSuccessful() const override - { return statSuccessful ; } - - /** - * @return size_t Count of failed metric operations (due to invalid names, etc.) - */ - [[nodiscard]] size_t getErrors() const override - { return statErrors ; } - - /** - * @brief This method is called automatically by the logging system - * when this client is registered as a notifier - * Increments counters based on log severity levels. - */ - bool sendMessage( int level, const std::string message ) override ; - - /** - * @brief Increment a counter by 1 - * - * Creates the counter if it doesn't exist, then increments by 1. - * Counter names are automatically sanitized to comply with Prometheus naming rules. - * The counter name will be prefixed with the bot's nickname to avoid conflicts. - * - * @param counterName Name of the counter (will be sanitized) - * - * @note Counters are monotonically increasing - use for events like: - * - Connection attempts - * - Messages processed - * - Errors encountered - * - * @warning This method is thread-safe but metric creation is not atomic. - * Multiple threads creating the same metric simultaneously may cause issues. - */ - void incrementCounter( const std::string& counterName ) ; - - /** - * @brief Increment a counter by a specific value - * - * Creates the counter if it doesn't exist, then increments by the specified amount. - * Useful for batch operations or weighted metrics. - * - * @param counterName Name of the counter (will be sanitized) - * @param value Amount to increment (must be >= 0 for counters) - * - * @note If value is negative, it will be treated as 0 (counters cannot decrease) - */ - void incrementCounterBy( const std::string& counterName, double value ) ; - - /** - * @brief Set a gauge to a specific value - * - * Creates the gauge if it doesn't exist, then sets it to the specified value. - * Gauges can increase or decrease and represent current state. - * The gauge name will be prefixed with the bot's nickname to avoid conflicts. - * - * @param gaugeName Name of the gauge (will be sanitized) - * @param value Value to set the gauge to (can be any double) - * - * @note Gauges are for values that can go up/down - use for metrics like: - * - Active user count - * - Memory usage - * - Queue lengths - * - Temperature readings - */ - void setGauge( const std::string& gaugeName, double value ) ; - -private: - xClient* bot = nullptr ; - - /** - * @brief Sanitize metric names to comply with Prometheus standards - * - * Prometheus metric names must match: [a-zA-Z_:][a-zA-Z0-9_:]* - * This function: - * - Converts to lowercase - * - Replaces invalid characters with underscores - * - Ensures the first character is valid - * - Adds bot name prefix to avoid conflicts - * - * @param name Original metric name - * @return std::string Sanitized metric name safe for Prometheus - * - * @note Examples: - * - "user-count" → "botname_user_count" - * - "123invalid" → "botname_123invalid" - * - "SASL.SUCCESS" → "botname_sasl_success" - */ - std::string sanitizeMetricName( const std::string& name ) ; +class PrometheusClient : public notifier { + + public: + /** + * @brief Construct a new Prometheus Client + * + * Initializes the Prometheus exposer and registry, starts the HTTP server + * to serve metrics on the specified IP and port. + * + * @param bot Pointer to the xClient instance (for logging and identification) + * @param ip IP address to bind the HTTP server (e.g., "0.0.0.0", "127.0.0.1") + * @param port Port number for the HTTP server (e.g., 9090) + * + * @throws std::runtime_error If the HTTP server cannot bind to the specified address/port + * @throws std::invalid_argument If parameters are invalid + * + * @note The constructor will throw if the port is already in use or if + * the Prometheus library cannot initialize properly + */ + PrometheusClient(xClient* bot, const std::string& ip, unsigned short port); + + /** + * @brief Destroy the Prometheus Client + * + * Automatically stops the HTTP server and cleans up all metrics. + */ + virtual ~PrometheusClient() = default; + + /** + * @return size_t Count of successful metric updates (counters + gauges) + */ + [[nodiscard]] size_t getSuccessful() const override { return statSuccessful; } + + /** + * @return size_t Count of failed metric operations (due to invalid names, etc.) + */ + [[nodiscard]] size_t getErrors() const override { return statErrors; } + + /** + * @brief This method is called automatically by the logging system + * when this client is registered as a notifier + * Increments counters based on log severity levels. + */ + bool sendMessage(int level, const std::string message) override; + + /** + * @brief Increment a counter by 1 + * + * Creates the counter if it doesn't exist, then increments by 1. + * Counter names are automatically sanitized to comply with Prometheus naming rules. + * The counter name will be prefixed with the bot's nickname to avoid conflicts. + * + * @param counterName Name of the counter (will be sanitized) + * + * @note Counters are monotonically increasing - use for events like: + * - Connection attempts + * - Messages processed + * - Errors encountered + * + * @warning This method is thread-safe but metric creation is not atomic. + * Multiple threads creating the same metric simultaneously may cause issues. + */ + void incrementCounter(const std::string& counterName); + + /** + * @brief Increment a counter by a specific value + * + * Creates the counter if it doesn't exist, then increments by the specified amount. + * Useful for batch operations or weighted metrics. + * + * @param counterName Name of the counter (will be sanitized) + * @param value Amount to increment (must be >= 0 for counters) + * + * @note If value is negative, it will be treated as 0 (counters cannot decrease) + */ + void incrementCounterBy(const std::string& counterName, double value); + + /** + * @brief Set a gauge to a specific value + * + * Creates the gauge if it doesn't exist, then sets it to the specified value. + * Gauges can increase or decrease and represent current state. + * The gauge name will be prefixed with the bot's nickname to avoid conflicts. + * + * @param gaugeName Name of the gauge (will be sanitized) + * @param value Value to set the gauge to (can be any double) + * + * @note Gauges are for values that can go up/down - use for metrics like: + * - Active user count + * - Memory usage + * - Queue lengths + * - Temperature readings + */ + void setGauge(const std::string& gaugeName, double value); + + private: + xClient* bot = nullptr; + + /** + * @brief Sanitize metric names to comply with Prometheus standards + * + * Prometheus metric names must match: [a-zA-Z_:][a-zA-Z0-9_:]* + * This function: + * - Converts to lowercase + * - Replaces invalid characters with underscores + * - Ensures the first character is valid + * - Adds bot name prefix to avoid conflicts + * + * @param name Original metric name + * @return std::string Sanitized metric name safe for Prometheus + * + * @note Examples: + * - "user-count" → "botname_user_count" + * - "123invalid" → "botname_123invalid" + * - "SASL.SUCCESS" → "botname_sasl_success" + */ + std::string sanitizeMetricName(const std::string& name); #ifdef HAVE_PROMETHEUS - /** @brief Prometheus HTTP server for exposing metrics */ - prometheus::Exposer exposer_ ; + /** @brief Prometheus HTTP server for exposing metrics */ + prometheus::Exposer exposer_; - /** @brief Registry for all metrics - shared pointer for thread safety */ - std::shared_ptr< prometheus::Registry > registry_ ; + /** @brief Registry for all metrics - shared pointer for thread safety */ + std::shared_ptr registry_; - /** @brief Map of counter names to counter instances for fast lookup */ - std::unordered_map< std::string, prometheus::Counter* > counters_ ; + /** @brief Map of counter names to counter instances for fast lookup */ + std::unordered_map counters_; - /** @brief Map of gauge names to gauge instances for fast lookup */ - std::unordered_map< std::string, prometheus::Gauge* > gauges_ ; + /** @brief Map of gauge names to gauge instances for fast lookup */ + std::unordered_map gauges_; #endif - /** @brief Count of successful metric operations */ - size_t statSuccessful = 0 ; + /** @brief Count of successful metric operations */ + size_t statSuccessful = 0; - /** @brief Count of failed metric operations */ - size_t statErrors = 0 ; - -} ; + /** @brief Count of failed metric operations */ + size_t statErrors = 0; +}; } // namespace gnuworld diff --git a/libnotifier/pushover.cc b/libnotifier/pushover.cc index 524b3021..adafd6b7 100644 --- a/libnotifier/pushover.cc +++ b/libnotifier/pushover.cc @@ -20,7 +20,7 @@ #include "defs.h" #ifdef HAVE_LIBCURL - #include +#include #endif #include @@ -33,162 +33,138 @@ #include "threadworker.h" #include "logger.h" -namespace gnuworld -{ +namespace gnuworld { -PushoverClient::PushoverClient( xClient* _bot, std::string token, - pushoverKeysType users +PushoverClient::PushoverClient(xClient* _bot, std::string token, pushoverKeysType users #ifdef USE_THREAD - , ThreadWorker* worker + , + ThreadWorker* worker #endif -) - : bot( _bot ), apiToken( token ), userKeys( users ) + ) + : bot(_bot), apiToken(token), userKeys(users) #ifdef USE_THREAD - , threadWorker( worker ) + , + threadWorker(worker) #endif -{} +{ +} #ifdef HAVE_LIBCURL -void PushoverClient::initialise_curl() -{ - static bool initialized = false ; - if( !initialized ) - { - curl_global_init( CURL_GLOBAL_DEFAULT ) ; - initialized = true ; +void PushoverClient::initialise_curl() { + static bool initialized = false; + if (!initialized) { + curl_global_init(CURL_GLOBAL_DEFAULT); + initialized = true; } } #endif -bool PushoverClient::sendMessage( int level, const std::string message ) -{ +bool PushoverClient::sendMessage(int level, const std::string message) { #ifdef HAVE_FORMAT - return sendMessage( std::format( "[{}] {}", bot->getNickName(), Logger::levels[ level ].name ), message ) ; + return sendMessage(std::format("[{}] {}", bot->getNickName(), Logger::levels[level].name), + message); #else - return false ; + return false; #endif } -bool PushoverClient::sendMessage( const std::string title, - const std::string message ) -{ - return sendMessage( title, message, 0, 60, 3600 ) ; +bool PushoverClient::sendMessage(const std::string title, const std::string message) { + return sendMessage(title, message, 0, 60, 3600); } -bool PushoverClient::sendMessage( const std::string title, - const std::string message, - int priority, - int retry, - int expire ) -{ +bool PushoverClient::sendMessage(const std::string title, const std::string message, int priority, + int retry, int expire) { #ifdef USE_THREAD - if( threadWorker ) - { - threadWorker->submitJob( [this, title, message, priority, retry, expire]() { - this->processMessage( title, message, priority, retry, expire ) ; - } ) ; - return true; // Assume success for async operations - } - else + if (threadWorker) { + threadWorker->submitJob([this, title, message, priority, retry, expire]() { + this->processMessage(title, message, priority, retry, expire); + }); + return true; // Assume success for async operations + } else #endif { - bool ok = processMessage( title, message, priority, retry, expire ) ; - if( !ok ) - { - elog << "[PUSHOVER-ERROR] Failed to send message: " << message << std::endl ; - statErrors++ ; - } - return ok ; + bool ok = processMessage(title, message, priority, retry, expire); + if (!ok) { + elog << "[PUSHOVER-ERROR] Failed to send message: " << message << std::endl; + statErrors++; + } + return ok; } } -bool PushoverClient::processMessage( const std::string title, - const std::string message, - int priority, - int retry, - int expire ) -{ -bool allSucceeded = true ; - -for( const auto& user : userKeys ) - { - bool ok = sendToUser( user, title, message, priority, retry, expire ) ; - if( !ok ) - { - elog << "[PUSHOVER-ERROR] Failed to send to user: " << user << std::endl ; - statErrors++ ; - allSucceeded = false; +bool PushoverClient::processMessage(const std::string title, const std::string message, + int priority, int retry, int expire) { + bool allSucceeded = true; + + for (const auto& user : userKeys) { + bool ok = sendToUser(user, title, message, priority, retry, expire); + if (!ok) { + elog << "[PUSHOVER-ERROR] Failed to send to user: " << user << std::endl; + statErrors++; + allSucceeded = false; + } } - } -return allSucceeded ; + return allSucceeded; } - -bool PushoverClient::sendToUser( [[maybe_unused]] const std::string user, - [[maybe_unused]] const std::string title, - [[maybe_unused]] const std::string message, - [[maybe_unused]] int priority, - [[maybe_unused]] int retry, - [[maybe_unused]] int expire ) -{ -#ifdef HAVE_LIBCURL -try { - initialise_curl() ; - - std::string safeTitle = truncate( title, 250 ) ; - std::string safeMessage = truncate( message, 1024 ) ; - std::ostringstream postData ; - postData << "token=" << apiToken - << "&user=" << user - << "&title=" << safeTitle - << "&message=" << safeMessage - << "&priority=" << priority ; - - if( priority == 2 ) - { - retry = std::max( 10, retry ) ; - expire = std::min( 10800, expire ) ; - postData << "&retry=" << retry << "&expire=" << expire ; +bool PushoverClient::sendToUser([[maybe_unused]] const std::string user, + [[maybe_unused]] const std::string title, + [[maybe_unused]] const std::string message, + [[maybe_unused]] int priority, [[maybe_unused]] int retry, + [[maybe_unused]] int expire) { +#ifdef HAVE_LIBCURL + try { + initialise_curl(); + + std::string safeTitle = truncate(title, 250); + std::string safeMessage = truncate(message, 1024); + + std::ostringstream postData; + postData << "token=" << apiToken << "&user=" << user << "&title=" << safeTitle + << "&message=" << safeMessage << "&priority=" << priority; + + if (priority == 2) { + retry = std::max(10, retry); + expire = std::min(10800, expire); + postData << "&retry=" << retry << "&expire=" << expire; + } + + std::string url = "https://api.pushover.net/1/messages.json"; + std::string body = postData.str(); + + CURL* curl = curl_easy_init(); + if (nullptr == curl) + throw std::runtime_error("curl_easy_init failed"); + + struct curl_slist* hdrs = nullptr; + hdrs = curl_slist_append(hdrs, "Content-Type: application/x-www-form-urlencoded"); + + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hdrs); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, body.c_str()); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3L); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L); + curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_1_1); + + CURLcode rc = curl_easy_perform(curl); + curl_slist_free_all(hdrs); + curl_easy_cleanup(curl); + if (rc != CURLE_OK) + throw std::runtime_error(curl_easy_strerror(rc)); + + statSuccessful++; + elog << "[PUSHOVER] Message sent to user: " << user << " with title: " << safeTitle + << " and message: " << safeMessage << std::endl; + return true; + } catch (const std::exception& e) { + elog << "[PUSHOVER-ERROR] exception: " << e.what() << std::endl; + } catch (...) { + elog << "[PUSHOVER-ERROR] unknown exception" << std::endl; } - - std::string url = "https://api.pushover.net/1/messages.json" ; - std::string body = postData.str() ; - - CURL* curl = curl_easy_init() ; - if( nullptr == curl ) - throw std::runtime_error( "curl_easy_init failed" ) ; - - struct curl_slist* hdrs = nullptr ; - hdrs = curl_slist_append( hdrs, "Content-Type: application/x-www-form-urlencoded" ) ; - - curl_easy_setopt( curl, CURLOPT_URL, url.c_str() ) ; - curl_easy_setopt( curl, CURLOPT_HTTPHEADER, hdrs ) ; - curl_easy_setopt( curl, CURLOPT_POST, 1L ) ; - curl_easy_setopt( curl, CURLOPT_COPYPOSTFIELDS, body.c_str() ) ; - curl_easy_setopt( curl, CURLOPT_CONNECTTIMEOUT, 3L ) ; - curl_easy_setopt( curl, CURLOPT_TIMEOUT, 5L ) ; - curl_easy_setopt( curl, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_1_1 ) ; - - CURLcode rc = curl_easy_perform( curl ) ; - curl_slist_free_all( hdrs ) ; - curl_easy_cleanup( curl ) ; - if( rc != CURLE_OK ) - throw std::runtime_error( curl_easy_strerror( rc ) ) ; - - statSuccessful++ ; - elog << "[PUSHOVER] Message sent to user: " << user - << " with title: " << safeTitle - << " and message: " << safeMessage - << std::endl ; - return true ; -} catch( const std::exception& e ) { - elog << "[PUSHOVER-ERROR] exception: " << e.what() << std::endl ; -} catch( ... ) { - elog << "[PUSHOVER-ERROR] unknown exception" << std::endl ; -} #endif -return false ; + return false; } } // namespace gnuworld diff --git a/libnotifier/pushover.h b/libnotifier/pushover.h index 9cccc117..85dc1220 100644 --- a/libnotifier/pushover.h +++ b/libnotifier/pushover.h @@ -26,82 +26,66 @@ #include "gnuworld_config.h" #include "notifier.h" -namespace gnuworld -{ +namespace gnuworld { -typedef std::vector< std::string > pushoverKeysType ; +typedef std::vector pushoverKeysType; #ifdef USE_THREAD -class ThreadWorker ; +class ThreadWorker; #endif -class PushoverClient : public notifier -{ +class PushoverClient : public notifier { -public: - PushoverClient( xClient*, std::string, pushoverKeysType + public: + PushoverClient(xClient*, std::string, pushoverKeysType #ifdef USE_THREAD - , ThreadWorker* + , + ThreadWorker* #endif - ) ; + ); - virtual ~PushoverClient() = default ; + virtual ~PushoverClient() = default; - void setUserKeys( const pushoverKeysType& newUsers ) - { userKeys = newUsers ; } + void setUserKeys(const pushoverKeysType& newUsers) { userKeys = newUsers; } - void setToken( const std::string& newToken ) - { apiToken = newToken ; } + void setToken(const std::string& newToken) { apiToken = newToken; } - [[nodiscard]] size_t getSuccessful() const override - { return statSuccessful ; } + [[nodiscard]] size_t getSuccessful() const override { return statSuccessful; } - [[nodiscard]] size_t getErrors() const override - { return statErrors ; } + [[nodiscard]] size_t getErrors() const override { return statErrors; } - [[nodiscard]] size_t userKeys_size() const - { return userKeys.size() ; } + [[nodiscard]] size_t userKeys_size() const { return userKeys.size(); } - bool sendMessage( int level, const std::string message ) override ; + bool sendMessage(int level, const std::string message) override; - bool sendMessage( const std::string title, - const std::string message ) ; + bool sendMessage(const std::string title, const std::string message); - bool sendMessage( const std::string title, - const std::string message, - int priority, - int retry = 60, - int expire = 3600 ) ; + bool sendMessage(const std::string title, const std::string message, int priority, + int retry = 60, int expire = 3600); -private: - xClient* bot ; - std::string apiToken ; - pushoverKeysType userKeys ; - size_t statSuccessful = 0 ; - size_t statErrors = 0 ; + private: + xClient* bot; + std::string apiToken; + pushoverKeysType userKeys; + size_t statSuccessful = 0; + size_t statErrors = 0; #ifdef USE_THREAD - ThreadWorker* threadWorker = nullptr ; + ThreadWorker* threadWorker = nullptr; #endif #ifdef HAVE_LIBCURL - void initialise_curl() ; + void initialise_curl(); #endif - std::string truncate( const std::string input, std::size_t maxLength ) const - { return input.size() <= maxLength ? input : input.substr( 0, maxLength - 3 ) + "..." ; } - - bool processMessage( const std::string title, - const std::string message, - int priority, - int retry, - int expire ) ; - - bool sendToUser( const std::string user, - const std::string title, - const std::string message, - int priority, - int retry, - int expire ) ; -} ; + std::string truncate(const std::string input, std::size_t maxLength) const { + return input.size() <= maxLength ? input : input.substr(0, maxLength - 3) + "..."; + } + + bool processMessage(const std::string title, const std::string message, int priority, int retry, + int expire); + + bool sendToUser(const std::string user, const std::string title, const std::string message, + int priority, int retry, int expire); +}; } // namespace gnuworld diff --git a/mod.ccontrol/ADDCOMMANDCommand.cc b/mod.ccontrol/ADDCOMMANDCommand.cc index ad8debbd..384dc40f 100644 --- a/mod.ccontrol/ADDCOMMANDCommand.cc +++ b/mod.ccontrol/ADDCOMMANDCommand.cc @@ -19,335 +19,268 @@ * * $Id: ADDCOMMANDCommand.cc,v 1.31 2009/07/25 18:12:34 hidden1 Exp $ */ - -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "ccUser.h" -#include "misc.h" +#include -namespace gnuworld -{ +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "ccUser.h" +#include "misc.h" -using std::string ; +namespace gnuworld { -namespace uworld -{ +using std::string; -bool ADDCOMMANDCommand::Exec( iClient* theClient, const string& Message) -{ -StringTokenizer st( Message ) ; +namespace uworld { -if( st.size() < 3 ) - { - Usage(theClient); - return true; - } +bool ADDCOMMANDCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -StringTokenizer::size_type pos = 1; -ccUser *AClient = bot->IsAuth( theClient ); + if (st.size() < 3) { + Usage(theClient); + return true; + } -if( NULL == AClient ) - { - bot->Notice( theClient, "You must be authenticated to use this command." ) ; - return true ; - } + StringTokenizer::size_type pos = 1; + ccUser* AClient = bot->IsAuth(theClient); -bool Forced = false; -if(!strcasecmp(st[pos],"-fr")) - { - Forced = true; - pos++; - if(st.size() < 4) - { - Usage(theClient); - } - } + if (NULL == AClient) { + bot->Notice(theClient, "You must be authenticated to use this command."); + return true; + } -bool AllOpers = false; -bool AllAdmins = false; -bool AllSmts = false; -bool AllCoders = false; -while ((!strcasecmp(st[pos],"-allopers")) || (!strcasecmp(st[pos],"-alladmins")) || (!strcasecmp(st[pos],"-allsmts")) || (!strcasecmp(st[pos],"-allcoders"))) { -if(!strcasecmp(st[pos],"-allopers")) - { - if (AClient->getType() < operLevel::CODERLEVEL) - { - bot->Notice(theClient, "-allopers: This is coder level"); - return true; - } - pos++; - AllOpers = true; - if ((st.size() - pos) < 1) - { - Usage(theClient); - } - } + bool Forced = false; + if (!strcasecmp(st[pos], "-fr")) { + Forced = true; + pos++; + if (st.size() < 4) { + Usage(theClient); + } + } -if(!strcasecmp(st[pos],"-alladmins")) - { - if (AClient->getType() < operLevel::CODERLEVEL) - { - bot->Notice(theClient, "-alladmins: This is coder level"); - return true; - } - pos++; - AllAdmins = true; - if ((st.size() - pos) < 1) - { - Usage(theClient); - } - } + bool AllOpers = false; + bool AllAdmins = false; + bool AllSmts = false; + bool AllCoders = false; + while ((!strcasecmp(st[pos], "-allopers")) || (!strcasecmp(st[pos], "-alladmins")) || + (!strcasecmp(st[pos], "-allsmts")) || (!strcasecmp(st[pos], "-allcoders"))) { + if (!strcasecmp(st[pos], "-allopers")) { + if (AClient->getType() < operLevel::CODERLEVEL) { + bot->Notice(theClient, "-allopers: This is coder level"); + return true; + } + pos++; + AllOpers = true; + if ((st.size() - pos) < 1) { + Usage(theClient); + } + } -if(!strcasecmp(st[pos],"-allsmts")) - { - if (AClient->getType() < operLevel::CODERLEVEL) - { - bot->Notice(theClient, "-allsmts: This is coder level"); - return true; - } - pos++; - AllSmts = true; - if ((st.size() - pos) < 1) - { - Usage(theClient); - } - } + if (!strcasecmp(st[pos], "-alladmins")) { + if (AClient->getType() < operLevel::CODERLEVEL) { + bot->Notice(theClient, "-alladmins: This is coder level"); + return true; + } + pos++; + AllAdmins = true; + if ((st.size() - pos) < 1) { + Usage(theClient); + } + } -if(!strcasecmp(st[pos],"-allcoders")) - { - if (AClient->getType() < operLevel::CODERLEVEL) - { - bot->Notice(theClient, "-allcoders: This is coder level"); - return true; - } - pos++; - AllCoders = true; - if ((st.size() - pos) < 1) - { - Usage(theClient); - } - } -} + if (!strcasecmp(st[pos], "-allsmts")) { + if (AClient->getType() < operLevel::CODERLEVEL) { + bot->Notice(theClient, "-allsmts: This is coder level"); + return true; + } + pos++; + AllSmts = true; + if ((st.size() - pos) < 1) { + Usage(theClient); + } + } -// Fetch the oper record from the db -ccUser* theUser; -if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) - { - if (st[pos].size() > 64) - { - bot->Notice(theClient,"Oper name can't be more than 64 characters in length."); - return false; - } + if (!strcasecmp(st[pos], "-allcoders")) { + if (AClient->getType() < operLevel::CODERLEVEL) { + bot->Notice(theClient, "-allcoders: This is coder level"); + return true; + } + pos++; + AllCoders = true; + if ((st.size() - pos) < 1) { + Usage(theClient); + } + } + } - theUser = bot->GetOper(st[pos]); - if( !theUser ) - { - bot->Notice( theClient, - "I can't find oper %s", - st[pos].c_str()); - return false; - } - pos++; - } -else - theUser = 0; + // Fetch the oper record from the db + ccUser* theUser; + if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) { + if (st[pos].size() > 64) { + bot->Notice(theClient, "Oper name can't be more than 64 characters in length."); + return false; + } -//int CommandLevel = bot->getCommandLevel(st[pos]); -if(st[pos].size() > 128) - { - bot->Notice(theClient,"Command name can't be more than 128 characters in length."); - return false; - } -Command* Comm = bot->findCommandInMem(st[pos]); -if( !Comm ) - { - bot->Notice( theClient, - "Command '%s' does not exist!", - st[pos].c_str()); - return false; - } + theUser = bot->GetOper(st[pos]); + if (!theUser) { + bot->Notice(theClient, "I can't find oper %s", st[pos].c_str()); + return false; + } + pos++; + } else + theUser = 0; -bot->MsgChanLog("ADDCOMMAND %s\n",st.assemble(1).c_str()); + // int CommandLevel = bot->getCommandLevel(st[pos]); + if (st[pos].size() > 128) { + bot->Notice(theClient, "Command name can't be more than 128 characters in length."); + return false; + } + Command* Comm = bot->findCommandInMem(st[pos]); + if (!Comm) { + bot->Notice(theClient, "Command '%s' does not exist!", st[pos].c_str()); + return false; + } -// Only allow opers who have access to that command to add it to new opers -if (!AClient->gotAccess(Comm) && AClient->getType() != operLevel::CODERLEVEL) // Coders can add any command - { - bot->Notice( theClient, - "You must have access to a command in order to add it."); - return false; - } + bot->MsgChanLog("ADDCOMMAND %s\n", st.assemble(1).c_str()); -list ccList; -if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) - { - ccList.push_back(theUser); - } -else - { - if (AllOpers) - { - if (AllAdmins) - { - bot->Notice(theClient, "No need to specify -alladmins if you specified -allopers"); - AllAdmins = false; - } - if (AllSmts) - { - bot->Notice(theClient, "No need to specify -allsmts if you specified -allopers"); - AllSmts = false; - } - if (AllCoders) - { - bot->Notice(theClient, "No need to specify -allcoders if you specified -allopers"); - AllCoders = false; - } - } - if (AllAdmins) - { - if (AllSmts) - { - bot->Notice(theClient, "No need to specify -allsmts if you specified -alladmins"); - AllSmts = false; - } - if (AllCoders) - { - bot->Notice(theClient, "No need to specify -allcoders if you specified -alladmins"); - AllCoders = false; - } - } - if (AllSmts) - { - if (AllCoders) - { - bot->Notice(theClient, "No need to specify -allcoders if you specified -allsmts"); - AllCoders = false; - } - } + // Only allow opers who have access to that command to add it to new opers + if (!AClient->gotAccess(Comm) && + AClient->getType() != operLevel::CODERLEVEL) // Coders can add any command + { + bot->Notice(theClient, "You must have access to a command in order to add it."); + return false; + } - ccontrol::usersconstiterator uItr = bot->usersmap_begin(); - for (; uItr != bot->usersmap_end(); uItr++) - { - if (AllOpers) - { - ccList.push_back(uItr->second); - } - else if ((AllAdmins) && (uItr->second->getType() >= operLevel::ADMINLEVEL)) - { - ccList.push_back(uItr->second); - } - else if ((AllSmts) && (uItr->second->getType() >= operLevel::SMTLEVEL)) - { - ccList.push_back(uItr->second); - } - else if ((AllCoders) && (uItr->second->getType() >= operLevel::CODERLEVEL)) - { - ccList.push_back(uItr->second); - } - } - } + list ccList; + if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) { + ccList.push_back(theUser); + } else { + if (AllOpers) { + if (AllAdmins) { + bot->Notice(theClient, "No need to specify -alladmins if you specified -allopers"); + AllAdmins = false; + } + if (AllSmts) { + bot->Notice(theClient, "No need to specify -allsmts if you specified -allopers"); + AllSmts = false; + } + if (AllCoders) { + bot->Notice(theClient, "No need to specify -allcoders if you specified -allopers"); + AllCoders = false; + } + } + if (AllAdmins) { + if (AllSmts) { + bot->Notice(theClient, "No need to specify -allsmts if you specified -alladmins"); + AllSmts = false; + } + if (AllCoders) { + bot->Notice(theClient, "No need to specify -allcoders if you specified -alladmins"); + AllCoders = false; + } + } + if (AllSmts) { + if (AllCoders) { + bot->Notice(theClient, "No need to specify -allcoders if you specified -allsmts"); + AllCoders = false; + } + } -bool sentOnce = false; -int count = 0; -for (list::iterator Itr = ccList.begin(); Itr != ccList.end(); Itr++) - { - theUser = *Itr; + ccontrol::usersconstiterator uItr = bot->usersmap_begin(); + for (; uItr != bot->usersmap_end(); uItr++) { + if (AllOpers) { + ccList.push_back(uItr->second); + } else if ((AllAdmins) && (uItr->second->getType() >= operLevel::ADMINLEVEL)) { + ccList.push_back(uItr->second); + } else if ((AllSmts) && (uItr->second->getType() >= operLevel::SMTLEVEL)) { + ccList.push_back(uItr->second); + } else if ((AllCoders) && (uItr->second->getType() >= operLevel::CODERLEVEL)) { + ccList.push_back(uItr->second); + } + } + } - bool Admin = false ; - if(AClient->getType() < operLevel::SMTLEVEL) - Admin = true; - else - Admin = false; + bool sentOnce = false; + int count = 0; + for (list::iterator Itr = ccList.begin(); Itr != ccList.end(); Itr++) { + theUser = *Itr; - if((Admin) && (AClient->getType() <= theUser->getType())) - { - bot->Notice(theClient,"You can't modify a user who has an " - "equal or higher access level than you"); - return false; - } - else if(!(Admin) && (AClient->getType() < theUser->getType())) - { - bot->Notice(theClient,"You can't modify a user who has a higher " - "access level than you"); - return false; - } - if((Admin) && (strcasecmp(AClient->getServer(),theUser->getServer()))) - { - bot->Notice(theClient,"You can only modify a user who is " - "associated with the same server as you"); - return false; - } - if(Forced) - { - if((AClient->getType() < operLevel::SMTLEVEL) && ((bot->findCommandInMem(st[pos]))->getMinLevel() > theUser->getType())) - { - bot->Notice(theClient,"Only SMT+ can force the addition of a command"); - return false; - } - } - else if (Comm->getMinLevel() > theUser->getType()) - { - if (!sentOnce) - { - if (AClient->getType() >= operLevel::SMTLEVEL) - bot->Notice(theClient, - "The minimum level required to use this command " - "is higher than the one the oper has, use " - "\002-fr\002 if you still want to add it"); - else - bot->Notice(theClient, - "The minimum level required to use this command " - "is higher than the one the oper has"); - sentOnce = true; - } - if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) - return false; - else - continue; - } - - if (theUser->gotAccess(Comm)) - { - if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) - { - bot->Notice( theClient, - "%s already has access to '%s'", - theUser->getUserName().c_str(), - st[pos].c_str()); - return false; - } - else - continue; - } + bool Admin = false; + if (AClient->getType() < operLevel::SMTLEVEL) + Admin = true; + else + Admin = false; - //Add the command and update the user db record - theUser->addCommand(Comm); - theUser->setLast_Updated_By(theClient->getRealNickUserHost()); - if(theUser->Update()) - { - bot->Notice( theClient, - "Successfully added the command for %s", - theUser->getUserName().c_str()); - if(Forced) - bot->MsgChanLog("%s is using -fr to add '%s' to %s" - ,theClient->getNickName().c_str(),st[pos].c_str() - ,theUser->getUserName().c_str()); - // If the user is authenticated update his authenticate entry - count++; - if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) - return true; - else - continue; - } + if ((Admin) && (AClient->getType() <= theUser->getType())) { + bot->Notice(theClient, "You can't modify a user who has an " + "equal or higher access level than you"); + return false; + } else if (!(Admin) && (AClient->getType() < theUser->getType())) { + bot->Notice(theClient, "You can't modify a user who has a higher " + "access level than you"); + return false; + } + if ((Admin) && (strcasecmp(AClient->getServer(), theUser->getServer()))) { + bot->Notice(theClient, "You can only modify a user who is " + "associated with the same server as you"); + return false; + } + if (Forced) { + if ((AClient->getType() < operLevel::SMTLEVEL) && + ((bot->findCommandInMem(st[pos]))->getMinLevel() > theUser->getType())) { + bot->Notice(theClient, "Only SMT+ can force the addition of a command"); + return false; + } + } else if (Comm->getMinLevel() > theUser->getType()) { + if (!sentOnce) { + if (AClient->getType() >= operLevel::SMTLEVEL) + bot->Notice(theClient, "The minimum level required to use this command " + "is higher than the one the oper has, use " + "\002-fr\002 if you still want to add it"); + else + bot->Notice(theClient, "The minimum level required to use this command " + "is higher than the one the oper has"); + sentOnce = true; + } + if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) + return false; + else + continue; + } - bot->Notice( theClient, "Error while adding command for %s", - theUser->getUserName().c_str()); - return false; - } -bot->Notice(theClient, "Gave %s access to %d users", Comm->getName().c_str(), count); -return true; -} -} + if (theUser->gotAccess(Comm)) { + if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) { + bot->Notice(theClient, "%s already has access to '%s'", + theUser->getUserName().c_str(), st[pos].c_str()); + return false; + } else + continue; + } + + // Add the command and update the user db record + theUser->addCommand(Comm); + theUser->setLast_Updated_By(theClient->getRealNickUserHost()); + if (theUser->Update()) { + bot->Notice(theClient, "Successfully added the command for %s", + theUser->getUserName().c_str()); + if (Forced) + bot->MsgChanLog("%s is using -fr to add '%s' to %s", + theClient->getNickName().c_str(), st[pos].c_str(), + theUser->getUserName().c_str()); + // If the user is authenticated update his authenticate entry + count++; + if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) + return true; + else + continue; + } + + bot->Notice(theClient, "Error while adding command for %s", theUser->getUserName().c_str()); + return false; + } + bot->Notice(theClient, "Gave %s access to %d users", Comm->getName().c_str(), count); + return true; } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/ADDOPERCHANCommand.cc b/mod.ccontrol/ADDOPERCHANCommand.cc index d9e46598..5af86ca7 100644 --- a/mod.ccontrol/ADDOPERCHANCommand.cc +++ b/mod.ccontrol/ADDOPERCHANCommand.cc @@ -1,6 +1,6 @@ /** * ADDOPERCHANCommand.cc - * Add a new irc operator channel + * Add a new irc operator channel * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,56 +19,44 @@ * * $Id: ADDOPERCHANCommand.cc,v 1.12 2006/09/26 17:35:57 kewlio Exp $ */ - -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" +#include -namespace gnuworld -{ +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" -namespace uworld -{ +namespace gnuworld { -using std::string ; +namespace uworld { -bool ADDOPERCHANCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } +using std::string; -string chanName = st[ 1 ] ; -if( '#' != chanName[ 0 ] ) - { - bot->Notice( theClient, "Invalid channel name" ) ; - return true ; - } +bool ADDOPERCHANCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + if (st.size() < 2) { + Usage(theClient); + return true; + } -if(chanName.length() > channel::MaxName) - { - bot->Notice( theClient,"Channel name too long" ); - return true; - } + string chanName = st[1]; + if ('#' != chanName[0]) { + bot->Notice(theClient, "Invalid channel name"); + return true; + } -if( bot->addOperChan( chanName ) ) - { - bot->Notice( theClient, "Addition of %s as oper chan has SUCCEEDED", - chanName.c_str() ) ; - } -else - { - bot->Notice( theClient, "Addition of %s as oper chan has FAILED", - chanName.c_str() ) ; - } -return true ; -} -} -} + if (chanName.length() > channel::MaxName) { + bot->Notice(theClient, "Channel name too long"); + return true; + } + if (bot->addOperChan(chanName)) { + bot->Notice(theClient, "Addition of %s as oper chan has SUCCEEDED", chanName.c_str()); + } else { + bot->Notice(theClient, "Addition of %s as oper chan has FAILED", chanName.c_str()); + } + return true; +} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/ADDSERVERCommand.cc b/mod.ccontrol/ADDSERVERCommand.cc index 9c6280fc..0c87806a 100644 --- a/mod.ccontrol/ADDSERVERCommand.cc +++ b/mod.ccontrol/ADDSERVERCommand.cc @@ -20,106 +20,90 @@ * $Id: ADDSERVERCommand.cc,v 1.17 2006/09/26 17:35:58 kewlio Exp $ */ -#include +#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "Constants.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "Constants.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { -bool ADDSERVERCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } +bool ADDSERVERCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + if (st.size() < 2) { + Usage(theClient); + return true; + } -if(st[1].size() > server::MaxName) - { - bot->Notice(theClient,"Server name can't be more than %d " - "characters in length.", - server::MaxName); - return false; - } + if (st[1].size() > server::MaxName) { + bot->Notice(theClient, + "Server name can't be more than %d " + "characters in length.", + server::MaxName); + return false; + } -string SName; -if(string::npos != st[1].find_first_of('*')) - { - iServer* tServer = Network->findExpandedServerName(st[1]); + string SName; + if (string::npos != st[1].find_first_of('*')) { + iServer* tServer = Network->findExpandedServerName(st[1]); - if(!tServer) - { - bot->Notice(theClient,"I can't find a linked server " - "that matches %s", - st[1].c_str()); - return false; - } + if (!tServer) { + bot->Notice(theClient, + "I can't find a linked server " + "that matches %s", + st[1].c_str()); + return false; + } - SName = tServer->getName(); - } -else - { - SName = st[1]; - } -bot->MsgChanLog("ADDSERVER %s\n",SName.c_str()); - -ccServer* NewServer = new ccServer(bot->SQLDb); -if(NewServer->loadData(SName)) - { - bot->Notice(theClient, "Server '%s' is already in my database!", - SName.c_str()); - delete NewServer; - return false; - } -NewServer->setName(SName); -bool Report = true; -if(st.size() > 2) - { - if(!strcasecmp(st[2],"-nr")) - { - Report = false; - } - } + SName = tServer->getName(); + } else { + SName = st[1]; + } + bot->MsgChanLog("ADDSERVER %s\n", SName.c_str()); -//We need to check if the server is currently connected , -//if so update all the data -iServer* CurServer = Network->findServerName(SName); -if(CurServer) - { - NewServer->setLastNumeric(CurServer->getCharYY()); - NewServer->setLastConnected(CurServer->getConnectTime()); - NewServer->setUplink( - (Network->findServer(CurServer->getIntYY()))->getName()); - NewServer->setNetServer(CurServer); - bot->Write("%s V :%s\n",bot->getCharYYXXX().c_str(), - CurServer->getCharYY().c_str()); - } -NewServer->setReportMissing(Report); -if(!Report) - { - NewServer->setVersion("Virtual Server V1.0123B3"); - } -NewServer->setAddedOn(::time(0)); -NewServer->setLastUpdated(::time(0)); -if(NewServer->Insert()) - bot->Notice(theClient,"Server '%s' has been added successfully\n",SName.c_str()); -else - bot->Notice(theClient,"Database error while adding server '%s'\n", - SName.c_str()); + ccServer* NewServer = new ccServer(bot->SQLDb); + if (NewServer->loadData(SName)) { + bot->Notice(theClient, "Server '%s' is already in my database!", SName.c_str()); + delete NewServer; + return false; + } + NewServer->setName(SName); + bool Report = true; + if (st.size() > 2) { + if (!strcasecmp(st[2], "-nr")) { + Report = false; + } + } -bot->addServer(NewServer); -return true; -} + // We need to check if the server is currently connected , + // if so update all the data + iServer* CurServer = Network->findServerName(SName); + if (CurServer) { + NewServer->setLastNumeric(CurServer->getCharYY()); + NewServer->setLastConnected(CurServer->getConnectTime()); + NewServer->setUplink((Network->findServer(CurServer->getIntYY()))->getName()); + NewServer->setNetServer(CurServer); + bot->Write("%s V :%s\n", bot->getCharYYXXX().c_str(), CurServer->getCharYY().c_str()); + } + NewServer->setReportMissing(Report); + if (!Report) { + NewServer->setVersion("Virtual Server V1.0123B3"); + } + NewServer->setAddedOn(::time(0)); + NewServer->setLastUpdated(::time(0)); + if (NewServer->Insert()) + bot->Notice(theClient, "Server '%s' has been added successfully\n", SName.c_str()); + else + bot->Notice(theClient, "Database error while adding server '%s'\n", SName.c_str()); + + bot->addServer(NewServer); + return true; } +} // namespace uworld } // namespace gnuworld diff --git a/mod.ccontrol/ADDUSERCommand.cc b/mod.ccontrol/ADDUSERCommand.cc index 28f4628b..612415f1 100644 --- a/mod.ccontrol/ADDUSERCommand.cc +++ b/mod.ccontrol/ADDUSERCommand.cc @@ -2,7 +2,7 @@ * ADDUSERCommand.cc * Adds a new oper to the bot database * when adding a new oper one must specify access flags - * the oper initial commands is defined by these flags + * the oper initial commands is defined by these flags * the defualt flags can be found in CControlCommands.h file * * This program is free software; you can redistribute it and/or @@ -23,189 +23,159 @@ * $Id: ADDUSERCommand.cc,v 1.21 2006/09/26 17:35:58 kewlio Exp $ */ -#include - -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "ccUser.h" -#include "misc.h" -#include "commLevels.h" -#include "Constants.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool ADDUSERCommand::Exec( iClient* theClient, const string& Message) -{ -StringTokenizer st( Message ) ; -if( st.size() < 4 ) - { - Usage(theClient); - return true; - } - -if(st[1].size() > User::MaxName) - { - bot->Notice(theClient,"Oper name can't be more than %d " - "characters in length.", - User::MaxName); - return false; - } - -// Try fetching the user data from the database, note this is -// the new user handle -ccUser* theUser = bot->GetOper(st[1]); -if (theUser) - { - bot->Notice(theClient,"Oper '%s' already exists in my database, " - "please change the oper handle and try again.", - theUser->getUserName().c_str()); - return false; - } - -unsigned long int NewAccess = 0 ; -unsigned long int NewSAccess = 0 ; - -unsigned int NewFlags = 0 ; - -if(!strcasecmp(st[2],"coder")) - { - NewAccess = commandLevel::CODER; - NewSAccess = commandLevel::SCODER; - NewFlags = operLevel::CODERLEVEL; - } -else if(!strcasecmp(st[2],"smt")) - { - NewAccess = commandLevel::SMT; - NewSAccess = commandLevel::SSMT; - NewFlags = operLevel::SMTLEVEL; - } - -else if(!strcasecmp(st[2],"admin")) - { - if(st.size() < 5) - { - bot->Notice(theClient,"When adding a new admin, you " - "must specify a server."); - return false; - } - NewAccess = commandLevel::ADMIN; - NewSAccess = commandLevel::SADMIN; +#include + +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "ccUser.h" +#include "misc.h" +#include "commLevels.h" +#include "Constants.h" +#include "gnuworld_config.h" + +namespace gnuworld { + +using std::string; + +namespace uworld { + +bool ADDUSERCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + if (st.size() < 4) { + Usage(theClient); + return true; + } + + if (st[1].size() > User::MaxName) { + bot->Notice(theClient, + "Oper name can't be more than %d " + "characters in length.", + User::MaxName); + return false; + } + + // Try fetching the user data from the database, note this is + // the new user handle + ccUser* theUser = bot->GetOper(st[1]); + if (theUser) { + bot->Notice(theClient, + "Oper '%s' already exists in my database, " + "please change the oper handle and try again.", + theUser->getUserName().c_str()); + return false; + } + + unsigned long int NewAccess = 0; + unsigned long int NewSAccess = 0; + + unsigned int NewFlags = 0; + + if (!strcasecmp(st[2], "coder")) { + NewAccess = commandLevel::CODER; + NewSAccess = commandLevel::SCODER; + NewFlags = operLevel::CODERLEVEL; + } else if (!strcasecmp(st[2], "smt")) { + NewAccess = commandLevel::SMT; + NewSAccess = commandLevel::SSMT; + NewFlags = operLevel::SMTLEVEL; + } + + else if (!strcasecmp(st[2], "admin")) { + if (st.size() < 5) { + bot->Notice(theClient, "When adding a new admin, you " + "must specify a server."); + return false; + } + NewAccess = commandLevel::ADMIN; + NewSAccess = commandLevel::SADMIN; NewFlags = operLevel::ADMINLEVEL; - } -else if(!strcasecmp(st[2],"oper")) - { + } else if (!strcasecmp(st[2], "oper")) { NewAccess = commandLevel::OPER; - NewSAccess = commandLevel::SOPER; + NewSAccess = commandLevel::SOPER; NewFlags = operLevel::OPERLEVEL; -} else if (!strcasecmp(st[2], "uhs")) { - NewAccess = commandLevel::UHS; - NewSAccess = commandLevel::SUHS; - NewFlags = operLevel::UHSLEVEL; -} -else - { - bot->Notice(theClient, - "Illegal oper type; types are: uhs, oper, admin, smt and coder"); - return false; - } - -ccUser *tOper = bot->IsAuth( theClient ); -if( NULL == tOper ) - { - bot->Notice( theClient, - "You must be authenticated to use this command." ) ; - return true ; - } - -bot->MsgChanLog("ADDUSER %s %s\n",st[1].c_str(),st[2].c_str()); - -//Make sure the new oper wont have a command the old one doesnt have enabled -NewAccess &= tOper->getAccess(); -//NewAccess = bot->getTrueAccess(NewAccess); - -//Check if the user doesnt try to add an oper with higher flag than he is -unsigned int OperFlags = tOper->getType(); -if(OperFlags < operLevel::ADMINLEVEL) - { - bot->Notice(theClient, - "Sorry, but only admins+ can add new opers"); - return false; - } - -if((OperFlags < operLevel::SMTLEVEL) && (OperFlags <= NewFlags)) - { - bot->Notice(theClient, - "Sorry, but you can't add an oper with a higher or " - "equal access to your own"); - return false; - } -else if(OperFlags < NewFlags) - { - bot->Notice(theClient, - "Sorry, but you can't add an oper with a higher " - "access than your own"); - return false; - } - -//Create the new user and update the database -theUser = new ccUser(bot->SQLDb); -theUser->setUserName(st[1]); -if(st.size() < 5) - { - theUser->setPassword(bot->CryptPass(st[3])); - theUser->setServer(tOper->getServer()); - } -else - { - if(OperFlags < operLevel::SMTLEVEL) - { - bot->Notice(theClient,"Sorry, only SMT+ can specify " - "a server name"); - return false; - } - - string Server( bot->expandDbServer(st[3]) ) ; - if( Server.empty() ) - { - bot->Notice(theClient,"I can't find a server that " - "matches '%s' in the database", - st[3].c_str()); - return false; - } - theUser->setPassword(bot->CryptPass(st[4])); - theUser->setServer(Server); - } - -theUser->setAccess(NewAccess); -theUser->setSAccess(NewSAccess); -theUser->setType(NewFlags); -theUser->setLast_Updated_By(theClient->getRealNickUserHost()); -theUser->setNeedOp(true); -theUser->setNotice(true); //default to notice -theUser->setLogs(false); -theUser->setLag(false); -theUser->setSso(true); -theUser->setSsooo(true); -theUser->setAutoOp(false); -theUser->setAccountID(::time(0)); - - -if(bot->AddOper(theUser) == true) - { - bot->Notice(theClient, "Oper successfully added."); - theUser->loadData(theUser->getUserName()); - } -else - bot->Notice(theClient, "Error while adding the new oper."); -return true; -} -} + } else if (!strcasecmp(st[2], "uhs")) { + NewAccess = commandLevel::UHS; + NewSAccess = commandLevel::SUHS; + NewFlags = operLevel::UHSLEVEL; + } else { + bot->Notice(theClient, "Illegal oper type; types are: uhs, oper, admin, smt and coder"); + return false; + } + + ccUser* tOper = bot->IsAuth(theClient); + if (NULL == tOper) { + bot->Notice(theClient, "You must be authenticated to use this command."); + return true; + } + + bot->MsgChanLog("ADDUSER %s %s\n", st[1].c_str(), st[2].c_str()); + + // Make sure the new oper wont have a command the old one doesnt have enabled + NewAccess &= tOper->getAccess(); + // NewAccess = bot->getTrueAccess(NewAccess); + + // Check if the user doesnt try to add an oper with higher flag than he is + unsigned int OperFlags = tOper->getType(); + if (OperFlags < operLevel::ADMINLEVEL) { + bot->Notice(theClient, "Sorry, but only admins+ can add new opers"); + return false; + } + + if ((OperFlags < operLevel::SMTLEVEL) && (OperFlags <= NewFlags)) { + bot->Notice(theClient, "Sorry, but you can't add an oper with a higher or " + "equal access to your own"); + return false; + } else if (OperFlags < NewFlags) { + bot->Notice(theClient, "Sorry, but you can't add an oper with a higher " + "access than your own"); + return false; + } + + // Create the new user and update the database + theUser = new ccUser(bot->SQLDb); + theUser->setUserName(st[1]); + if (st.size() < 5) { + theUser->setPassword(bot->CryptPass(st[3])); + theUser->setServer(tOper->getServer()); + } else { + if (OperFlags < operLevel::SMTLEVEL) { + bot->Notice(theClient, "Sorry, only SMT+ can specify " + "a server name"); + return false; + } + + string Server(bot->expandDbServer(st[3])); + if (Server.empty()) { + bot->Notice(theClient, + "I can't find a server that " + "matches '%s' in the database", + st[3].c_str()); + return false; + } + theUser->setPassword(bot->CryptPass(st[4])); + theUser->setServer(Server); + } + + theUser->setAccess(NewAccess); + theUser->setSAccess(NewSAccess); + theUser->setType(NewFlags); + theUser->setLast_Updated_By(theClient->getRealNickUserHost()); + theUser->setNeedOp(true); + theUser->setNotice(true); // default to notice + theUser->setLogs(false); + theUser->setLag(false); + theUser->setSso(true); + theUser->setSsooo(true); + theUser->setAutoOp(false); + theUser->setAccountID(::time(0)); + + if (bot->AddOper(theUser) == true) { + bot->Notice(theClient, "Oper successfully added."); + theUser->loadData(theUser->getUserName()); + } else + bot->Notice(theClient, "Error while adding the new oper."); + return true; } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/ANNOUNCECommand.cc b/mod.ccontrol/ANNOUNCECommand.cc index 476ac691..0e3cfb7e 100644 --- a/mod.ccontrol/ANNOUNCECommand.cc +++ b/mod.ccontrol/ANNOUNCECommand.cc @@ -20,40 +20,35 @@ * $Id: ANNOUNCECommand.cc,v 1.2 2009/06/13 06:43:34 hidden1 Exp $ */ -#include -#include - -#include - -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool ANNOUNCECommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -bot->MsgChanLog("ANNOUNCE %s\n",st.assemble(1).c_str()); - -if(st.size() < 2) - { - Usage(theClient); - return true; - } - -bot->announce(theClient, st.assemble(1)); -return true; -} +#include +#include + +#include + +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" +#include "gnuworld_config.h" + +namespace gnuworld { + +using std::string; +namespace uworld { + +bool ANNOUNCECommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + bot->MsgChanLog("ANNOUNCE %s\n", st.assemble(1).c_str()); + + if (st.size() < 2) { + Usage(theClient); + return true; + } + + bot->announce(theClient, st.assemble(1)); + return true; } -} // namespace gnuworld +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/CControlCommands.cc b/mod.ccontrol/CControlCommands.cc index 58cf5a8c..aefce682 100644 --- a/mod.ccontrol/CControlCommands.cc +++ b/mod.ccontrol/CControlCommands.cc @@ -19,27 +19,24 @@ * $Id: CControlCommands.cc,v 1.16 2005/01/12 03:50:28 dan_karrels Exp $ */ -#include +#include -#include +#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "iClient.h" -#include "gnuworld_config.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "iClient.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { -void Command::Usage( iClient* theClient ) -{ -bot->Notice( theClient, string( "Usage: " ) + ' ' + getInfo() ) ; +void Command::Usage(iClient* theClient) { + bot->Notice(theClient, string("Usage: ") + ' ' + getInfo()); } -} +} // namespace uworld } // namespace gnuworld diff --git a/mod.ccontrol/CControlCommands.h b/mod.ccontrol/CControlCommands.h index a2af1436..28b557ee 100644 --- a/mod.ccontrol/CControlCommands.h +++ b/mod.ccontrol/CControlCommands.h @@ -22,119 +22,86 @@ #ifndef __CCONTROLCOMMANDS_H #define __CCONTROLCOMMANDS_H "$Id: CControlCommands.h,v 1.34 2009/07/26 18:30:37 mrbean_ Exp $" -#include - -#include "iClient.h" - -using std::string ; - -namespace gnuworld -{ - -class xServer ; - -namespace uworld -{ - -class ccontrol ; - -class Command -{ - -public: - Command( ccontrol* _bot, const string& _commName, - const bool _needsDB, - const string& _help, const unsigned long _flags, - const bool _disabled, const bool _needOp, - const bool _noLog,const int unsigned _minLevel, - const bool _secondAccess) - : bot( _bot ), - server( 0 ), - commName( _commName ), - commRealName( _commName ), - needDB ( _needsDB ), - help( _help ), - flags ( _flags ), - isDisabled ( _disabled ), - needOp ( _needOp), - noLog ( _noLog ), - minLevel ( _minLevel ), - secondAccess ( _secondAccess ) - {} - virtual ~Command() {} - - /// Exec returns true if the command was successfully - /// executed, false otherwise. - virtual bool Exec( iClient*, const string&) = 0 ; - - void setServer( xServer* _server ) - { server = _server ; } - virtual string getInfo() const - { return commName + ' ' + help ; } - virtual void Usage( iClient* theClient ) ; - - void setName( const string& _name ) - { commName = string_upper( _name ); } - - void Disable() - { isDisabled = true ; } - - void Enable() - { isDisabled = false ; } - - void setNeedOp ( const bool _needOp ) - { needOp = _needOp ; } - - void setNoLog ( const bool _noLog ) - { noLog = _noLog ; } - - void setMinLevel ( const int unsigned _minLevel ) - { minLevel = _minLevel ; } - - inline const string& getName() const - { return commName ; } - - inline const string& getRealName() const - { return commRealName ; } - - inline const bool& needsDB() const - { return needDB ; } - - inline const string& getHelp() const - { return help ; } - - inline const unsigned long& getFlags() const - { return flags ; } - - inline const bool& getIsDisabled() const - { return isDisabled ; } - - inline const bool& getNeedOp() const - { return needOp ; } - - inline const bool& getNoLog() const - { return noLog ; } - - inline const unsigned int& getMinLevel() const - { return minLevel ; } - - inline const bool& getSecondAccess() const - { return secondAccess ; } -protected: - ccontrol* bot ; - xServer* server ; - string commName ; - string commRealName ; - bool needDB; - string help ; - unsigned long flags; - bool isDisabled; - bool needOp; - bool noLog; - unsigned int minLevel; - bool secondAccess; -} ; -} +#include + +#include "iClient.h" + +using std::string; + +namespace gnuworld { + +class xServer; + +namespace uworld { + +class ccontrol; + +class Command { + + public: + Command(ccontrol* _bot, const string& _commName, const bool _needsDB, const string& _help, + const unsigned long _flags, const bool _disabled, const bool _needOp, const bool _noLog, + const int unsigned _minLevel, const bool _secondAccess) + : bot(_bot), server(0), commName(_commName), commRealName(_commName), needDB(_needsDB), + help(_help), flags(_flags), isDisabled(_disabled), needOp(_needOp), noLog(_noLog), + minLevel(_minLevel), secondAccess(_secondAccess) {} + virtual ~Command() {} + + /// Exec returns true if the command was successfully + /// executed, false otherwise. + virtual bool Exec(iClient*, const string&) = 0; + + void setServer(xServer* _server) { server = _server; } + virtual string getInfo() const { return commName + ' ' + help; } + virtual void Usage(iClient* theClient); + + void setName(const string& _name) { commName = string_upper(_name); } + + void Disable() { isDisabled = true; } + + void Enable() { isDisabled = false; } + + void setNeedOp(const bool _needOp) { needOp = _needOp; } + + void setNoLog(const bool _noLog) { noLog = _noLog; } + + void setMinLevel(const int unsigned _minLevel) { minLevel = _minLevel; } + + inline const string& getName() const { return commName; } + + inline const string& getRealName() const { return commRealName; } + + inline const bool& needsDB() const { return needDB; } + + inline const string& getHelp() const { return help; } + + inline const unsigned long& getFlags() const { return flags; } + + inline const bool& getIsDisabled() const { return isDisabled; } + + inline const bool& getNeedOp() const { return needOp; } + + inline const bool& getNoLog() const { return noLog; } + + inline const unsigned int& getMinLevel() const { return minLevel; } + + inline const bool& getSecondAccess() const { return secondAccess; } + + protected: + ccontrol* bot; + xServer* server; + string commName; + string commRealName; + bool needDB; + string help; + unsigned long flags; + bool isDisabled; + bool needOp; + bool noLog; + unsigned int minLevel; + bool secondAccess; +}; +} // namespace uworld } // namespace gnuworld diff --git a/mod.ccontrol/CHANINFOCommand.cc b/mod.ccontrol/CHANINFOCommand.cc index ea0d3002..d9d061d7 100644 --- a/mod.ccontrol/CHANINFOCommand.cc +++ b/mod.ccontrol/CHANINFOCommand.cc @@ -20,111 +20,93 @@ * $Id: CHANINFOCommand.cc,v 1.20 2007/11/05 10:04:23 kewlio Exp $ */ -#include - -#include "Network.h" -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" -#include "ccontrol_generic.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool CHANINFOCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } - -if(st[1].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d characters", - channel::MaxName); - return false; - } - -ccUser* tmpAuth = bot->IsAuth(theClient); -if (!tmpAuth) - return false; -unsigned int OpFlag = tmpAuth->getType(); - -bot->MsgChanLog("CHANINFO %s\n",st[1].c_str()); - -Channel* theChan = Network->findChannel( st[ 1 ] ) ; -if( NULL == theChan ) - { - bot->Notice( theClient, "Unable to find channel %s", - st[ 1 ].c_str() ) ; - return true ; - } - -bot->Notice( theClient, "Channel %s is mode %s", - st[ 1 ].c_str(), - theChan->getModeString().c_str() ) ; -bot->Notice( theClient, "Created at time: %d (%s ago)", - theChan->getCreationTime(), Ago(theChan->getCreationTime())); - -/* iterate the channel user list to get statistics on each mode - and possibly a user list in future */ -int totalOps = 0; -int totalVoice = 0; -string tmpMode; - -for (Channel::userIterator userItr = theChan->userList_begin(); - userItr != theChan->userList_end(); ++userItr) -{ - ChannelUser* theUser = userItr->second; - - if (theUser->isModeO()) - totalOps++; - if (theUser->isModeV()) - totalVoice++; - if (OpFlag == operLevel::CODERLEVEL) - { - /* show full info to coders - make it format for easy viewing */ - if (theUser->isModeO() && theUser->isModeV()) - tmpMode = "+o+v: "; - else if (theUser->isModeO()) - tmpMode = "+o: "; - else if (theUser->isModeV()) - tmpMode = "+v: "; - else - tmpMode = "none: "; - bot->Notice(theClient, "%s%s!%s@%s", - tmpMode.c_str(), - theUser->getNickName().c_str(), - theUser->getUserName().c_str(), - theUser->getHostName().c_str()); - } -} - -bot->Notice( theClient, "Number of channel users: %d (%d ops, %d voice)", - theChan->size(), totalOps, totalVoice); +#include + +#include "Network.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" +#include "ccontrol_generic.h" +#include "gnuworld_config.h" + +namespace gnuworld { + +using std::string; + +namespace uworld { + +bool CHANINFOCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + if (st.size() < 2) { + Usage(theClient); + return true; + } + + if (st[1].size() > channel::MaxName) { + bot->Notice(theClient, "Channel name can't be more than %d characters", channel::MaxName); + return false; + } + + ccUser* tmpAuth = bot->IsAuth(theClient); + if (!tmpAuth) + return false; + unsigned int OpFlag = tmpAuth->getType(); + + bot->MsgChanLog("CHANINFO %s\n", st[1].c_str()); + + Channel* theChan = Network->findChannel(st[1]); + if (NULL == theChan) { + bot->Notice(theClient, "Unable to find channel %s", st[1].c_str()); + return true; + } + + bot->Notice(theClient, "Channel %s is mode %s", st[1].c_str(), + theChan->getModeString().c_str()); + bot->Notice(theClient, "Created at time: %d (%s ago)", theChan->getCreationTime(), + Ago(theChan->getCreationTime())); + + /* iterate the channel user list to get statistics on each mode + and possibly a user list in future */ + int totalOps = 0; + int totalVoice = 0; + string tmpMode; + + for (Channel::userIterator userItr = theChan->userList_begin(); + userItr != theChan->userList_end(); ++userItr) { + ChannelUser* theUser = userItr->second; + + if (theUser->isModeO()) + totalOps++; + if (theUser->isModeV()) + totalVoice++; + if (OpFlag == operLevel::CODERLEVEL) { + /* show full info to coders - make it format for easy viewing */ + if (theUser->isModeO() && theUser->isModeV()) + tmpMode = "+o+v: "; + else if (theUser->isModeO()) + tmpMode = "+o: "; + else if (theUser->isModeV()) + tmpMode = "+v: "; + else + tmpMode = "none: "; + bot->Notice(theClient, "%s%s!%s@%s", tmpMode.c_str(), theUser->getNickName().c_str(), + theUser->getUserName().c_str(), theUser->getHostName().c_str()); + } + } + + bot->Notice(theClient, "Number of channel users: %d (%d ops, %d voice)", theChan->size(), + totalOps, totalVoice); #ifdef TOPIC_TRACK -bot->Notice(theClient,"Topic: %s", - theChan->getTopic().c_str()); -if (theChan->getTopicTS() != 0) -{ - bot->Notice(theClient, "Topic set %s ago [%ld] by %s", - Ago(theChan->getTopicTS()), - theChan->getTopicTS(), - theChan->getTopicWhoSet().c_str()); -} + bot->Notice(theClient, "Topic: %s", theChan->getTopic().c_str()); + if (theChan->getTopicTS() != 0) { + bot->Notice(theClient, "Topic set %s ago [%ld] by %s", Ago(theChan->getTopicTS()), + theChan->getTopicTS(), theChan->getTopicWhoSet().c_str()); + } #endif -return true ; + return true; } -} +} // namespace uworld } // namespace gnuworld diff --git a/mod.ccontrol/CHECKNETCommand.cc b/mod.ccontrol/CHECKNETCommand.cc index 3e70bf87..faee50f1 100644 --- a/mod.ccontrol/CHECKNETCommand.cc +++ b/mod.ccontrol/CHECKNETCommand.cc @@ -20,122 +20,112 @@ * $Id: CHECKNETCommand.cc,v 1.20 2009/07/26 23:55:52 hidden1 Exp $ */ -#include -#include - -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "ccServer.h" -#include "ccontrol_generic.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool CHECKNETCommand::Exec( iClient* theClient, const string& ) -{ -unsigned int TServers = 0; - -bot->Notice(theClient,"Checking network status as at %ld\n",::time(NULL)); -bot->MsgChanLog("CHECKNET\n"); - -ccServer* CurServer = 0; -string Msg; -char tNum[512]; -std::stringstream s; - -for (ccontrol::serversconstiterator ptr = bot->serversMap_begin() ; - ptr != bot->serversMap_end();++ptr) - { - //For each server on the database check if its connetcted - CurServer = ptr->second; - - //If the server isnt connected - if(CurServer->getReportMissing() && !CurServer->getNetServer()) - { - Msg = "Server \002"; - Msg += CurServer->getName(); - Msg +="\002 Is missing, "; - Msg += "Last split: "; - if(CurServer->getLastSplitted() != 0) - { - sprintf(tNum, "%ld", (long)CurServer->getLastSplitted()); - Msg += "["; - Msg += tNum; - Msg += "] "; - Msg += Ago(CurServer->getLastSplitted()); - Msg += " ago, Split Reason:"; - Msg += CurServer->getSplitReason(); - } - else - Msg += " unknown "; - - Msg += " Last connected: "; - - if(CurServer->getLastConnected() != 0) - { - sprintf(tNum, "%ld", (long)CurServer->getLastConnected()); - Msg += "["; - Msg += tNum; - Msg += "] "; - Msg += Ago(CurServer->getLastConnected()); - Msg += " ago"; - } - else - Msg += " unknown "; - bot->Notice(theClient,"%s",Msg.c_str()); - TServers++; - } - } - -/* -for (ccontrol::serversconstiterator ptr = bot->serversMap_begin() ; - ptr != bot->serversMap_end();++ptr) - { - //For each server on the database check if its connetcted - CurServer = ptr->second; - - //If the server isnt connected - if (!CurServer->getReportMissing() || CurServer->getNetServer()) - { - if (s.str().size() > 400) - { - bot->Notice(theClient, "Server RPINGS: %s", s.str().c_str()); - s.str(""); - count = 0; - } - count++; - if (count > 1) - s << ", "; - s << CurServer->getName() << " ("; - if (CurServer->getLagTime() > 10000) - { - s << "\002" << (int) (CurServer->getLagTime() / 1000) << "seconds\002)"; - } - else if (CurServer->getLagTime() > 5000) - { - s << "\002" << CurServer->getLagTime() << "ms\002)"; - } - else - { - s << CurServer->getLagTime() << "ms)"; - } - } - } - -bot->Notice(theClient, "Server RPINGS: %s", s.str().c_str()); -*/ -bot->Notice(theClient,"Finished checking the status of the network.\n"); -bot->Notice(theClient,"Found a total of %d missing servers\n",TServers); -return true; +#include +#include -} +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "ccServer.h" +#include "ccontrol_generic.h" +#include "gnuworld_config.h" +namespace gnuworld { + +using std::string; + +namespace uworld { + +bool CHECKNETCommand::Exec(iClient* theClient, const string&) { + unsigned int TServers = 0; + + bot->Notice(theClient, "Checking network status as at %ld\n", ::time(NULL)); + bot->MsgChanLog("CHECKNET\n"); + + ccServer* CurServer = 0; + string Msg; + char tNum[512]; + std::stringstream s; + + for (ccontrol::serversconstiterator ptr = bot->serversMap_begin(); ptr != bot->serversMap_end(); + ++ptr) { + // For each server on the database check if its connetcted + CurServer = ptr->second; + + // If the server isnt connected + if (CurServer->getReportMissing() && !CurServer->getNetServer()) { + Msg = "Server \002"; + Msg += CurServer->getName(); + Msg += "\002 Is missing, "; + Msg += "Last split: "; + if (CurServer->getLastSplitted() != 0) { + sprintf(tNum, "%ld", (long)CurServer->getLastSplitted()); + Msg += "["; + Msg += tNum; + Msg += "] "; + Msg += Ago(CurServer->getLastSplitted()); + Msg += " ago, Split Reason:"; + Msg += CurServer->getSplitReason(); + } else + Msg += " unknown "; + + Msg += " Last connected: "; + + if (CurServer->getLastConnected() != 0) { + sprintf(tNum, "%ld", (long)CurServer->getLastConnected()); + Msg += "["; + Msg += tNum; + Msg += "] "; + Msg += Ago(CurServer->getLastConnected()); + Msg += " ago"; + } else + Msg += " unknown "; + bot->Notice(theClient, "%s", Msg.c_str()); + TServers++; + } + } + + /* + for (ccontrol::serversconstiterator ptr = bot->serversMap_begin() ; + ptr != bot->serversMap_end();++ptr) + { + //For each server on the database check if its connetcted + CurServer = ptr->second; + + //If the server isnt connected + if (!CurServer->getReportMissing() || CurServer->getNetServer()) + { + if (s.str().size() > 400) + { + bot->Notice(theClient, "Server RPINGS: %s", s.str().c_str()); + s.str(""); + count = 0; + } + count++; + if (count > 1) + s << ", "; + s << CurServer->getName() << " ("; + if (CurServer->getLagTime() > 10000) + { + s << "\002" << (int) (CurServer->getLagTime() / 1000) << "seconds\002)"; + } + else if (CurServer->getLagTime() > 5000) + { + s << "\002" << CurServer->getLagTime() << "ms\002)"; + } + else + { + s << CurServer->getLagTime() << "ms)"; + } + } + } + + bot->Notice(theClient, "Server RPINGS: %s", s.str().c_str()); + */ + bot->Notice(theClient, "Finished checking the status of the network.\n"); + bot->Notice(theClient, "Found a total of %d missing servers\n", TServers); + return true; } -} + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/CLEARCHANCommand.cc b/mod.ccontrol/CLEARCHANCommand.cc index 46b855f8..1dabba65 100644 --- a/mod.ccontrol/CLEARCHANCommand.cc +++ b/mod.ccontrol/CLEARCHANCommand.cc @@ -1,5 +1,5 @@ /** - * CLEARCHANCommand.cc + * CLEARCHANCommand.cc * Clears all/some channel modes * * This program is free software; you can redistribute it and/or @@ -20,243 +20,230 @@ * $Id: CLEARCHANCommand.cc,v 1.26 2006/09/26 17:35:58 kewlio Exp $ */ -#include -#include -#include -#include "Network.h" -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" -#include "ccBadChannel.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "Network.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" +#include "ccBadChannel.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::vector ; using gnuworld::iClient; +using std::string; +using std::vector; -namespace uworld -{ +namespace uworld { -bool CLEARCHANCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -bool Desynch = false; +bool CLEARCHANCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + bool Desynch = false; -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } + if (st.size() < 2) { + Usage(theClient); + return true; + } -if(st[1].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d characters.", - channel::MaxName); - return false; - } + if (st[1].size() > channel::MaxName) { + bot->Notice(theClient, "Channel name can't be more than %d characters.", channel::MaxName); + return false; + } -Channel* theChan = Network->findChannel( st[ 1 ] ) ; -if( NULL == theChan ) - { - bot->Notice( theClient, "Unable to find channel %s", - st[ 1 ].c_str() ) ; - return true ; - } -if(bot->isOperChan(theChan)) - { - bot->Notice(theClient,"C'mon, you know you can't clear an oper channel."); - return false; - } + Channel* theChan = Network->findChannel(st[1]); + if (NULL == theChan) { + bot->Notice(theClient, "Unable to find channel %s", st[1].c_str()); + return true; + } + if (bot->isOperChan(theChan)) { + bot->Notice(theClient, "C'mon, you know you can't clear an oper channel."); + return false; + } -string doModes; //This holds the modes the user asked to be removed -string remModes = ""; //Holds the modes that we are removing -string args = ""; //Holds the arguments for the remModes + string doModes; // This holds the modes the user asked to be removed + string remModes = ""; // Holds the modes that we are removing + string args = ""; // Holds the arguments for the remModes -bot->MsgChanLog("CLEARCHAN %s\n",st.assemble(1).c_str()); -ccBadChannel* Chan = bot->isBadChannel(st[1]); -if(Chan) - { - bot->Notice(theClient,"Sorry, you can't change modes in " - "this channel because: %s", - Chan->getReason().c_str()); + bot->MsgChanLog("CLEARCHAN %s\n", st.assemble(1).c_str()); + ccBadChannel* Chan = bot->isBadChannel(st[1]); + if (Chan) { + bot->Notice(theClient, + "Sorry, you can't change modes in " + "this channel because: %s", + Chan->getReason().c_str()); return false; - } + } + + // Check if the user specified the modes, if not assume he ment all of the modes + if (st.size() == 2) + doModes = "obklimrDZ"; + else if (!strcasecmp(string_upper(st[2]), "ALL")) + doModes = "obklimnsptrDCcuMZ"; + else if (!strcasecmp(string_upper(st[2]), "-d")) + Desynch = true; + else + doModes = st[2]; -//Check if the user specified the modes, if not assume he ment all of the modes -if(st.size() == 2) - doModes = "obklimrDZ"; -else if(!strcasecmp(string_upper(st[ 2 ]),"ALL")) - doModes = "obklimnsptrDCcuMZ"; -else if(!strcasecmp(string_upper(st [ 2]),"-d")) - Desynch = true; -else - doModes = st [ 2 ]; + if (Desynch) { + vector KickVec; + bot->Join(theChan->getName(), "+i", 0, true); + for (Channel::const_userIterator ptr = theChan->userList_begin(); + ptr != theChan->userList_end(); ++ptr) { -if(Desynch) - { - vector KickVec; - bot->Join(theChan->getName(),"+i",0,true); - for( Channel::const_userIterator ptr = theChan->userList_begin(); - ptr != theChan->userList_end() ; ++ptr ) - { - - if ( !ptr->second->getClient()->getMode(iClient::MODE_SERVICES) ) - { - KickVec.push_back(ptr->second->getClient()); - } - else - { - /* - its a +k user, need to make sure its not us - */ - if(strcmp(ptr->second->getClient()->getCharYYXXX().c_str(), - bot->getCharYYXXX().c_str())) - { - bot->Message(ptr->second->getClient(),"OPERPART %s" - ,theChan->getName().c_str()); - } - } - } - if(KickVec.size() > 0) - { - string reason = "Desynch clearing"; - bot->Kick(theChan,KickVec,reason); - } - bot->Part(theChan->getName()); - return true; - } + if (!ptr->second->getClient()->getMode(iClient::MODE_SERVICES)) { + KickVec.push_back(ptr->second->getClient()); + } else { + /* + its a +k user, need to make sure its not us + */ + if (strcmp(ptr->second->getClient()->getCharYYXXX().c_str(), + bot->getCharYYXXX().c_str())) { + bot->Message(ptr->second->getClient(), "OPERPART %s", + theChan->getName().c_str()); + } + } + } + if (KickVec.size() > 0) { + string reason = "Desynch clearing"; + bot->Kick(theChan, KickVec, reason); + } + bot->Part(theChan->getName()); + return true; + } -bot->ClearMode( theChan, doModes, true ) ; -return true ; + bot->ClearMode(theChan, doModes, true); + return true; -/* -for( string::size_type modePos = 0 ; modePos < doModes.size() ; ++modePos ) - { - switch( doModes[ modePos ] ) - { - case 'B': //Ban? - { - string ban; - string modes = "-"; - string args = ""; - Channel::banListSizeType end = theChan->banList_size(); - Channel::banIterator ptr = theChan->banList_begin() ; - for(Channel::banListSizeType i=0; i != end ;i++) - { - ban = *ptr; - ptr++; - args += ban + ' '; - modes+= "b"; - theChan->removeBan(ban); - if(modes.size() > 5) //if we got more than 5 , set the mode and continue - { - bot->ModeAsServer( theChan, modes + ' ' + args ) ; - modes = "-"; - args = ""; - } - } - if(!args.empty()) - bot->ModeAsServer( theChan, modes + ' ' + args ) ; - break; - } - case 'O': //Chanops? - { - string modes = "-"; - string args = ""; - for( Channel::const_userIterator ptr = theChan->userList_begin(); - ptr != theChan->userList_end() ; ++ptr ) - { - if( ptr->second->getMode(ChannelUser::MODE_O)) - { - // Don't deop +k things - if ( !ptr->second->getClient()->getMode(iClient::MODE_SERVICES) ) - { - modes+= 'o'; - args+= ptr->second->getCharYYXXX() + " "; - ptr->second->removeMode(ChannelUser::MODE_O); - } - } // If opped. - if(modes.size() > 5) //if we got more than 5 , set the mode and continue - { - bot->ModeAsServer( theChan, modes + ' ' + args ) ; - modes = "-"; - args = ""; - } - } - if(!args.empty()) - bot->ModeAsServer(theChan,modes + " " + args); - } - break; - case 'K': //Key? - if(theChan->getMode(Channel::MODE_K)) - { - theChan->removeMode(Channel::MODE_K); - remModes+= "k"; - args+= theChan->getKey() + " "; - theChan->setKey(""); - } - break; - case 'I': //Invite? - if(theChan->getMode(Channel::MODE_I)) - { - theChan->removeMode(Channel::MODE_I); - remModes+= "i"; - } - break; - case 'L': //Limit? - if(theChan->getMode(Channel::MODE_L)) - { - theChan->removeMode(Channel::MODE_L); - remModes+= "l"; - //args+= theChan->getLimit() + " "; - } - break; - case 'P': //Private? - if(theChan->getMode(Channel::MODE_P)) - { - theChan->removeMode(Channel::MODE_P); - remModes+= "p"; - } - break; - case 'S': //Secret? - if(theChan->getMode(Channel::MODE_S)) - { - theChan->removeMode(Channel::MODE_S); - remModes+= "s"; - } - break; - case 'M': //Moderated? - if(theChan->getMode(Channel::MODE_M)) - { - theChan->removeMode(Channel::MODE_M); - remModes+= "m"; - } - break; - case 'N': //No External Messages? - if(theChan->getMode(Channel::MODE_N)) - { - theChan->removeMode(Channel::MODE_N); - remModes+= "n"; - } - break; - case 'T': //Topic? - if(theChan->getMode(Channel::MODE_T)) - { - theChan->removeMode(Channel::MODE_T); - remModes+= "t"; - } - break; - default:; - } } -if(!remModes.empty()) - bot->ModeAsServer(theChan,"-" + remModes + " " + args); -return true; -*/ + /* + for( string::size_type modePos = 0 ; modePos < doModes.size() ; ++modePos ) + { + switch( doModes[ modePos ] ) + { + case 'B': //Ban? + { + string ban; + string modes = "-"; + string args = ""; + Channel::banListSizeType end = theChan->banList_size(); + Channel::banIterator ptr = theChan->banList_begin() ; + for(Channel::banListSizeType i=0; i != end ;i++) + { + ban = *ptr; + ptr++; + args += ban + ' '; + modes+= "b"; + theChan->removeBan(ban); + if(modes.size() > 5) //if we got more than 5 , set the mode and + continue + { + bot->ModeAsServer( theChan, modes + ' ' + args ) ; + modes = "-"; + args = ""; + } + } + if(!args.empty()) + bot->ModeAsServer( theChan, modes + ' ' + args ) ; + break; + } + case 'O': //Chanops? + { + string modes = "-"; + string args = ""; + for( Channel::const_userIterator ptr = theChan->userList_begin(); + ptr != theChan->userList_end() ; ++ptr ) + { + if( ptr->second->getMode(ChannelUser::MODE_O)) + { + // Don't deop +k things + if ( + !ptr->second->getClient()->getMode(iClient::MODE_SERVICES) ) + { + modes+= 'o'; + args+= ptr->second->getCharYYXXX() + " "; + ptr->second->removeMode(ChannelUser::MODE_O); + } + } // If opped. + if(modes.size() > 5) //if we got more than 5 , set the mode and + continue + { + bot->ModeAsServer( theChan, modes + ' ' + args ) ; + modes = "-"; + args = ""; + } + } + if(!args.empty()) + bot->ModeAsServer(theChan,modes + " " + args); + } + break; + case 'K': //Key? + if(theChan->getMode(Channel::MODE_K)) + { + theChan->removeMode(Channel::MODE_K); + remModes+= "k"; + args+= theChan->getKey() + " "; + theChan->setKey(""); + } + break; + case 'I': //Invite? + if(theChan->getMode(Channel::MODE_I)) + { + theChan->removeMode(Channel::MODE_I); + remModes+= "i"; + } + break; + case 'L': //Limit? + if(theChan->getMode(Channel::MODE_L)) + { + theChan->removeMode(Channel::MODE_L); + remModes+= "l"; + //args+= theChan->getLimit() + " "; + } + break; + case 'P': //Private? + if(theChan->getMode(Channel::MODE_P)) + { + theChan->removeMode(Channel::MODE_P); + remModes+= "p"; + } + break; + case 'S': //Secret? + if(theChan->getMode(Channel::MODE_S)) + { + theChan->removeMode(Channel::MODE_S); + remModes+= "s"; + } + break; + case 'M': //Moderated? + if(theChan->getMode(Channel::MODE_M)) + { + theChan->removeMode(Channel::MODE_M); + remModes+= "m"; + } + break; + case 'N': //No External Messages? + if(theChan->getMode(Channel::MODE_N)) + { + theChan->removeMode(Channel::MODE_N); + remModes+= "n"; + } + break; + case 'T': //Topic? + if(theChan->getMode(Channel::MODE_T)) + { + theChan->removeMode(Channel::MODE_T); + remModes+= "t"; + } + break; + default:; + } } + if(!remModes.empty()) + bot->ModeAsServer(theChan,"-" + remModes + " " + args); + return true; + */ } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/COMMANDSCommand.cc b/mod.ccontrol/COMMANDSCommand.cc index 8a443150..d94fc880 100644 --- a/mod.ccontrol/COMMANDSCommand.cc +++ b/mod.ccontrol/COMMANDSCommand.cc @@ -1,7 +1,7 @@ /** * COMMANDSCommand.cc * Changes all kind of commands options - * + * * 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 @@ -19,244 +19,176 @@ * * $Id: COMMANDSCommand.cc,v 1.15 2006/09/26 17:35:58 kewlio Exp $ */ - -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "ccUser.h" -#include "misc.h" -#include "gnuworld_config.h" +#include -namespace gnuworld -{ +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "ccUser.h" +#include "misc.h" +#include "gnuworld_config.h" -using std::string ; +namespace gnuworld { -namespace uworld -{ +using std::string; -bool COMMANDSCommand::Exec( iClient* theClient, const string& Message) -{ -StringTokenizer st( Message ) ; +namespace uworld { -if( st.size() < 3 ) - { - Usage(theClient); - return true; - } +bool COMMANDSCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -if(st[1].size() > 128) - { - bot->Notice(theClient,"Command name can't be more than 128 characters."); - return false; - } + if (st.size() < 3) { + Usage(theClient); + return true; + } -bot->MsgChanLog("COMMANDS %s\n",st.assemble(1).c_str()); - -Command* Comm = bot->findCommandInMem(st[2]); -if(!Comm) - { - bot->Notice(theClient,"Can't find command name '%s'",st[2].c_str()); - return false; - } -if(!strcasecmp(st[1],"-ds")) - { - Comm->Disable(); - if(!bot->updateCommand(Comm)) - { - bot->Notice(theClient,"Error while disabling command"); - return false; - } - else - { - bot->Notice(theClient,"Command has been disabled"); - return true; - } - } -else if(!strcasecmp(st[1],"-en")) - { - Comm->Enable(); - if(!bot->updateCommand(Comm)) - { - bot->Notice(theClient,"Error while enabling command"); - return false; - } - else - { - bot->Notice(theClient,"Command has been enabled"); - return true; - } - } -else if(!strcasecmp(st[1],"-no")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"-no must get a on/off option"); - return false; - } - if(!strcasecmp(st[3],"on")) - { - Comm->setNeedOp(true); - if(!bot->updateCommand(Comm)) - { - bot->Notice(theClient,"error while setting need op"); - return false; - } - else - { - bot->Notice(theClient,"needop has been enabled"); - return true; - } - - } - else if(!strcasecmp(st[3],"off")) - { - Comm->setNeedOp(false); - if(!bot->updateCommand(Comm)) - { - bot->Notice(theClient,"error while removing need op"); - return false; - } - else - { - bot->Notice(theClient,"needop has been disabled"); - return true; - } - - } - else - { - bot->Notice(theClient,"unknown option for -no must be on/off"); - return false; - } - } -else if(!strcasecmp(st[1],"-nl")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"-nl must get a on/off option"); - return false; - } - if(!strcasecmp(st[3],"on")) - { - Comm->setNoLog(true); - if(!bot->updateCommand(Comm)) - { - bot->Notice(theClient,"error while setting no log"); - return false; - } - else - { - bot->Notice(theClient,"no log has been enabled"); - return true; - } - - } - else if(!strcasecmp(st[3],"off")) - { - Comm->setNoLog(false); - if(!bot->updateCommand(Comm)) - { - bot->Notice(theClient,"error while removing no log"); - return false; - } - else - { - bot->Notice(theClient,"no log has been disabled"); - return true; - } - - } + if (st[1].size() > 128) { + bot->Notice(theClient, "Command name can't be more than 128 characters."); + return false; + } - else - { - bot->Notice(theClient,"unknown option for -nl must be on/off"); - return false; - } - } + bot->MsgChanLog("COMMANDS %s\n", st.assemble(1).c_str()); -else if(!strcasecmp(st[1],"-na")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"-na must get a new command name"); - return false; - } - if(st[3].size() > 128) - { - bot->Notice(theClient,"Command name can't be more than 128 characters"); - return false; - } - if(!strcasecmp(Comm->getName(),st[3])) - { - bot->Notice(theClient,"the command is already called like that"); - return false; - } - Comm->setName(string_upper(st[3])); - if(!bot->updateCommand(Comm)) - { - bot->Notice(theClient,"error while changing command name"); - return false; - } - else - { - bot->Notice(theClient,"command name has been changed"); - return true; - } - } -else if(!strcasecmp(st[1],"-ml")) - { - unsigned int MINLEVEL; - if(st.size() < 4) - { - bot->Notice(theClient,"-ml must get a new min level"); - return false; - } - if(!strcasecmp(st[3],"CODER")) - { - MINLEVEL = operLevel::CODERLEVEL; - } - else if(!strcasecmp(st[3],"SMT")) - { - MINLEVEL = operLevel::SMTLEVEL; - } - else if(!strcasecmp(st[3],"ADMIN")) - { - MINLEVEL = operLevel::ADMINLEVEL; - } - else if(!strcasecmp(st[3],"OPER")) - { - MINLEVEL = operLevel::OPERLEVEL; - } - else if(!strcasecmp(st[3],"UHS")) - { - MINLEVEL = operLevel::UHSLEVEL; - } - else - { - bot->Notice(theClient,"Unknown level, must be CODER,SMT,ADMIN,OPER or UHS"); - return false; - } - Comm->setMinLevel(MINLEVEL); - if(!bot->updateCommand(Comm)) - { - bot->Notice(theClient,"error while changing command min level"); - return false; - } - else - { - bot->Notice(theClient,"command min level has been changed"); - return true; - } - } -else - { - bot->Notice(theClient,"Unknown option for commands, must be -en,-ds,-no,-nl"); - } + Command* Comm = bot->findCommandInMem(st[2]); + if (!Comm) { + bot->Notice(theClient, "Can't find command name '%s'", st[2].c_str()); + return false; + } + if (!strcasecmp(st[1], "-ds")) { + Comm->Disable(); + if (!bot->updateCommand(Comm)) { + bot->Notice(theClient, "Error while disabling command"); + return false; + } else { + bot->Notice(theClient, "Command has been disabled"); + return true; + } + } else if (!strcasecmp(st[1], "-en")) { + Comm->Enable(); + if (!bot->updateCommand(Comm)) { + bot->Notice(theClient, "Error while enabling command"); + return false; + } else { + bot->Notice(theClient, "Command has been enabled"); + return true; + } + } else if (!strcasecmp(st[1], "-no")) { + if (st.size() < 4) { + bot->Notice(theClient, "-no must get a on/off option"); + return false; + } + if (!strcasecmp(st[3], "on")) { + Comm->setNeedOp(true); + if (!bot->updateCommand(Comm)) { + bot->Notice(theClient, "error while setting need op"); + return false; + } else { + bot->Notice(theClient, "needop has been enabled"); + return true; + } -return true; -} -} + } else if (!strcasecmp(st[3], "off")) { + Comm->setNeedOp(false); + if (!bot->updateCommand(Comm)) { + bot->Notice(theClient, "error while removing need op"); + return false; + } else { + bot->Notice(theClient, "needop has been disabled"); + return true; + } + + } else { + bot->Notice(theClient, "unknown option for -no must be on/off"); + return false; + } + } else if (!strcasecmp(st[1], "-nl")) { + if (st.size() < 4) { + bot->Notice(theClient, "-nl must get a on/off option"); + return false; + } + if (!strcasecmp(st[3], "on")) { + Comm->setNoLog(true); + if (!bot->updateCommand(Comm)) { + bot->Notice(theClient, "error while setting no log"); + return false; + } else { + bot->Notice(theClient, "no log has been enabled"); + return true; + } + + } else if (!strcasecmp(st[3], "off")) { + Comm->setNoLog(false); + if (!bot->updateCommand(Comm)) { + bot->Notice(theClient, "error while removing no log"); + return false; + } else { + bot->Notice(theClient, "no log has been disabled"); + return true; + } + + } + + else { + bot->Notice(theClient, "unknown option for -nl must be on/off"); + return false; + } + } + + else if (!strcasecmp(st[1], "-na")) { + if (st.size() < 4) { + bot->Notice(theClient, "-na must get a new command name"); + return false; + } + if (st[3].size() > 128) { + bot->Notice(theClient, "Command name can't be more than 128 characters"); + return false; + } + if (!strcasecmp(Comm->getName(), st[3])) { + bot->Notice(theClient, "the command is already called like that"); + return false; + } + Comm->setName(string_upper(st[3])); + if (!bot->updateCommand(Comm)) { + bot->Notice(theClient, "error while changing command name"); + return false; + } else { + bot->Notice(theClient, "command name has been changed"); + return true; + } + } else if (!strcasecmp(st[1], "-ml")) { + unsigned int MINLEVEL; + if (st.size() < 4) { + bot->Notice(theClient, "-ml must get a new min level"); + return false; + } + if (!strcasecmp(st[3], "CODER")) { + MINLEVEL = operLevel::CODERLEVEL; + } else if (!strcasecmp(st[3], "SMT")) { + MINLEVEL = operLevel::SMTLEVEL; + } else if (!strcasecmp(st[3], "ADMIN")) { + MINLEVEL = operLevel::ADMINLEVEL; + } else if (!strcasecmp(st[3], "OPER")) { + MINLEVEL = operLevel::OPERLEVEL; + } else if (!strcasecmp(st[3], "UHS")) { + MINLEVEL = operLevel::UHSLEVEL; + } else { + bot->Notice(theClient, "Unknown level, must be CODER,SMT,ADMIN,OPER or UHS"); + return false; + } + Comm->setMinLevel(MINLEVEL); + if (!bot->updateCommand(Comm)) { + bot->Notice(theClient, "error while changing command min level"); + return false; + } else { + bot->Notice(theClient, "command min level has been changed"); + return true; + } + } else { + bot->Notice(theClient, "Unknown option for commands, must be -en,-ds,-no,-nl"); + } + + return true; } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/CONFIGCommand.cc b/mod.ccontrol/CONFIGCommand.cc index f75155a1..ec5e7db4 100644 --- a/mod.ccontrol/CONFIGCommand.cc +++ b/mod.ccontrol/CONFIGCommand.cc @@ -1,5 +1,5 @@ /** - * CONFIGCommand.cc + * CONFIGCommand.cc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,219 +19,176 @@ * $Id: CONFIGCommand.cc,v 1.14 2008/01/03 04:26:22 kewlio Exp $ */ -#include +#include -#include "StringTokenizer.h" -#include "ccontrol.h" -#include "CControlCommands.h" -#include "gnuworld_config.h" -#include "ccontrol_generic.h" /* for Duration() and Ago() */ +#include "StringTokenizer.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "gnuworld_config.h" +#include "ccontrol_generic.h" /* for Duration() and Ago() */ -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::endl ; -using std::ends ; +using std::endl; +using std::ends; +using std::string; -namespace uworld -{ +namespace uworld { -bool CONFIGCommand::Exec( iClient* theClient, const string& Message) -{ -StringTokenizer st(Message); +bool CONFIGCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -if(st.size() < 3) - { - Usage(theClient); - return true; - } + if (st.size() < 3) { + Usage(theClient); + return true; + } -bot->MsgChanLog("CONFIG %s",st.assemble(1).c_str()); - -for(unsigned int pos =1; pos < st.size() ;) - { - if(!strcasecmp(st[pos],"-CClonesTime")) - { - if(st.size() < pos +2) - { - bot->Notice(theClient,"-CClonesTime must get the duration between announcements per netblock."); - return true; - } - if (!IsTimeSpec(st[pos+1])) - { - bot->Notice(theClient,"-CClonesTime must have a valid time specified, e.g. 60s or 1m"); - return true; - } - int g = extractTime(st[pos+1], 1); - if (g < 0 || g > 300) - { - bot->Notice(theClient,"-CClonesTime value must be between 0s and 5m."); - return true; - } - if(!bot->updateMisc("CClonesTime",g)) - { - bot->MsgChanLog("Error while updating the Duration time.\n"); - } - else - { - bot->Notice(theClient,"%s was successfully updated to %s", - st[pos].c_str(),Duration((long)g)); - } - pos+=2; - } - else if(!strcasecmp(st[pos],"-CClonesGTime")) - { - if (st.size() < pos +2) - { - bot->Notice(theClient,"-CClonesGTime must get the duration of the gline in seconds."); - return true; - } - if (!IsTimeSpec(st[pos+1])) - { - bot->Notice(theClient,"Invalid CIDR Clones Gline Time specified."); - return true; - } - int g = extractTime(st[pos+1], 1); - if (g < 1800 || g > 172800) - { - bot->Notice(theClient,"-CClonesGTime value must be between 1800 and 172800 seconds (30 mins - 2 days)."); - return true; - } - if (!bot->updateMisc("CClonesGTime",g)) - { - bot->MsgChanLog("Error while updating the CIDR Clones Gline Time.\n"); - } - else - { - bot->Notice(theClient,"%s was successfully updated to %s", - st[pos].c_str(),Duration((long)g)); - } - pos += 2; - } - else if(!strcasecmp(st[pos],"-IClones")) - { - if(st.size() < pos +2) - { - bot->Notice(theClient,"-IClones must get the number of ident clones"); - return true; - } - if(!bot->updateMisc("IClones",atoi(st[pos+1].c_str()))) - { - bot->MsgChanLog("Error while updating the max ident clones in the db!\n"); - } - else - { - bot->Notice(theClient,"%s was successfully updated to %s", - st[pos].c_str(),st[pos+1].c_str()); - } - pos+=2; - } - else if(!strcasecmp(st[pos],"-GBCount")) - { - if(st.size() < pos +2) - { - bot->Notice(theClient,"-GBCount must get the number glines to burst"); - return true; - } - if(!bot->updateMisc("GlineBurstCount",atoi(st[pos+1].c_str()))) - { - bot->MsgChanLog("Error while updating the gline burst count in the db!\n"); - } - else - { - bot->Notice(theClient,"%s was successfully updated to %s", - st[pos].c_str(),st[pos+1].c_str()); - } - pos+=2; - } - else if(!strcasecmp(st[pos],"-GBInterval")) - { - if(st.size() < pos +2) - { - bot->Notice(theClient,"-GBInterval must get the number of seconds between each burst"); - return true; - } - if (!IsTimeSpec(st[pos+1])) - { - bot->Notice(theClient,"-GBInterval must get the number of seconds between each burst - e.g. 3 or 3s"); - return true; - } - int g = extractTime(st[pos+1], 1); - if (g < 0 || g > 10) - { - bot->Notice(theClient,"-GBInterval must be between 0 and 10 seconds inclusive."); - return true; - } - if(!bot->updateMisc("GlineBurstInterval",g)) - { - bot->MsgChanLog("Error while updating the gline burst interval in the db!\n"); - } - else - { - bot->Notice(theClient,"%s was successfully updated to %s", - st[pos].c_str(),Duration((long)g)); - } - pos+=2; - } - else if(!strcasecmp(st[pos],"-GTime")) - { - if(st.size() < pos +2) - { - bot->Notice(theClient,"-GTime must get the duration for the excessive connections gline - e.g. 900s, 30m, 1h or 1d."); - return true; - } - if (!IsTimeSpec(st[pos+1])) - { - bot->Notice(theClient,"-GTime must get a valid duration - e.g. 900s, 30m, 1h or 1d."); - return true; - } - int g = extractTime(st[pos+1], 1); - if (g < 300 || g > 172800) - { - bot->Notice(theClient,"-GTime must get a duration between 300s and 2d"); - return true; - } - if(!bot->updateMisc("GTime",g)) - { - bot->MsgChanLog("Error while updating the gline duration in the db!\n"); - } - else - { - bot->Notice(theClient,"%s was successfully updated to %s", - st[pos].c_str(),Duration((long)g)); - } + bot->MsgChanLog("CONFIG %s", st.assemble(1).c_str()); - pos+=2; - } + for (unsigned int pos = 1; pos < st.size();) { + if (!strcasecmp(st[pos], "-CClonesTime")) { + if (st.size() < pos + 2) { + bot->Notice( + theClient, + "-CClonesTime must get the duration between announcements per netblock."); + return true; + } + if (!IsTimeSpec(st[pos + 1])) { + bot->Notice(theClient, + "-CClonesTime must have a valid time specified, e.g. 60s or 1m"); + return true; + } + int g = extractTime(st[pos + 1], 1); + if (g < 0 || g > 300) { + bot->Notice(theClient, "-CClonesTime value must be between 0s and 5m."); + return true; + } + if (!bot->updateMisc("CClonesTime", g)) { + bot->MsgChanLog("Error while updating the Duration time.\n"); + } else { + bot->Notice(theClient, "%s was successfully updated to %s", st[pos].c_str(), + Duration((long)g)); + } + pos += 2; + } else if (!strcasecmp(st[pos], "-CClonesGTime")) { + if (st.size() < pos + 2) { + bot->Notice(theClient, + "-CClonesGTime must get the duration of the gline in seconds."); + return true; + } + if (!IsTimeSpec(st[pos + 1])) { + bot->Notice(theClient, "Invalid CIDR Clones Gline Time specified."); + return true; + } + int g = extractTime(st[pos + 1], 1); + if (g < 1800 || g > 172800) { + bot->Notice(theClient, "-CClonesGTime value must be between 1800 and 172800 " + "seconds (30 mins - 2 days)."); + return true; + } + if (!bot->updateMisc("CClonesGTime", g)) { + bot->MsgChanLog("Error while updating the CIDR Clones Gline Time.\n"); + } else { + bot->Notice(theClient, "%s was successfully updated to %s", st[pos].c_str(), + Duration((long)g)); + } + pos += 2; + } else if (!strcasecmp(st[pos], "-IClones")) { + if (st.size() < pos + 2) { + bot->Notice(theClient, "-IClones must get the number of ident clones"); + return true; + } + if (!bot->updateMisc("IClones", atoi(st[pos + 1].c_str()))) { + bot->MsgChanLog("Error while updating the max ident clones in the db!\n"); + } else { + bot->Notice(theClient, "%s was successfully updated to %s", st[pos].c_str(), + st[pos + 1].c_str()); + } + pos += 2; + } else if (!strcasecmp(st[pos], "-GBCount")) { + if (st.size() < pos + 2) { + bot->Notice(theClient, "-GBCount must get the number glines to burst"); + return true; + } + if (!bot->updateMisc("GlineBurstCount", atoi(st[pos + 1].c_str()))) { + bot->MsgChanLog("Error while updating the gline burst count in the db!\n"); + } else { + bot->Notice(theClient, "%s was successfully updated to %s", st[pos].c_str(), + st[pos + 1].c_str()); + } + pos += 2; + } else if (!strcasecmp(st[pos], "-GBInterval")) { + if (st.size() < pos + 2) { + bot->Notice(theClient, + "-GBInterval must get the number of seconds between each burst"); + return true; + } + if (!IsTimeSpec(st[pos + 1])) { + bot->Notice( + theClient, + "-GBInterval must get the number of seconds between each burst - e.g. 3 or 3s"); + return true; + } + int g = extractTime(st[pos + 1], 1); + if (g < 0 || g > 10) { + bot->Notice(theClient, "-GBInterval must be between 0 and 10 seconds inclusive."); + return true; + } + if (!bot->updateMisc("GlineBurstInterval", g)) { + bot->MsgChanLog("Error while updating the gline burst interval in the db!\n"); + } else { + bot->Notice(theClient, "%s was successfully updated to %s", st[pos].c_str(), + Duration((long)g)); + } + pos += 2; + } else if (!strcasecmp(st[pos], "-GTime")) { + if (st.size() < pos + 2) { + bot->Notice(theClient, "-GTime must get the duration for the excessive connections " + "gline - e.g. 900s, 30m, 1h or 1d."); + return true; + } + if (!IsTimeSpec(st[pos + 1])) { + bot->Notice(theClient, + "-GTime must get a valid duration - e.g. 900s, 30m, 1h or 1d."); + return true; + } + int g = extractTime(st[pos + 1], 1); + if (g < 300 || g > 172800) { + bot->Notice(theClient, "-GTime must get a duration between 300s and 2d"); + return true; + } + if (!bot->updateMisc("GTime", g)) { + bot->MsgChanLog("Error while updating the gline duration in the db!\n"); + } else { + bot->Notice(theClient, "%s was successfully updated to %s", st[pos].c_str(), + Duration((long)g)); + } - else if(!strcasecmp(st[pos],"-SGline")) - { - if(st.size() < pos +2) - { - bot->Notice(theClient,"-SGline must get a yes/no answer indicating whether or not to save glines"); - return true; - } - if(!bot->updateMisc("SGLine",(strcasecmp(st[pos+1],"YES") == 0) ? 1 : 0)) - { - bot->MsgChanLog("Error while updating the save gline flag in the db\n"); - } - else - { - bot->Notice(theClient,"%s was successfully updated to %s", - st[pos].c_str(),st[pos+1].c_str()); - } - pos+=2; - } - else - { - bot->Notice(theClient,"Sorry, i am not familiar with option %s",st[pos].c_str()); - ++pos; - } - } -return true ; -} + pos += 2; + } + else if (!strcasecmp(st[pos], "-SGline")) { + if (st.size() < pos + 2) { + bot->Notice( + theClient, + "-SGline must get a yes/no answer indicating whether or not to save glines"); + return true; + } + if (!bot->updateMisc("SGLine", (strcasecmp(st[pos + 1], "YES") == 0) ? 1 : 0)) { + bot->MsgChanLog("Error while updating the save gline flag in the db\n"); + } else { + bot->Notice(theClient, "%s was successfully updated to %s", st[pos].c_str(), + st[pos + 1].c_str()); + } + pos += 2; + } else { + bot->Notice(theClient, "Sorry, i am not familiar with option %s", st[pos].c_str()); + ++pos; + } + } + return true; } +} // namespace uworld + } // namespace gnuworld diff --git a/mod.ccontrol/CommandsDec.h b/mod.ccontrol/CommandsDec.h index d8d606cc..bcb136ee 100644 --- a/mod.ccontrol/CommandsDec.h +++ b/mod.ccontrol/CommandsDec.h @@ -22,95 +22,86 @@ #ifndef __COMMANDSDEC_H #define __COMMANDSDEC_H "$Id: CommandsDec.h,v 1.22 2009/06/13 06:43:34 hidden1 Exp $" -namespace gnuworld -{ +namespace gnuworld { -namespace uworld -{ +namespace uworld { class Command; -#define DECLARE_COMMAND(commName) \ -class commName##Command : public Command \ -{ \ -public: \ - commName##Command( ccontrol* _bot, \ - const string& _commName, \ - const string& _help, \ - const bool _needDB, \ - int _flags , bool isDisabled, \ - bool needOp, bool noLog, \ - int minLevel , bool secondAccess ) \ - : Command( _bot, _commName, _needDB, _help,_flags, \ - isDisabled,needOp,noLog,minLevel,secondAccess) \ - {} \ - virtual bool Exec( iClient*, const string&) ; \ - virtual ~commName##Command() {} \ -} ; +#define DECLARE_COMMAND(commName) \ + class commName##Command : public Command { \ + public: \ + commName##Command(ccontrol* _bot, const string& _commName, const string& _help, \ + const bool _needDB, int _flags, bool isDisabled, bool needOp, \ + bool noLog, int minLevel, bool secondAccess) \ + : Command(_bot, _commName, _needDB, _help, _flags, isDisabled, needOp, noLog, \ + minLevel, secondAccess) {} \ + virtual bool Exec(iClient*, const string&); \ + virtual ~commName##Command() {} \ + }; -DECLARE_COMMAND( INVITE ) -DECLARE_COMMAND( HELP ) -DECLARE_COMMAND( JUPE ) -DECLARE_COMMAND( MODE ) -DECLARE_COMMAND( GLINE ) -DECLARE_COMMAND( SCHANGLINE ) -DECLARE_COMMAND( SCANGLINE ) -DECLARE_COMMAND( REMGLINE ) -DECLARE_COMMAND( TRANSLATE ) -DECLARE_COMMAND( WHOIS ) -DECLARE_COMMAND( KICK ) -DECLARE_COMMAND( ADDOPERCHAN ) -DECLARE_COMMAND( REMOPERCHAN ) -DECLARE_COMMAND( LISTOPERCHANS ) -DECLARE_COMMAND( CHANINFO ) -DECLARE_COMMAND( LOGIN ) -DECLARE_COMMAND( DEAUTH ) -DECLARE_COMMAND( ADDUSER ) -DECLARE_COMMAND( REMUSER ) -DECLARE_COMMAND( ADDCOMMAND ) -DECLARE_COMMAND( REMCOMMAND ) -DECLARE_COMMAND( NEWPASS ) -DECLARE_COMMAND( SUSPEND ) -DECLARE_COMMAND( UNSUSPEND ) -DECLARE_COMMAND( MODUSER ) -DECLARE_COMMAND( MODERATE ) -DECLARE_COMMAND( UNMODERATE ) -DECLARE_COMMAND( OP ) -DECLARE_COMMAND( DEOP ) -DECLARE_COMMAND( LISTHOSTS ) -DECLARE_COMMAND( CLEARCHAN ) -DECLARE_COMMAND( ADDSERVER ) -DECLARE_COMMAND( LEARNNET ) -DECLARE_COMMAND( REMSERVER ) -DECLARE_COMMAND( CHECKNET ) -DECLARE_COMMAND( LASTCOM ) -DECLARE_COMMAND( FORCEGLINE ) -DECLARE_COMMAND( EXCEPTION ) -DECLARE_COMMAND( LISTIGNORES ) -DECLARE_COMMAND( REMOVEIGNORE ) -DECLARE_COMMAND( LIST ) -DECLARE_COMMAND( COMMANDS ) -DECLARE_COMMAND( GCHAN ) -DECLARE_COMMAND( REMGCHAN ) -DECLARE_COMMAND( USERINFO ) -DECLARE_COMMAND( STATUS ) -DECLARE_COMMAND( SHUTDOWN ) -DECLARE_COMMAND( SCAN ) -DECLARE_COMMAND( MAXUSERS ) -DECLARE_COMMAND( CONFIG ) -DECLARE_COMMAND( SAY ) -DECLARE_COMMAND( NOMODE ) -DECLARE_COMMAND( REOP ) -DECLARE_COMMAND( SGLINE ) -DECLARE_COMMAND( REMSGLINE ) -DECLARE_COMMAND( UNJUPE ) -DECLARE_COMMAND ( FORCECHANGLINE ) -DECLARE_COMMAND ( ANNOUNCE ) -DECLARE_COMMAND ( LIMITS ) -DECLARE_COMMAND (LISTUSERS) -DECLARE_COMMAND ( TOPIC ) +DECLARE_COMMAND(INVITE) +DECLARE_COMMAND(HELP) +DECLARE_COMMAND(JUPE) +DECLARE_COMMAND(MODE) +DECLARE_COMMAND(GLINE) +DECLARE_COMMAND(SCHANGLINE) +DECLARE_COMMAND(SCANGLINE) +DECLARE_COMMAND(REMGLINE) +DECLARE_COMMAND(TRANSLATE) +DECLARE_COMMAND(WHOIS) +DECLARE_COMMAND(KICK) +DECLARE_COMMAND(ADDOPERCHAN) +DECLARE_COMMAND(REMOPERCHAN) +DECLARE_COMMAND(LISTOPERCHANS) +DECLARE_COMMAND(CHANINFO) +DECLARE_COMMAND(LOGIN) +DECLARE_COMMAND(DEAUTH) +DECLARE_COMMAND(ADDUSER) +DECLARE_COMMAND(REMUSER) +DECLARE_COMMAND(ADDCOMMAND) +DECLARE_COMMAND(REMCOMMAND) +DECLARE_COMMAND(NEWPASS) +DECLARE_COMMAND(SUSPEND) +DECLARE_COMMAND(UNSUSPEND) +DECLARE_COMMAND(MODUSER) +DECLARE_COMMAND(MODERATE) +DECLARE_COMMAND(UNMODERATE) +DECLARE_COMMAND(OP) +DECLARE_COMMAND(DEOP) +DECLARE_COMMAND(LISTHOSTS) +DECLARE_COMMAND(CLEARCHAN) +DECLARE_COMMAND(ADDSERVER) +DECLARE_COMMAND(LEARNNET) +DECLARE_COMMAND(REMSERVER) +DECLARE_COMMAND(CHECKNET) +DECLARE_COMMAND(LASTCOM) +DECLARE_COMMAND(FORCEGLINE) +DECLARE_COMMAND(EXCEPTION) +DECLARE_COMMAND(LISTIGNORES) +DECLARE_COMMAND(REMOVEIGNORE) +DECLARE_COMMAND(LIST) +DECLARE_COMMAND(COMMANDS) +DECLARE_COMMAND(GCHAN) +DECLARE_COMMAND(REMGCHAN) +DECLARE_COMMAND(USERINFO) +DECLARE_COMMAND(STATUS) +DECLARE_COMMAND(SHUTDOWN) +DECLARE_COMMAND(SCAN) +DECLARE_COMMAND(MAXUSERS) +DECLARE_COMMAND(CONFIG) +DECLARE_COMMAND(SAY) +DECLARE_COMMAND(NOMODE) +DECLARE_COMMAND(REOP) +DECLARE_COMMAND(SGLINE) +DECLARE_COMMAND(REMSGLINE) +DECLARE_COMMAND(UNJUPE) +DECLARE_COMMAND(FORCECHANGLINE) +DECLARE_COMMAND(ANNOUNCE) +DECLARE_COMMAND(LIMITS) +DECLARE_COMMAND(LISTUSERS) +DECLARE_COMMAND(TOPIC) } // namespace uworld } // namespace gnuworld #endif // __COMMANDSDEC_H - diff --git a/mod.ccontrol/Constants.h b/mod.ccontrol/Constants.h index b5caea50..9d646544 100644 --- a/mod.ccontrol/Constants.h +++ b/mod.ccontrol/Constants.h @@ -22,35 +22,34 @@ #ifndef __CONSTANTS_H_ #define __CONSTANTS_H_ -namespace gnuworld -{ +namespace gnuworld { -namespace uworld -{ +namespace uworld { -namespace channel -{ +namespace channel { const unsigned int MaxName = 300; } -namespace server -{ +namespace server { const unsigned int MaxName = 63; -static const char Query[] = "SELECT name,lastuplink,lastconnected," - "splitedon,lastnumeric,splitreason,version,addedon,lastupdated,reportmissing" - " FROM servers "; -} +static const char Query[] = + "SELECT name,lastuplink,lastconnected," + "splitedon,lastnumeric,splitreason,version,addedon,lastupdated,reportmissing" + " FROM servers "; +} // namespace server -namespace User -{ +namespace User { const unsigned int MaxName = 32; -static const char Query[] = "SELECT user_id,user_name,password,access,saccess,flags,suspend_expires,suspended_by,server,isSuspended,IsUhs,IsOper,IsAdmin,IsSmt,IsCoder,GetLogs,NeedOp,Email,Suspend_Level,Suspend_Reason,notice,GetLag,LastPassChangeTS,Sso,Ssooo,AutoOp,Account,AccountTS FROM opers"; -} -namespace gline -{ -const unsigned int GLINE_OK =0x01; +static const char Query[] = + "SELECT " + "user_id,user_name,password,access,saccess,flags,suspend_expires,suspended_by,server," + "isSuspended,IsUhs,IsOper,IsAdmin,IsSmt,IsCoder,GetLogs,NeedOp,Email,Suspend_Level,Suspend_" + "Reason,notice,GetLag,LastPassChangeTS,Sso,Ssooo,AutoOp,Account,AccountTS FROM opers"; +} // namespace User +namespace gline { +const unsigned int GLINE_OK = 0x01; const unsigned int FORCE_NEEDED_HOST = 0x02; const unsigned int FORCE_NEEDED_TIME = 0x04; const unsigned int FU_NEEDED_USERS = 0x08; @@ -66,51 +65,47 @@ const unsigned int BAD_CIDRMASK = 0x1000; const unsigned int BAD_CIDROVERRIDE = 0x2000; const unsigned int HUH_IS_EXCEPTION = 0x4000; const unsigned int HUH_IS_IP_OF_OPER = 0x8000; -const unsigned int MGLINE_TIME = 3*24*3600; +const unsigned int MGLINE_TIME = 3 * 24 * 3600; const unsigned int MGLINE_WILD_NOID_TIME = 7200; -const unsigned int MGLINE_WILD_TIME = 24*3600; +const unsigned int MGLINE_WILD_TIME = 24 * 3600; const unsigned int MFGLINE_USERS = 255; -const unsigned int MFGLINE_TIME = 14*3600*24; -const unsigned int PERM_TIME = 730*3600*24; -const unsigned int MFU_TIME = 100*3600*24; -const unsigned int NOLOGIN_TIME = 3600; +const unsigned int MFGLINE_TIME = 14 * 3600 * 24; +const unsigned int PERM_TIME = 730 * 3600 * 24; +const unsigned int MFU_TIME = 100 * 3600 * 24; +const unsigned int NOLOGIN_TIME = 3600; const unsigned int MAX_REASON_LENGTH = 255; -} +} // namespace gline -namespace flood -{ +namespace flood { const unsigned int MESSAGE_POINTS = 4; const unsigned int CTCP_POINTS = 5; const unsigned int RESET_TIME = 5; const unsigned int FLOOD_POINTS = 20; -const int IGNORE_TIME = 15*60; -} +const int IGNORE_TIME = 15 * 60; +} // namespace flood -namespace password -{ +namespace password { const unsigned int MIN_SIZE = 5; const unsigned int TOO_SHORT = 1; const unsigned int LIKE_UNAME = 2; const unsigned int PASS_OK = 3; -} +} // namespace password -namespace badChannels -{ +namespace badChannels { static const char Query[] = "SELECT Name,Reason,AddedBy FROM BadChannels"; } -namespace scan -{ +namespace scan { static const unsigned int MAX_SHOW = 15; } -namespace exceptions -{ -static const char Query[] = "SELECT Host,Connections,AddedBy,AddedOn,Reason FROM Exceptions WHERE lower(Host)='"; +namespace exceptions { +static const char Query[] = + "SELECT Host,Connections,AddedBy,AddedOn,Reason FROM Exceptions WHERE lower(Host)='"; const unsigned int MAX_REASON = 449; -} +} // namespace exceptions -} -} +} // namespace uworld +} // namespace gnuworld #endif diff --git a/mod.ccontrol/DEAUTHCommand.cc b/mod.ccontrol/DEAUTHCommand.cc index 08884f98..289fdfe9 100644 --- a/mod.ccontrol/DEAUTHCommand.cc +++ b/mod.ccontrol/DEAUTHCommand.cc @@ -20,47 +20,41 @@ * $Id: DEAUTHCommand.cc,v 1.14 2006/09/26 17:35:58 kewlio Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { -bool DEAUTHCommand::Exec( iClient* theClient, const string& ) -{ -//Fetch the user authenticate entry -ccUser* tmpUser = bot->IsAuth(theClient->getCharYYXXX()); -if (!tmpUser) - { - bot->Notice(theClient,"You are not currently authenticated"); - return false; - } -if(bot->deAuthUser(tmpUser, theClient)) - { - bot->Notice(theClient,"DeAuthentication successfull"); - bot->MsgChanLog("(%s) - %s : Deauthenticated\n",tmpUser->getUserName().c_str() - ,theClient->getRealNickUserHost().c_str()); - /* forget their details to stop them getting auto-authenticated after netsplit */ - tmpUser->setLastAuthTS(1); /* if uninitialised, this would be 0 - so 1 should be a safe figure! */ - tmpUser->setLastAuthNumeric(""); - return true; - } -else - { - bot->Notice(theClient,"DeAuthentication failed"); - return false; - } -} - -} +bool DEAUTHCommand::Exec(iClient* theClient, const string&) { + // Fetch the user authenticate entry + ccUser* tmpUser = bot->IsAuth(theClient->getCharYYXXX()); + if (!tmpUser) { + bot->Notice(theClient, "You are not currently authenticated"); + return false; + } + if (bot->deAuthUser(tmpUser, theClient)) { + bot->Notice(theClient, "DeAuthentication successfull"); + bot->MsgChanLog("(%s) - %s : Deauthenticated\n", tmpUser->getUserName().c_str(), + theClient->getRealNickUserHost().c_str()); + /* forget their details to stop them getting auto-authenticated after netsplit */ + tmpUser->setLastAuthTS( + 1); /* if uninitialised, this would be 0 - so 1 should be a safe figure! */ + tmpUser->setLastAuthNumeric(""); + return true; + } else { + bot->Notice(theClient, "DeAuthentication failed"); + return false; + } } + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/DEOPCommand.cc b/mod.ccontrol/DEOPCommand.cc index f506d21b..f5b6b9cb 100644 --- a/mod.ccontrol/DEOPCommand.cc +++ b/mod.ccontrol/DEOPCommand.cc @@ -20,115 +20,97 @@ * $Id: DEOPCommand.cc,v 1.16 2006/09/26 17:35:58 kewlio Exp $ */ -#include -#include -#include - -#include - -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "Constants.h" -#include "ccBadChannel.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool DEOPCommand::Exec( iClient* theClient, const string& Message ) -{ -bool foundUser = false; - -StringTokenizer st( Message ) ; -if( st.size() < 3 ) - { - Usage( theClient ) ; - return true ; - } - -if(st[1].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d characters", - channel::MaxName); - return false; - } -Channel* theChan = Network->findChannel( st[ 1 ] ) ; -if( NULL == theChan ) - { - bot->Notice( theClient, "Unable to find channel %s\n", - st[ 1 ].c_str() ) ; - return true ; - } - -ccBadChannel* Chan = bot->isBadChannel(st[1]); -if(Chan) - { - bot->Notice(theClient,"Sorry, but you can not change modes in " - "this channel because: %s", - Chan->getReason().c_str()); +#include +#include +#include + +#include + +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "Constants.h" +#include "ccBadChannel.h" +#include "gnuworld_config.h" + +namespace gnuworld { + +using std::string; + +namespace uworld { + +bool DEOPCommand::Exec(iClient* theClient, const string& Message) { + bool foundUser = false; + + StringTokenizer st(Message); + if (st.size() < 3) { + Usage(theClient); + return true; + } + + if (st[1].size() > channel::MaxName) { + bot->Notice(theClient, "Channel name can't be more than %d characters", channel::MaxName); return false; + } + Channel* theChan = Network->findChannel(st[1]); + if (NULL == theChan) { + bot->Notice(theClient, "Unable to find channel %s\n", st[1].c_str()); + return true; + } + + ccBadChannel* Chan = bot->isBadChannel(st[1]); + if (Chan) { + bot->Notice(theClient, + "Sorry, but you can not change modes in " + "this channel because: %s", + Chan->getReason().c_str()); + return false; + } + + iClient* Target = 0; + + bot->MsgChanLog("DEOP %s\n", st.assemble(1).c_str()); + string modes = "-"; + string args = ""; + + for (StringTokenizer::size_type i = 2; i < st.size(); ++i) { + if (st[i].size() > 64) { + bot->Notice(theClient, "Nick can't be more than 64 characters"); + return false; } -iClient* Target = 0; - - -bot->MsgChanLog("DEOP %s\n",st.assemble(1).c_str()); -string modes = "-"; -string args = ""; - -for( StringTokenizer::size_type i = 2 ; i < st.size() ; ++i ) - { - if(st[i].size() > 64) - { - bot->Notice(theClient,"Nick can't be more than 64 characters"); - return false; - } - - Target = Network->findNick( st[ i ] ) ; - if( 0 == Target ) - { - continue ; - } - - // Check if the user is in the channel and he's not already opped - ChannelUser* tmpChanUser = theChan->findUser(Target) ; - if( !tmpChanUser ) - { - continue ; - } - - if( Target->getMode( iClient::MODE_SERVICES ) ) - { - // Don't op services clients, they can op themselves. - continue ; - } - /* ok, the user is in the channel, flag it */ - foundUser = true; - modes += "o"; - args += st[i] + " "; - } // for - -if (!foundUser) -{ - bot->Notice(theClient, "I couldn't find anyone to deop in %s!", - st[1].c_str()); - return false; -} + Target = Network->findNick(st[i]); + if (0 == Target) { + continue; + } -if( !args.empty() ) - { - bot->Mode(theChan,modes,args,true); - } -return true; -} + // Check if the user is in the channel and he's not already opped + ChannelUser* tmpChanUser = theChan->findUser(Target); + if (!tmpChanUser) { + continue; + } + if (Target->getMode(iClient::MODE_SERVICES)) { + // Don't op services clients, they can op themselves. + continue; + } + /* ok, the user is in the channel, flag it */ + foundUser = true; + modes += "o"; + args += st[i] + " "; + } // for + + if (!foundUser) { + bot->Notice(theClient, "I couldn't find anyone to deop in %s!", st[1].c_str()); + return false; + } + + if (!args.empty()) { + bot->Mode(theChan, modes, args, true); + } + return true; } -} - + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/FORCECHANGLINECommand.cc b/mod.ccontrol/FORCECHANGLINECommand.cc index e118fada..022ebc1f 100644 --- a/mod.ccontrol/FORCECHANGLINECommand.cc +++ b/mod.ccontrol/FORCECHANGLINECommand.cc @@ -20,29 +20,28 @@ * $Id: FORCECHANGLINECommand.cc,v 1.5 2009/06/06 07:53:34 hidden1 Exp $ */ -#include -#include -#include - -#include - -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "misc.h" -#include "Gline.h" -#include "ip.h" -#include "ELog.h" -#include "Gline.h" -//#include "gline.h" -#include "time.h" -#include "ccUser.h" -#include "Constants.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ +#include +#include +#include + +#include + +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "misc.h" +#include "Gline.h" +#include "ip.h" +#include "ELog.h" +#include "Gline.h" +// #include "gline.h" +#include "time.h" +#include "ccUser.h" +#include "Constants.h" +#include "gnuworld_config.h" + +namespace gnuworld { using std::string; @@ -51,92 +50,86 @@ using std::string; // Output: C GL * +*@lamer.net 3600 :Banned (*@lamer) ... // -namespace uworld -{ - -bool FORCECHANGLINECommand::Exec( iClient* theClient, const string& Message ) -{ - const int MAX_CHANGLINE_LENGTH = 24*3600; - StringTokenizer st(Message); - unsigned int ResStart = 2; - int uParam = 0; // if the -u paramter is used in the command, it will only gline unidented connections - - if (st.size() < 4) - { - Usage(theClient); - return true; - } - - if (st[1] == "-u") { - if (st.size() < 5) { - Usage(theClient); - return true; - } - uParam = 1; - } - - StringTokenizer::size_type pos = 1; - time_t gLength = bot->getDefaultGlineLength(); - ccUser* tmpUser = bot->IsAuth(theClient); - - /* log use of the command */ - bot->MsgChanLog("FORCECHANGLINE %s\n",st.assemble(1).c_str()); - - /* make sure they're trying a channel gline! */ - if (st[pos+uParam].substr(0,1) != "#") - { - bot->Notice(theClient,"Umm... this is CHANGLINE, not GLINE - Try " - "glining a channel maybe?"); - return true; - } - if (IsTimeSpec(st[2+uParam])) - { - gLength = extractTime( st[2+uParam], 1 ); - } else { - gLength = bot->getDefaultGlineLength(); - ResStart = 1; - } - if (gLength > MAX_CHANGLINE_LENGTH) - { - bot->Notice(theClient,"FORCECHANGLINE is limited for maximum %d seconds, " - "please use the CHANGLINE command instead",MAX_CHANGLINE_LENGTH); - return false; - } - string nickUserHost = theClient->getRealNickUserHost(); - - if (!tmpUser) - { - bot->Notice(theClient,"You must login to issue this channel gline!"); - return false; - } - - if (st[1+uParam].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d " - "characters", channel::MaxName); - return false; - } - if(bot->isBadChannel(st[1+uParam]) != NULL) - { - bot->Notice(theClient,"You cant gline a nomode channel"); - return false; - } - Channel* theChan = Network->findChannel(st[1+uParam]); - if (NULL == theChan) - { - bot->Notice(theClient, "Unable to find channel %s", - st[1+uParam].c_str()); - return true; - } - - StringTokenizer reason(st.assemble(pos + ResStart + uParam), '|'); - - if(!bot->glineChannelUsers(theClient, theChan, reason[0], gLength, nickUserHost,true,uParam)) - { - bot->Notice(theClient, "You cant gline a channel which has an oper in it"); - } - return true; +namespace uworld { + +bool FORCECHANGLINECommand::Exec(iClient* theClient, const string& Message) { + const int MAX_CHANGLINE_LENGTH = 24 * 3600; + StringTokenizer st(Message); + unsigned int ResStart = 2; + int uParam = + 0; // if the -u paramter is used in the command, it will only gline unidented connections + + if (st.size() < 4) { + Usage(theClient); + return true; + } + + if (st[1] == "-u") { + if (st.size() < 5) { + Usage(theClient); + return true; + } + uParam = 1; + } + + StringTokenizer::size_type pos = 1; + time_t gLength = bot->getDefaultGlineLength(); + ccUser* tmpUser = bot->IsAuth(theClient); + + /* log use of the command */ + bot->MsgChanLog("FORCECHANGLINE %s\n", st.assemble(1).c_str()); + + /* make sure they're trying a channel gline! */ + if (st[pos + uParam].substr(0, 1) != "#") { + bot->Notice(theClient, "Umm... this is CHANGLINE, not GLINE - Try " + "glining a channel maybe?"); + return true; + } + if (IsTimeSpec(st[2 + uParam])) { + gLength = extractTime(st[2 + uParam], 1); + } else { + gLength = bot->getDefaultGlineLength(); + ResStart = 1; + } + if (gLength > MAX_CHANGLINE_LENGTH) { + bot->Notice(theClient, + "FORCECHANGLINE is limited for maximum %d seconds, " + "please use the CHANGLINE command instead", + MAX_CHANGLINE_LENGTH); + return false; + } + string nickUserHost = theClient->getRealNickUserHost(); + + if (!tmpUser) { + bot->Notice(theClient, "You must login to issue this channel gline!"); + return false; + } + + if (st[1 + uParam].size() > channel::MaxName) { + bot->Notice(theClient, + "Channel name can't be more than %d " + "characters", + channel::MaxName); + return false; + } + if (bot->isBadChannel(st[1 + uParam]) != NULL) { + bot->Notice(theClient, "You cant gline a nomode channel"); + return false; + } + Channel* theChan = Network->findChannel(st[1 + uParam]); + if (NULL == theChan) { + bot->Notice(theClient, "Unable to find channel %s", st[1 + uParam].c_str()); + return true; + } + + StringTokenizer reason(st.assemble(pos + ResStart + uParam), '|'); + + if (!bot->glineChannelUsers(theClient, theChan, reason[0], gLength, nickUserHost, true, + uParam)) { + bot->Notice(theClient, "You cant gline a channel which has an oper in it"); + } + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/FORCEGLINECommand.cc b/mod.ccontrol/FORCEGLINECommand.cc index fc1c5ea6..65dd7430 100644 --- a/mod.ccontrol/FORCEGLINECommand.cc +++ b/mod.ccontrol/FORCEGLINECommand.cc @@ -1,6 +1,6 @@ /** * FORCECommand.cc - * Glines a specific mask + * Glines a specific mask * 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 @@ -19,301 +19,270 @@ * $Id: FORCEGLINECommand.cc,v 1.39 2009/06/09 05:55:55 hidden1 Exp $ */ -#include -#include +#include +#include -#include +#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "misc.h" -#include "Gline.h" -#include "ip.h" -#include "ELog.h" -#include "Constants.h" -#include "gnuworld_config.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "misc.h" +#include "Gline.h" +#include "ip.h" +#include "ELog.h" +#include "Constants.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; // Input: forcegline *@blah.net reason // Input: forcegline 3600 *@blah.net reason // // Output: C GL * +*@lamer.net 3600 :Banned (*@lamer) ... // -namespace uworld -{ +namespace uworld { -bool FORCEGLINECommand::Exec( iClient* theClient, const string& Message ) -{ +bool FORCEGLINECommand::Exec(iClient* theClient, const string& Message) { -StringTokenizer st( Message ) ; + StringTokenizer st(Message); -if( st.size() < 3 ) - { - Usage( theClient ) ; - return true ; - } + if (st.size() < 3) { + Usage(theClient); + return true; + } -StringTokenizer::size_type pos = 1 ; + StringTokenizer::size_type pos = 1; -bool Forced = false; -string cmdStr = "FORCEGLINE "; + bool Forced = false; + string cmdStr = "FORCEGLINE "; -ccUser* tmpUser = bot->IsAuth(theClient); -//bot->MsgChanLog("FORCEGLINE %s\n",st.assemble(1).c_str()); -if(!strcasecmp(st[pos],"-fu")) - { - Forced = true; - pos++; - cmdStr += "-fu "; - if( st.size() < 4 ) - { - Usage( theClient ) ; - return true ; - } - } -time_t gLength = bot->getDefaultGlineLength() ; + ccUser* tmpUser = bot->IsAuth(theClient); + // bot->MsgChanLog("FORCEGLINE %s\n",st.assemble(1).c_str()); + if (!strcasecmp(st[pos], "-fu")) { + Forced = true; + pos++; + cmdStr += "-fu "; + if (st.size() < 4) { + Usage(theClient); + return true; + } + } + time_t gLength = bot->getDefaultGlineLength(); -// (pos) is the index of the next token, the user@host mask. + // (pos) is the index of the next token, the user@host mask. -if(string::npos != st[pos].find_first_of('#')) - { - bot->Notice(theClient,"I don't think glining that host is such a good idea, lose the #"); - return true; - } -if(st[pos].substr(0,1) == "$") - { - bot->Notice(theClient,"Please use SGLINE to set that gline"); - return true; - } -string::size_type atPos = st[ pos ].find_first_of( '@' ) ; -if( string::npos == atPos ) - { - // User has only specified hostname, not a user name - bot->Notice( theClient, "GLINE: Please specify gline mask in the " - "format: user@host" ) ; - return true ; - } + if (string::npos != st[pos].find_first_of('#')) { + bot->Notice(theClient, "I don't think glining that host is such a good idea, lose the #"); + return true; + } + if (st[pos].substr(0, 1) == "$") { + bot->Notice(theClient, "Please use SGLINE to set that gline"); + return true; + } + string::size_type atPos = st[pos].find_first_of('@'); + if (string::npos == atPos) { + // User has only specified hostname, not a user name + bot->Notice(theClient, "GLINE: Please specify gline mask in the " + "format: user@host"); + return true; + } -string userName = st[ pos ].substr( 0, pos ) ; -string hostName = st[ pos ].substr( pos + 1 ) ; -string Length; -Length.assign(st[pos+1]); -unsigned int ResStart = 2; -bool Ok = true; -if (IsTimeSpec(st[2])) -{ - gLength = extractTime( st[2], 1 ); -} else { - gLength = bot->getDefaultGlineLength() ; - ResStart = 1; -} -//ccUser *tmpAuth = bot->IsAuth(theClient); -if(!tmpUser) - { // We shouldnt have got here in the first place, but check it anyway - return false; - } -if((Forced) && (tmpUser->getType() < operLevel::SMTLEVEL)) - { - bot->Notice(theClient,"Only SMT+ can use the -fu option"); - return false; - } - -unsigned int Users; -string gHost = st[pos]; -int gCheck = bot->checkGline(gHost,gLength,Users); -hostName = gHost; -cmdStr += gHost + " " + st.assemble(pos+1); + string userName = st[pos].substr(0, pos); + string hostName = st[pos].substr(pos + 1); + string Length; + Length.assign(st[pos + 1]); + unsigned int ResStart = 2; + bool Ok = true; + if (IsTimeSpec(st[2])) { + gLength = extractTime(st[2], 1); + } else { + gLength = bot->getDefaultGlineLength(); + ResStart = 1; + } + // ccUser *tmpAuth = bot->IsAuth(theClient); + if (!tmpUser) { // We shouldnt have got here in the first place, but check it anyway + return false; + } + if ((Forced) && (tmpUser->getType() < operLevel::SMTLEVEL)) { + bot->Notice(theClient, "Only SMT+ can use the -fu option"); + return false; + } -if(gCheck & gline::NEG_TIME) - { - bot->Notice(theClient,"You can't gline for a negative amount of time!"); - Ok = false; - } + unsigned int Users; + string gHost = st[pos]; + int gCheck = bot->checkGline(gHost, gLength, Users); + hostName = gHost; + cmdStr += gHost + " " + st.assemble(pos + 1); -if(gCheck & gline::HUH_NO_HOST) - { - bot->Notice(theClient,"I don't think glining that host is such a good idea, do you?"); - Ok = false; - } -if(gCheck & gline::BAD_HOST) - { - bot->Notice(theClient,"illegal host"); - Ok = false; - } -if(gCheck & gline::BAD_CIDRMASK) - { - bot->Notice(theClient,"The IP listed is not on a bit boundary for the CIDR mask specified."); + if (gCheck & gline::NEG_TIME) { + bot->Notice(theClient, "You can't gline for a negative amount of time!"); Ok = false; - } -if(gCheck & gline::BAD_CIDRLEN) - { - bot->Notice(theClient,"Bad CIDR length - try something more specific."); + } + + if (gCheck & gline::HUH_NO_HOST) { + bot->Notice(theClient, "I don't think glining that host is such a good idea, do you?"); Ok = false; - } -if(gCheck & gline::BAD_CIDROVERRIDE) - { - bot->Notice(theClient,"For CIDR glines, you must enter all 4 parts of the IP."); + } + if (gCheck & gline::BAD_HOST) { + bot->Notice(theClient, "illegal host"); + Ok = false; + } + if (gCheck & gline::BAD_CIDRMASK) { + bot->Notice(theClient, + "The IP listed is not on a bit boundary for the CIDR mask specified."); + Ok = false; + } + if (gCheck & gline::BAD_CIDRLEN) { + bot->Notice(theClient, "Bad CIDR length - try something more specific."); + Ok = false; + } + if (gCheck & gline::BAD_CIDROVERRIDE) { + bot->Notice(theClient, "For CIDR glines, you must enter all 4 parts of the IP."); Ok = false; + } + if (gCheck & gline::BAD_TIME) { + bot->Notice(theClient, "Glining for more than %d seconds is not allowed", + gline::MFGLINE_TIME); + Ok = false; + } + if ((gCheck & gline::FU_NEEDED_USERS) && (Ok)) { + if (!Forced) { + Ok = false; + if (tmpUser->getFlags() < operLevel::SMTLEVEL) { + bot->Notice(theClient, + "Sorry, you can't set a gline which affects more than %d users", + gline::MFGLINE_USERS); + } else { + bot->Notice(theClient, + "This gline affects more than %d users, please use the -fu flag", + gline::MFGLINE_USERS); + } } -if(gCheck & gline::BAD_TIME) - { - bot->Notice(theClient,"Glining for more than %d seconds is not allowed",gline::MFGLINE_TIME); - Ok = false; - } -if((gCheck & gline::FU_NEEDED_USERS) && (Ok)) - { - if(!Forced) - { - Ok = false; - if(tmpUser->getFlags() < operLevel::SMTLEVEL) - { - bot->Notice(theClient,"Sorry, you can't set a gline which affects more than %d users", - gline::MFGLINE_USERS); - } - else - { - bot->Notice(theClient,"This gline affects more than %d users, please use the -fu flag", - gline::MFGLINE_USERS); - } - - } - } -if((gCheck & gline::FU_NEEDED_TIME) && (Ok)) - { - if(!Forced) - { - Ok = false; - if(tmpUser->getFlags() < operLevel::SMTLEVEL) - { - bot->Notice(theClient,"Sorry, you can't set a gline for more than %d seconds", - gline::MFGLINE_TIME); - } - else - { - bot->Notice(theClient,"This gline is for more than %d seconds, please use the -fu flag", - gline::MFGLINE_TIME); - } - } - } -if((gCheck & gline::HUH_IS_IP_OF_OPER) && (Ok)) - { - if (bot->isGlinedException(userName + "@" + hostName) > 0) { - bot->Notice(theClient,"There is someone who previously opered from that host. G-line sent (forced)"); - } - else { - bot->Notice(theClient,"There is someone who previously opered from that host (%s). Send the gline again to force.", bot->getLastNUHOfOperFromIP(hostName).c_str()); - bot->addGlinedException(userName + "@" + hostName); - Ok = false; - } - } -if((gCheck & gline::HUH_IS_EXCEPTION) && (Ok)) - { - if (bot->isGlinedException(userName + "@" + hostName) > 0) { - bot->Notice(theClient,"There is an exception for that host. G-line sent (forced)"); - } - else { - bot->Notice(theClient,"There is an exception for that host. Send the gline again to force."); - bot->addGlinedException(userName + "@" + hostName); - Ok = false; - } - } - -/*if((gCheck & gline::FORCE_NEEDED_HOST) && (Ok)) - { - bot->MsgChanLog("%s is using forcegline to gline a wildcard host (%s@%s)" - ,theClient->getNickName().c_str() - ,userName.c_str(),hostName.c_str()); - } + } + if ((gCheck & gline::FU_NEEDED_TIME) && (Ok)) { + if (!Forced) { + Ok = false; + if (tmpUser->getFlags() < operLevel::SMTLEVEL) { + bot->Notice(theClient, "Sorry, you can't set a gline for more than %d seconds", + gline::MFGLINE_TIME); + } else { + bot->Notice(theClient, + "This gline is for more than %d seconds, please use the -fu flag", + gline::MFGLINE_TIME); + } + } + } + if ((gCheck & gline::HUH_IS_IP_OF_OPER) && (Ok)) { + if (bot->isGlinedException(userName + "@" + hostName) > 0) { + bot->Notice( + theClient, + "There is someone who previously opered from that host. G-line sent (forced)"); + } else { + bot->Notice(theClient, + "There is someone who previously opered from that host (%s). Send the " + "gline again to force.", + bot->getLastNUHOfOperFromIP(hostName).c_str()); + bot->addGlinedException(userName + "@" + hostName); + Ok = false; + } + } + if ((gCheck & gline::HUH_IS_EXCEPTION) && (Ok)) { + if (bot->isGlinedException(userName + "@" + hostName) > 0) { + bot->Notice(theClient, "There is an exception for that host. G-line sent (forced)"); + } else { + bot->Notice(theClient, + "There is an exception for that host. Send the gline again to force."); + bot->addGlinedException(userName + "@" + hostName); + Ok = false; + } + } + /*if((gCheck & gline::FORCE_NEEDED_HOST) && (Ok)) + { + bot->MsgChanLog("%s is using forcegline to gline a wildcard host (%s@%s)" + ,theClient->getNickName().c_str() + ,userName.c_str(),hostName.c_str()); + } -if((gCheck & gline::FORCE_NEEDED_TIME) && (Ok)) - { - bot->MsgChanLog("%s is using forcegline to gline for %d seconds" - ,theClient->getNickName().c_str(),gLength); - } -if(gCheck & gline::FORCE_NEEDED_WILDTIME) - { - bot->MsgChanLog("%s is using forcegline to gline a wildcard host for more than %d seconds" - ,theClient->getNickName().c_str() - ,gline::MGLINE_WILD_TIME); - }*/ -string Cidr = hostName.substr(hostName.find('@')+1); + if((gCheck & gline::FORCE_NEEDED_TIME) && (Ok)) + { + bot->MsgChanLog("%s is using forcegline to gline for %d seconds" + ,theClient->getNickName().c_str(),gLength); + } -if (Cidr.find('/') != string::npos) - { - string tCidr; - if (!bot->getValidCidr(Cidr, tCidr)) - { - bot->Notice(theClient, "Unwanted cidr format: %s - Suggestion: %s", Cidr.c_str(), tCidr.c_str()); - Ok = false; - } - } -if(!Ok) - { - bot->Notice(theClient,"Please fix all of the above, and try again"); - return false; + if(gCheck & gline::FORCE_NEEDED_WILDTIME) + { + bot->MsgChanLog("%s is using forcegline to gline a wildcard host for more than %d + seconds" ,theClient->getNickName().c_str() ,gline::MGLINE_WILD_TIME); + }*/ + string Cidr = hostName.substr(hostName.find('@') + 1); - } -if(gCheck & gline::GLINE_OK) - { - bot->Notice(theClient,"Please use the GLINE command to set that gline"); - return false; - } -// Avoid passing a reference to a temporary variable. -string nickUserHost = theClient->getRealNickUserHost() ; -char Us[100]; -Us[0] = '\0'; -sprintf(Us,"%d",Users); -string Reason = st.assemble( pos + ResStart ); -StringTokenizer ReasonTokenizer(Reason,'|'); -Reason = string("[") + Us + "] " + ReasonTokenizer[0]; -if(Reason.size() > gline::MAX_REASON_LENGTH) - { - bot->Notice(theClient,"Gline reason can't be more than %d characters", - gline::MAX_REASON_LENGTH); - return false; - } -/*server->setGline( nickUserHost, - st[ pos ], - string("[") + Us + "] " + Reason, - //st.assemble( pos + ResStart ) + "[" + Us + "]", - gLength , bot) ;*/ + if (Cidr.find('/') != string::npos) { + string tCidr; + if (!bot->getValidCidr(Cidr, tCidr)) { + bot->Notice(theClient, "Unwanted cidr format: %s - Suggestion: %s", Cidr.c_str(), + tCidr.c_str()); + Ok = false; + } + } + if (!Ok) { + bot->Notice(theClient, "Please fix all of the above, and try again"); + return false; + } + if (gCheck & gline::GLINE_OK) { + bot->Notice(theClient, "Please use the GLINE command to set that gline"); + return false; + } + // Avoid passing a reference to a temporary variable. + string nickUserHost = theClient->getRealNickUserHost(); + char Us[100]; + Us[0] = '\0'; + sprintf(Us, "%d", Users); + string Reason = st.assemble(pos + ResStart); + StringTokenizer ReasonTokenizer(Reason, '|'); + Reason = string("[") + Us + "] " + ReasonTokenizer[0]; + if (Reason.size() > gline::MAX_REASON_LENGTH) { + bot->Notice(theClient, "Gline reason can't be more than %d characters", + gline::MAX_REASON_LENGTH); + return false; + } + /*server->setGline( nickUserHost, + st[ pos ], + string("[") + Us + "] " + Reason, + //st.assemble( pos + ResStart ) + "[" + Us + "]", + gLength , bot) ;*/ -ccGline *TmpGline = bot->findGline(gHost); -bool Up = false; + ccGline* TmpGline = bot->findGline(gHost); + bool Up = false; -if(TmpGline) - Up = true; -else TmpGline = new ccGline(bot->SQLDb); -TmpGline->setHost(gHost); -TmpGline->setExpires(unsigned(::time(0) + gLength)); -TmpGline->setAddedBy(nickUserHost); -TmpGline->setReason(Reason); -TmpGline->setAddedOn(::time(0)); -TmpGline->setLastUpdated(::time(0)); -bot->addGlineToUplink(TmpGline); -if(Up) - { - TmpGline->Update(); - } -else - { - TmpGline->Insert(); - //We need to update the Id - TmpGline->loadData(TmpGline->getHost()); - bot->addGline(TmpGline); - } + if (TmpGline) + Up = true; + else + TmpGline = new ccGline(bot->SQLDb); + TmpGline->setHost(gHost); + TmpGline->setExpires(unsigned(::time(0) + gLength)); + TmpGline->setAddedBy(nickUserHost); + TmpGline->setReason(Reason); + TmpGline->setAddedOn(::time(0)); + TmpGline->setLastUpdated(::time(0)); + bot->addGlineToUplink(TmpGline); + if (Up) { + TmpGline->Update(); + } else { + TmpGline->Insert(); + // We need to update the Id + TmpGline->loadData(TmpGline->getHost()); + bot->addGline(TmpGline); + } -bot->MsgChanLog(cmdStr.c_str()); -return true ; + bot->MsgChanLog(cmdStr.c_str()); + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/GCHANCommand.cc b/mod.ccontrol/GCHANCommand.cc index 9b6b25eb..e676f1a6 100644 --- a/mod.ccontrol/GCHANCommand.cc +++ b/mod.ccontrol/GCHANCommand.cc @@ -20,158 +20,137 @@ * $Id: GCHANCommand.cc,v 1.17 2006/09/26 17:35:58 kewlio Exp $ */ -#include -#include - -#include - -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "misc.h" -#include "Gline.h" -#include "ip.h" -#include "ELog.h" -#include "Gline.h" -//#include "gline.h" -#include "time.h" -#include "Constants.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool GCHANCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; - -if( st.size() < 4 ) - { - Usage( theClient ) ; - return true ; - } - -StringTokenizer::size_type pos = 1 ; - -bot->MsgChanLog("GCHAN %s\n",st.assemble(1).c_str()); -time_t gLength = bot->getDefaultGlineLength() ; - -// (pos) is the index of the next token, the user@host mask. - -if( (st[pos].substr(0,1) != "#" ) || (st[pos].size() > channel::MaxName)) - { - // Channel name must start with # - bot->Notice( theClient, "GCHAN: Please specify a legal channel name " - "(must start with # and no longer than %d characters)", - channel::MaxName ) ; - return true ; - } - -string Length; -Length.assign(st[pos+1]); -unsigned int Units = 1; //Defualt for seconds -unsigned int ResStart = 2; -bool isPerm = false; -if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"d")) - { - Units = 24*3600; - Length.resize(Length.length()-1); - //ResStart = 2; - } -else if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"h")) - { - Units = 3600; - Length.resize(Length.length()-1); -// ResStart = 2; - } -else if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"m")) - { - Units = 60; - Length.resize(Length.length()-1); -// ResStart = 2; - } - -else if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"s")) - { - Units = 1; - Length.resize(Length.length()-1); -// ResStart = 2; - } -gLength = atoi(Length.c_str()) * Units; -if(gLength == 0) - { //ok its a string, check if it marks permanent gline - if(!strcasecmp(Length,"-per")) - { - isPerm = true; - gLength = gline::PERM_TIME; //Set for two years , its long enough - if(st.size() < 4) - { - Usage(theClient); - return false; - } - } - else - { - gLength = bot->getDefaultGlineLength() ; - bot->Notice(theClient,"No duration was set, using %d seconds by default", - gLength); - ResStart = 1; - } - } -else if(st.size() < 4) - { - Usage(theClient); - return false; - } - -// Avoid passing a reference to a temporary variable. -string nickUserHost = theClient->getRealNickUserHost() ; -string Reason = st.assemble( pos + ResStart ); -if(Reason.size() > 255) - { - bot->Notice(theClient,"Gline reason can't be more than 255 characters"); - return false; - } - -/*server->setGline( nickUserHost, - st[ pos ], - Reason , - gLength , bot) ;*/ -ccGline *TmpGline = bot->findGline(st[pos]); -bool Up = false; -if(TmpGline) - Up = true; -else TmpGline = new ccGline(bot->SQLDb); -TmpGline->setHost(st [ pos ]); -if(!isPerm) - TmpGline->setExpires(::time(0) + gLength); -else - TmpGline->setExpires(0); -TmpGline->setAddedBy(nickUserHost); -TmpGline->setReason(st.assemble( pos + ResStart )); -TmpGline->setAddedOn(::time(0)); -TmpGline->setLastUpdated(::time(0)); -bot->addGlineToUplink(TmpGline); -if(Up) - { - TmpGline->Update(); - } -else - { - TmpGline->Insert(); - //We need to update the Id - TmpGline->loadData(TmpGline->getHost()); - bot->addGline(TmpGline); - } - -return true ; +#include +#include + +#include + +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "misc.h" +#include "Gline.h" +#include "ip.h" +#include "ELog.h" +#include "Gline.h" +// #include "gline.h" +#include "time.h" +#include "Constants.h" +#include "gnuworld_config.h" + +namespace gnuworld { + +using std::string; + +namespace uworld { + +bool GCHANCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + + if (st.size() < 4) { + Usage(theClient); + return true; + } + + StringTokenizer::size_type pos = 1; + + bot->MsgChanLog("GCHAN %s\n", st.assemble(1).c_str()); + time_t gLength = bot->getDefaultGlineLength(); + + // (pos) is the index of the next token, the user@host mask. + + if ((st[pos].substr(0, 1) != "#") || (st[pos].size() > channel::MaxName)) { + // Channel name must start with # + bot->Notice(theClient, + "GCHAN: Please specify a legal channel name " + "(must start with # and no longer than %d characters)", + channel::MaxName); + return true; + } + + string Length; + Length.assign(st[pos + 1]); + unsigned int Units = 1; // Defualt for seconds + unsigned int ResStart = 2; + bool isPerm = false; + if (!strcasecmp(Length.substr(Length.length() - 1).c_str(), "d")) { + Units = 24 * 3600; + Length.resize(Length.length() - 1); + // ResStart = 2; + } else if (!strcasecmp(Length.substr(Length.length() - 1).c_str(), "h")) { + Units = 3600; + Length.resize(Length.length() - 1); + // ResStart = 2; + } else if (!strcasecmp(Length.substr(Length.length() - 1).c_str(), "m")) { + Units = 60; + Length.resize(Length.length() - 1); + // ResStart = 2; + } + + else if (!strcasecmp(Length.substr(Length.length() - 1).c_str(), "s")) { + Units = 1; + Length.resize(Length.length() - 1); + // ResStart = 2; + } + gLength = atoi(Length.c_str()) * Units; + if (gLength == 0) { // ok its a string, check if it marks permanent gline + if (!strcasecmp(Length, "-per")) { + isPerm = true; + gLength = gline::PERM_TIME; // Set for two years , its long enough + if (st.size() < 4) { + Usage(theClient); + return false; + } + } else { + gLength = bot->getDefaultGlineLength(); + bot->Notice(theClient, "No duration was set, using %d seconds by default", gLength); + ResStart = 1; + } + } else if (st.size() < 4) { + Usage(theClient); + return false; + } + + // Avoid passing a reference to a temporary variable. + string nickUserHost = theClient->getRealNickUserHost(); + string Reason = st.assemble(pos + ResStart); + if (Reason.size() > 255) { + bot->Notice(theClient, "Gline reason can't be more than 255 characters"); + return false; + } + + /*server->setGline( nickUserHost, + st[ pos ], + Reason , + gLength , bot) ;*/ + ccGline* TmpGline = bot->findGline(st[pos]); + bool Up = false; + if (TmpGline) + Up = true; + else + TmpGline = new ccGline(bot->SQLDb); + TmpGline->setHost(st[pos]); + if (!isPerm) + TmpGline->setExpires(::time(0) + gLength); + else + TmpGline->setExpires(0); + TmpGline->setAddedBy(nickUserHost); + TmpGline->setReason(st.assemble(pos + ResStart)); + TmpGline->setAddedOn(::time(0)); + TmpGline->setLastUpdated(::time(0)); + bot->addGlineToUplink(TmpGline); + if (Up) { + TmpGline->Update(); + } else { + TmpGline->Insert(); + // We need to update the Id + TmpGline->loadData(TmpGline->getHost()); + bot->addGline(TmpGline); + } + + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/GLINECommand.cc b/mod.ccontrol/GLINECommand.cc index 33f59d3c..053eb65c 100644 --- a/mod.ccontrol/GLINECommand.cc +++ b/mod.ccontrol/GLINECommand.cc @@ -1,6 +1,6 @@ /** * GLINECommand.cc - * Glines a specific mask + * Glines a specific mask * 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 @@ -19,31 +19,30 @@ * $Id: GLINECommand.cc,v 1.64 2009/06/09 05:55:55 hidden1 Exp $ */ -#include -#include -#include +#include +#include +#include -#include +#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "misc.h" -#include "Gline.h" -#include "ip.h" -#include "ELog.h" -#include "Gline.h" -//#include "gline.h" -#include "time.h" -#include "ccUser.h" -#include "Constants.h" -#include "gnuworld_config.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "misc.h" +#include "Gline.h" +#include "ip.h" +#include "ELog.h" +#include "Gline.h" +// #include "gline.h" +#include "time.h" +#include "ccUser.h" +#include "Constants.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; // Input: gline *@blah.net reason // Input: gline 3600 *@blah.net reason @@ -51,267 +50,242 @@ using std::string ; // Output: C GL * +*@lamer.net 3600 :Banned (*@lamer) ... // -namespace uworld -{ +namespace uworld { -bool GLINECommand::Exec( iClient* theClient, const string& Message ) -{ -bool Ok = true; -StringTokenizer st( Message ) ; +bool GLINECommand::Exec(iClient* theClient, const string& Message) { + bool Ok = true; + StringTokenizer st(Message); -if( st.size() < 4 ) - { - Usage( theClient ) ; - return true ; - } + if (st.size() < 4) { + Usage(theClient); + return true; + } -StringTokenizer::size_type pos = 1 ; + StringTokenizer::size_type pos = 1; + time_t gLength = bot->getDefaultGlineLength(); -time_t gLength = bot->getDefaultGlineLength() ; + ccUser* tmpUser = bot->IsAuth(theClient); -ccUser* tmpUser = bot->IsAuth(theClient); + if (st[pos].substr(0, 1) == "#") { + bot->Notice(theClient, "Please use the CHANGLINE command to gline channels"); + return true; + } -if(st[pos].substr(0,1) == "#") -{ - bot->Notice(theClient, "Please use the CHANGLINE command to gline channels"); - return true; -} - -if(st[pos].find_first_of('#') != string::npos) - { - bot->Notice(theClient,"Nice try, but i dont think glining that host is such a good idea"); - return true; - } -string userName; -string hostName; - if(st[pos].substr(0,1) == "$") - { - bot->Notice(theClient,"Please use SGLINE to set this gline"); - return true; - } - string gHost = st[pos]; - if (!isUserHost(gHost)) - { - iClient* tClient = Network->findNick(st[pos]); - if(!tClient) - { - bot->Notice( theClient, "I can't find '%s' online, " - "please specify a host instead", - gHost.c_str()); - return true ; - } - else //Ohhh neat we found our target, lets grab his ip - { - userName = tClient->getUserName(); - if(userName[0] == '~') - userName = "~*"; - hostName = xIP(tClient->getIP()).GetNumericIP(); - fixToCIDR64(hostName); - string newMsg = "GLINE mask for " + gHost + " is " + userName + "@" + hostName; - bot->MsgChanLog("%s\n",newMsg.c_str()); - gHost = userName + "@" + hostName; + if (st[pos].find_first_of('#') != string::npos) { + bot->Notice(theClient, "Nice try, but i dont think glining that host is such a good idea"); + return true; + } + string userName; + string hostName; + if (st[pos].substr(0, 1) == "$") { + bot->Notice(theClient, "Please use SGLINE to set this gline"); + return true; + } + string gHost = st[pos]; + if (!isUserHost(gHost)) { + iClient* tClient = Network->findNick(st[pos]); + if (!tClient) { + bot->Notice(theClient, + "I can't find '%s' online, " + "please specify a host instead", + gHost.c_str()); + return true; + } else // Ohhh neat we found our target, lets grab his ip + { + userName = tClient->getUserName(); + if (userName[0] == '~') + userName = "~*"; + hostName = xIP(tClient->getIP()).GetNumericIP(); + fixToCIDR64(hostName); + string newMsg = "GLINE mask for " + gHost + " is " + userName + "@" + hostName; + bot->MsgChanLog("%s\n", newMsg.c_str()); + gHost = userName + "@" + hostName; #ifndef LOGTOHD - if(tmpUser) - bot->DailyLog(tmpUser,"%s",newMsg.c_str()); - else - bot->DailyLog(theClient,"%s",newMsg.c_str()); + if (tmpUser) + bot->DailyLog(tmpUser, "%s", newMsg.c_str()); + else + bot->DailyLog(theClient, "%s", newMsg.c_str()); #else - ccLog* newLog = new (std::nothrow) ccLog(); - newLog->Time = ::time(0); - newLog->Desc = newMsg.c_str(); - newLog->Host = theClient->getRealNickUserHost().c_str(); - if(tmpUser) - newLog->User = tmpUser->getUserName().c_str(); - else - newLog->User = "Unknown"; - newLog->CommandName = "GLINE"; - bot->DailyLog(newLog); + ccLog* newLog = new (std::nothrow) ccLog(); + newLog->Time = ::time(0); + newLog->Desc = newMsg.c_str(); + newLog->Host = theClient->getRealNickUserHost().c_str(); + if (tmpUser) + newLog->User = tmpUser->getUserName().c_str(); + else + newLog->User = "Unknown"; + newLog->CommandName = "GLINE"; + bot->DailyLog(newLog); #endif - } - } //isUserHost(gHost) - else // fix @ip to-> *@ip - if (gHost[0] == '@') - gHost = '*' + gHost; + } + } // isUserHost(gHost) + else // fix @ip to-> *@ip + if (gHost[0] == '@') + gHost = '*' + gHost; -unsigned int ResStart = 2; -if (IsTimeSpec(st[2])) -{ - gLength = extractTime( st[2], 1 ); -} else { - gLength = bot->getDefaultGlineLength(); - ResStart = 1; -} - -string nickUserHost = theClient->getRealNickUserHost() ; -//string gHost = userName + "@" + hostName; - unsigned int Users; - int gCheck = bot->checkGline(gHost,gLength,Users); - hostName = gHost.substr(gHost.find('@')+1); - if(!tmpUser) - { - if((string::npos != hostName.find_first_of("*")) - || (string::npos != hostName.find_first_of("?")) - || ((unsigned)gLength > gline::NOLOGIN_TIME)) - { - bot->Notice(theClient,"You must login to issue this gline!"); - return true; - } - Users = Network->countMatchingRealUserHost(gHost); - } - else - { - if(gCheck & gline::NEG_TIME) - { - bot->Notice(theClient,"You can't gline for a negative amount of time."); - Ok = false; - } - if(gCheck & gline::HUH_NO_HOST) - { - bot->Notice(theClient,"I don't think glining that host is such a good idea, do you?"); - Ok = false; - } - if(gCheck & gline::BAD_HOST) - { - bot->Notice(theClient,"illegal host"); - Ok = false; - } - if(gCheck & gline::BAD_CIDRMASK) - { - bot->Notice(theClient,"The IP listed is not on a bit boundary for the CIDR mask specified."); - Ok = false; - } - if (gCheck & gline::BAD_CIDRLEN) - { - bot->Notice(theClient,"Bad CIDR length - try something more specific."); - Ok = false; - } - if (gCheck & gline::BAD_CIDROVERRIDE) - { - bot->Notice(theClient,"For CIDR glines, you must enter all 4 parts of the IP."); - Ok = false; - } - if(gCheck & gline::BAD_TIME) - { - bot->Notice(theClient,"Glining for more than %d seconds is not allowed.", - gline::MFGLINE_TIME); - Ok = false; - } - if((gCheck & gline::FORCE_NEEDED_HOST) && (Ok)) - { - bot->Notice(theClient,"Please use FORCEGLINE to gline that host"); - Ok = false; - } - if((gCheck & gline::FORCE_NEEDED_TIME) && (Ok)) - { - bot->Notice(theClient,"Please use FORCEGLINE to gline for that amount of time"); - Ok = false; - } - if((gCheck & gline::FU_NEEDED_USERS) && (Ok)) - { - bot->Notice(theClient,"This gline would affect more than %d users, please " - "use FORCEGLINE",gline::MFGLINE_USERS); - Ok = false; - } - if((gCheck & gline::FU_NEEDED_TIME) && (Ok)) - { - bot->Notice(theClient,"Please use FORCEGLINE to gline for more than " - "%d seconds",gline::MFGLINE_TIME); - Ok = false; - } - if((gCheck & gline::FORCE_NEEDED_WILDTIME) && (Ok)) - { - bot->Notice(theClient,"Wildcard gline for more than %d" - " seconds (or more than %d without ident), " - "please use FORCEGLINE instead" - ,gline::MGLINE_WILD_TIME , - gline::MGLINE_WILD_NOID_TIME); - Ok = false; - } - if((gCheck & gline::HUH_IS_IP_OF_OPER) && (Ok)) - { - if (bot->isGlinedException(gHost) > 0) { - bot->Notice(theClient,"There is someone who previously opered from that host. G-line sent (forced)"); - } - else { - bot->Notice(theClient,"There is someone who previously opered from that host (%s). Send the gline again to force.", bot->getLastNUHOfOperFromIP(hostName).c_str()); - bot->addGlinedException(gHost); - Ok = false; - } - } - if((gCheck & gline::HUH_IS_EXCEPTION) && (Ok)) - { - if (bot->isGlinedException(gHost) > 0) { - bot->Notice(theClient,"There is an exception for that host. G-line sent (forced)"); - } - else { - bot->Notice(theClient,"There is an exception for that host. Send the gline again to force."); - bot->addGlinedException(gHost); - Ok = false; - } - } - if (hostName.find('/') != string::npos) - { - string tCidr; - if (!bot->getValidCidr(hostName, tCidr)) - { - bot->Notice(theClient, "Unwanted cidr format: %s - Suggestion: %s", hostName.c_str(), tCidr.c_str()); - Ok = false; - } - } - if(!Ok) - { - bot->Notice(theClient,"Please fix all of the above, and try again"); - return false; - } - } - char Us[100]; - Us[0] = '\0'; - sprintf(Us,"%d",Users); - StringTokenizer reasonTokenizer(st.assemble( pos + ResStart),'|'); - string Reason = reasonTokenizer[0]; - if(Reason.size() > gline::MAX_REASON_LENGTH) - { - bot->Notice(theClient,"Gline reason can't be more than %d characters", - gline::MAX_REASON_LENGTH); - return false; - } - Reason = string("[") + Us + string("] ") + Reason; -/* server->setGline( nickUserHost, - userName + "@" +hostName, - string("[") + Us + "] " + Reason, - //Reason + "[" + Us + "]", - gLength ,::time(0),bot) ;*/ - ccGline *TmpGline = bot->findGline(gHost); - bool Up = false; - - if(TmpGline) - Up = true; - else TmpGline = new ccGline(bot->SQLDb); - TmpGline->setHost(gHost); - TmpGline->setExpires(unsigned(::time(0) + gLength)); - TmpGline->setAddedBy(nickUserHost); - TmpGline->setReason(Reason); - TmpGline->setAddedOn(::time(0)); - TmpGline->setLastUpdated(::time(0)); - bot->addGlineToUplink(TmpGline); - if(Up) - { - TmpGline->Update(); - } - else - { - TmpGline->Insert(); - //We need to update the Id - TmpGline->loadData(TmpGline->getHost()); - bot->addGline(TmpGline); - } + unsigned int ResStart = 2; + if (IsTimeSpec(st[2])) { + gLength = extractTime(st[2], 1); + } else { + gLength = bot->getDefaultGlineLength(); + ResStart = 1; + } - bot->MsgChanLog("GLINE %s %s\n",gHost.c_str(), st.assemble(2).c_str()); + string nickUserHost = theClient->getRealNickUserHost(); + // string gHost = userName + "@" + hostName; + unsigned int Users; + int gCheck = bot->checkGline(gHost, gLength, Users); + hostName = gHost.substr(gHost.find('@') + 1); + if (!tmpUser) { + if ((string::npos != hostName.find_first_of("*")) || + (string::npos != hostName.find_first_of("?")) || + ((unsigned)gLength > gline::NOLOGIN_TIME)) { + bot->Notice(theClient, "You must login to issue this gline!"); + return true; + } + Users = Network->countMatchingRealUserHost(gHost); + } else { + if (gCheck & gline::NEG_TIME) { + bot->Notice(theClient, "You can't gline for a negative amount of time."); + Ok = false; + } + if (gCheck & gline::HUH_NO_HOST) { + bot->Notice(theClient, "I don't think glining that host is such a good idea, do you?"); + Ok = false; + } + if (gCheck & gline::BAD_HOST) { + bot->Notice(theClient, "illegal host"); + Ok = false; + } + if (gCheck & gline::BAD_CIDRMASK) { + bot->Notice(theClient, + "The IP listed is not on a bit boundary for the CIDR mask specified."); + Ok = false; + } + if (gCheck & gline::BAD_CIDRLEN) { + bot->Notice(theClient, "Bad CIDR length - try something more specific."); + Ok = false; + } + if (gCheck & gline::BAD_CIDROVERRIDE) { + bot->Notice(theClient, "For CIDR glines, you must enter all 4 parts of the IP."); + Ok = false; + } + if (gCheck & gline::BAD_TIME) { + bot->Notice(theClient, "Glining for more than %d seconds is not allowed.", + gline::MFGLINE_TIME); + Ok = false; + } + if ((gCheck & gline::FORCE_NEEDED_HOST) && (Ok)) { + bot->Notice(theClient, "Please use FORCEGLINE to gline that host"); + Ok = false; + } + if ((gCheck & gline::FORCE_NEEDED_TIME) && (Ok)) { + bot->Notice(theClient, "Please use FORCEGLINE to gline for that amount of time"); + Ok = false; + } + if ((gCheck & gline::FU_NEEDED_USERS) && (Ok)) { + bot->Notice(theClient, + "This gline would affect more than %d users, please " + "use FORCEGLINE", + gline::MFGLINE_USERS); + Ok = false; + } + if ((gCheck & gline::FU_NEEDED_TIME) && (Ok)) { + bot->Notice(theClient, + "Please use FORCEGLINE to gline for more than " + "%d seconds", + gline::MFGLINE_TIME); + Ok = false; + } + if ((gCheck & gline::FORCE_NEEDED_WILDTIME) && (Ok)) { + bot->Notice(theClient, + "Wildcard gline for more than %d" + " seconds (or more than %d without ident), " + "please use FORCEGLINE instead", + gline::MGLINE_WILD_TIME, gline::MGLINE_WILD_NOID_TIME); + Ok = false; + } + if ((gCheck & gline::HUH_IS_IP_OF_OPER) && (Ok)) { + if (bot->isGlinedException(gHost) > 0) { + bot->Notice( + theClient, + "There is someone who previously opered from that host. G-line sent (forced)"); + } else { + bot->Notice(theClient, + "There is someone who previously opered from that host (%s). Send the " + "gline again to force.", + bot->getLastNUHOfOperFromIP(hostName).c_str()); + bot->addGlinedException(gHost); + Ok = false; + } + } + if ((gCheck & gline::HUH_IS_EXCEPTION) && (Ok)) { + if (bot->isGlinedException(gHost) > 0) { + bot->Notice(theClient, "There is an exception for that host. G-line sent (forced)"); + } else { + bot->Notice(theClient, + "There is an exception for that host. Send the gline again to force."); + bot->addGlinedException(gHost); + Ok = false; + } + } + if (hostName.find('/') != string::npos) { + string tCidr; + if (!bot->getValidCidr(hostName, tCidr)) { + bot->Notice(theClient, "Unwanted cidr format: %s - Suggestion: %s", + hostName.c_str(), tCidr.c_str()); + Ok = false; + } + } + if (!Ok) { + bot->Notice(theClient, "Please fix all of the above, and try again"); + return false; + } + } + char Us[100]; + Us[0] = '\0'; + sprintf(Us, "%d", Users); + StringTokenizer reasonTokenizer(st.assemble(pos + ResStart), '|'); + string Reason = reasonTokenizer[0]; + if (Reason.size() > gline::MAX_REASON_LENGTH) { + bot->Notice(theClient, "Gline reason can't be more than %d characters", + gline::MAX_REASON_LENGTH); + return false; + } + Reason = string("[") + Us + string("] ") + Reason; + /* server->setGline( nickUserHost, + userName + "@" +hostName, + string("[") + Us + "] " + Reason, + //Reason + "[" + Us + "]", + gLength ,::time(0),bot) ;*/ + ccGline* TmpGline = bot->findGline(gHost); + bool Up = false; - return true; + if (TmpGline) + Up = true; + else + TmpGline = new ccGline(bot->SQLDb); + TmpGline->setHost(gHost); + TmpGline->setExpires(unsigned(::time(0) + gLength)); + TmpGline->setAddedBy(nickUserHost); + TmpGline->setReason(Reason); + TmpGline->setAddedOn(::time(0)); + TmpGline->setLastUpdated(::time(0)); + bot->addGlineToUplink(TmpGline); + if (Up) { + TmpGline->Update(); + } else { + TmpGline->Insert(); + // We need to update the Id + TmpGline->loadData(TmpGline->getHost()); + bot->addGline(TmpGline); + } -} + bot->MsgChanLog("GLINE %s %s\n", gHost.c_str(), st.assemble(2).c_str()); + return true; } -} + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/HELPCommand.cc b/mod.ccontrol/HELPCommand.cc index 96f26465..94bf744e 100644 --- a/mod.ccontrol/HELPCommand.cc +++ b/mod.ccontrol/HELPCommand.cc @@ -20,83 +20,71 @@ * $Id: HELPCommand.cc,v 1.23 2006/09/26 17:35:58 kewlio Exp $ */ -#include -#include +#include +#include -#include +#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "commLevels.h" -#include "gnuworld_config.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "commLevels.h" +#include "gnuworld_config.h" -namespace gnuworld -{ - -using std::string ; +namespace gnuworld { +using std::string; // help [command] -namespace uworld -{ +namespace uworld { -bool HELPCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; +bool HELPCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -ccUser *tmpAuth = bot->IsAuth(theClient); -//if(!tmpAuth) -// return false; -string banner = "--- Help Menu for " ; -banner += bot->getNickName() + " --- (Showing commands which are available for you)" ; + ccUser* tmpAuth = bot->IsAuth(theClient); + // if(!tmpAuth) + // return false; + string banner = "--- Help Menu for "; + banner += bot->getNickName() + " --- (Showing commands which are available for you)"; -bot->Notice( theClient, "%s", banner.c_str() ) ; + bot->Notice(theClient, "%s", banner.c_str()); -int ComLevel; -// Check if the user didnt supply a command -if( 1 == st.size() ) - { - // Spit out all commands - string Show; - for( ccontrol::constCommandIterator ptr = bot->command_begin() ; - ptr != bot->command_end() ; ++ptr ) - { - ComLevel = ptr->second->getFlags(); - //ComLevel &= ~flg_NOLOG; - if((ComLevel & commandLevel::flg_NOLOGIN) || ((tmpAuth) && (tmpAuth->gotAccess(ptr->second))) ) - { - Show += (ptr->second->getName() + " "); - if(Show.size() > 80) - { - bot->Notice( theClient, "%s", Show.c_str()) ; - Show.assign(""); - } - } - } - if(!Show.empty()) - bot->Notice( theClient, "%s", Show.c_str()) ; - bot->Notice(theClient,"End of command list"); - } -else //Supplied a command, show only the help for that command (if it exists) - { - ccontrol::constCommandIterator ptr = - bot->findCommand( string_upper( st[ 1 ] ) ) ; - if( ptr == bot->command_end() ) - { - bot->Notice( theClient, "Command not found" ) ; - } - else - { - if (st.size()==2) - bot->GetHelp(theClient,st[1],static_cast("")); - else - bot->GetHelp(theClient,st[1],st[2]); - } - } + int ComLevel; + // Check if the user didnt supply a command + if (1 == st.size()) { + // Spit out all commands + string Show; + for (ccontrol::constCommandIterator ptr = bot->command_begin(); ptr != bot->command_end(); + ++ptr) { + ComLevel = ptr->second->getFlags(); + // ComLevel &= ~flg_NOLOG; + if ((ComLevel & commandLevel::flg_NOLOGIN) || + ((tmpAuth) && (tmpAuth->gotAccess(ptr->second)))) { + Show += (ptr->second->getName() + " "); + if (Show.size() > 80) { + bot->Notice(theClient, "%s", Show.c_str()); + Show.assign(""); + } + } + } + if (!Show.empty()) + bot->Notice(theClient, "%s", Show.c_str()); + bot->Notice(theClient, "End of command list"); + } else // Supplied a command, show only the help for that command (if it exists) + { + ccontrol::constCommandIterator ptr = bot->findCommand(string_upper(st[1])); + if (ptr == bot->command_end()) { + bot->Notice(theClient, "Command not found"); + } else { + if (st.size() == 2) + bot->GetHelp(theClient, st[1], static_cast("")); + else + bot->GetHelp(theClient, st[1], st[2]); + } + } -return true ; + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/INVITECommand.cc b/mod.ccontrol/INVITECommand.cc index d1f4d7e8..a5c90fc9 100644 --- a/mod.ccontrol/INVITECommand.cc +++ b/mod.ccontrol/INVITECommand.cc @@ -20,88 +20,73 @@ * $Id: INVITECommand.cc,v 1.21 2006/09/26 17:35:58 kewlio Exp $ */ -#include -#include +#include +#include -#include +#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" -#include "Network.h" -#include "gnuworld_config.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" +#include "Network.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { // invite #channel -bool INVITECommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; +bool INVITECommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -if( st.size() == 1 ) - { - // send help - Usage( theClient ) ; - return false ; - } -if(st[1].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d characters", - channel::MaxName); - return false; - } -ccUser* tmpUser = bot->IsAuth(theClient); -bot->MsgChanLog("INVITE %s\n",st.assemble(1).c_str()); + if (st.size() == 1) { + // send help + Usage(theClient); + return false; + } + if (st[1].size() > channel::MaxName) { + bot->Notice(theClient, "Channel name can't be more than %d characters", channel::MaxName); + return false; + } + ccUser* tmpUser = bot->IsAuth(theClient); + bot->MsgChanLog("INVITE %s\n", st.assemble(1).c_str()); -//If the channel doesnt begin with # add it -string chanName = st[ 1 ] ; -if( chanName[ 0 ] != '#' ) - { - chanName.insert( chanName.begin(), '#' ) ; - } + // If the channel doesnt begin with # add it + string chanName = st[1]; + if (chanName[0] != '#') { + chanName.insert(chanName.begin(), '#'); + } -iClient* inviteClient = 0 ; -if(st.size() > 2) - { - // Invite a different user - inviteClient = Network->findNick(st[2]); - if( inviteClient == NULL) - { - bot->Notice(theClient,"I cant find '%s' anywhere", - st[2].c_str()); - return true; - } + iClient* inviteClient = 0; + if (st.size() > 2) { + // Invite a different user + inviteClient = Network->findNick(st[2]); + if (inviteClient == NULL) { + bot->Notice(theClient, "I cant find '%s' anywhere", st[2].c_str()); + return true; + } - if( !tmpUser && (inviteClient != theClient)) - { - bot->Notice(theClient,"You must login to invite someone else!"); - return true; - } - } -else - { - // Invite the requesting user - inviteClient = theClient ; - } + if (!tmpUser && (inviteClient != theClient)) { + bot->Notice(theClient, "You must login to invite someone else!"); + return true; + } + } else { + // Invite the requesting user + inviteClient = theClient; + } -Channel* theChan = Network->findChannel(st[1]); -if (theChan == NULL) -{ - bot->Notice(theClient, "Channel '%s' does not exist!", st[1].c_str()); - return true; -} - -// xClient::Invite() will Join/Part the channel if necessary. -return bot->Invite( inviteClient, chanName ) ; -} + Channel* theChan = Network->findChannel(st[1]); + if (theChan == NULL) { + bot->Notice(theClient, "Channel '%s' does not exist!", st[1].c_str()); + return true; + } -} + // xClient::Invite() will Join/Part the channel if necessary. + return bot->Invite(inviteClient, chanName); } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/JUPECommand.cc b/mod.ccontrol/JUPECommand.cc index 4eb6819a..e82e90d4 100644 --- a/mod.ccontrol/JUPECommand.cc +++ b/mod.ccontrol/JUPECommand.cc @@ -20,95 +20,79 @@ * $Id: JUPECommand.cc,v 1.23 2006/09/26 17:35:58 kewlio Exp $ */ -#include -#include -#include - -#include - -#include "ccontrol.h" -#include "iServer.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "Constants.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool JUPECommand::Exec( iClient* theClient, const string& Message ) -{ - -StringTokenizer st( Message ) ; -if( st.size() < 3 ) - { - Usage( theClient ) ; - return false ; - } - -// The server name to be juped must have at least 1 '.' -if( st[1].length() > server::MaxName) - { - bot->Notice( theClient, "Bogus server name" ) ; - return false ; - } -bot->MsgChanLog("JUPE %s\n",st.assemble(1).c_str()); - -iServer* Server; -string SName; -if(string::npos != st[ 1 ].find_first_of( '*' )) - { - bot->Notice(theClient,"Sorry, but you must give a full server name when juping!"); - return false; - } -else if(string::npos == st[ 1 ].find_first_of( '.' )) - { - bot->Notice( theClient, "Bogus server name" ) ; - return false ; - } - -Server = Network->findServerName(st[1]); -if(Server) - { - bot->Notice(theClient,"%s is currently linked to the network" - ", it will be automatically squit.", - st[1].c_str()); - } -SName = st[1]; - -if(!strcasecmp(SName,Network->findServer(bot->getUplink()->getUplinkCharYY())->getName())) - { - bot->Notice(theClient,"What are you trying to do? kill me?"); - bot->MsgChanLog("%s just tried to jupe my uplink!\n",theClient->getNickName().c_str()); - return false; - } -bot->MsgChanLog("%s is asking me to jupe %s because: %s\n", - theClient->getNickName().c_str(), - SName.c_str(), - st.assemble(2).c_str()); - -string yyxxx( "00]]]" ) ; -iServer* jupeServer = new (std::nothrow) iServer( - bot->getUplinkIntYY(), // uplinkIntYY - yyxxx, - SName, - time( 0 ), - st.assemble( 2 ) ) ; -assert( jupeServer != 0 ) ; -jupeServer->setJupe(); - -// Attach the new (fake) server. -server->AttachServer( jupeServer, bot ) ; - -return true ; - +#include +#include +#include + +#include + +#include "ccontrol.h" +#include "iServer.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "Constants.h" +#include "gnuworld_config.h" + +namespace gnuworld { + +using std::string; + +namespace uworld { + +bool JUPECommand::Exec(iClient* theClient, const string& Message) { + + StringTokenizer st(Message); + if (st.size() < 3) { + Usage(theClient); + return false; + } + + // The server name to be juped must have at least 1 '.' + if (st[1].length() > server::MaxName) { + bot->Notice(theClient, "Bogus server name"); + return false; + } + bot->MsgChanLog("JUPE %s\n", st.assemble(1).c_str()); + + iServer* Server; + string SName; + if (string::npos != st[1].find_first_of('*')) { + bot->Notice(theClient, "Sorry, but you must give a full server name when juping!"); + return false; + } else if (string::npos == st[1].find_first_of('.')) { + bot->Notice(theClient, "Bogus server name"); + return false; + } + + Server = Network->findServerName(st[1]); + if (Server) { + bot->Notice(theClient, + "%s is currently linked to the network" + ", it will be automatically squit.", + st[1].c_str()); + } + SName = st[1]; + + if (!strcasecmp(SName, Network->findServer(bot->getUplink()->getUplinkCharYY())->getName())) { + bot->Notice(theClient, "What are you trying to do? kill me?"); + bot->MsgChanLog("%s just tried to jupe my uplink!\n", theClient->getNickName().c_str()); + return false; + } + bot->MsgChanLog("%s is asking me to jupe %s because: %s\n", theClient->getNickName().c_str(), + SName.c_str(), st.assemble(2).c_str()); + + string yyxxx("00]]]"); + iServer* jupeServer = new (std::nothrow) iServer(bot->getUplinkIntYY(), // uplinkIntYY + yyxxx, SName, time(0), st.assemble(2)); + assert(jupeServer != 0); + jupeServer->setJupe(); + + // Attach the new (fake) server. + server->AttachServer(jupeServer, bot); + + return true; } -} +} // namespace uworld } // namespace gnuworld diff --git a/mod.ccontrol/KICKCommand.cc b/mod.ccontrol/KICKCommand.cc index f15e15b0..8b502459 100644 --- a/mod.ccontrol/KICKCommand.cc +++ b/mod.ccontrol/KICKCommand.cc @@ -20,109 +20,93 @@ * $Id: KICKCommand.cc,v 1.15 2006/09/26 17:35:58 kewlio Exp $ */ -#include -#include +#include +#include -#include +#include -#include "Network.h" -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" -#include "ccBadChannel.h" -#include "gnuworld_config.h" +#include "Network.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" +#include "ccBadChannel.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { // kick #channel nick reason -bool KICKCommand::Exec( iClient* theClient, const string& Message ) -{ - -StringTokenizer st( Message ) ; -if( st.size() < 4 ) - { - Usage( theClient ) ; - return true ; - } - -//Check if the channel begins with # , if not add it -string chanName = st[ 1 ] ; -if( chanName[ 0 ] != '#' ) - { - chanName.insert( chanName.begin(), '#' ) ; - } - -if(chanName.size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d characters", - channel::MaxName); - } - -bot->MsgChanLog("KICK %s\n",st.assemble(1).c_str()); - -ccBadChannel* Chan = bot->isBadChannel(st[1]); -if(Chan) - { - bot->Notice(theClient,"Sorry, you can't kick from " - "this channel because: %s", - Chan->getReason().c_str()); +bool KICKCommand::Exec(iClient* theClient, const string& Message) { + + StringTokenizer st(Message); + if (st.size() < 4) { + Usage(theClient); + return true; + } + + // Check if the channel begins with # , if not add it + string chanName = st[1]; + if (chanName[0] != '#') { + chanName.insert(chanName.begin(), '#'); + } + + if (chanName.size() > channel::MaxName) { + bot->Notice(theClient, "Channel name can't be more than %d characters", channel::MaxName); + } + + bot->MsgChanLog("KICK %s\n", st.assemble(1).c_str()); + + ccBadChannel* Chan = bot->isBadChannel(st[1]); + if (Chan) { + bot->Notice(theClient, + "Sorry, you can't kick from " + "this channel because: %s", + Chan->getReason().c_str()); return false; - } - -Channel* theChan = Network->findChannel( chanName ) ; -if( NULL == theChan ) - { - bot->Notice( theClient, "Unable to find channel: %s", - chanName.c_str() ) ; - return true ; - } - -iClient* Target = Network->findNick( st[ 2 ] ) ; -if( NULL == Target ) - { - bot->Notice( theClient, "Unable to find nick: %s", - st[ 2 ].c_str() ) ; - return true ; - } - -if( NULL == theChan->findUser( Target ) ) - { - bot->Notice( theClient, "User %s was not found " - "on channel %s", - st[ 1 ].c_str(), - theChan->getName().c_str()); - return true ; - } - -if( Target->getMode(iClient::MODE_SERVICES)) - { - bot->Notice(theClient,"Are you trying to get me in trouble with %s?",st[ 2 ].c_str()); - return false; - } -bot->Notice( theClient, "Kicking %s from channel %s because %s", - Target->getNickName().c_str(), - chanName.c_str(), - st.assemble( 3 ).c_str() ) ; - -//If its an oper channel , no need to join and part the channel , so just kick the user -if( bot->isOperChan( chanName ) ) - { - bot->Kick( theChan, Target, st.assemble( 3 ) ) ; - return true ; - } - -//Its not an oper channel -bot->Kick( theChan, Target, st.assemble(3), true) ; - -return true ; -} + } + + Channel* theChan = Network->findChannel(chanName); + if (NULL == theChan) { + bot->Notice(theClient, "Unable to find channel: %s", chanName.c_str()); + return true; + } + + iClient* Target = Network->findNick(st[2]); + if (NULL == Target) { + bot->Notice(theClient, "Unable to find nick: %s", st[2].c_str()); + return true; + } + + if (NULL == theChan->findUser(Target)) { + bot->Notice(theClient, + "User %s was not found " + "on channel %s", + st[1].c_str(), theChan->getName().c_str()); + return true; + } + + if (Target->getMode(iClient::MODE_SERVICES)) { + bot->Notice(theClient, "Are you trying to get me in trouble with %s?", st[2].c_str()); + return false; + } + bot->Notice(theClient, "Kicking %s from channel %s because %s", Target->getNickName().c_str(), + chanName.c_str(), st.assemble(3).c_str()); + // If its an oper channel , no need to join and part the channel , so just kick the user + if (bot->isOperChan(chanName)) { + bot->Kick(theChan, Target, st.assemble(3)); + return true; + } + + // Its not an oper channel + bot->Kick(theChan, Target, st.assemble(3), true); + + return true; } -} + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/LASTCOMCommand.cc b/mod.ccontrol/LASTCOMCommand.cc index 1fed1d52..14eb21b6 100644 --- a/mod.ccontrol/LASTCOMCommand.cc +++ b/mod.ccontrol/LASTCOMCommand.cc @@ -21,111 +21,85 @@ * $Id: LASTCOMCommand.cc,v 1.18 2009/03/17 09:50:58 denspike Exp $ */ -#include -#include -#include -#include +#include +#include +#include +#include -#include +#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "iClient.h" -#include "StringTokenizer.h" -#include "ELog.h" -#include "gnuworld_config.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "iClient.h" +#include "StringTokenizer.h" +#include "ELog.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::endl ; -using std::stringstream ; -using std::ends ; -using std::string ; +using std::endl; +using std::ends; +using std::string; +using std::stringstream; -namespace uworld -{ +namespace uworld { -bool LASTCOMCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -bot->MsgChanLog("LASTCOM\n"); +bool LASTCOMCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + bot->MsgChanLog("LASTCOM\n"); #ifndef LOGTOHD -unsigned int NumOfCom; -unsigned int Days = 0; -stringstream theQuery; + unsigned int NumOfCom; + unsigned int Days = 0; + stringstream theQuery; -if( st.size() == 1 ) - { - NumOfCom = 20; - static const char* queryHeader = "SELECT * FROM comlog "; - theQuery << queryHeader - << " ORDER BY ts DESC" - << " LIMIT " << NumOfCom - << ends; - } -else - { - NumOfCom = atoi(st[1].c_str()); - if(st.size() > 2) - { - Days = atoi(st[2].c_str()); - if(Days > 365) - { - bot->Notice(theClient,"You can't see the log for more than a year ago"); - return false; - } - static const char* queryHeader - = "SELECT * FROM comlog where ts >"; - theQuery << queryHeader - << (::time(0) - Days * 24 * 3600) - << " ORDER BY ts ASC" - << " LIMIT " << NumOfCom - << ends; - } - else - { - static const char* queryHeader - = "SELECT * FROM comlog "; - theQuery << queryHeader - << " ORDER BY ts DESC" - << " LIMIT " << NumOfCom - << ends; - - - } - } - -elog << "LASTCOM> " - << theQuery.str().c_str() - << endl; - + if (st.size() == 1) { + NumOfCom = 20; + static const char* queryHeader = "SELECT * FROM comlog "; + theQuery << queryHeader << " ORDER BY ts DESC" + << " LIMIT " << NumOfCom << ends; + } else { + NumOfCom = atoi(st[1].c_str()); + if (st.size() > 2) { + Days = atoi(st[2].c_str()); + if (Days > 365) { + bot->Notice(theClient, "You can't see the log for more than a year ago"); + return false; + } + static const char* queryHeader = "SELECT * FROM comlog where ts >"; + theQuery << queryHeader << (::time(0) - Days * 24 * 3600) << " ORDER BY ts ASC" + << " LIMIT " << NumOfCom << ends; + } else { + static const char* queryHeader = "SELECT * FROM comlog "; + theQuery << queryHeader << " ORDER BY ts DESC" + << " LIMIT " << NumOfCom << ends; + } + } -if (!bot->SQLDb->Exec(theQuery, true)) -//if( PGRES_TUPLES_OK != status ) - { - elog << "LASTCOM> SQL Error: " - << bot->SQLDb->ErrorMessage() - << endl ; - return false ; - } + elog << "LASTCOM> " << theQuery.str().c_str() << endl; -// SQL Query succeeded -bot->Notice(theClient,"Listing last %d messages from day %d",NumOfCom,Days); -for (int i = (bot->SQLDb->Tuples() - 1) ; i >= 0; i--) - { - bot->Notice(theClient,"[ %s - %s ] %s",bot->convertToAscTime(atoi(bot->SQLDb->GetValue(i, 0))),bot->SQLDb->GetValue(i,1).c_str(),bot->SQLDb->GetValue(i,2).c_str()); - } + if (!bot->SQLDb->Exec(theQuery, true)) + // if( PGRES_TUPLES_OK != status ) + { + elog << "LASTCOM> SQL Error: " << bot->SQLDb->ErrorMessage() << endl; + return false; + } + + // SQL Query succeeded + bot->Notice(theClient, "Listing last %d messages from day %d", NumOfCom, Days); + for (int i = (bot->SQLDb->Tuples() - 1); i >= 0; i--) { + bot->Notice(theClient, "[ %s - %s ] %s", + bot->convertToAscTime(atoi(bot->SQLDb->GetValue(i, 0))), + bot->SQLDb->GetValue(i, 1).c_str(), bot->SQLDb->GetValue(i, 2).c_str()); + } #else - if(st.size() > 1) - bot->showLogs(theClient,atoi(st[1].c_str())); - else - bot->showLogs(theClient); + if (st.size() > 1) + bot->showLogs(theClient, atoi(st[1].c_str())); + else + bot->showLogs(theClient); #endif -bot->Notice(theClient,"End of debug log"); -return true; -} - -} + bot->Notice(theClient, "End of debug log"); + return true; } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/LEARNNETCommand.cc b/mod.ccontrol/LEARNNETCommand.cc index 733034b3..3d9c30f7 100644 --- a/mod.ccontrol/LEARNNETCommand.cc +++ b/mod.ccontrol/LEARNNETCommand.cc @@ -20,102 +20,91 @@ * $Id: LEARNNETCommand.cc,v 1.16 2006/09/26 17:35:58 kewlio Exp $ */ -#include -#include - -#include -#include - -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "iServer.h" -#include "Network.h" -#include "server.h" -#include "ccUser.h" -#include "misc.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ -using std::string ; - -namespace uworld -{ - -bool LEARNNETCommand::Exec( iClient* theClient, const string& Message ) -{ - -bot->MsgChanLog("LEARNNET \n"); - -unsigned int AddedServers = 0; -StringTokenizer st(Message); - -bot->MsgChanLog("Learning network status at the request of: %s\n", - theClient->getNickName().c_str()); - -xNetwork::serverIterator ptr = Network->servers_begin(); -xNetwork::serverIterator end = Network->servers_end(); - -for( ; ptr != end ; ptr++ ) - { - iServer* CurServer = ptr->second ; - if( NULL == CurServer) - { - continue ; - } - - // NOTE: Changed from isJuped() - if((0 == Network->findFakeServer(CurServer)) && - (strcmp(CurServer->getName().c_str(), - bot->getUplinkName().c_str()))) - { - if(!bot->getServer(CurServer->getName())) - { - //If the server isnt in the database , update it - ccServer* NewServer = new (std::nothrow) - ccServer(bot->SQLDb); - assert( NewServer != 0 ) ; - - // TODO: Shouldn't all of this be in the - // ccServer constructor? - NewServer->setName(CurServer->getName()); - NewServer->setUplink(Network->findServer(CurServer->getUplinkIntYY())->getName()); - NewServer->setLastNumeric(CurServer->getCharYY()); - NewServer->setLastConnected(CurServer->getConnectTime()); - NewServer->setLastSplitted(0); - NewServer->setAddedOn(::time(0)); - NewServer->setLastUpdated(::time(0)); - NewServer->setNetServer(CurServer); - - bot->addServer(NewServer); - bot->Write("%s V :%s\n", - bot->getCharYYXXX().c_str(), - CurServer->getCharYY().c_str()); - - if(NewServer->Insert()) - { - AddedServers++; - } - else - { - bot->MsgChanLog("Error while learning " - "server: %s\n", - NewServer->getName().c_str()); - } - } - } - } - -bot->MsgChanLog( "Finished learning the network. Learned a total of %d " - "servers\n", AddedServers ) ; -bot->Notice( theClient, "Finished learning the network. Learned a " - "total of %d servers\n", AddedServers ) ; - -return true; +#include +#include + +#include +#include + +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "iServer.h" +#include "Network.h" +#include "server.h" +#include "ccUser.h" +#include "misc.h" +#include "gnuworld_config.h" + +namespace gnuworld { +using std::string; + +namespace uworld { + +bool LEARNNETCommand::Exec(iClient* theClient, const string& Message) { + + bot->MsgChanLog("LEARNNET \n"); + + unsigned int AddedServers = 0; + StringTokenizer st(Message); + + bot->MsgChanLog("Learning network status at the request of: %s\n", + theClient->getNickName().c_str()); + + xNetwork::serverIterator ptr = Network->servers_begin(); + xNetwork::serverIterator end = Network->servers_end(); + + for (; ptr != end; ptr++) { + iServer* CurServer = ptr->second; + if (NULL == CurServer) { + continue; + } + + // NOTE: Changed from isJuped() + if ((0 == Network->findFakeServer(CurServer)) && + (strcmp(CurServer->getName().c_str(), bot->getUplinkName().c_str()))) { + if (!bot->getServer(CurServer->getName())) { + // If the server isnt in the database , update it + ccServer* NewServer = new (std::nothrow) ccServer(bot->SQLDb); + assert(NewServer != 0); + + // TODO: Shouldn't all of this be in the + // ccServer constructor? + NewServer->setName(CurServer->getName()); + NewServer->setUplink(Network->findServer(CurServer->getUplinkIntYY())->getName()); + NewServer->setLastNumeric(CurServer->getCharYY()); + NewServer->setLastConnected(CurServer->getConnectTime()); + NewServer->setLastSplitted(0); + NewServer->setAddedOn(::time(0)); + NewServer->setLastUpdated(::time(0)); + NewServer->setNetServer(CurServer); + + bot->addServer(NewServer); + bot->Write("%s V :%s\n", bot->getCharYYXXX().c_str(), + CurServer->getCharYY().c_str()); + + if (NewServer->Insert()) { + AddedServers++; + } else { + bot->MsgChanLog("Error while learning " + "server: %s\n", + NewServer->getName().c_str()); + } + } + } + } + + bot->MsgChanLog("Finished learning the network. Learned a total of %d " + "servers\n", + AddedServers); + bot->Notice(theClient, + "Finished learning the network. Learned a " + "total of %d servers\n", + AddedServers); + + return true; } } // namespace uworld } // namespace gnuworld - diff --git a/mod.ccontrol/LIMITSCommand.cc b/mod.ccontrol/LIMITSCommand.cc index f7f5a0c6..d0b81318 100644 --- a/mod.ccontrol/LIMITSCommand.cc +++ b/mod.ccontrol/LIMITSCommand.cc @@ -20,606 +20,486 @@ * $Id: LIMITSCommand.cc,v 1.3 2008/12/28 12:21:15 hidden1 Exp $ */ -#include -#include - -#include - -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" -#include "gnuworld_config.h" -#include "ccException.h" -#include "Network.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool LIMITSCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -ccIpLisp* IpLisp; -//ccIpLnb* IpLnb; - -if(st.size() < 2) - { - Usage(theClient); - return true; - } - -bot->MsgChanLog("LIMITS %s\n",st.assemble(1).c_str()); -if(!strcasecmp(st[1].c_str(),"list")) - { - bot->listIpLExceptions(theClient); - return true; - } -if(!strcasecmp(st[1].c_str(),"list-old")) - { - bool listEmail = false; - if ((st.size() > 2) && (!strcasecmp(st[2].c_str(), "-e"))) { - listEmail = true; - } - bot->listIpLExceptionsOld(theClient, "", listEmail); - return true; - } -if(!strcasecmp(st[1].c_str(),"info")) - { - if (st.size() < 3) { - bot->Notice(theClient,"SYNTAX: info "); - return true; - } - bot->listIpLExceptionsOld(theClient, st[2], true); - return true; - } -else if(!strcasecmp(st[1].c_str(),"addisp")) - { - if(st.size() < 5) - { - bot->Notice(theClient,"SYNTAX: ADDISP [abuse email]"); - //bot->Notice(theClient, "-f: forcecount - use it if you want limits to still be enforced even if the netblocks" - // " of this isp are not the closest match for a client"); - //bot->Notice(theClient, "-i: inactive - deactivates glines and does not prevent new clients from connecting using iauth. It does reports only."); - return true; - } - if(st[2].size() > 32) - { - bot->Notice(theClient,"Isp name cannot exceeed 32 characters"); - return true; - } - if (atoi(st[3].c_str()) == 0) - { - bot->Notice(theClient,"SYNTAX: ADDISP [abuse email]"); - return true; - } - - IpLisp = bot->getIpLisp(st[2]); - - if (IpLisp != 0) - { - bot->Notice(theClient,"An isp already exists with that name."); - return true; - } - - else - { - string email = (st.size() > 5 ? st[5] : "none@available"); - if(bot->insertIpLisp(theClient,st[2],atoi(st[3].c_str()),atoi(st[4].c_str()),email, 1, 0)) - { - bot->Notice(theClient,"Successfully added isp '%s' for %d connections per /%d" - ,st[2].c_str(),atoi(st[3].c_str()),atoi(st[4].c_str())); - } - } - } -else if(!strcasecmp(st[1].c_str(),"addnetblock")) - { - if(st.size() != 4) - { - bot->Notice(theClient,"SYNTAX: ADDNETBLOCK "); - return true; - } - IpLisp = bot->getIpLisp(st[2]); - - if (IpLisp == 0) - { - bot->Notice(theClient,"Isp not found. Use ADDISP first"); - return true; - } - else - { - if(bot->insertIpLnb(theClient,st[3],IpLisp->getID(), false)) - { - bot->Notice(theClient,"Successfully added '%s' to '%s'" - ,st[3].c_str(),st[2].c_str()); - } - } - } -else if(!strcasecmp(st[1].c_str(),"active")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"SYNTAX: ACTIVE "); - return true; - } - if(st[2].size() > 32) - { - bot->Notice(theClient,"Isp can't exceed 32 characters"); - return true; - } - IpLisp = bot->getIpLisp(st[2]); - - if (IpLisp == 0) - { - bot->Notice(theClient,"Isp not found."); - return true; - } - int res; - if (!strcasecmp(st[3].c_str(), "yes")) - res = 1; - else if (!strcasecmp(st[3].c_str(), "no")) - res = 0; - else - { - bot->Notice(theClient,"must be yes or no"); - return true; - } - IpLisp->setActive(res); - IpLisp->setModOn(::time(0)); - IpLisp->setModBy(theClient->getRealNickUserHost()); - bot->reloadIpLisp(theClient, IpLisp); - if (!IpLisp->updateData()) - { - bot->Notice(theClient, "SQL insertion failed."); - } - else - bot->Notice(theClient,"Limits are %s enforced on %s", res ? "now" : "no longer", IpLisp->getName().c_str()); - } - -else if(!strcasecmp(st[1].c_str(),"nogline")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"SYNTAX: NOGLINE "); - return true; - } - if(st[2].size() > 32) - { - bot->Notice(theClient,"Isp can't exceed 32 characters"); - return true; - } - IpLisp = bot->getIpLisp(st[2]); - - if (IpLisp == 0) - { - bot->Notice(theClient,"Isp not found."); - return true; - } - int res; - if (!strcasecmp(st[3].c_str(), "yes")) - res = 1; - else if (!strcasecmp(st[3].c_str(), "no")) - res = 0; - else - { - bot->Notice(theClient,"must be yes or no"); - return true; - } - IpLisp->setNoGline(res); - IpLisp->setModOn(::time(0)); - IpLisp->setModBy(theClient->getRealNickUserHost()); - bot->reloadIpLisp(theClient, IpLisp); - if (!IpLisp->updateData()) - { - bot->Notice(theClient, "SQL insertion failed."); - } - else - bot->Notice(theClient,"G-lines on %s %sactivated.%s", IpLisp->getName().c_str(), res ? "de" : "", res ? " Limits will keep being enforced via iauth." : ""); - } -else if(!strcasecmp(st[1].c_str(),"chemail")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"SYNTAX: CHEMAIL "); - return true; - } - if(st[2].size() > 32) - { - bot->Notice(theClient,"Isp can't exceed 32 characters"); - return true; - } - IpLisp = bot->getIpLisp(st[2]); - - if (IpLisp == 0) - { - bot->Notice(theClient,"Isp not found."); - return true; - } - IpLisp->setEmail(st[3]); - IpLisp->setModOn(::time(0)); - IpLisp->setModBy(theClient->getRealNickUserHost()); - bot->reloadIpLisp(theClient, IpLisp); - if (!IpLisp->updateData()) - { - bot->Notice(theClient, "SQL insertion failed."); - } - else - bot->Notice(theClient,"Email for %s set to: %s", IpLisp->getName().c_str(), st[3].c_str()); - } -else if(!strcasecmp(st[1].c_str(),"group")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"SYNTAX: GROUP "); - return true; - } - if(st[2].size() > 32) - { - bot->Notice(theClient,"Isp can't exceed 32 characters"); - return true; - } - IpLisp = bot->getIpLisp(st[2]); - - if (IpLisp == 0) - { - bot->Notice(theClient,"Isp not found."); - return true; - } - int res; - if (!strcasecmp(st[3].c_str(), "yes")) - res = 1; - else if (!strcasecmp(st[3].c_str(), "no")) - res = 0; - else - { - bot->Notice(theClient,"must be yes or no"); - return true; - } - IpLisp->setGroup(res); - IpLisp->setModOn(::time(0)); - IpLisp->setModBy(theClient->getRealNickUserHost()); - bot->reloadIpLisp(theClient, IpLisp); - if (!IpLisp->updateData()) - { - bot->Notice(theClient, "SQL insertion failed."); - } - else - bot->Notice(theClient,"group for %s is now %sabled", IpLisp->getName().c_str(), res ? "en" : "dis"); - } -else if(!strcasecmp(st[1].c_str(),"glunidented")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"SYNTAX: GLUNIDENTED "); - return true; - } - if(st[2].size() > 32) - { - bot->Notice(theClient,"Isp can't exceed 32 characters"); - return true; - } - IpLisp = bot->getIpLisp(st[2]); - - if (IpLisp == 0) - { - bot->Notice(theClient,"Isp not found."); - return true; - } - int res; - if (!strcasecmp(st[3].c_str(), "yes")) - res = 1; - else if (!strcasecmp(st[3].c_str(), "no")) - res = 0; - else - { - bot->Notice(theClient,"must be yes or no"); - return true; - } - IpLisp->setGlunidented(res); - IpLisp->setModOn(::time(0)); - IpLisp->setModBy(theClient->getRealNickUserHost()); - bot->reloadIpLisp(theClient, IpLisp); - if (!IpLisp->updateData()) - { - bot->Notice(theClient, "SQL insertion failed."); - } - else - bot->Notice(theClient,"glunidented for %s is now %sabled", IpLisp->getName().c_str(), res ? "en" : "dis"); - } -else if(!strcasecmp(st[1].c_str(),"forcecount")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"SYNTAX: FORCECOUNT "); - return true; - } - if(st[2].size() > 32) - { - bot->Notice(theClient,"Isp can't exceed 32 characters"); - return true; - } - IpLisp = bot->getIpLisp(st[2]); - - if (IpLisp == 0) - { - bot->Notice(theClient,"Isp not found."); - return true; - } - int res; - if (!strcasecmp(st[3].c_str(), "yes")) - res = 1; - else if (!strcasecmp(st[3].c_str(), "no")) - res = 0; - else - { - bot->Notice(theClient,"must be yes or no"); - return true; - } - IpLisp->setForcecount(res); - IpLisp->setModOn(::time(0)); - IpLisp->setModBy(theClient->getRealNickUserHost()); - bot->reloadIpLisp(theClient, IpLisp); - if (!IpLisp->updateData()) - { - bot->Notice(theClient, "SQL insertion failed."); - } - else - bot->Notice(theClient,"forcecount for %s is now %sabled", IpLisp->getName().c_str(), res ? "en" : "dis"); - } -else if(!strcasecmp(st[1].c_str(),"chccidr")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"SYNTAX: CHCCIDR "); - return true; - } - if(st[2].size() > 32) - { - bot->Notice(theClient,"Isp can't exceed 32 characters"); - return true; - } - IpLisp = bot->getIpLisp(st[2]); - - if (IpLisp == 0) - { - bot->Notice(theClient,"Isp not found."); - return true; - } - else - { - if (!bot->ipLcidrChangeCheck(theClient, IpLisp, atoi(st[3]))) - return true; - IpLisp->setCloneCidr(atoi(st[3].c_str())); - IpLisp->setModOn(::time(0)); - IpLisp->setModBy(theClient->getRealNickUserHost()); - bot->reloadIpLisp(theClient, IpLisp); - if (!IpLisp->updateData()) - { - bot->Notice(theClient, "SQL insertion failed."); - } - else - bot->Notice(theClient,"%s is now checking clones on /%ds. Limit: %d", IpLisp->getName().c_str(), atoi(st[3].c_str()), IpLisp->getLimit()); - } - } -else if(!strcasecmp(st[1].c_str(),"chilimit")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"SYNTAX: CHILIMIT "); - return true; - } - if(atoi(st[3].c_str()) < 1) - { - bot->Notice(theClient,"The limit must be > 0"); - return true; - } - if(st[2].size() > 32) - { - bot->Notice(theClient,"Isp can't exceed 32 characters"); - return true; - } - IpLisp = bot->getIpLisp(st[2]); - - if (IpLisp == 0) - { - bot->Notice(theClient,"Isp not found."); - return true; - } - else - { - IpLisp->setIdentLimit(atoi(st[3].c_str())); - IpLisp->setModOn(::time(0)); - IpLisp->setModBy(theClient->getRealNickUserHost()); - if (!IpLisp->updateData()) - { - bot->Notice(theClient, "SQL insertion failed."); - } - else - bot->Notice(theClient,"New Ident limit for %s is now %d", IpLisp->getName().c_str(), IpLisp->getIdentLimit()); - } - } -else if(!strcasecmp(st[1].c_str(),"chlimit")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"SYNTAX: CHLIMIT "); - return true; - } - if(atoi(st[3].c_str()) < 1) - { - bot->Notice(theClient,"The limit must be > 0"); - return true; - } - if(st[2].size() > 32) - { - bot->Notice(theClient,"Isp can't exceed 32 characters"); - return true; - } - IpLisp = bot->getIpLisp(st[2]); - - if (IpLisp == 0) - { - bot->Notice(theClient,"Isp not found."); - return true; - } - else - { - IpLisp->setLimit(atoi(st[3].c_str())); - IpLisp->setModOn(::time(0)); - IpLisp->setModBy(theClient->getRealNickUserHost()); - if (!IpLisp->updateData()) - { - bot->Notice(theClient, "SQL insertion failed."); - } - else - bot->Notice(theClient,"New limit for %s is now %d", IpLisp->getName().c_str(), IpLisp->getLimit()); - } - } -else if(!strcasecmp(st[1].c_str(),"chname")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"SYNTAX: CHNAME "); - return true; - } - if(st[2].size() > 32) - { - bot->Notice(theClient,"Isp can't be more than 32 characters"); - return true; - } - IpLisp = bot->getIpLisp(st[3]); - - if (IpLisp != 0) - { - bot->Notice(theClient,"Isp %s already exists.", IpLisp->getName().c_str()); - return true; - } - IpLisp = bot->getIpLisp(st[2]); - - if (IpLisp == 0) - { - bot->Notice(theClient,"Isp not found."); - return true; - } - else - { - IpLisp->setName(st[3]); - IpLisp->setModOn(::time(0)); - IpLisp->setModBy(theClient->getRealNickUserHost()); - if (!IpLisp->updateData()) - { - bot->Notice(theClient, "SQL insertion failed."); - } - else - bot->Notice(theClient,"Renamed %s to %s", st[2].c_str(), IpLisp->getName().c_str()); - } - } -else if(!strcasecmp(st[1].c_str(),"delisp")) - { - if(st.size() < 3) - { - bot->Notice(theClient,"You must specify the isp you want to delete"); - return true; - } - if(st[2].size() > 32) - { - bot->Notice(theClient,"Isp can't exceed 32 characters"); - return true; - } - else - { - if(bot->delIpLisp(theClient,st[2])) - { - bot->Notice(theClient,"Successfully deleted isp '%s'",st[2].c_str()); - } - - } - } -else if(!strcasecmp(st[1].c_str(),"clearall")) - { - if (st.size() < 3) { - bot->Notice(theClient, "Are you sure? Use CLEARALL -f"); - return true; - } - if (strcasecmp(st[2].c_str(),"-f")) { - bot->Notice(theClient, "Are you sure? Use CLEARALL -f"); - return true; - } - - if(bot->clearIsps(theClient)) - { - bot->Notice(theClient,"Successfully deleted all isps"); - } - } - -else if(!strcasecmp(st[1].c_str(),"test")) - { - if (st.size() > 2) - { - //bot->test(theClient, st[2]); - } - return true; - - } - -//ipLuserInfo( - -else if(!strcasecmp(st[1].c_str(),"userinfo")) - { - if(st.size() < 3) - { - bot->Notice(theClient,"Syntax: USERINFO "); - return true; - } - iClient* Target = Network->findNick(st[2]) ; - if( NULL == Target ) - { - bot->Notice( theClient, "Unable to find nick: %s", st[ 2 ].c_str() ) ; - return true ; - } - return bot->ipLuserInfo(theClient, Target); - } - -else if(!strcasecmp(st[1].c_str(),"ipinfo")) - { - if(st.size() < 3) - { - bot->Notice(theClient,"Syntax: IPINFO <[user@]ip>"); - return true; - } - return bot->ipLipInfo(theClient, st[2]); - } - -else if(!strcasecmp(st[1].c_str(),"delnetblock")) - { - if(st.size() < 4) - { - bot->Notice(theClient,"Syntax: DELNETBLOCK "); - return true; - } - else - { - if(bot->delIpLnb(theClient,st[2],st[3], false)) - { - bot->Notice(theClient,"Successfully deleted netblock '%s'",st[3].c_str()); - } - } - - } -else { - /* unknown command */ - Usage(theClient); - return true; -} -return true; -} +#include +#include +#include -} -} // namespace gnuworld +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" +#include "gnuworld_config.h" +#include "ccException.h" +#include "Network.h" + +namespace gnuworld { + +using std::string; + +namespace uworld { + +bool LIMITSCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + ccIpLisp* IpLisp; + // ccIpLnb* IpLnb; + + if (st.size() < 2) { + Usage(theClient); + return true; + } + + bot->MsgChanLog("LIMITS %s\n", st.assemble(1).c_str()); + if (!strcasecmp(st[1].c_str(), "list")) { + bot->listIpLExceptions(theClient); + return true; + } + if (!strcasecmp(st[1].c_str(), "list-old")) { + bool listEmail = false; + if ((st.size() > 2) && (!strcasecmp(st[2].c_str(), "-e"))) { + listEmail = true; + } + bot->listIpLExceptionsOld(theClient, "", listEmail); + return true; + } + if (!strcasecmp(st[1].c_str(), "info")) { + if (st.size() < 3) { + bot->Notice(theClient, "SYNTAX: info "); + return true; + } + bot->listIpLExceptionsOld(theClient, st[2], true); + return true; + } else if (!strcasecmp(st[1].c_str(), "addisp")) { + if (st.size() < 5) { + bot->Notice(theClient, + "SYNTAX: ADDISP [abuse email]"); + // bot->Notice(theClient, "-f: forcecount - use it if you want limits to still be + // enforced even if the netblocks" " of this isp are not the closest match for a + //client"); bot->Notice(theClient, "-i: inactive - deactivates glines and does not + // prevent new clients from connecting using iauth. It does reports only."); + return true; + } + if (st[2].size() > 32) { + bot->Notice(theClient, "Isp name cannot exceeed 32 characters"); + return true; + } + if (atoi(st[3].c_str()) == 0) { + bot->Notice(theClient, + "SYNTAX: ADDISP [abuse email]"); + return true; + } + + IpLisp = bot->getIpLisp(st[2]); + + if (IpLisp != 0) { + bot->Notice(theClient, "An isp already exists with that name."); + return true; + } + + else { + string email = (st.size() > 5 ? st[5] : "none@available"); + if (bot->insertIpLisp(theClient, st[2], atoi(st[3].c_str()), atoi(st[4].c_str()), email, + 1, 0)) { + bot->Notice(theClient, "Successfully added isp '%s' for %d connections per /%d", + st[2].c_str(), atoi(st[3].c_str()), atoi(st[4].c_str())); + } + } + } else if (!strcasecmp(st[1].c_str(), "addnetblock")) { + if (st.size() != 4) { + bot->Notice(theClient, "SYNTAX: ADDNETBLOCK "); + return true; + } + IpLisp = bot->getIpLisp(st[2]); + + if (IpLisp == 0) { + bot->Notice(theClient, "Isp not found. Use ADDISP first"); + return true; + } else { + if (bot->insertIpLnb(theClient, st[3], IpLisp->getID(), false)) { + bot->Notice(theClient, "Successfully added '%s' to '%s'", st[3].c_str(), + st[2].c_str()); + } + } + } else if (!strcasecmp(st[1].c_str(), "active")) { + if (st.size() < 4) { + bot->Notice(theClient, "SYNTAX: ACTIVE "); + return true; + } + if (st[2].size() > 32) { + bot->Notice(theClient, "Isp can't exceed 32 characters"); + return true; + } + IpLisp = bot->getIpLisp(st[2]); + + if (IpLisp == 0) { + bot->Notice(theClient, "Isp not found."); + return true; + } + int res; + if (!strcasecmp(st[3].c_str(), "yes")) + res = 1; + else if (!strcasecmp(st[3].c_str(), "no")) + res = 0; + else { + bot->Notice(theClient, "must be yes or no"); + return true; + } + IpLisp->setActive(res); + IpLisp->setModOn(::time(0)); + IpLisp->setModBy(theClient->getRealNickUserHost()); + bot->reloadIpLisp(theClient, IpLisp); + if (!IpLisp->updateData()) { + bot->Notice(theClient, "SQL insertion failed."); + } else + bot->Notice(theClient, "Limits are %s enforced on %s", res ? "now" : "no longer", + IpLisp->getName().c_str()); + } + + else if (!strcasecmp(st[1].c_str(), "nogline")) { + if (st.size() < 4) { + bot->Notice(theClient, "SYNTAX: NOGLINE "); + return true; + } + if (st[2].size() > 32) { + bot->Notice(theClient, "Isp can't exceed 32 characters"); + return true; + } + IpLisp = bot->getIpLisp(st[2]); + + if (IpLisp == 0) { + bot->Notice(theClient, "Isp not found."); + return true; + } + int res; + if (!strcasecmp(st[3].c_str(), "yes")) + res = 1; + else if (!strcasecmp(st[3].c_str(), "no")) + res = 0; + else { + bot->Notice(theClient, "must be yes or no"); + return true; + } + IpLisp->setNoGline(res); + IpLisp->setModOn(::time(0)); + IpLisp->setModBy(theClient->getRealNickUserHost()); + bot->reloadIpLisp(theClient, IpLisp); + if (!IpLisp->updateData()) { + bot->Notice(theClient, "SQL insertion failed."); + } else + bot->Notice(theClient, "G-lines on %s %sactivated.%s", IpLisp->getName().c_str(), + res ? "de" : "", res ? " Limits will keep being enforced via iauth." : ""); + } else if (!strcasecmp(st[1].c_str(), "chemail")) { + if (st.size() < 4) { + bot->Notice(theClient, "SYNTAX: CHEMAIL "); + return true; + } + if (st[2].size() > 32) { + bot->Notice(theClient, "Isp can't exceed 32 characters"); + return true; + } + IpLisp = bot->getIpLisp(st[2]); + + if (IpLisp == 0) { + bot->Notice(theClient, "Isp not found."); + return true; + } + IpLisp->setEmail(st[3]); + IpLisp->setModOn(::time(0)); + IpLisp->setModBy(theClient->getRealNickUserHost()); + bot->reloadIpLisp(theClient, IpLisp); + if (!IpLisp->updateData()) { + bot->Notice(theClient, "SQL insertion failed."); + } else + bot->Notice(theClient, "Email for %s set to: %s", IpLisp->getName().c_str(), + st[3].c_str()); + } else if (!strcasecmp(st[1].c_str(), "group")) { + if (st.size() < 4) { + bot->Notice(theClient, "SYNTAX: GROUP "); + return true; + } + if (st[2].size() > 32) { + bot->Notice(theClient, "Isp can't exceed 32 characters"); + return true; + } + IpLisp = bot->getIpLisp(st[2]); + if (IpLisp == 0) { + bot->Notice(theClient, "Isp not found."); + return true; + } + int res; + if (!strcasecmp(st[3].c_str(), "yes")) + res = 1; + else if (!strcasecmp(st[3].c_str(), "no")) + res = 0; + else { + bot->Notice(theClient, "must be yes or no"); + return true; + } + IpLisp->setGroup(res); + IpLisp->setModOn(::time(0)); + IpLisp->setModBy(theClient->getRealNickUserHost()); + bot->reloadIpLisp(theClient, IpLisp); + if (!IpLisp->updateData()) { + bot->Notice(theClient, "SQL insertion failed."); + } else + bot->Notice(theClient, "group for %s is now %sabled", IpLisp->getName().c_str(), + res ? "en" : "dis"); + } else if (!strcasecmp(st[1].c_str(), "glunidented")) { + if (st.size() < 4) { + bot->Notice(theClient, "SYNTAX: GLUNIDENTED "); + return true; + } + if (st[2].size() > 32) { + bot->Notice(theClient, "Isp can't exceed 32 characters"); + return true; + } + IpLisp = bot->getIpLisp(st[2]); + if (IpLisp == 0) { + bot->Notice(theClient, "Isp not found."); + return true; + } + int res; + if (!strcasecmp(st[3].c_str(), "yes")) + res = 1; + else if (!strcasecmp(st[3].c_str(), "no")) + res = 0; + else { + bot->Notice(theClient, "must be yes or no"); + return true; + } + IpLisp->setGlunidented(res); + IpLisp->setModOn(::time(0)); + IpLisp->setModBy(theClient->getRealNickUserHost()); + bot->reloadIpLisp(theClient, IpLisp); + if (!IpLisp->updateData()) { + bot->Notice(theClient, "SQL insertion failed."); + } else + bot->Notice(theClient, "glunidented for %s is now %sabled", IpLisp->getName().c_str(), + res ? "en" : "dis"); + } else if (!strcasecmp(st[1].c_str(), "forcecount")) { + if (st.size() < 4) { + bot->Notice(theClient, "SYNTAX: FORCECOUNT "); + return true; + } + if (st[2].size() > 32) { + bot->Notice(theClient, "Isp can't exceed 32 characters"); + return true; + } + IpLisp = bot->getIpLisp(st[2]); + + if (IpLisp == 0) { + bot->Notice(theClient, "Isp not found."); + return true; + } + int res; + if (!strcasecmp(st[3].c_str(), "yes")) + res = 1; + else if (!strcasecmp(st[3].c_str(), "no")) + res = 0; + else { + bot->Notice(theClient, "must be yes or no"); + return true; + } + IpLisp->setForcecount(res); + IpLisp->setModOn(::time(0)); + IpLisp->setModBy(theClient->getRealNickUserHost()); + bot->reloadIpLisp(theClient, IpLisp); + if (!IpLisp->updateData()) { + bot->Notice(theClient, "SQL insertion failed."); + } else + bot->Notice(theClient, "forcecount for %s is now %sabled", IpLisp->getName().c_str(), + res ? "en" : "dis"); + } else if (!strcasecmp(st[1].c_str(), "chccidr")) { + if (st.size() < 4) { + bot->Notice(theClient, "SYNTAX: CHCCIDR "); + return true; + } + if (st[2].size() > 32) { + bot->Notice(theClient, "Isp can't exceed 32 characters"); + return true; + } + IpLisp = bot->getIpLisp(st[2]); + + if (IpLisp == 0) { + bot->Notice(theClient, "Isp not found."); + return true; + } else { + if (!bot->ipLcidrChangeCheck(theClient, IpLisp, atoi(st[3]))) + return true; + IpLisp->setCloneCidr(atoi(st[3].c_str())); + IpLisp->setModOn(::time(0)); + IpLisp->setModBy(theClient->getRealNickUserHost()); + bot->reloadIpLisp(theClient, IpLisp); + if (!IpLisp->updateData()) { + bot->Notice(theClient, "SQL insertion failed."); + } else + bot->Notice(theClient, "%s is now checking clones on /%ds. Limit: %d", + IpLisp->getName().c_str(), atoi(st[3].c_str()), IpLisp->getLimit()); + } + } else if (!strcasecmp(st[1].c_str(), "chilimit")) { + if (st.size() < 4) { + bot->Notice(theClient, "SYNTAX: CHILIMIT "); + return true; + } + if (atoi(st[3].c_str()) < 1) { + bot->Notice(theClient, "The limit must be > 0"); + return true; + } + if (st[2].size() > 32) { + bot->Notice(theClient, "Isp can't exceed 32 characters"); + return true; + } + IpLisp = bot->getIpLisp(st[2]); + + if (IpLisp == 0) { + bot->Notice(theClient, "Isp not found."); + return true; + } else { + IpLisp->setIdentLimit(atoi(st[3].c_str())); + IpLisp->setModOn(::time(0)); + IpLisp->setModBy(theClient->getRealNickUserHost()); + if (!IpLisp->updateData()) { + bot->Notice(theClient, "SQL insertion failed."); + } else + bot->Notice(theClient, "New Ident limit for %s is now %d", + IpLisp->getName().c_str(), IpLisp->getIdentLimit()); + } + } else if (!strcasecmp(st[1].c_str(), "chlimit")) { + if (st.size() < 4) { + bot->Notice(theClient, "SYNTAX: CHLIMIT "); + return true; + } + if (atoi(st[3].c_str()) < 1) { + bot->Notice(theClient, "The limit must be > 0"); + return true; + } + if (st[2].size() > 32) { + bot->Notice(theClient, "Isp can't exceed 32 characters"); + return true; + } + IpLisp = bot->getIpLisp(st[2]); + + if (IpLisp == 0) { + bot->Notice(theClient, "Isp not found."); + return true; + } else { + IpLisp->setLimit(atoi(st[3].c_str())); + IpLisp->setModOn(::time(0)); + IpLisp->setModBy(theClient->getRealNickUserHost()); + if (!IpLisp->updateData()) { + bot->Notice(theClient, "SQL insertion failed."); + } else + bot->Notice(theClient, "New limit for %s is now %d", IpLisp->getName().c_str(), + IpLisp->getLimit()); + } + } else if (!strcasecmp(st[1].c_str(), "chname")) { + if (st.size() < 4) { + bot->Notice(theClient, "SYNTAX: CHNAME "); + return true; + } + if (st[2].size() > 32) { + bot->Notice(theClient, "Isp can't be more than 32 characters"); + return true; + } + IpLisp = bot->getIpLisp(st[3]); + + if (IpLisp != 0) { + bot->Notice(theClient, "Isp %s already exists.", IpLisp->getName().c_str()); + return true; + } + IpLisp = bot->getIpLisp(st[2]); + + if (IpLisp == 0) { + bot->Notice(theClient, "Isp not found."); + return true; + } else { + IpLisp->setName(st[3]); + IpLisp->setModOn(::time(0)); + IpLisp->setModBy(theClient->getRealNickUserHost()); + if (!IpLisp->updateData()) { + bot->Notice(theClient, "SQL insertion failed."); + } else + bot->Notice(theClient, "Renamed %s to %s", st[2].c_str(), + IpLisp->getName().c_str()); + } + } else if (!strcasecmp(st[1].c_str(), "delisp")) { + if (st.size() < 3) { + bot->Notice(theClient, "You must specify the isp you want to delete"); + return true; + } + if (st[2].size() > 32) { + bot->Notice(theClient, "Isp can't exceed 32 characters"); + return true; + } else { + if (bot->delIpLisp(theClient, st[2])) { + bot->Notice(theClient, "Successfully deleted isp '%s'", st[2].c_str()); + } + } + } else if (!strcasecmp(st[1].c_str(), "clearall")) { + if (st.size() < 3) { + bot->Notice(theClient, "Are you sure? Use CLEARALL -f"); + return true; + } + if (strcasecmp(st[2].c_str(), "-f")) { + bot->Notice(theClient, "Are you sure? Use CLEARALL -f"); + return true; + } + + if (bot->clearIsps(theClient)) { + bot->Notice(theClient, "Successfully deleted all isps"); + } + } + + else if (!strcasecmp(st[1].c_str(), "test")) { + if (st.size() > 2) { + // bot->test(theClient, st[2]); + } + return true; + + } + + // ipLuserInfo( + + else if (!strcasecmp(st[1].c_str(), "userinfo")) { + if (st.size() < 3) { + bot->Notice(theClient, "Syntax: USERINFO "); + return true; + } + iClient* Target = Network->findNick(st[2]); + if (NULL == Target) { + bot->Notice(theClient, "Unable to find nick: %s", st[2].c_str()); + return true; + } + return bot->ipLuserInfo(theClient, Target); + } + + else if (!strcasecmp(st[1].c_str(), "ipinfo")) { + if (st.size() < 3) { + bot->Notice(theClient, "Syntax: IPINFO <[user@]ip>"); + return true; + } + return bot->ipLipInfo(theClient, st[2]); + } + + else if (!strcasecmp(st[1].c_str(), "delnetblock")) { + if (st.size() < 4) { + bot->Notice(theClient, "Syntax: DELNETBLOCK "); + return true; + } else { + if (bot->delIpLnb(theClient, st[2], st[3], false)) { + bot->Notice(theClient, "Successfully deleted netblock '%s'", st[3].c_str()); + } + } + + } else { + /* unknown command */ + Usage(theClient); + return true; + } + return true; +} + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/LISTCommand.cc b/mod.ccontrol/LISTCommand.cc index 304a7d50..caf767d5 100644 --- a/mod.ccontrol/LISTCommand.cc +++ b/mod.ccontrol/LISTCommand.cc @@ -20,293 +20,268 @@ * $Id: LISTCommand.cc,v 1.24 2008/08/06 19:35:58 hidden1 Exp $ */ -#include -#include +#include +#include -#include +#include -#include "ccontrol.h" -#include "Network.h" -#include "Channel.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "gnuworld_config.h" +#include "ccontrol.h" +#include "Network.h" +#include "Channel.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { -bool LISTCommand::Exec( iClient* theClient, const string& Message) -{ -typedef list channelListT; -const Channel* curChannel; -channelListT channelList; -unsigned int count = 0; -const char *c; -char ch; -string Mask; -bool isValid = false; +bool LISTCommand::Exec(iClient* theClient, const string& Message) { + typedef list channelListT; + const Channel* curChannel; + channelListT channelList; + unsigned int count = 0; + const char* c; + char ch; + string Mask; + bool isValid = false; -StringTokenizer st( Message ) ; -if(st.size() < 2) - { - Usage(theClient); - return true; - } + StringTokenizer st(Message); + if (st.size() < 2) { + Usage(theClient); + return true; + } -bot->MsgChanLog("LIST %s\n",st.assemble(1).c_str()); -if(!strcasecmp(st[1].c_str(),"glines")) - { - bot->listGlines(theClient); - } -else if(!strcasecmp(st[1].c_str(),"suspended")) - { - bot->listSuspended(theClient); - } -else if(!strcasecmp(st[1].c_str(),"servers")) - { - bot->listServers(theClient); - } -else if(!strcasecmp(st[1].c_str(),"badchannels")) - { - bot->Notice(theClient,"Please use LIST nomodechannels to get a list of the channels which are marked as no mode"); - } -else if(!strcasecmp(st[1].c_str(),"nomodechannels")) - { - bot->listBadChannels(theClient); - } -else if(!strcasecmp(st[1].c_str(),"limits")) - { - bot->listIpLExceptions(theClient); - } -else if(!strcasecmp(st[1].c_str(),"channels")) - { - /* new "list channels" command */ - if (st.size() < 3) - { - /* not enough parameters */ + bot->MsgChanLog("LIST %s\n", st.assemble(1).c_str()); + if (!strcasecmp(st[1].c_str(), "glines")) { + bot->listGlines(theClient); + } else if (!strcasecmp(st[1].c_str(), "suspended")) { + bot->listSuspended(theClient); + } else if (!strcasecmp(st[1].c_str(), "servers")) { + bot->listServers(theClient); + } else if (!strcasecmp(st[1].c_str(), "badchannels")) { + bot->Notice(theClient, "Please use LIST nomodechannels to get a list of the channels which " + "are marked as no mode"); + } else if (!strcasecmp(st[1].c_str(), "nomodechannels")) { + bot->listBadChannels(theClient); + } else if (!strcasecmp(st[1].c_str(), "limits")) { + bot->listIpLExceptions(theClient); + } else if (!strcasecmp(st[1].c_str(), "channels")) { + /* new "list channels" command */ + if (st.size() < 3) { + /* not enough parameters */ #ifdef TOPIC_TRACK - bot->Notice(theClient, "'list channels' requires 'key', 'modes', 'topic' or 'topicby'"); + bot->Notice(theClient, "'list channels' requires 'key', 'modes', 'topic' or 'topicby'"); #else - bot->Notice(theClient, "'list channels' requires 'key' or 'modes'"); + bot->Notice(theClient, "'list channels' requires 'key' or 'modes'"); #endif - return false; - } - if (!strcasecmp(st[2].c_str(),"key")) - { - if (st.size() < 4) - { - bot->Notice(theClient, "for 'list channels key', you must supply the key to search for!"); - return false; - } - /* ok, we have the key to search for in st[3] */ - channelList = Network->getChannelsWithKey(st[3]); + return false; + } + if (!strcasecmp(st[2].c_str(), "key")) { + if (st.size() < 4) { + bot->Notice(theClient, + "for 'list channels key', you must supply the key to search for!"); + return false; + } + /* ok, we have the key to search for in st[3] */ + channelList = Network->getChannelsWithKey(st[3]); - if (channelList.empty()) - { - bot->Notice(theClient, "I'm sorry, no channels have a key matching '%s'", st[3].c_str()); - return false; - } + if (channelList.empty()) { + bot->Notice(theClient, "I'm sorry, no channels have a key matching '%s'", + st[3].c_str()); + return false; + } - bot->Notice(theClient, "--==[ Channels matching key '%s' %s]==--", st[3].c_str(), - (channelList.size() > 15)?"- showing first 15 only":""); + bot->Notice(theClient, "--==[ Channels matching key '%s' %s]==--", st[3].c_str(), + (channelList.size() > 15) ? "- showing first 15 only" : ""); - for (channelListT::iterator cptr = channelList.begin(); (cptr != channelList.end()) && (count < 15); cptr++) - { - curChannel = *cptr; - bot->Notice(theClient, "Channel: [%4d] %s", - curChannel->size(), - curChannel->getName().c_str()); - count++; - } - bot->Notice(theClient, "--==[ End of 'list channels key %s' - %d found ]==--", - st[3].c_str(), channelList.size()); - } - else if (!strcasecmp(st[2].c_str(),"modes")) - { - if (st.size() < 4) - { - bot->Notice(theClient, "for 'list channels modes', you must supply the modes to match against!"); - bot->Notice(theClient, "e.g. 'list channels modes +tns-m' to require +tns and require not to have +m"); - bot->Notice(theClient, "(other modes may be set unless explicitly not required as above)"); - return false; - } - if (st.size() > 4) - { - bot->Notice(theClient, "You supplied too many arguments. arguments such as +k or +l here may not contain the key or limit!"); - return false; - } - /* ok, we have the modes to search for in st[3] - validate them */ - if ((!match("+", st[3].substr(0,1))) && (!match("-", st[3].substr(0,1)))) - { - bot->Notice(theClient, "The modes must start with + or - (e.g. +tns or -s)"); - return false; - } - isValid = true; - c = st[3].c_str(); - while ((ch = *c++)) - { - switch (ch) { - case '+': - case '-': - case 'k': - case 'l': - case 'i': - case 'm': - case 'n': - case 'p': - case 's': - case 't': - case 'r': - case 'D': /* acceptable modes */ - break; - default: /* unacceptable modes */ - isValid = false; - break; - } - } - if (!isValid) - { - bot->Notice(theClient, "The modes given are invalid (you supplied '%s', valid modes are klimnpstrD)", - st[3].c_str()); - return false; - } - /* ok, validated them */ - channelList = Network->getChannelsWithModes(st[3]); + for (channelListT::iterator cptr = channelList.begin(); + (cptr != channelList.end()) && (count < 15); cptr++) { + curChannel = *cptr; + bot->Notice(theClient, "Channel: [%4d] %s", curChannel->size(), + curChannel->getName().c_str()); + count++; + } + bot->Notice(theClient, "--==[ End of 'list channels key %s' - %d found ]==--", + st[3].c_str(), channelList.size()); + } else if (!strcasecmp(st[2].c_str(), "modes")) { + if (st.size() < 4) { + bot->Notice( + theClient, + "for 'list channels modes', you must supply the modes to match against!"); + bot->Notice( + theClient, + "e.g. 'list channels modes +tns-m' to require +tns and require not to have +m"); + bot->Notice(theClient, + "(other modes may be set unless explicitly not required as above)"); + return false; + } + if (st.size() > 4) { + bot->Notice(theClient, "You supplied too many arguments. arguments such as +k or " + "+l here may not contain the key or limit!"); + return false; + } + /* ok, we have the modes to search for in st[3] - validate them */ + if ((!match("+", st[3].substr(0, 1))) && (!match("-", st[3].substr(0, 1)))) { + bot->Notice(theClient, "The modes must start with + or - (e.g. +tns or -s)"); + return false; + } + isValid = true; + c = st[3].c_str(); + while ((ch = *c++)) { + switch (ch) { + case '+': + case '-': + case 'k': + case 'l': + case 'i': + case 'm': + case 'n': + case 'p': + case 's': + case 't': + case 'r': + case 'D': /* acceptable modes */ + break; + default: /* unacceptable modes */ + isValid = false; + break; + } + } + if (!isValid) { + bot->Notice( + theClient, + "The modes given are invalid (you supplied '%s', valid modes are klimnpstrD)", + st[3].c_str()); + return false; + } + /* ok, validated them */ + channelList = Network->getChannelsWithModes(st[3]); - if (channelList.empty()) - { - bot->Notice(theClient, "I'm sorry, no channels have modes matching '%s'", st[3].c_str()); - return false; - } + if (channelList.empty()) { + bot->Notice(theClient, "I'm sorry, no channels have modes matching '%s'", + st[3].c_str()); + return false; + } - bot->Notice(theClient, "--==[ Channels matching modes '%s' %s]==--", st[3].c_str(), - (channelList.size() > 15)?"- showing first 15 only":""); + bot->Notice(theClient, "--==[ Channels matching modes '%s' %s]==--", st[3].c_str(), + (channelList.size() > 15) ? "- showing first 15 only" : ""); - for (channelListT::iterator cptr = channelList.begin(); (cptr != channelList.end()) && (count < 16); cptr++) - { - curChannel = *cptr; - bot->Notice(theClient, "Channel: [%4d] %s", - curChannel->size(), - curChannel->getName().c_str()); - count++; - } - bot->Notice(theClient, "--==[ End of 'list channels modes %s' - %d found ]==--", - st[3].c_str(), channelList.size()); - } + for (channelListT::iterator cptr = channelList.begin(); + (cptr != channelList.end()) && (count < 16); cptr++) { + curChannel = *cptr; + bot->Notice(theClient, "Channel: [%4d] %s", curChannel->size(), + curChannel->getName().c_str()); + count++; + } + bot->Notice(theClient, "--==[ End of 'list channels modes %s' - %d found ]==--", + st[3].c_str(), channelList.size()); + } #ifdef TOPIC_TRACK - else if (!strcasecmp(st[2].c_str(),"topic")) - { - if (st.size() < 4) - { - bot->Notice(theClient, "for 'list channels topic', you must supply the topic to search for!"); - return false; - } - /* ok, we have the topic to search for in st[3] */ - channelList = Network->getChannelsWithTopic(st[3]); + else if (!strcasecmp(st[2].c_str(), "topic")) { + if (st.size() < 4) { + bot->Notice(theClient, + "for 'list channels topic', you must supply the topic to search for!"); + return false; + } + /* ok, we have the topic to search for in st[3] */ + channelList = Network->getChannelsWithTopic(st[3]); - if (channelList.empty()) - { - bot->Notice(theClient, "I'm sorry, no channels have a topic matching '%s'", st[3].c_str()); - return false; - } + if (channelList.empty()) { + bot->Notice(theClient, "I'm sorry, no channels have a topic matching '%s'", + st[3].c_str()); + return false; + } - bot->Notice(theClient, "--==[ Channels matching topic '%s' %s]==--", st[3].c_str(), - (channelList.size() > 15)?"- showing first 15 only":""); + bot->Notice(theClient, "--==[ Channels matching topic '%s' %s]==--", st[3].c_str(), + (channelList.size() > 15) ? "- showing first 15 only" : ""); - for (channelListT::iterator cptr = channelList.begin(); (cptr != channelList.end()) && (count < 15); cptr++) - { - curChannel = *cptr; - bot->Notice(theClient, "Channel: [%4d] %s", - curChannel->size(), - curChannel->getName().c_str()); - count++; - } - bot->Notice(theClient, "--==[ End of 'list channels topic '%s' - %d found ]==--", - st[3].c_str(), channelList.size()); - } - else if (!strcasecmp(st[2].c_str(),"topicby")) - { - if (st.size() < 4) - { - bot->Notice(theClient, "for 'list channels topicby', you must supply the nick!user@host mask to search for!"); - return false; - } - /* validate the nick!user@host */ - string::size_type atPos = st[3].find_first_of('!'); - if (string::npos == atPos) - { - /* not in nick!user@host format */ - /* assume they want to check nick only, but tell them just in case */ - Mask = ""; - Mask += st[3].c_str(); - Mask += "!*@*"; - bot->Notice(theClient, "Mask was not in nick!user@host format, re-writing mask to '%s'. This may not be what you want!", - Mask.c_str()); - } else { - /* we have nick!..., check for user@host! */ - string::size_type atPos2 = st[3].find_first_of('@'); - if ((string::npos == atPos2) || (atPos2 < atPos)) - { - /* either no '@' or it's before the first '!' */ - /* assume they want to check nick!user only, but tell them just in case */ - Mask = ""; - Mask += st[3].c_str(); - /* if the '!' is at the end of the line, we need to add a * */ - if (atPos == (st[3].length()-1)) - Mask += "*"; - Mask += "@*"; - bot->Notice(theClient, "Mask was not in nick!user@host format, re-writing mask to '%s'. This may not be what you want!", - Mask.c_str()); - } else { - /* we have a full nick!user@host - we dont need to alter it */ - Mask = st[3].c_str(); - } - } - /* ok, we have a valid topicby to search for in Mask */ - channelList = Network->getChannelsWithTopicBy(Mask); + for (channelListT::iterator cptr = channelList.begin(); + (cptr != channelList.end()) && (count < 15); cptr++) { + curChannel = *cptr; + bot->Notice(theClient, "Channel: [%4d] %s", curChannel->size(), + curChannel->getName().c_str()); + count++; + } + bot->Notice(theClient, "--==[ End of 'list channels topic '%s' - %d found ]==--", + st[3].c_str(), channelList.size()); + } else if (!strcasecmp(st[2].c_str(), "topicby")) { + if (st.size() < 4) { + bot->Notice(theClient, "for 'list channels topicby', you must supply the " + "nick!user@host mask to search for!"); + return false; + } + /* validate the nick!user@host */ + string::size_type atPos = st[3].find_first_of('!'); + if (string::npos == atPos) { + /* not in nick!user@host format */ + /* assume they want to check nick only, but tell them just in case */ + Mask = ""; + Mask += st[3].c_str(); + Mask += "!*@*"; + bot->Notice(theClient, + "Mask was not in nick!user@host format, re-writing mask to '%s'. This " + "may not be what you want!", + Mask.c_str()); + } else { + /* we have nick!..., check for user@host! */ + string::size_type atPos2 = st[3].find_first_of('@'); + if ((string::npos == atPos2) || (atPos2 < atPos)) { + /* either no '@' or it's before the first '!' */ + /* assume they want to check nick!user only, but tell them just in case */ + Mask = ""; + Mask += st[3].c_str(); + /* if the '!' is at the end of the line, we need to add a * */ + if (atPos == (st[3].length() - 1)) + Mask += "*"; + Mask += "@*"; + bot->Notice(theClient, + "Mask was not in nick!user@host format, re-writing mask to '%s'. " + "This may not be what you want!", + Mask.c_str()); + } else { + /* we have a full nick!user@host - we dont need to alter it */ + Mask = st[3].c_str(); + } + } + /* ok, we have a valid topicby to search for in Mask */ + channelList = Network->getChannelsWithTopicBy(Mask); - if (channelList.empty()) - { - bot->Notice(theClient, "I'm sorry, no channels have a topic matching '%s'", Mask.c_str()); - return false; - } + if (channelList.empty()) { + bot->Notice(theClient, "I'm sorry, no channels have a topic matching '%s'", + Mask.c_str()); + return false; + } - bot->Notice(theClient, "--==[ Channels with topics set by '%s' %s]==--", Mask.c_str(), - (channelList.size() > 15)?"- showing first 15 only":""); + bot->Notice(theClient, "--==[ Channels with topics set by '%s' %s]==--", Mask.c_str(), + (channelList.size() > 15) ? "- showing first 15 only" : ""); - for (channelListT::iterator cptr = channelList.begin(); (cptr != channelList.end()) && (count < 15); cptr++) - { - curChannel = *cptr; - bot->Notice(theClient, "Channel: [%4d] %s", - curChannel->size(), - curChannel->getName().c_str()); - count++; - } - bot->Notice(theClient, "--==[ End of 'list channels topicby '%s' - %d found ]==--", - Mask.c_str(), channelList.size()); - } else { - bot->Notice(theClient,"'list channels' requires 'key', 'modes', 'topic' or 'topicby'"); - return false; + for (channelListT::iterator cptr = channelList.begin(); + (cptr != channelList.end()) && (count < 15); cptr++) { + curChannel = *cptr; + bot->Notice(theClient, "Channel: [%4d] %s", curChannel->size(), + curChannel->getName().c_str()); + count++; + } + bot->Notice(theClient, "--==[ End of 'list channels topicby '%s' - %d found ]==--", + Mask.c_str(), channelList.size()); + } else { + bot->Notice(theClient, "'list channels' requires 'key', 'modes', 'topic' or 'topicby'"); + return false; #else - else { - bot->Notice(theClient,"'list channels' requires 'key' or 'modes'"); - return false; + else { + bot->Notice(theClient, "'list channels' requires 'key' or 'modes'"); + return false; #endif - } - } -else - { - bot->Notice(theClient,"Unknown list type - see HELP"); - } + } + } else { + bot->Notice(theClient, "Unknown list type - see HELP"); + } -return true ; -} - -} + return true; } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/LISTHOSTSCommand.cc b/mod.ccontrol/LISTHOSTSCommand.cc index 423764f1..4c32fc66 100644 --- a/mod.ccontrol/LISTHOSTSCommand.cc +++ b/mod.ccontrol/LISTHOSTSCommand.cc @@ -20,54 +20,44 @@ * $Id: LISTHOSTSCommand.cc,v 1.14 2006/09/26 17:35:59 kewlio Exp $ */ -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "gnuworld_config.h" +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { -bool LISTHOSTSCommand::Exec( iClient* theClient, const string& Message) -{ -StringTokenizer st( Message ) ; +bool LISTHOSTSCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + if (st.size() < 2) { + Usage(theClient); + return true; + } + ccUser* tmpUser = bot->IsAuth(theClient); + bot->MsgChanLog("LISTHOSTS %s\n", st.assemble(1).c_str()); -if( st.size() < 2 ) - { - Usage(theClient); - return true; - } -ccUser* tmpUser = bot->IsAuth(theClient); -bot->MsgChanLog("LISTHOSTS %s\n",st.assemble(1).c_str()); + tmpUser = bot->GetOper(st[1]); -tmpUser = bot->GetOper(st[1]); - -if(!tmpUser) - { - bot->Notice(theClient,"%s isn't on my access list",st[1].c_str()); + if (!tmpUser) { + bot->Notice(theClient, "%s isn't on my access list", st[1].c_str()); return false; - } + } -if(bot->listHosts(tmpUser,theClient)) - { - bot->Notice(theClient,"End of hosts for user %s",st[1].c_str()); - } -else - { - bot->Notice(theClient,"Error while accessing host list for %s",st[1].c_str()); - } + if (bot->listHosts(tmpUser, theClient)) { + bot->Notice(theClient, "End of hosts for user %s", st[1].c_str()); + } else { + bot->Notice(theClient, "Error while accessing host list for %s", st[1].c_str()); + } -return true; + return true; } -} +} // namespace uworld } // namespace gnuworld - diff --git a/mod.ccontrol/LISTIGNORESCommand.cc b/mod.ccontrol/LISTIGNORESCommand.cc index adabb70e..fd29e717 100644 --- a/mod.ccontrol/LISTIGNORESCommand.cc +++ b/mod.ccontrol/LISTIGNORESCommand.cc @@ -1,5 +1,5 @@ /** - * LISTIGNORESCommand.cc + * LISTIGNORESCommand.cc * Shows all ignored masks * * This program is free software; you can redistribute it and/or @@ -20,28 +20,24 @@ * $Id: LISTIGNORESCommand.cc,v 1.10 2006/09/26 17:35:59 kewlio Exp $ */ -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "gnuworld_config.h" +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::endl ; +using std::endl; +using std::string; -namespace uworld -{ +namespace uworld { -bool LISTIGNORESCommand::Exec( iClient* theClient, const string& ) -{ -bot->MsgChanLog("LISTIGNORES \n"); -bot->listIgnores(theClient); -return true; +bool LISTIGNORESCommand::Exec(iClient* theClient, const string&) { + bot->MsgChanLog("LISTIGNORES \n"); + bot->listIgnores(theClient); + return true; } -} +} // namespace uworld } // namespace gnuworld - diff --git a/mod.ccontrol/LISTOPERCHANSCommand.cc b/mod.ccontrol/LISTOPERCHANSCommand.cc index 4a24e32d..7d991d6a 100644 --- a/mod.ccontrol/LISTOPERCHANSCommand.cc +++ b/mod.ccontrol/LISTOPERCHANSCommand.cc @@ -20,53 +20,45 @@ * $Id: LISTOPERCHANSCommand.cc,v 1.9 2005/01/12 03:50:29 dan_karrels Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { // listoperchans -bool LISTOPERCHANSCommand::Exec( iClient* theClient, const string& ) -{ +bool LISTOPERCHANSCommand::Exec(iClient* theClient, const string&) { -bot->Notice( theClient, "There are currently %d IRCoperator only channels", - bot->operChan_size() ) ; + bot->Notice(theClient, "There are currently %d IRCoperator only channels", + bot->operChan_size()); -if( bot->operChan_empty() ) - { - return true ; - } + if (bot->operChan_empty()) { + return true; + } -string chanList = "" ; -ccontrol::const_operChanIterator ptr = bot->operChan_begin() ; + string chanList = ""; + ccontrol::const_operChanIterator ptr = bot->operChan_begin(); -while( ptr != bot->operChan_end() ) - { - if( !chanList.empty() ) - { - chanList += ", " ; - chanList += *ptr ; - } - else - { - chanList = *ptr ; - } - ++ptr ; - } + while (ptr != bot->operChan_end()) { + if (!chanList.empty()) { + chanList += ", "; + chanList += *ptr; + } else { + chanList = *ptr; + } + ++ptr; + } -bot->Notice( theClient, chanList ) ; -return true ; -} -} + bot->Notice(theClient, chanList); + return true; } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/LISTUSERSCommand.cc b/mod.ccontrol/LISTUSERSCommand.cc index 95950188..00fd217a 100644 --- a/mod.ccontrol/LISTUSERSCommand.cc +++ b/mod.ccontrol/LISTUSERSCommand.cc @@ -21,18 +21,18 @@ * $Id: REMCOMMANDCommand.cc,v 1.16 2009/06/13 06:43:34 hidden1 Exp $ */ -#include -#include +#include +#include -#include +#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "ccUser.h" -#include "misc.h" -#include "gnuworld_config.h" -#include "UserFilter.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "ccUser.h" +#include "misc.h" +#include "gnuworld_config.h" +#include "UserFilter.h" namespace gnuworld { @@ -41,62 +41,62 @@ using std::string; namespace uworld { bool LISTUSERSCommand::Exec(iClient* theClient, const string& Message) { - StringTokenizer st(Message); - UserFilterComposite filters; - ByLevelsUserFilter levelsFilter; - bool wantedLevels = false; - unsigned int pos = 1; - while(pos < st.size()) { - if(!strcmp(st[pos].c_str(),"-l")) { - pos++; - if(pos == st.size()) { - bot->Notice(theClient,"-l option must get the level of the oper to show"); - return false; - } - int level = bot->strToLevel(st[pos++]); - if(level < 0) { - bot->Notice(theClient,"invalid oper level %s, valid options are: coder/smt/admin/oper/uhs",st[pos].c_str()); - return false; - } - wantedLevels = true; - levelsFilter.addLevel(level); + StringTokenizer st(Message); + UserFilterComposite filters; + ByLevelsUserFilter levelsFilter; + bool wantedLevels = false; + unsigned int pos = 1; + while (pos < st.size()) { + if (!strcmp(st[pos].c_str(), "-l")) { + pos++; + if (pos == st.size()) { + bot->Notice(theClient, "-l option must get the level of the oper to show"); + return false; + } + int level = bot->strToLevel(st[pos++]); + if (level < 0) { + bot->Notice(theClient, + "invalid oper level %s, valid options are: coder/smt/admin/oper/uhs", + st[pos].c_str()); + return false; + } + wantedLevels = true; + levelsFilter.addLevel(level); + } + pos++; + } - } - pos++; - } + if (wantedLevels) { + filters.addFilter(&levelsFilter); + } + ccUser* user; + ccontrol::usersconstiterator uItr = bot->usersmap_begin(); + int count = 0; + stringstream sstr; + for (; uItr != bot->usersmap_end(); uItr++) { + user = uItr->second; - if(wantedLevels) { - filters.addFilter(&levelsFilter); - } - ccUser* user; - ccontrol::usersconstiterator uItr = bot->usersmap_begin(); - int count = 0; - stringstream sstr; - for (; uItr != bot->usersmap_end(); uItr++) { - user = uItr->second; - - if(filters.filter(user)) { - if(sstr.str().size() > 0) { - sstr << ","; - } - sstr << "User: " << user->getUserName() << " Level: " << bot->levelToStr(user->getType()); - count ++; - if(count % 2 == 0) { - bot->Notice(theClient,"%s",sstr.str().c_str()); - sstr.str(""); - } - } - } - if (!sstr.str().empty()) { - bot->Notice(theClient, "%s", sstr.str().c_str()); - } + if (filters.filter(user)) { + if (sstr.str().size() > 0) { + sstr << ","; + } + sstr << "User: " << user->getUserName() + << " Level: " << bot->levelToStr(user->getType()); + count++; + if (count % 2 == 0) { + bot->Notice(theClient, "%s", sstr.str().c_str()); + sstr.str(""); + } + } + } + if (!sstr.str().empty()) { + bot->Notice(theClient, "%s", sstr.str().c_str()); + } - bot->Notice(theClient,"Finished listing %d users",count); + bot->Notice(theClient, "Finished listing %d users", count); - return true; - -} - -} + return true; } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/LOGINCommand.cc b/mod.ccontrol/LOGINCommand.cc index 27e2fb8b..87d1bca2 100644 --- a/mod.ccontrol/LOGINCommand.cc +++ b/mod.ccontrol/LOGINCommand.cc @@ -20,156 +20,154 @@ * $Id: LOGINCommand.cc,v 1.32 2009/07/25 18:12:34 hidden1 Exp $ */ -#include -#include -#include -#include -#include "Network.h" -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "md5hash.h" -#include "ccUser.h" -#include "events.h" -#include "ip.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; -using std::endl ; -using std::ends ; -using std::stringstream ; - -namespace uworld -{ - -bool LOGINCommand::Exec( iClient* theClient, const string& Message) -{ -StringTokenizer st( Message ) ; - -bool isAuthedToX = false; - -if( st.size() < 3 ) - { - Usage(theClient); - return true; - } -//Try fetching the user authenticate entry -ccUser* theUser = bot->IsAuth(theClient); -if (theUser) - { - if ((theUser->getAutoOp()) && (!theClient->isOper())) - bot->deAuthUser(theUser, theClient); - else - { - //Dont let him authenticate under a new name (for now) - bot->Notice(theClient, "You are already authenticated! See DEAUTH command."); - return false; - } - } - - /* - * Find the user record, confirm authorisation and attach the record to this client. - */ -iServer* targetServer = Network->findServer( theClient->getIntYY() ) ; -if( NULL == targetServer ) - { - elog << "LOGINCommand> Unable to find server: " - << theClient->getIntYY() << endl ; - return false ; - } - -theUser = bot->GetOper(st[1]); -if (!theUser) - { - - bot->MsgChanLog("[FAILED LOGIN] %s - Bad Username: %s (%s)\n", - theClient->getRealNickUserHost().c_str(), - st[1].c_str(), - targetServer->getName().c_str()); - if(theClient->isOper()) - bot->Notice(theClient, "FALSE LOGIN, DENIED"); - bot->addLogin(theClient); - return false; - } -else - { - if (!strcasecmp(theClient->getAccount(), theUser->getAccount())) { - if ((theClient->getAccountID() == theUser->getAccountID()) || (theUser->getAccountID() == 0)) - isAuthedToX = true; - } - - //Check if the user need to be operd to login - if((!theClient->isOper()) && (theUser->getNeedOp())) { - if (!theUser->getAutoOp()) { - bot->MsgChanLog("[FAILED LOGIN] %s - Not Oper'd\n",theClient->getRealNickUserHost().c_str()); - bot->addLogin(theClient); - return false; - } - } - //Check if the users mask is in his access list - if((!theClient->isOper()) && (!bot->UserGotMask(theUser,theClient->getRealNickUserHost())) - &&(!bot->UserGotMask( theUser,theClient->getNickName() + "!" + theClient->getUserName() + "@" + xIP(theClient->getIP()).GetNumericIP()))) - { - bot->MsgChanLog("[FAILED LOGIN] %s - No HostMask\n",theClient->getRealNickUserHost().c_str()); - if(theClient->isOper()) - bot->Notice(theClient, "FALSE LOGIN, DENIED"); - bot->addLogin(theClient); - return false; - } - - md5 hash; // MD5 hash algorithm object. - md5Digest digest; // MD5Digest algorithm object. - stringstream output; - string salt = theUser->getPassword().substr(0, 8); - string md5Part = theUser->getPassword().substr(8); - string guess = salt + st.assemble(2); - - // Build a MD5 hash based on our salt + the guessed password. - hash.update( (unsigned char *)guess.c_str(), strlen( guess.c_str() )); - hash.report( digest ); - - // Convert the digest into an array of int's to output as hex for - // comparison with the passwords generated by PHP. - int data[ MD5_DIGEST_LENGTH ]; - int ii; - for( ii = 0; ii < MD5_DIGEST_LENGTH; ii++ ) - { - data[ii] = digest[ii]; - } - output << hex; - output.fill('0'); - for( ii = 0; ii < MD5_DIGEST_LENGTH; ii++ ) { - output << setw(2) << data[ii]; - } - output << ends; - - if (md5Part != output.str().c_str()) // If the MD5 hash's don't match.. - { - bot->MsgChanLog("[FAILED LOGIN] %s - Bad Password (%s)\n",theClient->getRealNickUserHost().c_str(), targetServer->getName().c_str()); - if(theClient->isOper()) - bot->Notice(theClient, "FALSE LOGIN, DENIED"); - bot->addLogin(theClient); - return false; - } - if (isAuthedToX) { - if ((theUser->getAccountID() != theClient->getAccountID()) && (theUser->getAccountID() == 0)) { - // euworld has never received an accountID for this account before. Update the db. - theUser->setAccountID(theClient->getAccountID()); - theUser->Update(); - bot->Notice(theClient, "Your X account ID (%d) is now stored in my database along with your X account.", theClient->getAccountID()); - bot->Notice(theClient, "This ensures that if your username expires and gets re-registered, I will see the difference. You should never see this message again"); - } - } - //Ok the password match , prepare the ccUser data - bot->OkAuthUser(theClient, theUser); - } - -return true; -} - +#include +#include +#include +#include +#include "Network.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "md5hash.h" +#include "ccUser.h" +#include "events.h" +#include "ip.h" +#include "gnuworld_config.h" + +namespace gnuworld { + +using std::endl; +using std::ends; +using std::string; +using std::stringstream; + +namespace uworld { + +bool LOGINCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + + bool isAuthedToX = false; + + if (st.size() < 3) { + Usage(theClient); + return true; + } + // Try fetching the user authenticate entry + ccUser* theUser = bot->IsAuth(theClient); + if (theUser) { + if ((theUser->getAutoOp()) && (!theClient->isOper())) + bot->deAuthUser(theUser, theClient); + else { + // Dont let him authenticate under a new name (for now) + bot->Notice(theClient, "You are already authenticated! See DEAUTH command."); + return false; + } + } + + /* + * Find the user record, confirm authorisation and attach the record to this client. + */ + iServer* targetServer = Network->findServer(theClient->getIntYY()); + if (NULL == targetServer) { + elog << "LOGINCommand> Unable to find server: " << theClient->getIntYY() << endl; + return false; + } + + theUser = bot->GetOper(st[1]); + if (!theUser) { + + bot->MsgChanLog("[FAILED LOGIN] %s - Bad Username: %s (%s)\n", + theClient->getRealNickUserHost().c_str(), st[1].c_str(), + targetServer->getName().c_str()); + if (theClient->isOper()) + bot->Notice(theClient, "FALSE LOGIN, DENIED"); + bot->addLogin(theClient); + return false; + } else { + if (!strcasecmp(theClient->getAccount(), theUser->getAccount())) { + if ((theClient->getAccountID() == theUser->getAccountID()) || + (theUser->getAccountID() == 0)) + isAuthedToX = true; + } + + // Check if the user need to be operd to login + if ((!theClient->isOper()) && (theUser->getNeedOp())) { + if (!theUser->getAutoOp()) { + bot->MsgChanLog("[FAILED LOGIN] %s - Not Oper'd\n", + theClient->getRealNickUserHost().c_str()); + bot->addLogin(theClient); + return false; + } + } + // Check if the users mask is in his access list + if ((!theClient->isOper()) && + (!bot->UserGotMask(theUser, theClient->getRealNickUserHost())) && + (!bot->UserGotMask(theUser, theClient->getNickName() + "!" + theClient->getUserName() + + "@" + xIP(theClient->getIP()).GetNumericIP()))) { + bot->MsgChanLog("[FAILED LOGIN] %s - No HostMask\n", + theClient->getRealNickUserHost().c_str()); + if (theClient->isOper()) + bot->Notice(theClient, "FALSE LOGIN, DENIED"); + bot->addLogin(theClient); + return false; + } + + md5 hash; // MD5 hash algorithm object. + md5Digest digest; // MD5Digest algorithm object. + stringstream output; + string salt = theUser->getPassword().substr(0, 8); + string md5Part = theUser->getPassword().substr(8); + string guess = salt + st.assemble(2); + + // Build a MD5 hash based on our salt + the guessed password. + hash.update((unsigned char*)guess.c_str(), strlen(guess.c_str())); + hash.report(digest); + + // Convert the digest into an array of int's to output as hex for + // comparison with the passwords generated by PHP. + int data[MD5_DIGEST_LENGTH]; + int ii; + for (ii = 0; ii < MD5_DIGEST_LENGTH; ii++) { + data[ii] = digest[ii]; + } + output << hex; + output.fill('0'); + for (ii = 0; ii < MD5_DIGEST_LENGTH; ii++) { + output << setw(2) << data[ii]; + } + output << ends; + + if (md5Part != output.str().c_str()) // If the MD5 hash's don't match.. + { + bot->MsgChanLog("[FAILED LOGIN] %s - Bad Password (%s)\n", + theClient->getRealNickUserHost().c_str(), + targetServer->getName().c_str()); + if (theClient->isOper()) + bot->Notice(theClient, "FALSE LOGIN, DENIED"); + bot->addLogin(theClient); + return false; + } + if (isAuthedToX) { + if ((theUser->getAccountID() != theClient->getAccountID()) && + (theUser->getAccountID() == 0)) { + // euworld has never received an accountID for this account before. Update the db. + theUser->setAccountID(theClient->getAccountID()); + theUser->Update(); + bot->Notice(theClient, + "Your X account ID (%d) is now stored in my database along with your X " + "account.", + theClient->getAccountID()); + bot->Notice(theClient, + "This ensures that if your username expires and gets re-registered, I " + "will see the difference. You should never see this message again"); + } + } + // Ok the password match , prepare the ccUser data + bot->OkAuthUser(theClient, theUser); + } + + return true; } -} // namespace gnuworld +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/MAXUSERSCommand.cc b/mod.ccontrol/MAXUSERSCommand.cc index b0f32897..46f27a1c 100644 --- a/mod.ccontrol/MAXUSERSCommand.cc +++ b/mod.ccontrol/MAXUSERSCommand.cc @@ -1,5 +1,5 @@ /** - * MAXUSERSCommand.cc + * MAXUSERSCommand.cc * Shows the maximum number of online users ever recorded * * This program is free software; you can redistribute it and/or @@ -20,30 +20,27 @@ * $Id: MAXUSERSCommand.cc,v 1.7 2006/09/26 17:35:59 kewlio Exp $ */ -#include +#include -#include "StringTokenizer.h" -#include "ccontrol.h" -#include "CControlCommands.h" -#include "ccontrol_generic.h" -#include "gnuworld_config.h" +#include "StringTokenizer.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "ccontrol_generic.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -namespace uworld -{ +namespace uworld { -bool MAXUSERSCommand::Exec( iClient* theClient, const string& ) -{ -bot->Notice(theClient,"Current number of users is: %d",bot->getCurUsers()); -bot->Notice(theClient,"Maximum number of users ever recorded is: %d",bot->getMaxUsers()); -bot->Notice(theClient,"Recorded on %s (%s ago)",bot->convertToAscTime(bot->getDateMax()), - Ago(bot->getDateMax())); +bool MAXUSERSCommand::Exec(iClient* theClient, const string&) { + bot->Notice(theClient, "Current number of users is: %d", bot->getCurUsers()); + bot->Notice(theClient, "Maximum number of users ever recorded is: %d", bot->getMaxUsers()); + bot->Notice(theClient, "Recorded on %s (%s ago)", bot->convertToAscTime(bot->getDateMax()), + Ago(bot->getDateMax())); -return true; + return true; } -} +} // namespace uworld } // namespace gnuworld diff --git a/mod.ccontrol/MODECommand.cc b/mod.ccontrol/MODECommand.cc index 0a6b79d5..05cfacc0 100644 --- a/mod.ccontrol/MODECommand.cc +++ b/mod.ccontrol/MODECommand.cc @@ -20,367 +20,359 @@ * $Id: MODECommand.cc,v 1.22 2006/09/26 17:35:59 kewlio Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "Constants.h" -#include "ccBadChannel.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "Constants.h" +#include "ccBadChannel.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { // LDd P AIAAA :mode #krushnet -o DawgSleep // mode channel modes -bool MODECommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -if( st.size() < 3 ) - { - Usage( theClient ) ; - return true ; - } - -if(st[1].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel can't be more than %d characters", - channel::MaxName); - } - -Channel* theChan = Network->findChannel( st[ 1 ] ) ; -if( NULL == theChan ) - { - bot->Notice( theClient, "Unable to find channel '%s'\n", - st[ 1 ].c_str() ) ; - return true ; - } -bot->MsgChanLog("MODE %s\n",st.assemble(1).c_str()); - -ccBadChannel* Chan = bot->isBadChannel(st[1]); -if(Chan) - { - bot->Notice(theClient,"Sorry, but you can't change modes in " - "this channel because: %s", - Chan->getReason().c_str()); +bool MODECommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + if (st.size() < 3) { + Usage(theClient); + return true; + } + + if (st[1].size() > channel::MaxName) { + bot->Notice(theClient, "Channel can't be more than %d characters", channel::MaxName); + } + + Channel* theChan = Network->findChannel(st[1]); + if (NULL == theChan) { + bot->Notice(theClient, "Unable to find channel '%s'\n", st[1].c_str()); + return true; + } + bot->MsgChanLog("MODE %s\n", st.assemble(1).c_str()); + + ccBadChannel* Chan = bot->isBadChannel(st[1]); + if (Chan) { + bot->Notice(theClient, + "Sorry, but you can't change modes in " + "this channel because: %s", + Chan->getReason().c_str()); return false; - } - -// This has been changed to use xServer::Mode(), which will from now -// on perform the bulk of the heavy lifting with setting modes. -// Note that this will have the negative effect of not telling -// the requesting client of this command why something did not succeed. -bot->Mode( theChan, st.assemble( 2 ), string(), true ) ; -return true ; - -/* - -// Define mode to be any mode, such as +abc-def -// Define argument to to be any argument to a particular mode: -o nickArgument - -// index into the st object, location of next mode -StringTokenizer::size_type modePos = 2 ; - -// index into the st object, location of next argument -StringTokenizer::size_type argPos = 3 ; - -// To be used later -iClient* Target = 0 ; -ChannelUser* ChanUser = NULL; -// Store the command to be sent to the network in two strings -// modeString holds the updated modes -string modeString = "" ; - -// argString holds the updated arguments, delimited by space (' ') -string argString = "" ; - -// Continue while there are more modes to parse -while( modePos < st.size() ) - { - - // modePos could be equal to argPos if a previous iteration of - // the while loop found one or more modes with arguments - if( modePos == argPos ) - { - argPos++ ; - } - - // This it the size of the increment to make to modePos. - // This could be greater than 1 if there are more than one mode - // arguments at st[ modePos ] that require arguments - string::size_type modePosIncrement = 1 ; - - // Keep track of the polarity of the mode change. - bool plus = true ; - bool Op = false; - // Iterate through the characters of the mode at st[ modePos ] - for( string::size_type charPos = 0 ; charPos < st[ modePos ].size() ; ++charPos ) - { - switch( toupper(st[ modePos ][ charPos ]) ) - { - case 'O': - Op = true; - case 'V': - - // Make sure there is an argument for this mode - if( argPos >= st.size() ) - { - Usage( theClient ) ; - return true ; - } - - - // arg needs to be a nickname - Target = Network->findNick( st[ argPos ] ) ; - - // Is the argument a valid nickname? - if( NULL == Target ) - { - bot->Notice( theClient, "Unable to find '%s'\n", - st[ argPos ].c_str() ) ; - return true ; - } - - // Make sure the user is in this particular channel - if( NULL == (ChanUser = theChan->findUser( Target ) )) - { - bot->Notice( theClient, "User %s was not found " - "on channel %s", - st[ argPos ].c_str(), - theChan->getName().c_str() ) ; - return true ; - } - //Dont deop +k - if((Target->getMode(iClient::MODE_SERVICES)) && (!plus)) - { - Op = false; - // Move to next argument - argPos++ ; - - // Make sure modePos skips over this argument - modePosIncrement++ ; - - continue; - } - if(plus) - if(Op) - ChanUser->setModeO() ; - else - ChanUser->setModeV() ; - else - - if(Op) - ChanUser->removeModeO() ; - else - ChanUser->removeModeV() ; - // Add the mode to the modeString - modeString += st[ modePos ][ charPos ] ; - - // Add this nick's numeric (plus a space) to the end - // of the current argument string - argString += Target->getCharYYXXX() + ' ' ; - - // Move to next argument - argPos++ ; - - // Make sure modePos skips over this argument - modePosIncrement++ ; - - //Make sure to turn off op bool for next mode - Op = false; - - break ; - case 'B': - // Each of these modes needs an argument - if( argPos >= st.size() ) - { - Usage( theClient ) ; - return true ; - } - - // Add this mode to the current modeString - modeString += st[ modePos ][ charPos ] ; - - // Add this argument to the current argument string - argString += st[ argPos ] + ' ' ; - if(!plus) - theChan->removeBan(st[ argPos ]); - else - theChan->setBan(st[ argPos ]); - // Mode to next argument - argPos++ ; - - // Make sure modePos skips over this argument - modePosIncrement++ ; - - break ; - - case 'K': - // Each of these modes needs an argument - if( argPos >= st.size() ) - { - Usage( theClient ) ; - return true ; - } - - // Add this mode to the current modeString - modeString += st[ modePos ][ charPos ] ; - - // Add this argument to the current argument string - argString += st[ argPos ] + ' ' ; - - if(plus) - { - theChan->setMode(Channel::MODE_K); - theChan->setKey(st [ argPos ]); - } - else - { - theChan->removeMode(Channel::MODE_K); - theChan->setKey(""); - } - - // Mode to next argument - argPos++ ; - - // Make sure modePos skips over this argument - modePosIncrement++ ; - - break ; - case 'L': - - // Mode -l requires no argument - if( !plus ) - { - // No args needed - modeString += st[ modePos ][ charPos ] ; - theChan->removeMode(Channel::MODE_L); - break ; - } - - // Else, the user has specified +l, need an - // argument. - - // Each of these modes needs an argument - if( argPos >= st.size() ) - { - Usage( theClient ) ; - return true ; - } - - theChan->setMode(Channel::MODE_L); - - // Add this mode to the current modeString - modeString += st[ modePos ][ charPos ] ; - - // Add this argument to the current argument string - argString += st[ argPos ] + ' ' ; - - // Mode to next argument - argPos++ ; - - // Make sure modePos skips over this argument - modePosIncrement++ ; - - break ; - case 'I': //Invite? - if(!plus) - theChan->removeMode(Channel::MODE_I); - else - theChan->setMode(Channel::MODE_I); - modeString += st[ modePos ][ charPos ] ; - - break; - case 'P': //Private? - if(!plus) - theChan->removeMode(Channel::MODE_P); - else - theChan->setMode(Channel::MODE_P); - modeString += st[ modePos ][ charPos ] ; - break; - case 'S': //Secret? - if(!plus) - theChan->removeMode(Channel::MODE_S); - else - theChan->setMode(Channel::MODE_S); - - modeString += st[ modePos ][ charPos ] ; - - break; - case 'M': //Moderated? - if(!plus) - theChan->removeMode(Channel::MODE_M); - else - theChan->setMode(Channel::MODE_M); - - modeString += st[ modePos ][ charPos ] ; - - break; - case 'N': //No External Messages? - if(!plus) - theChan->removeMode(Channel::MODE_N); - else - theChan->setMode(Channel::MODE_N); - - modeString += st[ modePos ][ charPos ] ; - - break; - case 'T': //Topic? - if(!plus) - theChan->removeMode(Channel::MODE_T); - else - theChan->setMode(Channel::MODE_T); - modeString += st[ modePos ][ charPos ] ; - break; - case '+': - if( plus ) - { - // Already plus - break ; - } - plus = true ; - modeString += st[ modePos ][ charPos ] ; - break ; - case '-': - if( !plus ) - { - // Already minus - break ; - } - plus = false ; - modeString += st[ modePos ][ charPos ] ; - break ; - default: - // Requires no arguments, just add the mode - // to the modeString - modeString += st[ modePos ][ charPos ] ; - break ; - - } // switch() - } // for() - - modePos += modePosIncrement ; - } // while( modePos < st.size() ) - -bot->ModeAsServer( theChan, modeString + ' ' + argString ) ; -*/ - -// Update internal tables. -// This is a cheat, but it makes things so much easier :) -// TODO -//theChan->OnModeChange( theClient->getCharYYXXX(), modeString, argString -//) ; - -return true ; + } + + // This has been changed to use xServer::Mode(), which will from now + // on perform the bulk of the heavy lifting with setting modes. + // Note that this will have the negative effect of not telling + // the requesting client of this command why something did not succeed. + bot->Mode(theChan, st.assemble(2), string(), true); + return true; + + /* + + // Define mode to be any mode, such as +abc-def + // Define argument to to be any argument to a particular mode: -o nickArgument + + // index into the st object, location of next mode + StringTokenizer::size_type modePos = 2 ; + + // index into the st object, location of next argument + StringTokenizer::size_type argPos = 3 ; + + // To be used later + iClient* Target = 0 ; + ChannelUser* ChanUser = NULL; + // Store the command to be sent to the network in two strings + // modeString holds the updated modes + string modeString = "" ; + + // argString holds the updated arguments, delimited by space (' ') + string argString = "" ; + + // Continue while there are more modes to parse + while( modePos < st.size() ) + { + + // modePos could be equal to argPos if a previous iteration of + // the while loop found one or more modes with arguments + if( modePos == argPos ) + { + argPos++ ; + } + + // This it the size of the increment to make to modePos. + // This could be greater than 1 if there are more than one mode + // arguments at st[ modePos ] that require arguments + string::size_type modePosIncrement = 1 ; + + // Keep track of the polarity of the mode change. + bool plus = true ; + bool Op = false; + // Iterate through the characters of the mode at st[ modePos ] + for( string::size_type charPos = 0 ; charPos < st[ modePos ].size() ; ++charPos ) + { + switch( toupper(st[ modePos ][ charPos ]) ) + { + case 'O': + Op = true; + case 'V': + + // Make sure there is an argument for this mode + if( argPos >= st.size() ) + { + Usage( theClient ) ; + return true ; + } + + + // arg needs to be a nickname + Target = Network->findNick( st[ argPos ] ) ; + + // Is the argument a valid nickname? + if( NULL == Target ) + { + bot->Notice( theClient, "Unable to find '%s'\n", + st[ argPos ].c_str() ) ; + return true ; + } + + // Make sure the user is in this particular channel + if( NULL == (ChanUser = theChan->findUser( Target ) )) + { + bot->Notice( theClient, "User %s was not found " + "on channel %s", + st[ argPos ].c_str(), + theChan->getName().c_str() ) ; + return true ; + } + //Dont deop +k + if((Target->getMode(iClient::MODE_SERVICES)) && (!plus)) + { + Op = false; + // Move to next argument + argPos++ ; + + // Make sure modePos skips over this argument + modePosIncrement++ ; + + continue; + } + if(plus) + if(Op) + ChanUser->setModeO() ; + else + ChanUser->setModeV() ; + else + + if(Op) + ChanUser->removeModeO() ; + else + ChanUser->removeModeV() ; + // Add the mode to the modeString + modeString += st[ modePos ][ charPos ] ; + + // Add this nick's numeric (plus a space) to the end + // of the current argument string + argString += Target->getCharYYXXX() + ' ' ; + + // Move to next argument + argPos++ ; + + // Make sure modePos skips over this argument + modePosIncrement++ ; + + //Make sure to turn off op bool for next mode + Op = false; + + break ; + case 'B': + // Each of these modes needs an argument + if( argPos >= st.size() ) + { + Usage( theClient ) ; + return true ; + } + + // Add this mode to the current modeString + modeString += st[ modePos ][ charPos ] ; + + // Add this argument to the current argument string + argString += st[ argPos ] + ' ' ; + if(!plus) + theChan->removeBan(st[ argPos ]); + else + theChan->setBan(st[ argPos ]); + // Mode to next argument + argPos++ ; + + // Make sure modePos skips over this argument + modePosIncrement++ ; + + break ; + + case 'K': + // Each of these modes needs an argument + if( argPos >= st.size() ) + { + Usage( theClient ) ; + return true ; + } + + // Add this mode to the current modeString + modeString += st[ modePos ][ charPos ] ; + + // Add this argument to the current argument string + argString += st[ argPos ] + ' ' ; + + if(plus) + { + theChan->setMode(Channel::MODE_K); + theChan->setKey(st [ argPos ]); + } + else + { + theChan->removeMode(Channel::MODE_K); + theChan->setKey(""); + } + + // Mode to next argument + argPos++ ; + + // Make sure modePos skips over this argument + modePosIncrement++ ; + + break ; + case 'L': + + // Mode -l requires no argument + if( !plus ) + { + // No args needed + modeString += st[ modePos ][ charPos ] ; + theChan->removeMode(Channel::MODE_L); + break ; + } + + // Else, the user has specified +l, need an + // argument. + + // Each of these modes needs an argument + if( argPos >= st.size() ) + { + Usage( theClient ) ; + return true ; + } + + theChan->setMode(Channel::MODE_L); + + // Add this mode to the current modeString + modeString += st[ modePos ][ charPos ] ; + + // Add this argument to the current argument string + argString += st[ argPos ] + ' ' ; + + // Mode to next argument + argPos++ ; + + // Make sure modePos skips over this argument + modePosIncrement++ ; + + break ; + case 'I': //Invite? + if(!plus) + theChan->removeMode(Channel::MODE_I); + else + theChan->setMode(Channel::MODE_I); + modeString += st[ modePos ][ charPos ] ; + + break; + case 'P': //Private? + if(!plus) + theChan->removeMode(Channel::MODE_P); + else + theChan->setMode(Channel::MODE_P); + modeString += st[ modePos ][ charPos ] ; + break; + case 'S': //Secret? + if(!plus) + theChan->removeMode(Channel::MODE_S); + else + theChan->setMode(Channel::MODE_S); + + modeString += st[ modePos ][ charPos ] ; + + break; + case 'M': //Moderated? + if(!plus) + theChan->removeMode(Channel::MODE_M); + else + theChan->setMode(Channel::MODE_M); + + modeString += st[ modePos ][ charPos ] ; + + break; + case 'N': //No External Messages? + if(!plus) + theChan->removeMode(Channel::MODE_N); + else + theChan->setMode(Channel::MODE_N); + + modeString += st[ modePos ][ charPos ] ; + + break; + case 'T': //Topic? + if(!plus) + theChan->removeMode(Channel::MODE_T); + else + theChan->setMode(Channel::MODE_T); + modeString += st[ modePos ][ charPos ] ; + break; + case '+': + if( plus ) + { + // Already plus + break ; + } + plus = true ; + modeString += st[ modePos ][ charPos ] ; + break ; + case '-': + if( !plus ) + { + // Already minus + break ; + } + plus = false ; + modeString += st[ modePos ][ charPos ] ; + break ; + default: + // Requires no arguments, just add the mode + // to the modeString + modeString += st[ modePos ][ charPos ] ; + break ; + + } // switch() + } // for() + + modePos += modePosIncrement ; + } // while( modePos < st.size() ) + + bot->ModeAsServer( theChan, modeString + ' ' + argString ) ; + */ + + // Update internal tables. + // This is a cheat, but it makes things so much easier :) + // TODO + // theChan->OnModeChange( theClient->getCharYYXXX(), modeString, argString + //) ; + + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/MODERATECommand.cc b/mod.ccontrol/MODERATECommand.cc index 5df447ef..5b5eddc3 100644 --- a/mod.ccontrol/MODERATECommand.cc +++ b/mod.ccontrol/MODERATECommand.cc @@ -20,68 +20,59 @@ * $Id: MODERATECommand.cc,v 1.16 2006/09/26 17:35:59 kewlio Exp $ */ -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "Constants.h" -#include "ccBadChannel.h" -#include "gnuworld_config.h" +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "Constants.h" +#include "ccBadChannel.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { -bool MODERATECommand::Exec( iClient* theClient, const string& Message ) -{ +bool MODERATECommand::Exec(iClient* theClient, const string& Message) { -StringTokenizer st( Message ) ; -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } + StringTokenizer st(Message); + if (st.size() < 2) { + Usage(theClient); + return true; + } -if(st[1].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d characters", - channel::MaxName); - return false; - } -Channel* theChan = Network->findChannel( st[ 1 ] ) ; -if( NULL == theChan ) - { - bot->Notice( theClient, "Unable to find channel %s\n", - st[ 1 ].c_str() ) ; - return true ; - } -bot->MsgChanLog("MODERATE %s\n",st.assemble(1).c_str()); + if (st[1].size() > channel::MaxName) { + bot->Notice(theClient, "Channel name can't be more than %d characters", channel::MaxName); + return false; + } + Channel* theChan = Network->findChannel(st[1]); + if (NULL == theChan) { + bot->Notice(theClient, "Unable to find channel %s\n", st[1].c_str()); + return true; + } + bot->MsgChanLog("MODERATE %s\n", st.assemble(1).c_str()); -ccBadChannel* Chan = bot->isBadChannel(st[1]); -if(Chan) - { - bot->Notice(theClient,"Sorry, but you can't change modes in " - "this channel because: %s", - Chan->getReason().c_str()); + ccBadChannel* Chan = bot->isBadChannel(st[1]); + if (Chan) { + bot->Notice(theClient, + "Sorry, but you can't change modes in " + "this channel because: %s", + Chan->getReason().c_str()); return false; - } + } -if(theChan->getMode(Channel::MODE_M)) - { - bot->Notice( theClient,"Channel %s is already moderated",st[ 1 ].c_str()); - return false; - } + if (theChan->getMode(Channel::MODE_M)) { + bot->Notice(theClient, "Channel %s is already moderated", st[1].c_str()); + return false; + } -//theChan->setMode(Channel::MODE_M); -bot->Mode( theChan, "+m", string(), true ); -return true; + // theChan->setMode(Channel::MODE_M); + bot->Mode(theChan, "+m", string(), true); + return true; } -} +} // namespace uworld } // namespace gnuworld diff --git a/mod.ccontrol/MODUSERCommand.cc b/mod.ccontrol/MODUSERCommand.cc index ae092268..f61aafd8 100644 --- a/mod.ccontrol/MODUSERCommand.cc +++ b/mod.ccontrol/MODUSERCommand.cc @@ -20,588 +20,481 @@ * $Id: MODUSERCommand.cc,v 1.28 2009/08/28 18:14:44 hidden1 Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "ccUser.h" -#include "misc.h" -#include "Constants.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "ccUser.h" +#include "misc.h" +#include "Constants.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { -bool MODUSERCommand::Exec( iClient* theClient, const string& Message) -{ -StringTokenizer st( Message ) ; +bool MODUSERCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -if(st.size() < 2) - { - Usage(theClient); - return false; - } -//Fetch the oper data base entry -if(st[1].size() > 64) - { - bot->Notice(theClient,"Oper name can't be more than 64 characters"); - return false; - } + if (st.size() < 2) { + Usage(theClient); + return false; + } + // Fetch the oper data base entry + if (st[1].size() > 64) { + bot->Notice(theClient, "Oper name can't be more than 64 characters"); + return false; + } -ccUser* tmpUser = bot->GetOper(st[1]); + ccUser* tmpUser = bot->GetOper(st[1]); -if(!tmpUser) - { - bot->Notice(theClient,"%s isn't on my access list",st[1].c_str()); + if (!tmpUser) { + bot->Notice(theClient, "%s isn't on my access list", st[1].c_str()); return false; - } -//Check if the user got a higher or equal flags than the one he's trying to edit -ccUser* tmpAuth = bot->IsAuth(theClient); -if(!tmpAuth) - { //we should never get here - return false; - } -bot->MsgChanLog("MODUSER %s\n",st[1].c_str()); + } + // Check if the user got a higher or equal flags than the one he's trying to edit + ccUser* tmpAuth = bot->IsAuth(theClient); + if (!tmpAuth) { // we should never get here + return false; + } + bot->MsgChanLog("MODUSER %s\n", st[1].c_str()); -unsigned int AdFlag = tmpAuth->getType(); //Get the admin flag -unsigned int OpFlag = tmpUser->getType(); //Get the oper flag -bool Admin = (AdFlag < operLevel::SMTLEVEL); -bool Same = (tmpUser->getID() == tmpAuth->getID()); + unsigned int AdFlag = tmpAuth->getType(); // Get the admin flag + unsigned int OpFlag = tmpUser->getType(); // Get the oper flag + bool Admin = (AdFlag < operLevel::SMTLEVEL); + bool Same = (tmpUser->getID() == tmpAuth->getID()); -if((Admin) && (AdFlag <= OpFlag) && (!Same)) - { - bot->Notice(theClient,"You can't modify a user who has a higher or " - "equal level to your own."); - return false; - } -else if(AdFlag < OpFlag) - { - bot->Notice(theClient,"You can't modify a user who has a higher level " - "than your own."); - return false; - } -if((Admin) && (strcasecmp(tmpAuth->getServer().c_str(),tmpUser->getServer().c_str()))) - { - bot->Notice(theClient,"You can only modify a user who is associated to " - "the same server as you."); - return false; - } -unsigned int pos = 2; -while(pos < st.size()) - { - if(!strcasecmp(st[pos],"-p")) //Trying to change the password ? - { - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-p option must get new password"); - return false; - } - unsigned int passStat = bot->checkPassword(st[pos+1],tmpUser); - switch(passStat) - { - case password::TOO_SHORT: - bot->Notice(theClient,"Password must be atleast %d " - "characters", - password::MIN_SIZE); - pos+=2; - break; - case password::LIKE_UNAME: - bot->Notice(theClient,"Password can't be the same as the username"); - pos+=2; - break; - case password::PASS_OK: - { - tmpUser->setPassword(bot->CryptPass(st[pos+1])); - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - tmpUser->setPassChangeTS(::time(0)); - if(tmpUser->Update()) - { - bot->Notice(theClient,"Password for %s has been changed to %s", - st[1].c_str(),st[pos+1].c_str()); - } - else - { - bot->Notice(theClient,"Error while changing password for %s",st[1].c_str()); - } - pos+=2; - } - } - } - else if(!strcasecmp(st[pos],"-ah")) //Trying to add a new host ? - { - if((Same) && (AdFlag < operLevel::ADMINLEVEL)) - { - bot->Notice(theClient,"You can't add yourself another host"); - pos+=2; - continue; - } + if ((Admin) && (AdFlag <= OpFlag) && (!Same)) { + bot->Notice(theClient, "You can't modify a user who has a higher or " + "equal level to your own."); + return false; + } else if (AdFlag < OpFlag) { + bot->Notice(theClient, "You can't modify a user who has a higher level " + "than your own."); + return false; + } + if ((Admin) && (strcasecmp(tmpAuth->getServer().c_str(), tmpUser->getServer().c_str()))) { + bot->Notice(theClient, "You can only modify a user who is associated to " + "the same server as you."); + return false; + } + unsigned int pos = 2; + while (pos < st.size()) { + if (!strcasecmp(st[pos], "-p")) // Trying to change the password ? + { + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-p option must get new password"); + return false; + } + unsigned int passStat = bot->checkPassword(st[pos + 1], tmpUser); + switch (passStat) { + case password::TOO_SHORT: + bot->Notice(theClient, + "Password must be atleast %d " + "characters", + password::MIN_SIZE); + pos += 2; + break; + case password::LIKE_UNAME: + bot->Notice(theClient, "Password can't be the same as the username"); + pos += 2; + break; + case password::PASS_OK: { + tmpUser->setPassword(bot->CryptPass(st[pos + 1])); + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + tmpUser->setPassChangeTS(::time(0)); + if (tmpUser->Update()) { + bot->Notice(theClient, "Password for %s has been changed to %s", st[1].c_str(), + st[pos + 1].c_str()); + } else { + bot->Notice(theClient, "Error while changing password for %s", st[1].c_str()); + } + pos += 2; + } + } + } else if (!strcasecmp(st[pos], "-ah")) // Trying to add a new host ? + { + if ((Same) && (AdFlag < operLevel::ADMINLEVEL)) { + bot->Notice(theClient, "You can't add yourself another host"); + pos += 2; + continue; + } - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-ah option must get new hostmask"); - return false; - } - if(st[pos + 1].size() > 128) - { - bot->Notice(theClient,"Hostname can't be more than 128 characters"); - return false; - } - if(!validUserMask(st[pos+1])) - { - bot->Notice(theClient,"Mask '%s' is not a valid mask in the form of *!*@*", - st[pos+1].c_str()); - } - else if(bot->UserGotHost(tmpUser,st[pos+1])) - { - bot->Notice(theClient,"'%s' already has the host (%s) listed.", - st[1].c_str(),st[pos+1].c_str()); - } - else if(bot->AddHost(tmpUser,st[pos+1])) - { - bot->Notice(theClient,"Mask %s added for %s",st[pos+1].c_str(),st[1].c_str()); - } - else - { - bot->Notice(theClient,"Error while adding the mask (%s) for %s", - st[pos+1].c_str(),st[1].c_str()); - } - pos += 2; - } - else if(!strcasecmp(st[pos],"-dh")) //Trying to delete an host ? - { - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-dh option must get a host mask"); - return false; - } - if(st[pos + 1].size() > 128) - { - bot->Notice(theClient,"Hostname can't be more than 128 characters"); - return false; - } - if(!bot->UserGotHost(tmpUser,st[pos+1])) - { - bot->Notice(theClient,"%s doesn't have the host '%s' in my access list", - st[1].c_str(),st[pos+1].c_str()); - } - else if(bot->DelHost(tmpUser,st[pos+1])) - { - bot->Notice(theClient,"Mask '%s' was deleted from %s's access list", - st[pos+1].c_str(),st[1].c_str()); - } - else - { - bot->Notice(theClient,"Error while deleting mask '%s' from %s's access list", - st[pos+1].c_str(),st[1].c_str()); - } - pos += 2; - } - else if(!strcasecmp(st[pos],"-gl")) //Trying to toggle the get of logs - { - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-gl option must get on/off"); - return false; - } - if(!strcasecmp(st[pos+1],"on")) - { - // Only a smt+ can set getlogs to on for an oper - if ((OpFlag < operLevel::ADMINLEVEL) && (AdFlag < operLevel::SMTLEVEL)) - { - bot->Notice(theClient,"-gl can only be set for ADMINS+"); - return false; - } - tmpUser->setLogs(true); - bot->Notice(theClient,"getLogs have been turned on for %s",st[1].c_str()); - } - else if(!strcasecmp(st[pos+1],"off")) - { - tmpUser->setLogs(false); - bot->Notice(theClient,"getLogs have been turned off for %s",st[1].c_str()); - } - else - { - bot->Notice(theClient,"unknown option %s for -gl must be on/off",st[pos+1].c_str()); - return false; - } - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - tmpUser->Update(); - pos += 2; - } + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-ah option must get new hostmask"); + return false; + } + if (st[pos + 1].size() > 128) { + bot->Notice(theClient, "Hostname can't be more than 128 characters"); + return false; + } + if (!validUserMask(st[pos + 1])) { + bot->Notice(theClient, "Mask '%s' is not a valid mask in the form of *!*@*", + st[pos + 1].c_str()); + } else if (bot->UserGotHost(tmpUser, st[pos + 1])) { + bot->Notice(theClient, "'%s' already has the host (%s) listed.", st[1].c_str(), + st[pos + 1].c_str()); + } else if (bot->AddHost(tmpUser, st[pos + 1])) { + bot->Notice(theClient, "Mask %s added for %s", st[pos + 1].c_str(), st[1].c_str()); + } else { + bot->Notice(theClient, "Error while adding the mask (%s) for %s", + st[pos + 1].c_str(), st[1].c_str()); + } + pos += 2; + } else if (!strcasecmp(st[pos], "-dh")) // Trying to delete an host ? + { + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-dh option must get a host mask"); + return false; + } + if (st[pos + 1].size() > 128) { + bot->Notice(theClient, "Hostname can't be more than 128 characters"); + return false; + } + if (!bot->UserGotHost(tmpUser, st[pos + 1])) { + bot->Notice(theClient, "%s doesn't have the host '%s' in my access list", + st[1].c_str(), st[pos + 1].c_str()); + } else if (bot->DelHost(tmpUser, st[pos + 1])) { + bot->Notice(theClient, "Mask '%s' was deleted from %s's access list", + st[pos + 1].c_str(), st[1].c_str()); + } else { + bot->Notice(theClient, "Error while deleting mask '%s' from %s's access list", + st[pos + 1].c_str(), st[1].c_str()); + } + pos += 2; + } else if (!strcasecmp(st[pos], "-gl")) // Trying to toggle the get of logs + { + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-gl option must get on/off"); + return false; + } + if (!strcasecmp(st[pos + 1], "on")) { + // Only a smt+ can set getlogs to on for an oper + if ((OpFlag < operLevel::ADMINLEVEL) && (AdFlag < operLevel::SMTLEVEL)) { + bot->Notice(theClient, "-gl can only be set for ADMINS+"); + return false; + } + tmpUser->setLogs(true); + bot->Notice(theClient, "getLogs have been turned on for %s", st[1].c_str()); + } else if (!strcasecmp(st[pos + 1], "off")) { + tmpUser->setLogs(false); + bot->Notice(theClient, "getLogs have been turned off for %s", st[1].c_str()); + } else { + bot->Notice(theClient, "unknown option %s for -gl must be on/off", + st[pos + 1].c_str()); + return false; + } + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + tmpUser->Update(); + pos += 2; + } - else if(!strcasecmp(st[pos],"-sso")) //Trying to toggle the Single Sign On - { - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-sso option must get on/off"); - return false; - } - if(!strcasecmp(st[pos+1],"on")) - { - tmpUser->setSso(true); - bot->Notice(theClient,"Single Sign On has been turned on for %s",st[1].c_str()); - } - else if(!strcasecmp(st[pos+1],"off")) - { - tmpUser->setSso(false); - bot->Notice(theClient,"Single Sign On has been turned off for %s",st[1].c_str()); - } - else - { - bot->Notice(theClient,"unknown option %s for -sso must be on/off",st[pos+1].c_str()); - return false; - } - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - tmpUser->Update(); - pos += 2; - } + else if (!strcasecmp(st[pos], "-sso")) // Trying to toggle the Single Sign On + { + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-sso option must get on/off"); + return false; + } + if (!strcasecmp(st[pos + 1], "on")) { + tmpUser->setSso(true); + bot->Notice(theClient, "Single Sign On has been turned on for %s", st[1].c_str()); + } else if (!strcasecmp(st[pos + 1], "off")) { + tmpUser->setSso(false); + bot->Notice(theClient, "Single Sign On has been turned off for %s", st[1].c_str()); + } else { + bot->Notice(theClient, "unknown option %s for -sso must be on/off", + st[pos + 1].c_str()); + return false; + } + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + tmpUser->Update(); + pos += 2; + } - else if(!strcasecmp(st[pos],"-ssooo")) //Trying to toggle the Single Sign On if Opered Only - { - if (AdFlag < operLevel::SMTLEVEL) - { - bot->Notice(theClient,"Single sign on with oper requirement can only be modified by SMT+"); - return false; - } - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-ssooo option must get on/off"); - return false; - } - if(!strcasecmp(st[pos+1],"on")) - { - tmpUser->setSsooo(true); - bot->Notice(theClient,"Single sign on with oper requirement has been turned on for %s",st[1].c_str()); - } - else if(!strcasecmp(st[pos+1],"off")) - { - // Only a smt+ can set Ssooo to off for an oper - if (AdFlag < operLevel::SMTLEVEL) - { - bot->Notice(theClient,"Single sign on with oper requirement can only be turned off by SMT+"); - return false; - } - tmpUser->setSsooo(false); - bot->Notice(theClient,"Single sign on with oper requirement has been turned off for %s",st[1].c_str()); - } - else - { - bot->Notice(theClient,"unknown option %s for -ssooo must be on/off",st[pos+1].c_str()); - return false; - } - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - tmpUser->Update(); - pos += 2; - } + else if (!strcasecmp(st[pos], + "-ssooo")) // Trying to toggle the Single Sign On if Opered Only + { + if (AdFlag < operLevel::SMTLEVEL) { + bot->Notice(theClient, + "Single sign on with oper requirement can only be modified by SMT+"); + return false; + } + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-ssooo option must get on/off"); + return false; + } + if (!strcasecmp(st[pos + 1], "on")) { + tmpUser->setSsooo(true); + bot->Notice(theClient, + "Single sign on with oper requirement has been turned on for %s", + st[1].c_str()); + } else if (!strcasecmp(st[pos + 1], "off")) { + // Only a smt+ can set Ssooo to off for an oper + if (AdFlag < operLevel::SMTLEVEL) { + bot->Notice( + theClient, + "Single sign on with oper requirement can only be turned off by SMT+"); + return false; + } + tmpUser->setSsooo(false); + bot->Notice(theClient, + "Single sign on with oper requirement has been turned off for %s", + st[1].c_str()); + } else { + bot->Notice(theClient, "unknown option %s for -ssooo must be on/off", + st[pos + 1].c_str()); + return false; + } + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + tmpUser->Update(); + pos += 2; + } - else if(!strcasecmp(st[pos],"-autoop")) //Trying to toggle autoop - { - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-autoop option must get on/off"); - return false; - } - if(!strcasecmp(st[pos+1],"on")) - { - // Only a smt+ can set AutoOp to on - if (AdFlag < operLevel::SMTLEVEL) - { - bot->Notice(theClient,"-autoop can only be turned on by SMT+"); - return false; - } - tmpUser->setAutoOp(true); - bot->Notice(theClient,"AutoOp has been turned on for %s",st[1].c_str()); - } - else if(!strcasecmp(st[pos+1],"off")) - { - tmpUser->setAutoOp(false); - bot->Notice(theClient,"AutoOp has been turned off for %s",st[1].c_str()); - } - else - { - bot->Notice(theClient,"unknown option %s. -autoop must be on/off",st[pos+1].c_str()); - } - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - tmpUser->Update(); - pos += 2; - } - else if(!strcasecmp(st[pos],"-mt")) //Trying to change the message type - { - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-mt option must get message type"); - return false; - } - if((!strcasecmp(st[pos+1],"N")) || (!strcasecmp(st[pos+1],"NOTICE"))) - { - tmpUser->setNotice(true); - bot->Notice(theClient,"%s will now get NOTICES",st[1].c_str()); - } - else if((!strcasecmp(st[pos+1],"M")) || (!strcasecmp(st[pos+1],"MESSAGE"))) - { - tmpUser->setNotice(false); - bot->Notice(theClient,"%s will now get MESSAGES",st[1].c_str()); - } - else - { - bot->Notice(theClient,"unknown option %s for -mt must be n/m/notice/message",st[pos+1].c_str()); - return false; - } - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - tmpUser->Update(); - pos += 2; - } + else if (!strcasecmp(st[pos], "-autoop")) // Trying to toggle autoop + { + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-autoop option must get on/off"); + return false; + } + if (!strcasecmp(st[pos + 1], "on")) { + // Only a smt+ can set AutoOp to on + if (AdFlag < operLevel::SMTLEVEL) { + bot->Notice(theClient, "-autoop can only be turned on by SMT+"); + return false; + } + tmpUser->setAutoOp(true); + bot->Notice(theClient, "AutoOp has been turned on for %s", st[1].c_str()); + } else if (!strcasecmp(st[pos + 1], "off")) { + tmpUser->setAutoOp(false); + bot->Notice(theClient, "AutoOp has been turned off for %s", st[1].c_str()); + } else { + bot->Notice(theClient, "unknown option %s. -autoop must be on/off", + st[pos + 1].c_str()); + } + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + tmpUser->Update(); + pos += 2; + } else if (!strcasecmp(st[pos], "-mt")) // Trying to change the message type + { + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-mt option must get message type"); + return false; + } + if ((!strcasecmp(st[pos + 1], "N")) || (!strcasecmp(st[pos + 1], "NOTICE"))) { + tmpUser->setNotice(true); + bot->Notice(theClient, "%s will now get NOTICES", st[1].c_str()); + } else if ((!strcasecmp(st[pos + 1], "M")) || (!strcasecmp(st[pos + 1], "MESSAGE"))) { + tmpUser->setNotice(false); + bot->Notice(theClient, "%s will now get MESSAGES", st[1].c_str()); + } else { + bot->Notice(theClient, "unknown option %s for -mt must be n/m/notice/message", + st[pos + 1].c_str()); + return false; + } + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + tmpUser->Update(); + pos += 2; + } - else if(!strcasecmp(st[pos],"-glag")) //Trying to toggle the get of lag reports - { - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-glag option must get on/off"); - return false; - } - if(!strcasecmp(st[pos+1],"on")) - { - tmpUser->setLag(true); - bot->Notice(theClient,"getLag has been turned on for %s",st[1].c_str()); - } - else if(!strcasecmp(st[pos+1],"off")) - { - tmpUser->setLag(false); - bot->Notice(theClient,"getLag has been turned off for %s",st[1].c_str()); - } - else - { - bot->Notice(theClient,"unknown option %s for -glag must be on/off",st[pos+1].c_str()); - return false; - } - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - tmpUser->Update(); - pos += 2; - } + else if (!strcasecmp(st[pos], "-glag")) // Trying to toggle the get of lag reports + { + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-glag option must get on/off"); + return false; + } + if (!strcasecmp(st[pos + 1], "on")) { + tmpUser->setLag(true); + bot->Notice(theClient, "getLag has been turned on for %s", st[1].c_str()); + } else if (!strcasecmp(st[pos + 1], "off")) { + tmpUser->setLag(false); + bot->Notice(theClient, "getLag has been turned off for %s", st[1].c_str()); + } else { + bot->Notice(theClient, "unknown option %s for -glag must be on/off", + st[pos + 1].c_str()); + return false; + } + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + tmpUser->Update(); + pos += 2; + } - else if(!strcasecmp(st[pos],"-s")) //Trying to change the user server - { - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-s option must get a server"); - return false; - } - if(Admin) - { - bot->Notice(theClient,"Sorry, only SMT+ users can change an admins' server"); - return false; - } - if(st[pos + 1].size() > server::MaxName) - { - bot->Notice(theClient,"Server name can't be more than 128 characters"); - return false; - } - string SName = bot->expandDbServer(st[pos+1]); - if(!strcasecmp(SName,"")) - { - bot->Notice(theClient,"I can't see a server in the database that matches %s", - st[pos+1].c_str()); - return false; - } - if(!strcasecmp(tmpUser->getServer(),SName)) - { - bot->Notice(theClient,"%s already is associated with %s",SName.c_str(),SName.c_str()); - pos+=2; - } - else - { - tmpUser->setServer(SName); - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - if(tmpUser->Update()) - { - bot->Notice(theClient,"%s has been associated with %s",st[1].c_str(),SName.c_str()); - } - else - { - bot->Notice(theClient,"Error while associating %s with %s",st[1].c_str(),SName.c_str()); - return false; - } - pos += 2; - } - } - else if(!strcasecmp(st[pos],"-op")) //Trying to toggle needop - { - if(Admin) - { - bot->Notice(theClient,"Sorry, the needop flag is required."); - pos+=2; - continue; - } - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-op option must get on/off"); - return false; - } - if(!strcasecmp(st[pos+1],"on")) - { - tmpUser->setNeedOp(true); - bot->Notice(theClient,"NeedOp has been turned on for %s",st[1].c_str()); - } - else if(!strcasecmp(st[pos+1],"off")) - { - tmpUser->setNeedOp(false); - bot->Notice(theClient,"NeedOp has been turned off for %s",st[1].c_str()); - } - else - { - bot->Notice(theClient,"unknown option %s for -no must be on/off",st[pos+1].c_str()); - } - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - tmpUser->Update(); - pos += 2; - } - else if(!strcasecmp(st[pos],"-ua")) //Trying to update the access? - { - if((AdFlag < operLevel::CODERLEVEL) && (AdFlag <= OpFlag)) - { - bot->Notice(theClient,"You can't update an access for a user who has a higher " - "or equal level to your own."); - } - else - { - tmpUser->updateAccessFromFlags(); - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - if(tmpUser->Update()) - { - bot->Notice(theClient,"Successfully updated access level for %s.",st[1].c_str()); - } - else - { - bot->Notice(theClient,"Error while updating access level for %s.",st[1].c_str()); - } - } - pos++; - } - else if(!strcasecmp(st[pos],"-uf")) //Trying to update the user flags - { - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-uf option must get an argument."); - return false; - } - unsigned int NewF; - if(!strcasecmp(st[pos+1],"CODER")) - { - NewF = operLevel::CODERLEVEL; - } - else if(!strcasecmp(st[pos+1],"SMT")) - { - NewF = operLevel::SMTLEVEL; - } - else if(!strcasecmp(st[pos+1],"ADMIN")) - { - NewF = operLevel::ADMINLEVEL; - } - else if(!strcasecmp(st[pos+1],"OPER")) - { - NewF = operLevel::OPERLEVEL; - } - else - { - bot->Notice(theClient,"Bad option for -uf, must be CODER, SMT, ADMIN or OPER"); - NewF = 0; - } - if(NewF > 0) - { - if((AdFlag < operLevel::CODERLEVEL) && (AdFlag <= NewF)) - { - bot->Notice(theClient,"You can't update the flags to a higher or equal " - "level than your own."); - } - else - { - tmpUser->setType(NewF); - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - if(tmpUser->Update()) - { - bot->Notice(theClient,"Successfully updated flags for %s.",st[1].c_str()); - } - else - { - bot->Notice(theClient,"Error while updating flags for %s.",st[1].c_str()); - } - } - } - pos+=2; - } - - else if(!strcasecmp(st[pos],"-x")) //Trying to set account - { - string cAC = theClient->getAccount(); - string dbAC = tmpUser->getAccount(); - if (!Same) { - bot->Notice(theClient,"You can only set an account for yourself"); - return false; - } - if (theClient->isModeR()) { - if (!strcasecmp(cAC,dbAC)) { - bot->Notice(theClient, "Your account is already set to %s", cAC.c_str()); - return false; - } - ccUser *otherUser; - if ((otherUser = bot->GetOperByAC(cAC))) { - bot->Notice(theClient, "This account already belongs to another user: %s", otherUser->getUserName().c_str()); - return false; - } - tmpUser->setAccount(cAC); - tmpUser->setAccountID(theClient->getAccountID()); - bot->accountsMapAdd(tmpUser, cAC); - bot->Notice(theClient,"Successfully set your account to: %s.",cAC.c_str()); - } - else { - if (!dbAC.empty()) - bot->accountsMapDel(dbAC); - tmpUser->setAccount(""); - tmpUser->setAccountID(0); - bot->Notice(theClient,"Successfully removed your account."); - } + else if (!strcasecmp(st[pos], "-s")) // Trying to change the user server + { + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-s option must get a server"); + return false; + } + if (Admin) { + bot->Notice(theClient, "Sorry, only SMT+ users can change an admins' server"); + return false; + } + if (st[pos + 1].size() > server::MaxName) { + bot->Notice(theClient, "Server name can't be more than 128 characters"); + return false; + } + string SName = bot->expandDbServer(st[pos + 1]); + if (!strcasecmp(SName, "")) { + bot->Notice(theClient, "I can't see a server in the database that matches %s", + st[pos + 1].c_str()); + return false; + } + if (!strcasecmp(tmpUser->getServer(), SName)) { + bot->Notice(theClient, "%s already is associated with %s", SName.c_str(), + SName.c_str()); + pos += 2; + } else { + tmpUser->setServer(SName); + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + if (tmpUser->Update()) { + bot->Notice(theClient, "%s has been associated with %s", st[1].c_str(), + SName.c_str()); + } else { + bot->Notice(theClient, "Error while associating %s with %s", st[1].c_str(), + SName.c_str()); + return false; + } + pos += 2; + } + } else if (!strcasecmp(st[pos], "-op")) // Trying to toggle needop + { + if (Admin) { + bot->Notice(theClient, "Sorry, the needop flag is required."); + pos += 2; + continue; + } + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-op option must get on/off"); + return false; + } + if (!strcasecmp(st[pos + 1], "on")) { + tmpUser->setNeedOp(true); + bot->Notice(theClient, "NeedOp has been turned on for %s", st[1].c_str()); + } else if (!strcasecmp(st[pos + 1], "off")) { + tmpUser->setNeedOp(false); + bot->Notice(theClient, "NeedOp has been turned off for %s", st[1].c_str()); + } else { + bot->Notice(theClient, "unknown option %s for -no must be on/off", + st[pos + 1].c_str()); + } + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + tmpUser->Update(); + pos += 2; + } else if (!strcasecmp(st[pos], "-ua")) // Trying to update the access? + { + if ((AdFlag < operLevel::CODERLEVEL) && (AdFlag <= OpFlag)) { + bot->Notice(theClient, "You can't update an access for a user who has a higher " + "or equal level to your own."); + } else { + tmpUser->updateAccessFromFlags(); + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + if (tmpUser->Update()) { + bot->Notice(theClient, "Successfully updated access level for %s.", + st[1].c_str()); + } else { + bot->Notice(theClient, "Error while updating access level for %s.", + st[1].c_str()); + } + } + pos++; + } else if (!strcasecmp(st[pos], "-uf")) // Trying to update the user flags + { + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-uf option must get an argument."); + return false; + } + unsigned int NewF; + if (!strcasecmp(st[pos + 1], "CODER")) { + NewF = operLevel::CODERLEVEL; + } else if (!strcasecmp(st[pos + 1], "SMT")) { + NewF = operLevel::SMTLEVEL; + } else if (!strcasecmp(st[pos + 1], "ADMIN")) { + NewF = operLevel::ADMINLEVEL; + } else if (!strcasecmp(st[pos + 1], "OPER")) { + NewF = operLevel::OPERLEVEL; + } else { + bot->Notice(theClient, "Bad option for -uf, must be CODER, SMT, ADMIN or OPER"); + NewF = 0; + } + if (NewF > 0) { + if ((AdFlag < operLevel::CODERLEVEL) && (AdFlag <= NewF)) { + bot->Notice(theClient, "You can't update the flags to a higher or equal " + "level than your own."); + } else { + tmpUser->setType(NewF); + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + if (tmpUser->Update()) { + bot->Notice(theClient, "Successfully updated flags for %s.", st[1].c_str()); + } else { + bot->Notice(theClient, "Error while updating flags for %s.", st[1].c_str()); + } + } + } + pos += 2; + } - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - if(!tmpUser->Update()) - { - bot->Notice(theClient,"Error while updating account"); - } - pos+=2; - } - else if(!strcasecmp(st[pos],"-e")) //Trying to change email - { - if((pos + 1) >= st.size()) - { - bot->Notice(theClient,"-e option requires an e-mail address."); - return false; - } - tmpUser->setEmail(st[pos+1]); - tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); - if(tmpUser->Update()) - { - bot->Notice(theClient,"Successfully updated e-mail address for %s.",st[1].c_str()); - } - else - { - bot->Notice(theClient,"Error while updating e-mail address for %s.",st[1].c_str()); - } - pos+=2; - } - else - { - bot->Notice(theClient,"Unknown option %s",st[pos].c_str()); - pos++; - } - } -return true; -} + else if (!strcasecmp(st[pos], "-x")) // Trying to set account + { + string cAC = theClient->getAccount(); + string dbAC = tmpUser->getAccount(); + if (!Same) { + bot->Notice(theClient, "You can only set an account for yourself"); + return false; + } + if (theClient->isModeR()) { + if (!strcasecmp(cAC, dbAC)) { + bot->Notice(theClient, "Your account is already set to %s", cAC.c_str()); + return false; + } + ccUser* otherUser; + if ((otherUser = bot->GetOperByAC(cAC))) { + bot->Notice(theClient, "This account already belongs to another user: %s", + otherUser->getUserName().c_str()); + return false; + } + tmpUser->setAccount(cAC); + tmpUser->setAccountID(theClient->getAccountID()); + bot->accountsMapAdd(tmpUser, cAC); + bot->Notice(theClient, "Successfully set your account to: %s.", cAC.c_str()); + } else { + if (!dbAC.empty()) + bot->accountsMapDel(dbAC); + tmpUser->setAccount(""); + tmpUser->setAccountID(0); + bot->Notice(theClient, "Successfully removed your account."); + } + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + if (!tmpUser->Update()) { + bot->Notice(theClient, "Error while updating account"); + } + pos += 2; + } else if (!strcasecmp(st[pos], "-e")) // Trying to change email + { + if ((pos + 1) >= st.size()) { + bot->Notice(theClient, "-e option requires an e-mail address."); + return false; + } + tmpUser->setEmail(st[pos + 1]); + tmpUser->setLast_Updated_By(theClient->getRealNickUserHost()); + if (tmpUser->Update()) { + bot->Notice(theClient, "Successfully updated e-mail address for %s.", + st[1].c_str()); + } else { + bot->Notice(theClient, "Error while updating e-mail address for %s.", + st[1].c_str()); + } + pos += 2; + } else { + bot->Notice(theClient, "Unknown option %s", st[pos].c_str()); + pos++; + } + } + return true; } -} + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/NEWPASSCommand.cc b/mod.ccontrol/NEWPASSCommand.cc index 2f291338..735208ff 100644 --- a/mod.ccontrol/NEWPASSCommand.cc +++ b/mod.ccontrol/NEWPASSCommand.cc @@ -20,75 +20,63 @@ * $Id: NEWPASSCommand.cc,v 1.24 2009/07/25 18:12:34 hidden1 Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "Constants.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "Constants.h" +#include "gnuworld_config.h" -namespace gnuworld -{ -using std::string ; +namespace gnuworld { +using std::string; -namespace uworld -{ +namespace uworld { -bool NEWPASSCommand::Exec( iClient* theClient, const string& Message) -{ -StringTokenizer st( Message ) ; - -if( st.size() < 2 ) - { - Usage(theClient); - return true; - } +bool NEWPASSCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -//Fetch the user authentication entry -ccUser *theUser = bot->IsAuth(theClient); + if (st.size() < 2) { + Usage(theClient); + return true; + } -if(!theUser) - { - bot->Notice(theClient,"You have to be logged in to use this command"); - return false; - } -unsigned int passRet = bot->checkPassword(st[1],theUser); -switch(passRet) - { - case password::TOO_SHORT: - bot->Notice(theClient,"Password must be at least %d characters", - password::MIN_SIZE); - break; - case password::LIKE_UNAME: - bot->Notice(theClient,"Password can't be similar to your username"); - break; - case password::PASS_OK: - { - theUser->setPassword(bot->CryptPass(st[1])); - theUser->setPassChangeTS(::time(0)); - if(theUser->Update()) - { - bot->Notice(theClient,"Password changed!"); - bot->MsgChanLog("(%s) - %s: Changed Password\n", - theUser->getUserName().c_str(), - theClient->getRealNickUserHost().c_str()); - return true; - } - else - { - bot->Notice(theClient,"Error while changing password"); - bot->MsgChanLog("Error while changing password for (%s) - %s\n", - theUser->getUserName().c_str(), - theClient->getRealNickUserHost().c_str(),st.assemble(1).c_str()); - return true; - } - } - } -return true; -} + // Fetch the user authentication entry + ccUser* theUser = bot->IsAuth(theClient); + if (!theUser) { + bot->Notice(theClient, "You have to be logged in to use this command"); + return false; + } + unsigned int passRet = bot->checkPassword(st[1], theUser); + switch (passRet) { + case password::TOO_SHORT: + bot->Notice(theClient, "Password must be at least %d characters", password::MIN_SIZE); + break; + case password::LIKE_UNAME: + bot->Notice(theClient, "Password can't be similar to your username"); + break; + case password::PASS_OK: { + theUser->setPassword(bot->CryptPass(st[1])); + theUser->setPassChangeTS(::time(0)); + if (theUser->Update()) { + bot->Notice(theClient, "Password changed!"); + bot->MsgChanLog("(%s) - %s: Changed Password\n", theUser->getUserName().c_str(), + theClient->getRealNickUserHost().c_str()); + return true; + } else { + bot->Notice(theClient, "Error while changing password"); + bot->MsgChanLog("Error while changing password for (%s) - %s\n", + theUser->getUserName().c_str(), + theClient->getRealNickUserHost().c_str(), st.assemble(1).c_str()); + return true; + } + } + } + return true; } -} + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/NOMODECommand.cc b/mod.ccontrol/NOMODECommand.cc index 2d942cb8..9c1a2d4e 100644 --- a/mod.ccontrol/NOMODECommand.cc +++ b/mod.ccontrol/NOMODECommand.cc @@ -20,95 +20,77 @@ * $Id: NOMODECommand.cc,v 1.8 2006/09/26 17:36:00 kewlio Exp $ */ -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" -#include "ccBadChannel.h" -#include "gnuworld_config.h" +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" +#include "ccBadChannel.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { -bool NOMODECommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -if( st.size() < 3 ) - { - Usage( theClient ) ; - return true ; - } +bool NOMODECommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + if (st.size() < 3) { + Usage(theClient); + return true; + } -if(st[2].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d characters", - channel::MaxName); - return false; - } + if (st[2].size() > channel::MaxName) { + bot->Notice(theClient, "Channel name can't be more than %d characters", channel::MaxName); + return false; + } -bot->MsgChanLog("NOMODE %s\n",st.assemble(1).c_str()); - -if(!strcasecmp(st[1],"ADD")) - { - if( st.size() < 4 ) - { - Usage( theClient ) ; - return true ; - } + bot->MsgChanLog("NOMODE %s\n", st.assemble(1).c_str()); - ccBadChannel* NewChannel = bot->isBadChannel(st[2]); - if(NewChannel) - { - bot->Notice(theClient,"There is already a NOMODE entry for channel %s",st[2].c_str()); - return true; - } - - NewChannel = new (std::nothrow) ccBadChannel(st[2], - st.assemble(3), - theClient->getRealNickUserHost()); - assert(NewChannel != NULL); - if(!NewChannel->Insert(bot->SQLDb)) - { - bot->Notice(theClient,"Error while inserting the NOMODE entry into the database"); - return false; - } - bot->addBadChannel(NewChannel); - bot->Notice(theClient,"NOMODE for %s added successfully.", st[2].c_str()); - } -else if(!strcasecmp(st[1],"REM")) - { - ccBadChannel* OldChannel = bot->isBadChannel(st[2]); - if(!OldChannel) - { - bot->Notice(theClient,"There is no NOMODE entry for channel %s",st[2].c_str()); - return true; - } - - bot->remBadChannel(OldChannel); - if(!OldChannel->Delete(bot->SQLDb)) - { - bot->Notice(theClient,"Error while removing the NOMODE entry from the database"); - return false; - } - delete OldChannel; - bot->Notice(theClient,"NOMODE for %s removed successfully.", st[2].c_str()); - } -else - { - bot->Notice(theClient,"NOMODE must get ADD/REM as first parameter"); - return true; - } + if (!strcasecmp(st[1], "ADD")) { + if (st.size() < 4) { + Usage(theClient); + return true; + } - -return true ; + ccBadChannel* NewChannel = bot->isBadChannel(st[2]); + if (NewChannel) { + bot->Notice(theClient, "There is already a NOMODE entry for channel %s", st[2].c_str()); + return true; + } + + NewChannel = new (std::nothrow) + ccBadChannel(st[2], st.assemble(3), theClient->getRealNickUserHost()); + assert(NewChannel != NULL); + if (!NewChannel->Insert(bot->SQLDb)) { + bot->Notice(theClient, "Error while inserting the NOMODE entry into the database"); + return false; + } + bot->addBadChannel(NewChannel); + bot->Notice(theClient, "NOMODE for %s added successfully.", st[2].c_str()); + } else if (!strcasecmp(st[1], "REM")) { + ccBadChannel* OldChannel = bot->isBadChannel(st[2]); + if (!OldChannel) { + bot->Notice(theClient, "There is no NOMODE entry for channel %s", st[2].c_str()); + return true; + } + + bot->remBadChannel(OldChannel); + if (!OldChannel->Delete(bot->SQLDb)) { + bot->Notice(theClient, "Error while removing the NOMODE entry from the database"); + return false; + } + delete OldChannel; + bot->Notice(theClient, "NOMODE for %s removed successfully.", st[2].c_str()); + } else { + bot->Notice(theClient, "NOMODE must get ADD/REM as first parameter"); + return true; + } + + return true; } -} // namepsace uworld +} // namespace uworld } // namespace gnuworld diff --git a/mod.ccontrol/OPCommand.cc b/mod.ccontrol/OPCommand.cc index e34a4fef..850ce9af 100644 --- a/mod.ccontrol/OPCommand.cc +++ b/mod.ccontrol/OPCommand.cc @@ -20,102 +20,87 @@ * $Id: OPCommand.cc,v 1.16 2006/09/26 17:36:00 kewlio Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "Constants.h" -#include "ccBadChannel.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool OPCommand::Exec( iClient* theClient, const string& Message ) -{ -bool foundUser = false; - -StringTokenizer st( Message ) ; -if( st.size() < 3 ) - { - Usage( theClient ) ; - return true ; - } - -if(st[1].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d characters", - channel::MaxName); - return false; - } - -Channel* theChan = Network->findChannel( st[ 1 ] ) ; -if( NULL == theChan ) - { - bot->Notice( theClient, "Unable to find channel %s\n", - st[ 1 ].c_str() ) ; - return true ; - } - -ccBadChannel* Chan = bot->isBadChannel(st[1]); -if(Chan) - { - bot->Notice(theClient,"Sorry, but you can't change modes in " - "this channel because: %s", - Chan->getReason().c_str()); - return false; - } - -iClient* Target = 0; - -// Use a std::set<> here to ensure that the same user is not -// included more than once. - -bot->MsgChanLog("OP %s\n",st.assemble(1).c_str()); -string modes = "+"; -string args=""; - -for( StringTokenizer::size_type i = 2 ; i < st.size() ; ++i ) - { - Target = Network->findNick( st[ i ] ) ; - if( 0 == Target ) - { - continue ; - } - - ChannelUser* tmpChanUser = theChan->findUser(Target) ; - if( 0 == tmpChanUser ) - { - continue ; - } - /* ok, the user is on the channel - flag it */ - foundUser = true; - modes +="o"; - args +=st[i]+ " "; - - } // for - -if (!foundUser) -{ - bot->Notice(theClient, "I'm sorry, I couldn't find anyone to op in %s!", - st[1].c_str()); - return false; -} -if( !args.empty() ) - { - bot->Mode(theChan,modes,args,true); - } -return true ; +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "Constants.h" +#include "ccBadChannel.h" +#include "gnuworld_config.h" + +namespace gnuworld { + +using std::string; + +namespace uworld { + +bool OPCommand::Exec(iClient* theClient, const string& Message) { + bool foundUser = false; + + StringTokenizer st(Message); + if (st.size() < 3) { + Usage(theClient); + return true; + } + + if (st[1].size() > channel::MaxName) { + bot->Notice(theClient, "Channel name can't be more than %d characters", channel::MaxName); + return false; + } + + Channel* theChan = Network->findChannel(st[1]); + if (NULL == theChan) { + bot->Notice(theClient, "Unable to find channel %s\n", st[1].c_str()); + return true; + } + + ccBadChannel* Chan = bot->isBadChannel(st[1]); + if (Chan) { + bot->Notice(theClient, + "Sorry, but you can't change modes in " + "this channel because: %s", + Chan->getReason().c_str()); + return false; + } + + iClient* Target = 0; + + // Use a std::set<> here to ensure that the same user is not + // included more than once. + + bot->MsgChanLog("OP %s\n", st.assemble(1).c_str()); + string modes = "+"; + string args = ""; + + for (StringTokenizer::size_type i = 2; i < st.size(); ++i) { + Target = Network->findNick(st[i]); + if (0 == Target) { + continue; + } + + ChannelUser* tmpChanUser = theChan->findUser(Target); + if (0 == tmpChanUser) { + continue; + } + /* ok, the user is on the channel - flag it */ + foundUser = true; + modes += "o"; + args += st[i] + " "; + + } // for + + if (!foundUser) { + bot->Notice(theClient, "I'm sorry, I couldn't find anyone to op in %s!", st[1].c_str()); + return false; + } + if (!args.empty()) { + bot->Mode(theChan, modes, args, true); + } + return true; } -} +} // namespace uworld } // namespace gnuworld - diff --git a/mod.ccontrol/REMCOMMANDCommand.cc b/mod.ccontrol/REMCOMMANDCommand.cc index bc97f4f3..e7674673 100644 --- a/mod.ccontrol/REMCOMMANDCommand.cc +++ b/mod.ccontrol/REMCOMMANDCommand.cc @@ -20,224 +20,184 @@ * $Id: REMCOMMANDCommand.cc,v 1.16 2009/06/13 06:43:34 hidden1 Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "ccUser.h" -#include "misc.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool REMCOMMANDCommand::Exec( iClient* theClient, const string& Message) -{ -StringTokenizer st( Message ) ; -ccUser* theUser; -if( st.size() < 3 ) - { - Usage(theClient); - return true; - } - -ccUser *AClient = bot->IsAuth( theClient ); - -if( NULL == AClient ) - { - bot->Notice( theClient, "You must be authenticated to use this command." ) ; - return true ; - } - -if(st[1].size() > 64) - { - bot->Notice(theClient,"Oper name can't be more than 64 characters"); - return false; - } -//Fetch the user record from the database - -bool AllOpers = false; -bool AllAdmins = false; -bool AllSmts = false; -bool AllCoders = false; -if(!strcasecmp(st[1],"-allopers")) - { - if (AClient->getType() < operLevel::CODERLEVEL) - { - bot->Notice(theClient, "-allopers: This is coder level"); - return true; - } - AllOpers = true; - } - -else if(!strcasecmp(st[1],"-alladmins")) - { - if (AClient->getType() < operLevel::CODERLEVEL) - { - bot->Notice(theClient, "-alladmins: This is coder level"); - return true; - } - AllAdmins = true; - } - -else if(!strcasecmp(st[1],"-allsmts")) - { - if (AClient->getType() < operLevel::CODERLEVEL) - { - bot->Notice(theClient, "-allsmts: This is coder level"); - return true; - } - AllSmts = true; - } - -else if(!strcasecmp(st[1],"-allcoders")) - { - if (AClient->getType() < operLevel::CODERLEVEL) - { - bot->Notice(theClient, "-allcoders: This is coder level"); - return true; - } - AllCoders = true; - } - -//ccUser* theUser = bot->GetUser(st[1]); -else - theUser = bot->GetOper(st[1]); - -if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders && !theUser) - { - bot->Notice(theClient,"I can't find oper %s",st[1].c_str()); - return false; - } - -if(st[2].size() > 128) - { - bot->Notice(theClient,"Command name can't be more than 128 characters"); - return false; - } -Command* Comm = bot->findCommandInMem(st[2]); -if(!Comm) - { - bot->Notice(theClient,"Command %s does not exist!",st[2].c_str()); - return false; - } - -bot->MsgChanLog("REMCOMMAND %s\n",st.assemble(1).c_str()); -if(!strcasecmp(AClient->getUserName(),st[1])) - { - bot->Notice(theClient,"You can't remove your own command access!"); - return false; - } - -list ccList; -if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) - { - ccList.push_back(theUser); - } -else - { - ccontrol::usersconstiterator uItr = bot->usersmap_begin(); - for (; uItr != bot->usersmap_end(); uItr++) - { - if (AllCoders) - { - ccList.push_back(uItr->second); - } - else if ((AllSmts) && (uItr->second->getType() <= operLevel::SMTLEVEL)) - { - ccList.push_back(uItr->second); - } - else if ((AllAdmins) && (uItr->second->getType() <= operLevel::ADMINLEVEL)) - { - ccList.push_back(uItr->second); - } - else if ((AllOpers) && (uItr->second->getType() <= operLevel::OPERLEVEL)) - { - ccList.push_back(uItr->second); - } - } - } - -int count = 0; -bool sentOnce = false; -for (list::iterator Itr = ccList.begin(); Itr != ccList.end(); Itr++) - { - theUser = *Itr; - - bool Admin = (AClient->getType() < operLevel::SMTLEVEL); - - if((Admin) && (AClient->getType() <= theUser->getType())) - { - bot->Notice(theClient,"You can't modify a user who has an equal or higher " - "access level to your own."); - return false; - } - else if(!(Admin) && (AClient->getType() < theUser->getType())) - { - bot->Notice(theClient,"You can't modify a user who has a higher access " - "level than you."); - return false; - } - if((Admin) && (strcasecmp(AClient->getServer(),theUser->getServer()))) - { - bot->Notice(theClient,"You can only modify a user who is associated with the same server as you"); - return false; - } - if ((!strcasecmp(st[2],"ADDCOMMAND")) && (theUser->getType() == operLevel::CODERLEVEL)) - { - if (!sentOnce) - bot->Notice(theClient, "You can't remove the ADDCOMMAND command from a coder."); - sentOnce = true; - if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) - return false; - else - continue; - } - - - if(!(theUser->gotAccess(Comm))) - { - if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) - { - bot->Notice(theClient,"%s doesn't have access to %s",theUser->getUserName().c_str(),st[2].c_str()); - return false; - } - else - continue; - } - //Remove the command - theUser->removeCommand(Comm); - theUser->setLast_Updated_By(theClient->getRealNickUserHost()); - if(theUser->Update()) - { - bot->Notice(theClient,"Successfully removed the command from %s",theUser->getUserName().c_str()); - count++; - if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) - return true; - else - continue; - } - else - { - bot->Notice(theClient,"Error while removing command from %s",theUser->getUserName().c_str()); - if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) - return false; - else - continue; - } - - } -bot->Notice(theClient, "Removed %s access from %d users", Comm->getName().c_str(), count); -return true; - +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "ccUser.h" +#include "misc.h" +#include "gnuworld_config.h" + +namespace gnuworld { + +using std::string; + +namespace uworld { + +bool REMCOMMANDCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + ccUser* theUser; + if (st.size() < 3) { + Usage(theClient); + return true; + } + + ccUser* AClient = bot->IsAuth(theClient); + + if (NULL == AClient) { + bot->Notice(theClient, "You must be authenticated to use this command."); + return true; + } + + if (st[1].size() > 64) { + bot->Notice(theClient, "Oper name can't be more than 64 characters"); + return false; + } + // Fetch the user record from the database + + bool AllOpers = false; + bool AllAdmins = false; + bool AllSmts = false; + bool AllCoders = false; + if (!strcasecmp(st[1], "-allopers")) { + if (AClient->getType() < operLevel::CODERLEVEL) { + bot->Notice(theClient, "-allopers: This is coder level"); + return true; + } + AllOpers = true; + } + + else if (!strcasecmp(st[1], "-alladmins")) { + if (AClient->getType() < operLevel::CODERLEVEL) { + bot->Notice(theClient, "-alladmins: This is coder level"); + return true; + } + AllAdmins = true; + } + + else if (!strcasecmp(st[1], "-allsmts")) { + if (AClient->getType() < operLevel::CODERLEVEL) { + bot->Notice(theClient, "-allsmts: This is coder level"); + return true; + } + AllSmts = true; + } + + else if (!strcasecmp(st[1], "-allcoders")) { + if (AClient->getType() < operLevel::CODERLEVEL) { + bot->Notice(theClient, "-allcoders: This is coder level"); + return true; + } + AllCoders = true; + } + + // ccUser* theUser = bot->GetUser(st[1]); + else + theUser = bot->GetOper(st[1]); + + if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders && !theUser) { + bot->Notice(theClient, "I can't find oper %s", st[1].c_str()); + return false; + } + + if (st[2].size() > 128) { + bot->Notice(theClient, "Command name can't be more than 128 characters"); + return false; + } + Command* Comm = bot->findCommandInMem(st[2]); + if (!Comm) { + bot->Notice(theClient, "Command %s does not exist!", st[2].c_str()); + return false; + } + + bot->MsgChanLog("REMCOMMAND %s\n", st.assemble(1).c_str()); + if (!strcasecmp(AClient->getUserName(), st[1])) { + bot->Notice(theClient, "You can't remove your own command access!"); + return false; + } + + list ccList; + if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) { + ccList.push_back(theUser); + } else { + ccontrol::usersconstiterator uItr = bot->usersmap_begin(); + for (; uItr != bot->usersmap_end(); uItr++) { + if (AllCoders) { + ccList.push_back(uItr->second); + } else if ((AllSmts) && (uItr->second->getType() <= operLevel::SMTLEVEL)) { + ccList.push_back(uItr->second); + } else if ((AllAdmins) && (uItr->second->getType() <= operLevel::ADMINLEVEL)) { + ccList.push_back(uItr->second); + } else if ((AllOpers) && (uItr->second->getType() <= operLevel::OPERLEVEL)) { + ccList.push_back(uItr->second); + } + } + } + + int count = 0; + bool sentOnce = false; + for (list::iterator Itr = ccList.begin(); Itr != ccList.end(); Itr++) { + theUser = *Itr; + + bool Admin = (AClient->getType() < operLevel::SMTLEVEL); + + if ((Admin) && (AClient->getType() <= theUser->getType())) { + bot->Notice(theClient, "You can't modify a user who has an equal or higher " + "access level to your own."); + return false; + } else if (!(Admin) && (AClient->getType() < theUser->getType())) { + bot->Notice(theClient, "You can't modify a user who has a higher access " + "level than you."); + return false; + } + if ((Admin) && (strcasecmp(AClient->getServer(), theUser->getServer()))) { + bot->Notice(theClient, + "You can only modify a user who is associated with the same server as you"); + return false; + } + if ((!strcasecmp(st[2], "ADDCOMMAND")) && (theUser->getType() == operLevel::CODERLEVEL)) { + if (!sentOnce) + bot->Notice(theClient, "You can't remove the ADDCOMMAND command from a coder."); + sentOnce = true; + if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) + return false; + else + continue; + } + + if (!(theUser->gotAccess(Comm))) { + if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) { + bot->Notice(theClient, "%s doesn't have access to %s", + theUser->getUserName().c_str(), st[2].c_str()); + return false; + } else + continue; + } + // Remove the command + theUser->removeCommand(Comm); + theUser->setLast_Updated_By(theClient->getRealNickUserHost()); + if (theUser->Update()) { + bot->Notice(theClient, "Successfully removed the command from %s", + theUser->getUserName().c_str()); + count++; + if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) + return true; + else + continue; + } else { + bot->Notice(theClient, "Error while removing command from %s", + theUser->getUserName().c_str()); + if (!AllOpers && !AllAdmins && !AllSmts && !AllCoders) + return false; + else + continue; + } + } + bot->Notice(theClient, "Removed %s access from %d users", Comm->getName().c_str(), count); + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/REMGCHANCommand.cc b/mod.ccontrol/REMGCHANCommand.cc index bb906422..720ed8dd 100644 --- a/mod.ccontrol/REMGCHANCommand.cc +++ b/mod.ccontrol/REMGCHANCommand.cc @@ -20,57 +20,52 @@ * $Id: REMGCHANCommand.cc,v 1.14 2006/09/26 17:36:00 kewlio Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { // remgline user@host -bool REMGCHANCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; +bool REMGCHANCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } + if (st.size() < 2) { + Usage(theClient); + return true; + } -if((st[1].substr(0,1) != "#") || (st[1].size() > channel::MaxName)) - { - bot->Notice(theClient,"Invalid channel name. It must begin with # and can't be " - "more than %d characters in length.", - channel::MaxName); - return false; - } -bot->MsgChanLog("REMGCHAN %s\n",st.assemble(1).c_str()); + if ((st[1].substr(0, 1) != "#") || (st[1].size() > channel::MaxName)) { + bot->Notice(theClient, + "Invalid channel name. It must begin with # and can't be " + "more than %d characters in length.", + channel::MaxName); + return false; + } + bot->MsgChanLog("REMGCHAN %s\n", st.assemble(1).c_str()); -ccGline *tmpGline = bot->findGline(st[1]); -if(tmpGline != NULL) - { - if(!tmpGline->Delete()) - bot->MsgChanLog("Error while removing gline for channel %s from the db\n",st[1].c_str()); - bot->remGline(tmpGline); - delete tmpGline; - } -//bot->setRemoving(st[1]); -server->removeGline( st [ 1 ] ,bot); -//bot->unSetRemoving(); -return true ; + ccGline* tmpGline = bot->findGline(st[1]); + if (tmpGline != NULL) { + if (!tmpGline->Delete()) + bot->MsgChanLog("Error while removing gline for channel %s from the db\n", + st[1].c_str()); + bot->remGline(tmpGline); + delete tmpGline; + } + // bot->setRemoving(st[1]); + server->removeGline(st[1], bot); + // bot->unSetRemoving(); + return true; } -} +} // namespace uworld } // namespace gnuworld - diff --git a/mod.ccontrol/REMGLINECommand.cc b/mod.ccontrol/REMGLINECommand.cc index a752530d..bd6b88d4 100644 --- a/mod.ccontrol/REMGLINECommand.cc +++ b/mod.ccontrol/REMGLINECommand.cc @@ -20,76 +20,66 @@ * $Id: REMGLINECommand.cc,v 1.27 2009/06/14 01:29:54 hidden1 Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { // remgline user@host -bool REMGLINECommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; +bool REMGLINECommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } -//bot->MsgChanLog("REMGLINE %s\n",st.assemble(1).c_str()); + if (st.size() < 2) { + Usage(theClient); + return true; + } + // bot->MsgChanLog("REMGLINE %s\n",st.assemble(1).c_str()); -if(st[1].substr(0,1) == "#") - { - bot->Notice(theClient,"Please use REMGCHAN to remove a BADCHAN gline"); - return false; - } -if(st[1].substr(0,1) == "$") - { - bot->Notice(theClient,"Please use REMSGLINE to remove a realname gline"); - return false; - } + if (st[1].substr(0, 1) == "#") { + bot->Notice(theClient, "Please use REMGCHAN to remove a BADCHAN gline"); + return false; + } + if (st[1].substr(0, 1) == "$") { + bot->Notice(theClient, "Please use REMSGLINE to remove a realname gline"); + return false; + } -if (st[1].find('@',1) == string::npos) - { - bot->Notice(theClient, "Invalid G-line. Please specify a user@. i.e: REMGLINE *@ip"); - return false; - } + if (st[1].find('@', 1) == string::npos) { + bot->Notice(theClient, "Invalid G-line. Please specify a user@. i.e: REMGLINE *@ip"); + return false; + } -unsigned int dummy; + unsigned int dummy; -string gHost = st[1]; + string gHost = st[1]; -if(bot->checkGline(gHost,0,dummy) & gline::HUH_NO_HOST) - { - bot->Notice(theClient,"Please use REMSGLINE to remove a this gline"); - return false; - } - -ccGline *tmpGline = bot->findGline(st[1]); -if(tmpGline != NULL) - { - if(!tmpGline->Delete()) - bot->MsgChanLog("Error while removing gline for host %s from the db\n",st[1].c_str()); - bot->remGline(tmpGline); - delete tmpGline; - } -bot->MsgChanLog("REMGLINE %s %s\n", st[1].c_str(), st.assemble(2).c_str()); -server->removeGline(st[1], bot); -bot->Notice(theClient, "Removal of gline succeeded: %s\n", st[1].c_str()); -return true ; -} + if (bot->checkGline(gHost, 0, dummy) & gline::HUH_NO_HOST) { + bot->Notice(theClient, "Please use REMSGLINE to remove a this gline"); + return false; + } + ccGline* tmpGline = bot->findGline(st[1]); + if (tmpGline != NULL) { + if (!tmpGline->Delete()) + bot->MsgChanLog("Error while removing gline for host %s from the db\n", st[1].c_str()); + bot->remGline(tmpGline); + delete tmpGline; + } + bot->MsgChanLog("REMGLINE %s %s\n", st[1].c_str(), st.assemble(2).c_str()); + server->removeGline(st[1], bot); + bot->Notice(theClient, "Removal of gline succeeded: %s\n", st[1].c_str()); + return true; } -} // namespace gnuworld +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/REMOPERCHANCommand.cc b/mod.ccontrol/REMOPERCHANCommand.cc index 899ebdc0..b91b9b95 100644 --- a/mod.ccontrol/REMOPERCHANCommand.cc +++ b/mod.ccontrol/REMOPERCHANCommand.cc @@ -20,59 +20,47 @@ * $Id: REMOPERCHANCommand.cc,v 1.12 2006/09/26 17:36:00 kewlio Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; // remoperchan #channel -namespace uworld -{ +namespace uworld { -bool REMOPERCHANCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } +bool REMOPERCHANCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + if (st.size() < 2) { + Usage(theClient); + return true; + } -if(st[1].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d characters", - channel::MaxName); - return false; - } -string chanName = st[ 1 ] ; -if( '#' != chanName[ 0 ] ) - { - bot->Notice( theClient, "Invalid channel name" ) ; - return true ; - } + if (st[1].size() > channel::MaxName) { + bot->Notice(theClient, "Channel name can't be more than %d characters", channel::MaxName); + return false; + } + string chanName = st[1]; + if ('#' != chanName[0]) { + bot->Notice(theClient, "Invalid channel name"); + return true; + } -if( bot->removeOperChan( chanName ) ) - { - bot->Notice( theClient, "Removal of %s as oper chan SUCCEEDED", - chanName.c_str() ) ; - } -else - { - bot->Notice( theClient, "Removal of %s as oper chan FAILED", - chanName.c_str() ) ; - } -return true ; + if (bot->removeOperChan(chanName)) { + bot->Notice(theClient, "Removal of %s as oper chan SUCCEEDED", chanName.c_str()); + } else { + bot->Notice(theClient, "Removal of %s as oper chan FAILED", chanName.c_str()); + } + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/REMOVEIGNORECommand.cc b/mod.ccontrol/REMOVEIGNORECommand.cc index 341c1725..93bf342d 100644 --- a/mod.ccontrol/REMOVEIGNORECommand.cc +++ b/mod.ccontrol/REMOVEIGNORECommand.cc @@ -20,65 +20,55 @@ * $Id: REMOVEIGNORECommand.cc,v 1.11 2006/09/26 17:36:01 kewlio Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; // remoperchan #channel -namespace uworld -{ +namespace uworld { -bool REMOVEIGNORECommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } -bot->MsgChanLog("REMIGNORE %s\n",st.assemble(1).c_str()); +bool REMOVEIGNORECommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + if (st.size() < 2) { + Usage(theClient); + return true; + } + bot->MsgChanLog("REMIGNORE %s\n", st.assemble(1).c_str()); -string::size_type atPos = st[ 1 ].find_first_of( '@' ) ; -if( string::npos == atPos ) - { - iClient *igClient = Network->findNick(st[1]); - if(!igClient) - { - bot->Notice(theClient,"There is no such user as %s",st[1].c_str()); - return false; - } - if(bot->removeIgnore(igClient) == IGNORE_REMOVED) - { - bot->Notice(theClient,"Successfully removed ignore for user %s",st[1].c_str()); - bot->MsgChanLog("Removed ignore for %s by request of %s\n",st[1].c_str(),theClient->getNickName().c_str()); - } + string::size_type atPos = st[1].find_first_of('@'); + if (string::npos == atPos) { + iClient* igClient = Network->findNick(st[1]); + if (!igClient) { + bot->Notice(theClient, "There is no such user as %s", st[1].c_str()); + return false; + } + if (bot->removeIgnore(igClient) == IGNORE_REMOVED) { + bot->Notice(theClient, "Successfully removed ignore for user %s", st[1].c_str()); + bot->MsgChanLog("Removed ignore for %s by request of %s\n", st[1].c_str(), + theClient->getNickName().c_str()); + } - else - bot->Notice(theClient,"Can't find ignore for user %s",st[1].c_str()); - } -else - if(bot->removeIgnore(st[1]) == IGNORE_REMOVED) - { - bot->Notice(theClient,"Successfully removed ignore for host %s",st[1].c_str()); - bot->MsgChanLog("Removed ignore for %s by request of %s\n",st[1].c_str(),theClient->getNickName().c_str()); - } - else - bot->Notice(theClient,"Can't find ignore for host %s",st[1].c_str()); + else + bot->Notice(theClient, "Can't find ignore for user %s", st[1].c_str()); + } else if (bot->removeIgnore(st[1]) == IGNORE_REMOVED) { + bot->Notice(theClient, "Successfully removed ignore for host %s", st[1].c_str()); + bot->MsgChanLog("Removed ignore for %s by request of %s\n", st[1].c_str(), + theClient->getNickName().c_str()); + } else + bot->Notice(theClient, "Can't find ignore for host %s", st[1].c_str()); -return true; + return true; } -} +} // namespace uworld } // namespace gnuworld - diff --git a/mod.ccontrol/REMSERVERCommand.cc b/mod.ccontrol/REMSERVERCommand.cc index 08867b53..25ca3c4f 100644 --- a/mod.ccontrol/REMSERVERCommand.cc +++ b/mod.ccontrol/REMSERVERCommand.cc @@ -20,96 +20,84 @@ * $Id: REMSERVERCommand.cc,v 1.14 2007/08/28 16:10:03 dan_karrels Exp $ */ -#include -#include -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "Constants.h" -#include "gnuworld_config.h" -#include "dbHandle.h" - -namespace gnuworld -{ -using std::endl ; -using std::ends ; -using std::stringstream ; -using std::string ; - -namespace uworld -{ - -bool REMSERVERCommand::Exec( iClient* theClient, const string& Message ) -{ - -StringTokenizer st( Message ) ; - -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } -if(st[1].size() > server::MaxName) - { - bot->Notice(theClient,"Server name can't be longer than %d characters", - server::MaxName); - return false; - } - -ccServer* tmpServer = bot->getServer(st[1]); -if(!tmpServer) - { - bot->Notice(theClient, "Server %s is not in my database!\n",st [ 1 ].c_str()); - return false; - } +#include +#include +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "Constants.h" +#include "gnuworld_config.h" +#include "dbHandle.h" + +namespace gnuworld { +using std::endl; +using std::ends; +using std::string; +using std::stringstream; + +namespace uworld { + +bool REMSERVERCommand::Exec(iClient* theClient, const string& Message) { + + StringTokenizer st(Message); + + if (st.size() < 2) { + Usage(theClient); + return true; + } + if (st[1].size() > server::MaxName) { + bot->Notice(theClient, "Server name can't be longer than %d characters", server::MaxName); + return false; + } -bot->MsgChanLog("REMSERVER %s\n",st.assemble(1).c_str()); + ccServer* tmpServer = bot->getServer(st[1]); + if (!tmpServer) { + bot->Notice(theClient, "Server %s is not in my database!\n", st[1].c_str()); + return false; + } -stringstream theQuery; -theQuery << User::Query - << " Where lower(server) = '" - << string_lower(tmpServer->getName()) << "'" - << ends; + bot->MsgChanLog("REMSERVER %s\n", st.assemble(1).c_str()); + stringstream theQuery; + theQuery << User::Query << " Where lower(server) = '" << string_lower(tmpServer->getName()) + << "'" << ends; -elog << theQuery.str().c_str() << endl; + elog << theQuery.str().c_str() << endl; -if( !bot->SQLDb->Exec( theQuery.str(), true ) ) -//if(PGRES_TUPLES_OK != status) - { - bot->Notice(theClient,"Database error, unable to remove the server."); + if (!bot->SQLDb->Exec(theQuery.str(), true)) + // if(PGRES_TUPLES_OK != status) + { + bot->Notice(theClient, "Database error, unable to remove the server."); return false; - } - -if(bot->SQLDb->Tuples() > 0) - { - bot->Notice(theClient,"There are %d users added to that server, please remove them first", - bot->SQLDb->Tuples()); - return false; - } + } -bot->MsgChanLog("Removing server '%s' from the database at the request of %s\n", - tmpServer->getName().c_str(),theClient->getNickName().c_str()); - -//NewServer->setName(SName); -if(tmpServer->Delete()) - { - bot->Notice(theClient,"Server \002%s\002 has been successfully removed\n",tmpServer->getName().c_str()); - bot->remServer(tmpServer); - delete tmpServer; - return true; - } -else - { - bot->Notice(theClient,"Database error while removing server \002%s\002\n",tmpServer->getName().c_str()); - return false; - } -return true; + if (bot->SQLDb->Tuples() > 0) { + bot->Notice(theClient, "There are %d users added to that server, please remove them first", + bot->SQLDb->Tuples()); + return false; + } + + bot->MsgChanLog("Removing server '%s' from the database at the request of %s\n", + tmpServer->getName().c_str(), theClient->getNickName().c_str()); + + // NewServer->setName(SName); + if (tmpServer->Delete()) { + bot->Notice(theClient, "Server \002%s\002 has been successfully removed\n", + tmpServer->getName().c_str()); + bot->remServer(tmpServer); + delete tmpServer; + return true; + } else { + bot->Notice(theClient, "Database error while removing server \002%s\002\n", + tmpServer->getName().c_str()); + return false; + } + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/REMSGLINECommand.cc b/mod.ccontrol/REMSGLINECommand.cc index 1edd483d..fd086f1d 100644 --- a/mod.ccontrol/REMSGLINECommand.cc +++ b/mod.ccontrol/REMSGLINECommand.cc @@ -20,74 +20,66 @@ * $Id: REMSGLINECommand.cc,v 1.8 2006/09/26 17:36:01 kewlio Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "gnuworld_config.h" -namespace gnuworld -{ -using std::string ; +namespace gnuworld { +using std::string; -namespace uworld -{ +namespace uworld { // remgline user@host -bool REMSGLINECommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; +bool REMSGLINECommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } + if (st.size() < 2) { + Usage(theClient); + return true; + } -StringTokenizer::size_type pos = 1 ; + StringTokenizer::size_type pos = 1; -string cmdStr = "REMSGLINE "; + string cmdStr = "REMSGLINE "; -bool ForceRemove = (!strcasecmp(st[pos],"-fr")); -if (ForceRemove && (st.size() < 3)) -{ - Usage(theClient); - return true; -} + bool ForceRemove = (!strcasecmp(st[pos], "-fr")); + if (ForceRemove && (st.size() < 3)) { + Usage(theClient); + return true; + } -if (ForceRemove) -{ - cmdStr += "-fr "; - pos++; -} + if (ForceRemove) { + cmdStr += "-fr "; + pos++; + } -if(st[pos].substr(0,1) == "#") - { - bot->Notice(theClient,"Please use REMGCHAN to remove a BADCHAN gline"); - return false; - } -string Ident = extractNickUser(st[pos]); -string Hostname = extractHostIP(st[pos]); -if (Ident.empty()) - Hostname = st[pos]; -string sgHost; -//If CIDR mask is specified, help out and calculate the CIDR address -if (Hostname.find('/') != string::npos) - fixToCIDR64(Hostname); -if (!Ident.empty()) - sgHost = Ident +'@'+ Hostname; -else - sgHost = Hostname; -cmdStr += sgHost; -bot->removeAllMatchingGlines(sgHost, ForceRemove); -bot->MsgChanLog("%s\n",cmdStr.c_str()); -bot->Notice( theClient, "Removal of gline (%s) succeeded\n",sgHost.c_str() ) ; + if (st[pos].substr(0, 1) == "#") { + bot->Notice(theClient, "Please use REMGCHAN to remove a BADCHAN gline"); + return false; + } + string Ident = extractNickUser(st[pos]); + string Hostname = extractHostIP(st[pos]); + if (Ident.empty()) + Hostname = st[pos]; + string sgHost; + // If CIDR mask is specified, help out and calculate the CIDR address + if (Hostname.find('/') != string::npos) + fixToCIDR64(Hostname); + if (!Ident.empty()) + sgHost = Ident + '@' + Hostname; + else + sgHost = Hostname; + cmdStr += sgHost; + bot->removeAllMatchingGlines(sgHost, ForceRemove); + bot->MsgChanLog("%s\n", cmdStr.c_str()); + bot->Notice(theClient, "Removal of gline (%s) succeeded\n", sgHost.c_str()); -return true ; + return true; } -} +} // namespace uworld } // namespace gnuworld - diff --git a/mod.ccontrol/REMUSERCommand.cc b/mod.ccontrol/REMUSERCommand.cc index 8d23c065..872eae1e 100644 --- a/mod.ccontrol/REMUSERCommand.cc +++ b/mod.ccontrol/REMUSERCommand.cc @@ -20,92 +20,79 @@ * $Id: REMUSERCommand.cc,v 1.14 2006/09/26 17:36:01 kewlio Exp $ */ -#include -#include -#include -#include "Network.h" -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "Network.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { -bool REMUSERCommand::Exec( iClient* theClient, const string& Message) -{ -StringTokenizer st( Message ) ; +bool REMUSERCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -if( st.size() < 2 ) - { - Usage(theClient); - return true; - } -//Fetch the user record from the database -ccUser* theUser = bot->GetOper(st[1]); -if (!theUser) - { - bot->Notice(theClient,"Oper %s does not exist in database, " - "check your handle and try again",st[1].c_str()); - return false; - } -ccUser* tempAuth = bot->IsAuth(theClient); + if (st.size() < 2) { + Usage(theClient); + return true; + } + // Fetch the user record from the database + ccUser* theUser = bot->GetOper(st[1]); + if (!theUser) { + bot->Notice(theClient, + "Oper %s does not exist in database, " + "check your handle and try again", + st[1].c_str()); + return false; + } + ccUser* tempAuth = bot->IsAuth(theClient); -if(!tempAuth) - { //we should never get here - return false; - } -if((tempAuth->getType() <= theUser->getType()) - && (tempAuth->getType() < operLevel::CODERLEVEL)) - { - bot->Notice(theClient,"You can't remove an oper who has a higher or equal " - " access level to you."); - return false; - } -if(((tempAuth->getType() < operLevel::SMTLEVEL)) && - (strcasecmp(tempAuth->getServer(),theUser->getServer()))) - { - bot->Notice(theClient,"You can't remove opers from other servers"); - return false; - } -bot->MsgChanLog("REMUSER %s\n",st.assemble(1).c_str()); + if (!tempAuth) { // we should never get here + return false; + } + if ((tempAuth->getType() <= theUser->getType()) && + (tempAuth->getType() < operLevel::CODERLEVEL)) { + bot->Notice(theClient, "You can't remove an oper who has a higher or equal " + " access level to you."); + return false; + } + if (((tempAuth->getType() < operLevel::SMTLEVEL)) && + (strcasecmp(tempAuth->getServer(), theUser->getServer()))) { + bot->Notice(theClient, "You can't remove opers from other servers"); + return false; + } + bot->MsgChanLog("REMUSER %s\n", st.assemble(1).c_str()); -if(bot->DeleteOper(string_lower(st[1]))) - { - bot->Notice(theClient,"Successfully deleted oper: %s",st[1].c_str()); - - //Check if the user is authenticate - if(theUser->getClients().size() > 0) - { - vector::iterator Itr; - vector Clients = theUser->getClients(); - bot->Notice(theClient, "Deauthenticated the following online clients:"); - for (Itr = Clients.begin(); Itr != Clients.end(); Itr++) - { - iClient* tClient = *Itr; - bot->Notice(theClient, " %s", tClient->getRealNickUserHost().c_str()); - if(tClient) - bot->Notice(tClient,"You have been removed from my access list, " - "and have been deauthenticated."); + if (bot->DeleteOper(string_lower(st[1]))) { + bot->Notice(theClient, "Successfully deleted oper: %s", st[1].c_str()); - } - } - bot->deAuthUser(theUser); - delete theUser; - return true; - } -else - { - bot->Notice(theClient,"Error while deleting oper: %s",st[1].c_str()); - return false; - } -} - -} + // Check if the user is authenticate + if (theUser->getClients().size() > 0) { + vector::iterator Itr; + vector Clients = theUser->getClients(); + bot->Notice(theClient, "Deauthenticated the following online clients:"); + for (Itr = Clients.begin(); Itr != Clients.end(); Itr++) { + iClient* tClient = *Itr; + bot->Notice(theClient, " %s", tClient->getRealNickUserHost().c_str()); + if (tClient) + bot->Notice(tClient, "You have been removed from my access list, " + "and have been deauthenticated."); + } + } + bot->deAuthUser(theUser); + delete theUser; + return true; + } else { + bot->Notice(theClient, "Error while deleting oper: %s", st[1].c_str()); + return false; + } } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/REOPCommand.cc b/mod.ccontrol/REOPCommand.cc index 315b342b..2d8f9480 100644 --- a/mod.ccontrol/REOPCommand.cc +++ b/mod.ccontrol/REOPCommand.cc @@ -1,5 +1,5 @@ /** - * REOPCommand.cc + * REOPCommand.cc * Clears all channel ops, and reops the specified nick * * This program is free software; you can redistribute it and/or @@ -19,91 +19,80 @@ * * $Id: REOPCommand.cc,v 1.7 2006/09/26 17:36:01 kewlio Exp $ */ -#include -#include -#include "Network.h" -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" -#include "ccBadChannel.h" -#include "gnuworld_config.h" +#include +#include +#include "Network.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" +#include "ccBadChannel.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::vector ; using gnuworld::iClient; +using std::string; +using std::vector; -namespace uworld -{ +namespace uworld { -bool REOPCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; +bool REOPCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -if( st.size() < 3 ) - { - Usage( theClient ) ; - return true ; - } + if (st.size() < 3) { + Usage(theClient); + return true; + } -if(st[1].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d characters", - channel::MaxName); - return false; - } + if (st[1].size() > channel::MaxName) { + bot->Notice(theClient, "Channel name can't be more than %d characters", channel::MaxName); + return false; + } -Channel* theChan = Network->findChannel( st[ 1 ] ) ; -if( NULL == theChan ) - { - bot->Notice( theClient, "Unable to find channel %s", - st[ 1 ].c_str() ) ; - return true ; - } + Channel* theChan = Network->findChannel(st[1]); + if (NULL == theChan) { + bot->Notice(theClient, "Unable to find channel %s", st[1].c_str()); + return true; + } -if(bot->isOperChan(theChan)) - { - bot->Notice(theClient,"You can't reop an oper channel."); - return false; - } + if (bot->isOperChan(theChan)) { + bot->Notice(theClient, "You can't reop an oper channel."); + return false; + } -iClient* reopClient = Network->findNick(st[2]); -if(!reopClient) - { - bot->Notice(theClient,"I can't find %s online",st[2].c_str()); - return true; - } + iClient* reopClient = Network->findNick(st[2]); + if (!reopClient) { + bot->Notice(theClient, "I can't find %s online", st[2].c_str()); + return true; + } -bot->MsgChanLog("REOP %s\n",st.assemble(1).c_str()); -ccBadChannel* Chan = bot->isBadChannel(st[1]); -if(Chan) - { - bot->Notice(theClient,"Sorry, but you can't change modes in " - "this channel because: %s", - Chan->getReason().c_str()); + bot->MsgChanLog("REOP %s\n", st.assemble(1).c_str()); + ccBadChannel* Chan = bot->isBadChannel(st[1]); + if (Chan) { + bot->Notice(theClient, + "Sorry, but you can't change modes in " + "this channel because: %s", + Chan->getReason().c_str()); return false; - } + } -/* check if the user to be opped is actually in the channel! */ -ChannelUser* tmpChanUser = theChan->findUser(reopClient); -if (0 == tmpChanUser) -{ - bot->Notice(theClient, "Sorry, but that user is not in the channel."); - return false; -} + /* check if the user to be opped is actually in the channel! */ + ChannelUser* tmpChanUser = theChan->findUser(reopClient); + if (0 == tmpChanUser) { + bot->Notice(theClient, "Sorry, but that user is not in the channel."); + return false; + } -// First, clear all ops -bot->ClearMode( theChan, string( "o" ), true ) ; + // First, clear all ops + bot->ClearMode(theChan, string("o"), true); -/* Now, op the proper user - use mode instead of op so the ccontrol user - doesnt have to enter the channel first */ -bot->Mode(theChan,"+o",st[2],true); + /* Now, op the proper user - use mode instead of op so the ccontrol user + doesnt have to enter the channel first */ + bot->Mode(theChan, "+o", st[2], true); -return true; + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/SAYCommand.cc b/mod.ccontrol/SAYCommand.cc index 4acef9d1..49f45600 100644 --- a/mod.ccontrol/SAYCommand.cc +++ b/mod.ccontrol/SAYCommand.cc @@ -20,91 +20,64 @@ * $Id: SAYCommand.cc,v 1.8 2006/09/26 17:36:01 kewlio Exp $ */ -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "gnuworld_config.h" +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { -bool SAYCommand::Exec( iClient* theClient, const string& Message) -{ +bool SAYCommand::Exec(iClient* theClient, const string& Message) { -StringTokenizer st( Message ) ; -string Numeric; -string Target; -if(st.size() < 4) - { - Usage(theClient); - return true; - } + StringTokenizer st(Message); + string Numeric; + string Target; + if (st.size() < 4) { + Usage(theClient); + return true; + } -bot->MsgChanLog("%s\n",st.assemble(0).c_str()); -if(!strcasecmp(st[1].c_str(),"-s")) - { - Numeric = bot->getUplink()->getCharYY(); - } -else if(!strcasecmp(st[1].c_str(),"-b")) - { - Numeric = bot->getCharYYXXX(); - } -else - { - bot->Notice(theClient,"First argument must be -s for server, or -b for bot"); - return true; - } + bot->MsgChanLog("%s\n", st.assemble(0).c_str()); + if (!strcasecmp(st[1].c_str(), "-s")) { + Numeric = bot->getUplink()->getCharYY(); + } else if (!strcasecmp(st[1].c_str(), "-b")) { + Numeric = bot->getCharYYXXX(); + } else { + bot->Notice(theClient, "First argument must be -s for server, or -b for bot"); + return true; + } -if(!strcasecmp(st[2].substr(0,1),"#")) - { - if(!Network->findChannel(st[2])) - { - bot->Notice(theClient,"Sorry, but i can't find channel %s", - st[2].c_str()); - return true; - } - else - { - Target = st[2]; - } - } -else - { - iClient* tClient = Network->findNick(st[2]); - if(!tClient) - { - bot->Notice(theClient,"Sorry, but i can't find nick: %s", - st[2].c_str()); - return true; - } - else - { - Target = tClient->getCharYYXXX(); - } - } + if (!strcasecmp(st[2].substr(0, 1), "#")) { + if (!Network->findChannel(st[2])) { + bot->Notice(theClient, "Sorry, but i can't find channel %s", st[2].c_str()); + return true; + } else { + Target = st[2]; + } + } else { + iClient* tClient = Network->findNick(st[2]); + if (!tClient) { + bot->Notice(theClient, "Sorry, but i can't find nick: %s", st[2].c_str()); + return true; + } else { + Target = tClient->getCharYYXXX(); + } + } -if (!match("SAY",st[0])) -{ - bot->Write("%s P %s :%s", - Numeric.c_str(), - Target.c_str(), - st.assemble(3).c_str()); -} else { - bot->Write("%s P %s :%cACTION %s%c", - Numeric.c_str(), - Target.c_str(), - 1, st.assemble(3).c_str(), 1); -} -return true ; -} - -} + if (!match("SAY", st[0])) { + bot->Write("%s P %s :%s", Numeric.c_str(), Target.c_str(), st.assemble(3).c_str()); + } else { + bot->Write("%s P %s :%cACTION %s%c", Numeric.c_str(), Target.c_str(), 1, + st.assemble(3).c_str(), 1); + } + return true; } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/SCANCommand.cc b/mod.ccontrol/SCANCommand.cc index bbbabf35..f2995536 100644 --- a/mod.ccontrol/SCANCommand.cc +++ b/mod.ccontrol/SCANCommand.cc @@ -20,224 +20,184 @@ * $Id: SCANCommand.cc,v 1.14 2006/09/26 17:36:01 kewlio Exp $ */ -#include -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "misc.h" -#include "match.h" -#include "Network.h" -#include "Constants.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool SCANCommand::Exec( iClient* theClient, const string& Message ) -{ - -StringTokenizer st( Message ) ; - - -if( st.size() < 3 ) - { - Usage(theClient); - return true; - } - -bot->MsgChanLog("SCAN %s\n",st.assemble(1).c_str()); - -typedef list clientsList; - -bool showUsers = false; -bool showIdentReport = false; -bool realHostLook = false; -bool fakeHostLook = false; -bool nameLook = false; -unsigned int pos = 1; -string userName; -string hostName; -string realName; -string ClientInfo; -const iClient* curClient; -typedef map identMapType; -identMapType identMap; -clientsList cList; - -for(pos = 1; pos < st.size() ; ) - { - if(!strcasecmp(st[pos],"-v")) - { - showUsers = true; - ++pos; - } - else if(!strcasecmp(st[pos],"-i")) - { - showIdentReport = true; - ++pos; - } - else if(!strcasecmp(st[pos],"-h")) - { - if(pos +1 >= st.size()) - { - bot->Notice(theClient,"-h must get a host to scan for"); - return true; - } - if((nameLook) || (fakeHostLook)) - { - bot->Notice(theClient,"You can't specify more than one scanning option"); - return true; - } - realHostLook = true; - hostName = st[pos+1]; - pos+=2; - } - else if(!strcasecmp(st[pos],"-fh")) - { - if(pos +1 >= st.size()) - { - bot->Notice(theClient,"-fh must get a host to scan for"); - return true; - } - if((nameLook) || (realHostLook)) - { - bot->Notice(theClient,"You can't specify more than one scanning option"); - return true; - } - fakeHostLook = true; - hostName = st[pos+1]; - pos+=2; - } - - else if(!strcasecmp(st[pos],"-n")) - { - if(pos +1 >= st.size()) - { - bot->Notice(theClient,"-n must get a real name to scan for"); - return true; - } - if((realHostLook) || (fakeHostLook)) - { - bot->Notice(theClient,"You can't specify more than one scanning option"); - return true; - } - nameLook = true; - realName = st[pos+1]; - pos+=2; - } - else - { - bot->Notice(theClient,"SCAN command can only get -h , -fh or -n "); - return true; - } - } -if(fakeHostLook) - { - if(string::npos == hostName.find_first_of("@")) - { - hostName = string("*@" + hostName); - } - cList = Network->matchUserHost(hostName); - } -else if(realHostLook) - { - if(string::npos == hostName.find_first_of("@")) - { - hostName = string("*@" + hostName); - } - cList = Network->matchRealUserHost(hostName); - } -else if(nameLook) - { - cList = Network->matchRealName(realName); - } -else - { - bot->Notice(theClient,"You didn't specify a search type (-h/-fh/-n) - please try again"); - return true; - } -if( (cList.size() > scan::MAX_SHOW) && (showUsers)) - { - bot->Notice(theClient,"There were %d users matching this search, only 15 will be shown", - cList.size()); - } -else - { - bot->Notice(theClient,"There were %d users matching this search",cList.size()); - } - -unsigned int shown = 0; -unsigned int ident_nonidented = 0; -unsigned int ident_count = 0; - -if(showUsers) - { - const ChannelUser* curChannel; - string ClientInfo; - for(clientsList::iterator cptr = cList.begin();((cptr!=cList.end()) && (shown < 15));++cptr) - { - curClient = *cptr; - ClientInfo = curClient->getNickUserHost(); - if(!curClient->getMode(iClient::MODE_SERVICES)) //Dont show channels for +k users - { - for( iClient::const_channelIterator ptr = curClient->channels_begin() ; - ptr != curClient->channels_end() ; ++ptr ) - { - ClientInfo += " "; - curChannel = (*ptr)->findUser(const_cast< iClient* >(curClient)); - if (((*ptr)->getMode(Channel::MODE_S)) || ((*ptr)->getMode(Channel::MODE_P))) - ClientInfo += "!"; - if(curChannel->isModeO()) - { - ClientInfo += "@"; - } - if(curChannel->isModeV()) - { - ClientInfo += "+"; - } - ClientInfo += (*ptr)->getName(); - } - ++shown; - } - bot->Notice(theClient,"%s",ClientInfo.c_str()); - } - } - -/* do ident report here (if selected) */ -if(showIdentReport) -{ - /* ok, show the report */ - for (clientsList::iterator cptr = cList.begin(); (cptr!=cList.end()); ++cptr) - { - /* cycle the userlist and gather stats */ - curClient = *cptr; - ClientInfo = curClient->getNickUserHost(); - userName = curClient->getUserName(); - if (userName[0]=='~') - { - /* unidented client */ - ident_nonidented++; - } else { - /* idented client */ - identMap[userName]++; - if (identMap[userName] == 1) - ident_count++; - } - } - bot->Notice(theClient, "Ident report: %d unidented clients, %d unique idents", - ident_nonidented, ident_count); -} - -return true; -} +#include +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "misc.h" +#include "match.h" +#include "Network.h" +#include "Constants.h" +#include "gnuworld_config.h" +namespace gnuworld { + +using std::string; + +namespace uworld { + +bool SCANCommand::Exec(iClient* theClient, const string& Message) { + + StringTokenizer st(Message); + + if (st.size() < 3) { + Usage(theClient); + return true; + } + + bot->MsgChanLog("SCAN %s\n", st.assemble(1).c_str()); + + typedef list clientsList; + + bool showUsers = false; + bool showIdentReport = false; + bool realHostLook = false; + bool fakeHostLook = false; + bool nameLook = false; + unsigned int pos = 1; + string userName; + string hostName; + string realName; + string ClientInfo; + const iClient* curClient; + typedef map identMapType; + identMapType identMap; + clientsList cList; + + for (pos = 1; pos < st.size();) { + if (!strcasecmp(st[pos], "-v")) { + showUsers = true; + ++pos; + } else if (!strcasecmp(st[pos], "-i")) { + showIdentReport = true; + ++pos; + } else if (!strcasecmp(st[pos], "-h")) { + if (pos + 1 >= st.size()) { + bot->Notice(theClient, "-h must get a host to scan for"); + return true; + } + if ((nameLook) || (fakeHostLook)) { + bot->Notice(theClient, "You can't specify more than one scanning option"); + return true; + } + realHostLook = true; + hostName = st[pos + 1]; + pos += 2; + } else if (!strcasecmp(st[pos], "-fh")) { + if (pos + 1 >= st.size()) { + bot->Notice(theClient, "-fh must get a host to scan for"); + return true; + } + if ((nameLook) || (realHostLook)) { + bot->Notice(theClient, "You can't specify more than one scanning option"); + return true; + } + fakeHostLook = true; + hostName = st[pos + 1]; + pos += 2; + } + + else if (!strcasecmp(st[pos], "-n")) { + if (pos + 1 >= st.size()) { + bot->Notice(theClient, "-n must get a real name to scan for"); + return true; + } + if ((realHostLook) || (fakeHostLook)) { + bot->Notice(theClient, "You can't specify more than one scanning option"); + return true; + } + nameLook = true; + realName = st[pos + 1]; + pos += 2; + } else { + bot->Notice(theClient, + "SCAN command can only get -h , -fh or -n "); + return true; + } + } + if (fakeHostLook) { + if (string::npos == hostName.find_first_of("@")) { + hostName = string("*@" + hostName); + } + cList = Network->matchUserHost(hostName); + } else if (realHostLook) { + if (string::npos == hostName.find_first_of("@")) { + hostName = string("*@" + hostName); + } + cList = Network->matchRealUserHost(hostName); + } else if (nameLook) { + cList = Network->matchRealName(realName); + } else { + bot->Notice(theClient, "You didn't specify a search type (-h/-fh/-n) - please try again"); + return true; + } + if ((cList.size() > scan::MAX_SHOW) && (showUsers)) { + bot->Notice(theClient, "There were %d users matching this search, only 15 will be shown", + cList.size()); + } else { + bot->Notice(theClient, "There were %d users matching this search", cList.size()); + } + + unsigned int shown = 0; + unsigned int ident_nonidented = 0; + unsigned int ident_count = 0; + + if (showUsers) { + const ChannelUser* curChannel; + string ClientInfo; + for (clientsList::iterator cptr = cList.begin(); ((cptr != cList.end()) && (shown < 15)); + ++cptr) { + curClient = *cptr; + ClientInfo = curClient->getNickUserHost(); + if (!curClient->getMode(iClient::MODE_SERVICES)) // Dont show channels for +k users + { + for (iClient::const_channelIterator ptr = curClient->channels_begin(); + ptr != curClient->channels_end(); ++ptr) { + ClientInfo += " "; + curChannel = (*ptr)->findUser(const_cast(curClient)); + if (((*ptr)->getMode(Channel::MODE_S)) || ((*ptr)->getMode(Channel::MODE_P))) + ClientInfo += "!"; + if (curChannel->isModeO()) { + ClientInfo += "@"; + } + if (curChannel->isModeV()) { + ClientInfo += "+"; + } + ClientInfo += (*ptr)->getName(); + } + ++shown; + } + bot->Notice(theClient, "%s", ClientInfo.c_str()); + } + } + + /* do ident report here (if selected) */ + if (showIdentReport) { + /* ok, show the report */ + for (clientsList::iterator cptr = cList.begin(); (cptr != cList.end()); ++cptr) { + /* cycle the userlist and gather stats */ + curClient = *cptr; + ClientInfo = curClient->getNickUserHost(); + userName = curClient->getUserName(); + if (userName[0] == '~') { + /* unidented client */ + ident_nonidented++; + } else { + /* idented client */ + identMap[userName]++; + if (identMap[userName] == 1) + ident_count++; + } + } + bot->Notice(theClient, "Ident report: %d unidented clients, %d unique idents", + ident_nonidented, ident_count); + } + + return true; } -} + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/SCANGLINECommand.cc b/mod.ccontrol/SCANGLINECommand.cc index 45f1fd29..8378c1c1 100644 --- a/mod.ccontrol/SCANGLINECommand.cc +++ b/mod.ccontrol/SCANGLINECommand.cc @@ -19,56 +19,51 @@ * * $Id: SCANGLINECommand.cc,v 1.13 2006/09/26 17:36:01 kewlio Exp $ */ -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "gnuworld_config.h" +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "gnuworld_config.h" -namespace gnuworld -{ -using std::string ; +namespace gnuworld { +using std::string; -namespace uworld -{ +namespace uworld { -bool SCANGLINECommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } +bool SCANGLINECommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + if (st.size() < 2) { + Usage(theClient); + return true; + } -bot->MsgChanLog("SCANGLINE %s\n",st.assemble(1).c_str()); + bot->MsgChanLog("SCANGLINE %s\n", st.assemble(1).c_str()); -bot->listGlines(theClient,st[1]); + bot->listGlines(theClient, st[1]); -/*vector< const Gline* > glines = server->matchGline( st[ 1 ] ) ; + /*vector< const Gline* > glines = server->matchGline( st[ 1 ] ) ; -bot->Notice( theClient, "Found %d matches", glines.size() ) ; -if( glines.empty() ) - { - return true ; - } + bot->Notice( theClient, "Found %d matches", glines.size() ) ; + if( glines.empty() ) + { + return true ; + } -bot->Notice( theClient, "Current time: %ld", (long)::time( 0 ) ) ; + bot->Notice( theClient, "Current time: %ld", (long)::time( 0 ) ) ; -for( vector< const Gline* >::const_iterator ptr = glines.begin() ; - ptr != glines.end() ; ++ptr ) - { - bot->Notice( theClient, "%s expires at %d, set by %s because %s", - (*ptr)->getUserHost().c_str(), - (*ptr)->getExpiration(), - (*ptr)->getSetBy().c_str(), - (*ptr)->getReason().c_str() ) ; - }*/ + for( vector< const Gline* >::const_iterator ptr = glines.begin() ; + ptr != glines.end() ; ++ptr ) + { + bot->Notice( theClient, "%s expires at %d, set by %s because %s", + (*ptr)->getUserHost().c_str(), + (*ptr)->getExpiration(), + (*ptr)->getSetBy().c_str(), + (*ptr)->getReason().c_str() ) ; + }*/ -return true ; + return true; } -} +} // namespace uworld } // namespace gnuworld - diff --git a/mod.ccontrol/SCHANGLINECommand.cc b/mod.ccontrol/SCHANGLINECommand.cc index c3e52e28..0412fbe3 100644 --- a/mod.ccontrol/SCHANGLINECommand.cc +++ b/mod.ccontrol/SCHANGLINECommand.cc @@ -19,105 +19,98 @@ * * $Id: SCHANGLINECommand.cc,v 1.5 2009/06/06 07:53:34 hidden1 Exp $ */ -#include -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "misc.h" -#include "Gline.h" -#include "ip.h" -#include "ELog.h" -#include "Gline.h" -#include "time.h" -#include "ccUser.h" -#include "Constants.h" -#include "gnuworld_config.h" +#include +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "misc.h" +#include "Gline.h" +#include "ip.h" +#include "ELog.h" +#include "Gline.h" +#include "time.h" +#include "ccUser.h" +#include "Constants.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { using std::string; // Input: changline #blah reason // // Output: C GL * +*@lamer.net 3600 :Banned (*@lamer) ... // -namespace uworld -{ +namespace uworld { -bool SCHANGLINECommand::Exec( iClient* theClient, const string& Message ) -{ - StringTokenizer st(Message); - unsigned ResStart = 2; - int uParam = 0; // if the -u paramter is used in the command, it will only gline unidented connections +bool SCHANGLINECommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + unsigned ResStart = 2; + int uParam = + 0; // if the -u paramter is used in the command, it will only gline unidented connections - if (st.size() < 4) - { - Usage(theClient); - return true; - } + if (st.size() < 4) { + Usage(theClient); + return true; + } - if (st[1] == "-u") { - if (st.size() < 5) { - Usage(theClient); - return true; - } - uParam = 1; - } + if (st[1] == "-u") { + if (st.size() < 5) { + Usage(theClient); + return true; + } + uParam = 1; + } - StringTokenizer::size_type pos = 1; - time_t gLength = bot->getDefaultGlineLength(); - ccUser* tmpUser = bot->IsAuth(theClient); + StringTokenizer::size_type pos = 1; + time_t gLength = bot->getDefaultGlineLength(); + ccUser* tmpUser = bot->IsAuth(theClient); - /* log use of the command */ - bot->MsgChanLog("SCHANGLINE %s\n",st.assemble(1).c_str()); + /* log use of the command */ + bot->MsgChanLog("SCHANGLINE %s\n", st.assemble(1).c_str()); - /* make sure they're trying a channel gline! */ - if (st[pos+uParam].substr(0,1) != "#") - { - bot->Notice(theClient,"Umm... this is SCHANGLINE, not GLINE - Try " - "glining a channel maybe?"); - return true; - } - if (IsTimeSpec(st[2+uParam])) - { - gLength = extractTime( st[2+uParam], 1 ); - } else { - gLength = bot->getDefaultGlineLength(); - ResStart = 1; - } + /* make sure they're trying a channel gline! */ + if (st[pos + uParam].substr(0, 1) != "#") { + bot->Notice(theClient, "Umm... this is SCHANGLINE, not GLINE - Try " + "glining a channel maybe?"); + return true; + } + if (IsTimeSpec(st[2 + uParam])) { + gLength = extractTime(st[2 + uParam], 1); + } else { + gLength = bot->getDefaultGlineLength(); + ResStart = 1; + } - string nickUserHost = theClient->getRealNickUserHost(); - - if (!tmpUser) - { - bot->Notice(theClient,"You must login to issue this channel gline!"); - return false; - } + string nickUserHost = theClient->getRealNickUserHost(); - if (st[1+uParam].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d " - "characters", channel::MaxName); - return false; - } + if (!tmpUser) { + bot->Notice(theClient, "You must login to issue this channel gline!"); + return false; + } - Channel* theChan = Network->findChannel(st[1+uParam]); - if (NULL == theChan) - { - bot->Notice(theClient, "Unable to find channel %s", - st[1+uParam].c_str()); - return true; - } + if (st[1 + uParam].size() > channel::MaxName) { + bot->Notice(theClient, + "Channel name can't be more than %d " + "characters", + channel::MaxName); + return false; + } - StringTokenizer reason(st.assemble ( pos + ResStart + uParam), '|'); + Channel* theChan = Network->findChannel(st[1 + uParam]); + if (NULL == theChan) { + bot->Notice(theClient, "Unable to find channel %s", st[1 + uParam].c_str()); + return true; + } - bot->glineChannelUsers(theClient, theChan, reason[0], gLength, nickUserHost, false, uParam); - return true; -} + StringTokenizer reason(st.assemble(pos + ResStart + uParam), '|'); + bot->glineChannelUsers(theClient, theChan, reason[0], gLength, nickUserHost, false, uParam); + return true; } -} + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/SGLINECommand.cc b/mod.ccontrol/SGLINECommand.cc index 6de3ef32..e2151450 100644 --- a/mod.ccontrol/SGLINECommand.cc +++ b/mod.ccontrol/SGLINECommand.cc @@ -1,6 +1,6 @@ /** * SGLINECommand.cc - * Glines a specific mask + * Glines a specific mask * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,272 +19,237 @@ * * $Id: SGLINECommand.cc,v 1.15 2009/05/16 07:47:23 danielaustin Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "misc.h" -#include "Gline.h" -#include "ip.h" -#include "ELog.h" -#include "Constants.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ -using std::string ; +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "misc.h" +#include "Gline.h" +#include "ip.h" +#include "ELog.h" +#include "Constants.h" +#include "gnuworld_config.h" + +namespace gnuworld { +using std::string; // Input: sgline *@blah.net reason // Input: sgline 3600 *@blah.net reason // // Output: C GL * +*@lamer.net 3600 :Banned (*@lamer) ... // -namespace uworld -{ +namespace uworld { -bool SGLINECommand::Exec( iClient* theClient, const string& Message ) -{ +bool SGLINECommand::Exec(iClient* theClient, const string& Message) { -StringTokenizer st( Message ) ; + StringTokenizer st(Message); -if(st.size() < 4) - { - Usage( theClient ) ; - return true ; - } -StringTokenizer::size_type pos = 1 ; + if (st.size() < 4) { + Usage(theClient); + return true; + } + StringTokenizer::size_type pos = 1; -string cmdStr = "SGLINE "; + string cmdStr = "SGLINE "; -bool RealName = (!strcasecmp(st[pos],"-rn")); -if (RealName && (st.size() < 5)) - { - Usage(theClient); - return true; - } + bool RealName = (!strcasecmp(st[pos], "-rn")); + if (RealName && (st.size() < 5)) { + Usage(theClient); + return true; + } -if (RealName) cmdStr += "-rn "; + if (RealName) + cmdStr += "-rn "; -string RealHost; + string RealHost; -ccUser* tmpUser = bot->IsAuth(theClient); -//bot->MsgChanLog("SGLINE %s\n",st.assemble(1).c_str()); + ccUser* tmpUser = bot->IsAuth(theClient); + // bot->MsgChanLog("SGLINE %s\n",st.assemble(1).c_str()); -if(!RealName &&(string::npos != st[pos].find_first_of('#'))) - { - bot->Notice(theClient,"I don't think glining that host is such a good idea"); - return true; - } -time_t gLength = bot->getDefaultGlineLength() ; + if (!RealName && (string::npos != st[pos].find_first_of('#'))) { + bot->Notice(theClient, "I don't think glining that host is such a good idea"); + return true; + } + time_t gLength = bot->getDefaultGlineLength(); -// (pos) is the index of the next token, the user@host mask. + // (pos) is the index of the next token, the user@host mask. -if(!RealName) - { - string::size_type atPos = st[ pos ].find_first_of( '@' ) ; - if( string::npos == atPos ) - { - // User has only specified hostname, not a user name - bot->Notice( theClient, "GLINE: Please specify gline mask in the " - "format of user@host" ) ; - return true ; - } + if (!RealName) { + string::size_type atPos = st[pos].find_first_of('@'); + if (string::npos == atPos) { + // User has only specified hostname, not a user name + bot->Notice(theClient, "GLINE: Please specify gline mask in the " + "format of user@host"); + return true; + } - string userName = st[ pos ].substr( 0, pos ) ; - string hostName = st[ pos ].substr( pos + 1 ) ; - } -else //RealName Gline - { - ++pos; - bool hostOk = false; - bool hasSlash = false; - if(st[pos].substr(0,2) != "$R") - { - RealHost = "$R" + st[pos]; - } - else - { - RealHost = st[pos]; - } - //Do alittle sanity check - for(string::size_type p =2; p< RealHost.size();++p) - { - if(RealHost[p] != '$' && RealHost[p] != '*' && RealHost[p] != '?') - hostOk = true; - if (RealHost[p] == '/') - hasSlash = true; - } - if(!hostOk) - { - bot->Notice(theClient,"You must specify at least one character other " - "than *?$ as the realname!"); - return true; - } - if(hasSlash) - { - bot->Notice(theClient, "You can't use a '/' in a realname gline, consider switching it to a '?'"); - return true; - } + string userName = st[pos].substr(0, pos); + string hostName = st[pos].substr(pos + 1); + } else // RealName Gline + { + ++pos; + bool hostOk = false; + bool hasSlash = false; + if (st[pos].substr(0, 2) != "$R") { + RealHost = "$R" + st[pos]; + } else { + RealHost = st[pos]; + } + // Do alittle sanity check + for (string::size_type p = 2; p < RealHost.size(); ++p) { + if (RealHost[p] != '$' && RealHost[p] != '*' && RealHost[p] != '?') + hostOk = true; + if (RealHost[p] == '/') + hasSlash = true; + } + if (!hostOk) { + bot->Notice(theClient, "You must specify at least one character other " + "than *?$ as the realname!"); + return true; + } + if (hasSlash) { + bot->Notice(theClient, + "You can't use a '/' in a realname gline, consider switching it to a '?'"); + return true; + } } - -string Length; -Length.assign(st[pos+1]); -unsigned int Units = 1; //Defualt for seconds -unsigned int ResStart = 2; -bool Ok = true; -if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"d")) - { - Units = 24*3600; - Length.resize(Length.length()-1); - } -else if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"h")) - { - Units = 3600; - Length.resize(Length.length()-1); - } -else if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"m")) - { - Units = 60; - Length.resize(Length.length()-1); - } -else if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"s")) - { - Units = 1; - Length.resize(Length.length()-1); - } -gLength = atoi(Length.c_str()) * Units; -if(gLength == 0) - { - gLength = bot->getDefaultGlineLength() ; - ResStart = 1; - } -if(!tmpUser) - { // We shouldnt have got here in the first place, but check it anyway - return false; - } - -unsigned int Users; -string nickUserHost = theClient->getRealNickUserHost() ; -StringTokenizer ReasonTokenizer ( st.assemble( pos + ResStart ), '|'); -string Reason = ReasonTokenizer[0]; -string sgHost = st[pos]; + string Length; + Length.assign(st[pos + 1]); + unsigned int Units = 1; // Defualt for seconds + unsigned int ResStart = 2; + bool Ok = true; + if (!strcasecmp(Length.substr(Length.length() - 1).c_str(), "d")) { + Units = 24 * 3600; + Length.resize(Length.length() - 1); + } else if (!strcasecmp(Length.substr(Length.length() - 1).c_str(), "h")) { + Units = 3600; + Length.resize(Length.length() - 1); + } else if (!strcasecmp(Length.substr(Length.length() - 1).c_str(), "m")) { + Units = 60; + Length.resize(Length.length() - 1); + } else if (!strcasecmp(Length.substr(Length.length() - 1).c_str(), "s")) { + Units = 1; + Length.resize(Length.length() - 1); + } + gLength = atoi(Length.c_str()) * Units; -if(!RealName) - { - int gCheck = bot->checkSGline(sgHost,gLength,Users); + if (gLength == 0) { + gLength = bot->getDefaultGlineLength(); + ResStart = 1; + } + if (!tmpUser) { // We shouldnt have got here in the first place, but check it anyway + return false; + } - if(gCheck & gline::NEG_TIME) - { - bot->Notice(theClient,"A negative gline duration is not valid."); - Ok = false; - } + unsigned int Users; + string nickUserHost = theClient->getRealNickUserHost(); + StringTokenizer ReasonTokenizer(st.assemble(pos + ResStart), '|'); + string Reason = ReasonTokenizer[0]; + string sgHost = st[pos]; - if(gCheck & gline::HUH_NO_HOST) - { - bot->Notice(theClient,"I don't think glining that host is such a good idea, do you?"); - Ok = false; - } - if(gCheck & gline::BAD_CIDRMASK) - { - bot->Notice(theClient,"The IP listed is not on a bit boundary for the CIDR mask specified."); - Ok = false; - } - if(gCheck & gline::BAD_CIDRLEN) - { - bot->Notice(theClient,"Bad CIDR length - try something more specific."); - Ok = false; - } - if(gCheck & gline::BAD_CIDROVERRIDE) - { - bot->Notice(theClient,"For CIDR sglines, you must enter all 4 parts of the IP."); - Ok = false; - } - if(gCheck & gline::BAD_HOST) - { - bot->Notice(theClient,"illegal host"); - Ok = false; - } - string hostName = sgHost.substr(sgHost.find('@')+1); - if (hostName.find('/') != string::npos) - { - string tCidr; - if (!bot->getValidCidr(hostName, tCidr)) - { - bot->Notice(theClient, "Unwanted cidr format: %s - Suggestion: %s", hostName.c_str(), tCidr.c_str()); - Ok = false; - } - } - if(!Ok) - { - bot->Notice(theClient,"Please fix all of the above, and try again"); - return false; + if (!RealName) { + int gCheck = bot->checkSGline(sgHost, gLength, Users); - } - - char Us[100]; - Us[0] = '\0'; - sprintf(Us,"%d",Users); - Reason = string("[") + Us + string("] ") + Reason; - } //RealName Gline -else - { - Users = Network->matchRealName(RealHost.substr(2,RealHost.size()-2)).size(); - char Us[100]; - Us[0] = '\0'; - sprintf(Us,"%d",Users); - Reason = string("[") + Us + string ("] ") + Reason; - } -if(Reason.size() > gline::MAX_REASON_LENGTH) - { - bot->Notice(theClient,"Gline reason can't be more than %d characters", - gline::MAX_REASON_LENGTH); - return false; - } -/*server->setGline( nickUserHost, - st[ pos ], - string("[") + Us + "] " + Reason, - //st.assemble( pos + ResStart ) + "[" + Us + "]", - gLength , bot) ;*/ + if (gCheck & gline::NEG_TIME) { + bot->Notice(theClient, "A negative gline duration is not valid."); + Ok = false; + } -ccGline *TmpGline = bot->findGline(sgHost); -bool Up = false; + if (gCheck & gline::HUH_NO_HOST) { + bot->Notice(theClient, "I don't think glining that host is such a good idea, do you?"); + Ok = false; + } + if (gCheck & gline::BAD_CIDRMASK) { + bot->Notice(theClient, + "The IP listed is not on a bit boundary for the CIDR mask specified."); + Ok = false; + } + if (gCheck & gline::BAD_CIDRLEN) { + bot->Notice(theClient, "Bad CIDR length - try something more specific."); + Ok = false; + } + if (gCheck & gline::BAD_CIDROVERRIDE) { + bot->Notice(theClient, "For CIDR sglines, you must enter all 4 parts of the IP."); + Ok = false; + } + if (gCheck & gline::BAD_HOST) { + bot->Notice(theClient, "illegal host"); + Ok = false; + } + string hostName = sgHost.substr(sgHost.find('@') + 1); + if (hostName.find('/') != string::npos) { + string tCidr; + if (!bot->getValidCidr(hostName, tCidr)) { + bot->Notice(theClient, "Unwanted cidr format: %s - Suggestion: %s", + hostName.c_str(), tCidr.c_str()); + Ok = false; + } + } + if (!Ok) { + bot->Notice(theClient, "Please fix all of the above, and try again"); + return false; + } -if(TmpGline) - Up = true; -else TmpGline = new ccGline(bot->SQLDb); -if(!RealName) - TmpGline->setHost(sgHost); -else - TmpGline->setHost(RealHost); -TmpGline->setExpires(::time(0) + gLength); -TmpGline->setAddedBy(nickUserHost); -TmpGline->setReason(Reason); -TmpGline->setAddedOn(::time(0)); -TmpGline->setLastUpdated(::time(0)); -bot->addGlineToUplink(TmpGline); -if(Up) - { - TmpGline->Update(); - } -else - { - TmpGline->Insert(); - //We need to update the Id - TmpGline->loadData(TmpGline->getHost()); - bot->addGline(TmpGline); - } + char Us[100]; + Us[0] = '\0'; + sprintf(Us, "%d", Users); + Reason = string("[") + Us + string("] ") + Reason; + } // RealName Gline + else { + Users = Network->matchRealName(RealHost.substr(2, RealHost.size() - 2)).size(); + char Us[100]; + Us[0] = '\0'; + sprintf(Us, "%d", Users); + Reason = string("[") + Us + string("] ") + Reason; + } + if (Reason.size() > gline::MAX_REASON_LENGTH) { + bot->Notice(theClient, "Gline reason can't be more than %d characters", + gline::MAX_REASON_LENGTH); + return false; + } + /*server->setGline( nickUserHost, + st[ pos ], + string("[") + Us + "] " + Reason, + //st.assemble( pos + ResStart ) + "[" + Us + "]", + gLength , bot) ;*/ + + ccGline* TmpGline = bot->findGline(sgHost); + bool Up = false; + + if (TmpGline) + Up = true; + else + TmpGline = new ccGline(bot->SQLDb); + if (!RealName) + TmpGline->setHost(sgHost); + else + TmpGline->setHost(RealHost); + TmpGline->setExpires(::time(0) + gLength); + TmpGline->setAddedBy(nickUserHost); + TmpGline->setReason(Reason); + TmpGline->setAddedOn(::time(0)); + TmpGline->setLastUpdated(::time(0)); + bot->addGlineToUplink(TmpGline); + if (Up) { + TmpGline->Update(); + } else { + TmpGline->Insert(); + // We need to update the Id + TmpGline->loadData(TmpGline->getHost()); + bot->addGline(TmpGline); + } -if(!RealName) - cmdStr += sgHost + " " + st.assemble(2); -else - cmdStr += sgHost + " " + st.assemble(3); -bot->MsgChanLog(cmdStr.c_str()); -return true ; + if (!RealName) + cmdStr += sgHost + " " + st.assemble(2); + else + cmdStr += sgHost + " " + st.assemble(3); + bot->MsgChanLog(cmdStr.c_str()); + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/SHUTDOWNCommand.cc b/mod.ccontrol/SHUTDOWNCommand.cc index 570c0f1e..d7ed5b20 100644 --- a/mod.ccontrol/SHUTDOWNCommand.cc +++ b/mod.ccontrol/SHUTDOWNCommand.cc @@ -19,35 +19,30 @@ * * $Id: SHUTDOWNCommand.cc,v 1.8 2005/01/08 23:33:42 dan_karrels Exp $ */ -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "server.h" +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "server.h" -namespace gnuworld -{ -using std::string ; +namespace gnuworld { +using std::string; -namespace uworld -{ +namespace uworld { -bool SHUTDOWNCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; - -if(st.size() < 2) - { - Usage(theClient); - return true; - } -bot->MsgChanLog("SHUTDOWN %s\n",st.assemble(1).c_str()); +bool SHUTDOWNCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -server->Shutdown( st.assemble( 1 ) ) ; + if (st.size() < 2) { + Usage(theClient); + return true; + } + bot->MsgChanLog("SHUTDOWN %s\n", st.assemble(1).c_str()); -return true; -} + server->Shutdown(st.assemble(1)); + return true; } -} // namespace gnuworld +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/STATUSCommand.cc b/mod.ccontrol/STATUSCommand.cc index acbe54d9..7614f09e 100644 --- a/mod.ccontrol/STATUSCommand.cc +++ b/mod.ccontrol/STATUSCommand.cc @@ -19,29 +19,25 @@ * * $Id: STATUSCommand.cc,v 1.8 2005/01/12 03:50:29 dan_karrels Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; +using std::string; -namespace uworld -{ +namespace uworld { -bool STATUSCommand::Exec( iClient* theClient, const string& ) -{ -bot->MsgChanLog("STATUS\n"); +bool STATUSCommand::Exec(iClient* theClient, const string&) { + bot->MsgChanLog("STATUS\n"); -bot->showStatus(theClient); -return true ; -} - -} + bot->showStatus(theClient); + return true; } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/SUSPENDCommand.cc b/mod.ccontrol/SUSPENDCommand.cc index 15450bfc..dde1d668 100644 --- a/mod.ccontrol/SUSPENDCommand.cc +++ b/mod.ccontrol/SUSPENDCommand.cc @@ -19,158 +19,124 @@ * * $Id: SUSPENDCommand.cc,v 1.15 2006/09/26 17:36:01 kewlio Exp $ */ -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "ccUser.h" -#include "gnuworld_config.h" +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "ccUser.h" +#include "gnuworld_config.h" -namespace gnuworld -{ -using std::string ; +namespace gnuworld { +using std::string; -namespace uworld -{ +namespace uworld { -bool SUSPENDCommand::Exec( iClient* theClient, const string& Message) -{ -StringTokenizer st( Message ) ; - -if( st.size() < 4 ) - { - Usage(theClient); - return true; - } -//Fetch the oper record from the database -ccUser* tmpUser = bot->GetOper(st[1]); +bool SUSPENDCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -if(!tmpUser) - { - bot->Notice(theClient,"%s isn't on my access list",st[1].c_str()); - return false; - } -ccUser* tmpAuth = bot->IsAuth(theClient); -if(!tmpAuth) - { //we should never get here - return false; - } -bot->MsgChanLog("SUSPEND %s\n",st.assemble(1).c_str()); + if (st.size() < 4) { + Usage(theClient); + return true; + } + // Fetch the oper record from the database + ccUser* tmpUser = bot->GetOper(st[1]); -unsigned int AdFlag = tmpAuth->getType(); //Get the admin flag -unsigned int OpFlag = tmpUser->getType(); //Get the oper flag -bool Admin = AdFlag < operLevel::SMTLEVEL; + if (!tmpUser) { + bot->Notice(theClient, "%s isn't on my access list", st[1].c_str()); + return false; + } + ccUser* tmpAuth = bot->IsAuth(theClient); + if (!tmpAuth) { // we should never get here + return false; + } + bot->MsgChanLog("SUSPEND %s\n", st.assemble(1).c_str()); -if((Admin) && (AdFlag <= OpFlag)) - { - bot->Notice(theClient,"You can't suspend a user who has a higher or equal " - "level to your own"); - return false; - } -else if(AdFlag < OpFlag) - { - bot->Notice(theClient,"You can't suspend a user who has a higher level than " - "your own"); - return false; - } -/*if((Admin) && (strcasecmp(tmpAuth->getServer().c_str(),tmpUser->getServer().c_str()))) - { - bot->Notice(theClient,"You can only suspend a user associated with the same server as you"); - return false; - } -*/ -if(bot->isSuspended(tmpUser)) - { - bot->Notice(theClient,"%s is already suspended",st[1].c_str()); - return false; - } -//Fill in the suspendtion period according to the user entry -unsigned int Units = 1; -string Length = st[2]; -string Un = Length.substr(Length.length() - 1); -if(!strcasecmp(Un,"d")) - { - Units = 24*3600; - Length.resize(Length.length()-1); - } -else if(!strcasecmp(Un,"h")) - { - Units = 3600; - Length.resize(Length.length()-1); - } -else if(!strcasecmp(Un,"m")) - { - Units = 60; - Length.resize(Length.length()-1); - } -else if(!strcasecmp(Un,"s")) - { - Units = 1; - Length.resize(Length.length()-1); - } -unsigned int Len = atoi(Length.c_str()) * Units; -if(Len == 0) - { - bot->Notice(theClient,"Invalid duration!"); - return false; - } -unsigned int Level = operLevel::OPERLEVEL;; -unsigned int ResPos = 3; -if(!strcasecmp(st[3],"-l")) - { - if(st.size() < 6) - { - Usage(theClient); - return false; - } - if(!strcasecmp(st[4],"OPER")) - { - Level = operLevel::OPERLEVEL; - } - else if(!strcasecmp(st[4],"ADMIN")) - { - Level = operLevel::ADMINLEVEL; - } - else if(!strcasecmp(st[4],"SMT")) - { - Level = operLevel::SMTLEVEL; - } - else if(!strcasecmp(st[4],"CODER")) - { - Level = operLevel::CODERLEVEL; - } - else - { - bot->Notice(theClient,"Invalid suspend level must be OPER, ADMIN, SMT or CODER"); - return false; - } - if(Level > AdFlag) - { - bot->Notice(theClient,"You can't suspend at a level higher than your own!"); - return false; - } - ResPos = 5; - } -//Set the suspention and update the db -tmpUser->setSuspendExpires(Len + time( 0 )); -tmpUser->setSuspendedBy(theClient->getRealNickUserHost()); -tmpUser->setIsSuspended(true); -tmpUser->setSuspendLevel(Level); -tmpUser->setSuspendReason(st.assemble(ResPos)); -if(tmpUser->Update()) - { - bot->Notice(theClient,"%s has been suspended",st[1].c_str()); - return true; - } -else - { - bot->Notice(theClient,"Error while suspending %s",st[1].c_str()); - return false; - } + unsigned int AdFlag = tmpAuth->getType(); // Get the admin flag + unsigned int OpFlag = tmpUser->getType(); // Get the oper flag + bool Admin = AdFlag < operLevel::SMTLEVEL; + if ((Admin) && (AdFlag <= OpFlag)) { + bot->Notice(theClient, "You can't suspend a user who has a higher or equal " + "level to your own"); + return false; + } else if (AdFlag < OpFlag) { + bot->Notice(theClient, "You can't suspend a user who has a higher level than " + "your own"); + return false; + } + /*if((Admin) && (strcasecmp(tmpAuth->getServer().c_str(),tmpUser->getServer().c_str()))) + { + bot->Notice(theClient,"You can only suspend a user associated with the same server as + you"); return false; + } + */ + if (bot->isSuspended(tmpUser)) { + bot->Notice(theClient, "%s is already suspended", st[1].c_str()); + return false; + } + // Fill in the suspendtion period according to the user entry + unsigned int Units = 1; + string Length = st[2]; + string Un = Length.substr(Length.length() - 1); + if (!strcasecmp(Un, "d")) { + Units = 24 * 3600; + Length.resize(Length.length() - 1); + } else if (!strcasecmp(Un, "h")) { + Units = 3600; + Length.resize(Length.length() - 1); + } else if (!strcasecmp(Un, "m")) { + Units = 60; + Length.resize(Length.length() - 1); + } else if (!strcasecmp(Un, "s")) { + Units = 1; + Length.resize(Length.length() - 1); + } + unsigned int Len = atoi(Length.c_str()) * Units; + if (Len == 0) { + bot->Notice(theClient, "Invalid duration!"); + return false; + } + unsigned int Level = operLevel::OPERLEVEL; + ; + unsigned int ResPos = 3; + if (!strcasecmp(st[3], "-l")) { + if (st.size() < 6) { + Usage(theClient); + return false; + } + if (!strcasecmp(st[4], "OPER")) { + Level = operLevel::OPERLEVEL; + } else if (!strcasecmp(st[4], "ADMIN")) { + Level = operLevel::ADMINLEVEL; + } else if (!strcasecmp(st[4], "SMT")) { + Level = operLevel::SMTLEVEL; + } else if (!strcasecmp(st[4], "CODER")) { + Level = operLevel::CODERLEVEL; + } else { + bot->Notice(theClient, "Invalid suspend level must be OPER, ADMIN, SMT or CODER"); + return false; + } + if (Level > AdFlag) { + bot->Notice(theClient, "You can't suspend at a level higher than your own!"); + return false; + } + ResPos = 5; + } + // Set the suspention and update the db + tmpUser->setSuspendExpires(Len + time(0)); + tmpUser->setSuspendedBy(theClient->getRealNickUserHost()); + tmpUser->setIsSuspended(true); + tmpUser->setSuspendLevel(Level); + tmpUser->setSuspendReason(st.assemble(ResPos)); + if (tmpUser->Update()) { + bot->Notice(theClient, "%s has been suspended", st[1].c_str()); + return true; + } else { + bot->Notice(theClient, "Error while suspending %s", st[1].c_str()); + return false; + } } -} +} // namespace uworld } // namespace gnuworld - diff --git a/mod.ccontrol/TOPICCommand.cc b/mod.ccontrol/TOPICCommand.cc index b6268acf..b094c275 100644 --- a/mod.ccontrol/TOPICCommand.cc +++ b/mod.ccontrol/TOPICCommand.cc @@ -20,87 +20,69 @@ * $Id: INVITECommand.cc,v 1.21 2006/09/26 17:35:58 kewlio Exp $ */ -#include -#include - -#include - -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Constants.h" -#include "Network.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool TOPICCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; - -if( st.size() < 2 ) - { - // send help - Usage( theClient ) ; - return false ; - } -if(st[1].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d characters", - channel::MaxName); - return false; - } -bot->MsgChanLog("TOPIC %s\n",st.assemble(1).c_str()); - -//If the channel doesnt begin with # add it -string chanName = st[ 1 ] ; -if( chanName[ 0 ] != '#' ) - { - chanName.insert( chanName.begin(), '#' ) ; - } - -string topic; -if (st.size() == 2) - topic = ""; -else - topic = "(" + theClient->getNickName() + ") " + st.assemble(2); - -if ( topic.size() > MAX_TOPIC_LENGTH ) - { - bot->Notice(theClient, "Topic cannot exceed %d characters", MAX_TOPIC_LENGTH); - return true; - } - - -Channel* theChan = Network->findChannel(st[1]); -if (theChan == NULL) - { - bot->Notice(theClient, "Channel '%s' does not exist!", st[1].c_str()); - return true; - } - - -stringstream s; -s << bot->getCharYY() - << " T " - << theChan->getName() - << " :" - << topic - << ends; - -bot->Write( s ); - -return true ; -} - -} - +#include +#include + +#include + +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Constants.h" +#include "Network.h" +#include "gnuworld_config.h" + +namespace gnuworld { + +using std::string; + +namespace uworld { + +bool TOPICCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + + if (st.size() < 2) { + // send help + Usage(theClient); + return false; + } + if (st[1].size() > channel::MaxName) { + bot->Notice(theClient, "Channel name can't be more than %d characters", channel::MaxName); + return false; + } + bot->MsgChanLog("TOPIC %s\n", st.assemble(1).c_str()); + + // If the channel doesnt begin with # add it + string chanName = st[1]; + if (chanName[0] != '#') { + chanName.insert(chanName.begin(), '#'); + } + + string topic; + if (st.size() == 2) + topic = ""; + else + topic = "(" + theClient->getNickName() + ") " + st.assemble(2); + + if (topic.size() > MAX_TOPIC_LENGTH) { + bot->Notice(theClient, "Topic cannot exceed %d characters", MAX_TOPIC_LENGTH); + return true; + } + + Channel* theChan = Network->findChannel(st[1]); + if (theChan == NULL) { + bot->Notice(theClient, "Channel '%s' does not exist!", st[1].c_str()); + return true; + } + + stringstream s; + s << bot->getCharYY() << " T " << theChan->getName() << " :" << topic << ends; + + bot->Write(s); + + return true; } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/TRANSLATECommand.cc b/mod.ccontrol/TRANSLATECommand.cc index dda22d8c..9b3920f4 100644 --- a/mod.ccontrol/TRANSLATECommand.cc +++ b/mod.ccontrol/TRANSLATECommand.cc @@ -19,70 +19,56 @@ * * $Id: TRANSLATECommand.cc,v 1.14 2005/01/12 03:50:29 dan_karrels Exp $ */ -#include -#include -#include -#include "Network.h" -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "Network.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "gnuworld_config.h" -namespace gnuworld -{ -using std::string ; +namespace gnuworld { +using std::string; -namespace uworld -{ +namespace uworld { // translate yyxxx -bool TRANSLATECommand::Exec( iClient* theClient, const string& Message ) -{ +bool TRANSLATECommand::Exec(iClient* theClient, const string& Message) { -StringTokenizer st( Message ) ; -if( st.size() != 2 ) - { - Usage( theClient ) ; - return true ; - } + StringTokenizer st(Message); + if (st.size() != 2) { + Usage(theClient); + return true; + } -iClient* Target = Network->findClient( st[ 1 ] ) ; + iClient* Target = Network->findClient(st[1]); -if( NULL == Target ) - { - bot->Notice( theClient, "Unable to find numeric %s\n", - st[ 1 ].c_str() ) ; - return true ; - } -bot->MsgChanLog("TRANSLATE %s\n",st.assemble(1).c_str()); + if (NULL == Target) { + bot->Notice(theClient, "Unable to find numeric %s\n", st[1].c_str()); + return true; + } + bot->MsgChanLog("TRANSLATE %s\n", st.assemble(1).c_str()); -iServer* theServer = Network->findServer( Target->getIntYY() ) ; -if( NULL == theServer ) - { - elog << "TRANSLATECommand> Unable to find server\n" ; - return false ; - } + iServer* theServer = Network->findServer(Target->getIntYY()); + if (NULL == theServer) { + elog << "TRANSLATECommand> Unable to find server\n"; + return false; + } -if((Target->isModeR()) && (Target->isModeX())) - { - bot->Notice( theClient, "%s is %s (%s) on server %s", - st[ 1 ].c_str(), - Target->getNickUserHost().c_str(), - Target->getRealNickUserHost().c_str(), - theServer->getName().c_str() ) ; - } - -else - { - - bot->Notice( theClient, "%s is %s on server %s", - st[ 1 ].c_str(), - Target->getNickUserHost().c_str(), - theServer->getName().c_str() ) ; - } + if ((Target->isModeR()) && (Target->isModeX())) { + bot->Notice(theClient, "%s is %s (%s) on server %s", st[1].c_str(), + Target->getNickUserHost().c_str(), Target->getRealNickUserHost().c_str(), + theServer->getName().c_str()); + } -return true ; + else { + bot->Notice(theClient, "%s is %s on server %s", st[1].c_str(), + Target->getNickUserHost().c_str(), theServer->getName().c_str()); + } + + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/UNJUPECommand.cc b/mod.ccontrol/UNJUPECommand.cc index 8015c633..4f6eb278 100644 --- a/mod.ccontrol/UNJUPECommand.cc +++ b/mod.ccontrol/UNJUPECommand.cc @@ -19,73 +19,61 @@ * * $Id: UNJUPECommand.cc,v 1.3 2006/09/26 17:36:01 kewlio Exp $ */ -#include -#include -#include -#include -#include "ccontrol.h" -#include "iServer.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "Constants.h" -#include "gnuworld_config.h" +#include +#include +#include +#include +#include "ccontrol.h" +#include "iServer.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "Constants.h" +#include "gnuworld_config.h" -namespace gnuworld -{ -using std::string ; +namespace gnuworld { +using std::string; -namespace uworld -{ +namespace uworld { -bool UNJUPECommand::Exec( iClient* theClient, const string& Message ) -{ +bool UNJUPECommand::Exec(iClient* theClient, const string& Message) { -StringTokenizer st( Message ) ; -if( st.size() < 2 ) - { - Usage( theClient ) ; - return false ; - } + StringTokenizer st(Message); + if (st.size() < 2) { + Usage(theClient); + return false; + } -// The server name to be juped must have at least 1 '.' -if( st[1].length() > server::MaxName) - { - bot->Notice( theClient, "Bogus server name" ) ; - return false ; - } -bot->MsgChanLog("UNJUPE %s\n",st.assemble(1).c_str()); + // The server name to be juped must have at least 1 '.' + if (st[1].length() > server::MaxName) { + bot->Notice(theClient, "Bogus server name"); + return false; + } + bot->MsgChanLog("UNJUPE %s\n", st.assemble(1).c_str()); -iServer* Server; + iServer* Server; -if(string::npos != st[ 1 ].find_first_of( '*' )) - { - bot->Notice(theClient,"Sorry, but you must give a full server name when juping!"); - return false; - } -else if(string::npos == st[ 1 ].find_first_of( '.' )) - { - bot->Notice( theClient, "Bogus server name" ) ; - return false ; - } + if (string::npos != st[1].find_first_of('*')) { + bot->Notice(theClient, "Sorry, but you must give a full server name when juping!"); + return false; + } else if (string::npos == st[1].find_first_of('.')) { + bot->Notice(theClient, "Bogus server name"); + return false; + } -Server = Network->findServerName(st[1]); -if(!Server) - { - bot->Notice(theClient,"Sorry, but i can't find that server!"); - return false; - } -if(!Server->isJupe()) - { - bot->Notice(theClient,"Sorry, but the server is not juped!"); - return false; - } -server->DetachServer(Server); - - -return true ; + Server = Network->findServerName(st[1]); + if (!Server) { + bot->Notice(theClient, "Sorry, but i can't find that server!"); + return false; + } + if (!Server->isJupe()) { + bot->Notice(theClient, "Sorry, but the server is not juped!"); + return false; + } + server->DetachServer(Server); + return true; } -} +} // namespace uworld } // namespace gnuworld diff --git a/mod.ccontrol/UNMODERATECommand.cc b/mod.ccontrol/UNMODERATECommand.cc index de32f064..0be3fd16 100644 --- a/mod.ccontrol/UNMODERATECommand.cc +++ b/mod.ccontrol/UNMODERATECommand.cc @@ -19,66 +19,55 @@ * * $Id: UNMODERATECommand.cc,v 1.14 2006/09/26 17:36:01 kewlio Exp $ */ -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "Network.h" -#include "Constants.h" -#include "ccBadChannel.h" -#include "gnuworld_config.h" +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "Network.h" +#include "Constants.h" +#include "ccBadChannel.h" +#include "gnuworld_config.h" -namespace gnuworld -{ -using std::string ; +namespace gnuworld { +using std::string; -namespace uworld -{ +namespace uworld { -bool UNMODERATECommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } -if(st[1].size() > channel::MaxName) - { - bot->Notice(theClient,"Channel name can't be more than %d characters", - channel::MaxName); - } +bool UNMODERATECommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + if (st.size() < 2) { + Usage(theClient); + return true; + } + if (st[1].size() > channel::MaxName) { + bot->Notice(theClient, "Channel name can't be more than %d characters", channel::MaxName); + } -bot->MsgChanLog("UNMODERATE %s\n",st.assemble(1).c_str()); + bot->MsgChanLog("UNMODERATE %s\n", st.assemble(1).c_str()); -ccBadChannel* Chan = bot->isBadChannel(st[1]); -if(Chan) - { - bot->Notice(theClient,"Sorry, but you can't change modes in " - "this channel because: %s", - Chan->getReason().c_str()); + ccBadChannel* Chan = bot->isBadChannel(st[1]); + if (Chan) { + bot->Notice(theClient, + "Sorry, but you can't change modes in " + "this channel because: %s", + Chan->getReason().c_str()); return false; - } + } -Channel* theChan = Network->findChannel( st[ 1 ] ) ; -if( NULL == theChan ) - { - bot->Notice( theClient, "Unable to find channel %s\n", - st[ 1 ].c_str() ) ; - return true ; - } + Channel* theChan = Network->findChannel(st[1]); + if (NULL == theChan) { + bot->Notice(theClient, "Unable to find channel %s\n", st[1].c_str()); + return true; + } -if(!theChan->getMode(Channel::MODE_M)) - { - bot->Notice( theClient,"Channel %s is not moderated", - st[ 1 ].c_str()); - return false; - } - -bot->Mode( theChan, "-m", string(), true ); + if (!theChan->getMode(Channel::MODE_M)) { + bot->Notice(theClient, "Channel %s is not moderated", st[1].c_str()); + return false; + } -return true ; + bot->Mode(theChan, "-m", string(), true); + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/UNSUSPENDCommand.cc b/mod.ccontrol/UNSUSPENDCommand.cc index da02fe5b..324dc45c 100644 --- a/mod.ccontrol/UNSUSPENDCommand.cc +++ b/mod.ccontrol/UNSUSPENDCommand.cc @@ -19,101 +19,86 @@ * * $Id: UNSUSPENDCommand.cc,v 1.14 2006/09/26 17:36:01 kewlio Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "gnuworld_config.h" +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "gnuworld_config.h" -namespace gnuworld -{ -using std::string ; +namespace gnuworld { +using std::string; -namespace uworld -{ +namespace uworld { -bool UNSUSPENDCommand::Exec( iClient* theClient, const string& Message) -{ -StringTokenizer st( Message ) ; - -if( st.size() < 2 ) - { - Usage(theClient); - return true; - } +bool UNSUSPENDCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); -//Fetch the user record from the database -//ccUser *tmpUser = bot->GetUser(st[1]); -ccUser* tmpUser = bot->GetOper(st[1]); + if (st.size() < 2) { + Usage(theClient); + return true; + } -if(!tmpUser) - { - bot->Notice(theClient,"%s isn't on my access list",st[1].c_str()); - return false; - } - -ccUser* tmpAuth = bot->IsAuth(theClient->getCharYYXXX()); -if(!tmpAuth) - { //we should never get here - return false; - } -bot->MsgChanLog("UNSUSPEND %s\n",st.assemble(1).c_str()); + // Fetch the user record from the database + // ccUser *tmpUser = bot->GetUser(st[1]); + ccUser* tmpUser = bot->GetOper(st[1]); -unsigned int AdFlag = tmpAuth->getType(); //Get the admin flag -unsigned int OpFlag = tmpUser->getType(); //Get the oper flag -bool Admin = AdFlag < operLevel::SMTLEVEL; + if (!tmpUser) { + bot->Notice(theClient, "%s isn't on my access list", st[1].c_str()); + return false; + } -if((Admin) && (AdFlag <= OpFlag)) - { - bot->Notice(theClient,"You can't unsuspend a user who has a higher or equal " - "access level than you."); - return false; - } -else if(AdFlag < OpFlag) - { - bot->Notice(theClient,"You can't unsuspend a user who has a higher level " - "than you."); - return false; - } -/*if((Admin) && (strcasecmp(tmpAuth->getServer().c_str(),tmpUser->getServer().c_str()))) - { - bot->Notice(theClient,"You can only unsuspend a user that is associated with " - "the same server as you"); - return false; - } -*/ -if(tmpUser->getSuspendLevel() > AdFlag) - { - bot->Notice(theClient,"The suspend level is set to a higher level than yours"); - return false; - } - -if(!(bot->isSuspended(tmpUser))) - { - bot->Notice(theClient,"%s is not suspended",st[1].c_str()); - return false; - } + ccUser* tmpAuth = bot->IsAuth(theClient->getCharYYXXX()); + if (!tmpAuth) { // we should never get here + return false; + } + bot->MsgChanLog("UNSUSPEND %s\n", st.assemble(1).c_str()); -//Remove the suspention and update the database -tmpUser->setSuspendExpires(0); -tmpUser->setIsSuspended(false); -tmpUser->setSuspendedBy(""); -tmpUser->setSuspendReason(""); -tmpUser->setSuspendLevel(0); -if(tmpUser->Update()) - { - bot->Notice(theClient,"%s has been unsuspended",st[1].c_str()); - return true; - } -else - { - bot->Notice(theClient,"Error while unsuspending %s",st[1].c_str()); - return false; - } + unsigned int AdFlag = tmpAuth->getType(); // Get the admin flag + unsigned int OpFlag = tmpUser->getType(); // Get the oper flag + bool Admin = AdFlag < operLevel::SMTLEVEL; -} + if ((Admin) && (AdFlag <= OpFlag)) { + bot->Notice(theClient, "You can't unsuspend a user who has a higher or equal " + "access level than you."); + return false; + } else if (AdFlag < OpFlag) { + bot->Notice(theClient, "You can't unsuspend a user who has a higher level " + "than you."); + return false; + } + /*if((Admin) && (strcasecmp(tmpAuth->getServer().c_str(),tmpUser->getServer().c_str()))) + { + bot->Notice(theClient,"You can only unsuspend a user that is associated with " + "the same server as you"); + return false; + } + */ + if (tmpUser->getSuspendLevel() > AdFlag) { + bot->Notice(theClient, "The suspend level is set to a higher level than yours"); + return false; + } + if (!(bot->isSuspended(tmpUser))) { + bot->Notice(theClient, "%s is not suspended", st[1].c_str()); + return false; + } + + // Remove the suspention and update the database + tmpUser->setSuspendExpires(0); + tmpUser->setIsSuspended(false); + tmpUser->setSuspendedBy(""); + tmpUser->setSuspendReason(""); + tmpUser->setSuspendLevel(0); + if (tmpUser->Update()) { + bot->Notice(theClient, "%s has been unsuspended", st[1].c_str()); + return true; + } else { + bot->Notice(theClient, "Error while unsuspending %s", st[1].c_str()); + return false; + } } -} + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/USERINFOCommand.cc b/mod.ccontrol/USERINFOCommand.cc index 49115671..eae084be 100644 --- a/mod.ccontrol/USERINFOCommand.cc +++ b/mod.ccontrol/USERINFOCommand.cc @@ -19,232 +19,187 @@ * * $Id: USERINFOCommand.cc,v 1.13 2009/07/25 18:12:34 hidden1 Exp $ */ -#include -#include -#include -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "commLevels.h" -#include "misc.h" -#include "match.h" -#include "Network.h" -#include "ccontrol_generic.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -bool USERINFOCommand::Exec( iClient* theClient, const string& Message ) -{ - -StringTokenizer st( Message ) ; - - -if( st.size() < 2 ) - { - Usage(theClient); - return true; - } - -bot->MsgChanLog("USERINFO %s\n",st.assemble(1).c_str()); - -ccUser* tempUser; -string Name; -string Level; -string Email; -string Server; -bool Suspended; -char GetLogs[4]; -char GetLag[4]; -char NeedOp[4]; -char SSO[4]; -char SSOOO[4]; -char AutoOp[4]; -string SuspendedBy; -string SuspendReason; -time_t SuspendExpires; -unsigned int SuspendLevel; -string SLevel; -ccontrol::usersconstiterator ptr; -for(ptr = bot->usersmap_begin();ptr != bot->usersmap_end();++ptr) - { - tempUser = ptr->second; - if(!(match(st[1],tempUser->getUserName())) || - !(match(st[1],tempUser->getServer()))) - { - Name.assign(tempUser->getUserName()); - Server.assign(tempUser->getServer()); - Email.assign(tempUser->getEmail()); - SuspendExpires = tempUser->getSuspendExpires(); - if((tempUser->getIsSuspended()) && (SuspendExpires > ::time(0))) - { - Suspended = true; - SuspendedBy.assign(tempUser->getSuspendedBy()); - SuspendReason.assign(tempUser->getSuspendReason()); - SuspendLevel=tempUser->getSuspendLevel(); - if(SuspendLevel == operLevel::OPERLEVEL) - { - SLevel.assign("OPER"); - } - else if(SuspendLevel == operLevel::ADMINLEVEL) - { - SLevel.assign("ADMIN"); - } - else if(SuspendLevel == operLevel::SMTLEVEL) - { - SLevel.assign("SMT"); - } - else if(SuspendLevel == operLevel::CODERLEVEL) - { - SLevel.assign("CODER"); - } - } - else - { - Suspended = false; - } - if (tempUser->isUhs()) - { - Level.assign("UHS"); - } - else if(tempUser->isOper()) - { - Level.assign("OPER"); - } - else if(tempUser->isAdmin()) - { - Level.assign("ADMIN"); - } - else if(tempUser->isSmt()) - { - Level.assign("SMT"); - } - else - Level.assign("CODER"); - - if(tempUser->getLogs()) - { - sprintf(GetLogs,"YES"); - } - else - { - sprintf(GetLogs,"NO"); - } - - if(tempUser->getLag()) - { - sprintf(GetLag,"YES"); - } - else - { - sprintf(GetLag,"NO"); - } - - if(tempUser->getSso()) - { - sprintf(SSO,"YES"); - } - else - { - sprintf(SSO,"NO"); - } - - if(tempUser->getSsooo()) - { - sprintf(SSOOO,"YES"); - } - else - { - sprintf(SSOOO,"NO"); - } - - if(tempUser->getAutoOp()) - { - sprintf(AutoOp,"YES"); - } - else - { - sprintf(AutoOp,"NO"); - } - - if(tempUser->getNeedOp()) - { - sprintf(NeedOp,"YES"); - } - else - { - sprintf(NeedOp,"NO"); - } - if(tempUser->getClients().size() > 0) - { - vector Clients = tempUser->getClients(); - vector::iterator Itr; - bot->Notice(theClient,"User Name: %s Currently logged in from:", Name.c_str()); - for (Itr = Clients.begin(); Itr != Clients.end(); Itr++) - { - iClient* tClient = *Itr; - StringTokenizer st2(tClient->getServer()->getName(), '.'); - bot->Notice(theClient, " %s (%s.*)", tClient->getRealNickUserHost().c_str(), st2[0].c_str()); - } - } - else - bot->Notice(theClient,"User Name: %s Not logged in",Name.c_str()); - if(Email == "") - Email.assign("Not assigned"); - bot->Notice(theClient,"Level: %s E-mail: %s",Level.c_str(),Email.c_str()); - if(Server == "") - Server.assign("Not assigned"); - bot->Notice(theClient,"Server: %s",Server.c_str()); - if(Suspended) - { - bot->Notice(theClient,"User was suspended by: %s until %s", - SuspendedBy.c_str(), - bot->convertToAscTime(SuspendExpires)); - bot->Notice(theClient,"Reason: %s",SuspendReason.c_str()); - bot->Notice(theClient,"Level: %s",SLevel.c_str()); - } - bot->Notice(theClient,"User Flags: GetLogs \002%s\002 NeedOp \002%s\002 GetLag \002%s\002", - GetLogs,NeedOp,GetLag); - bot->Notice(theClient,"Single Sign On: \002%s\002 (only if opered: \002%s\002) AutoOp: \002%s\002",SSO,SSOOO,AutoOp); - std::string Account = tempUser->getAccount(); - if (strcasecmp(Account,"") != 0) - bot->Notice(theClient,"Account associated: %s", Account.c_str()); - if ((st.size() > 2) && (!strcasecmp(st[2],"-cl"))) - { - bot->Notice(theClient, "Password last changed: %s ago", (tempUser->getPassChangeTS() == 0) ? "N/A" : Ago(tempUser->getPassChangeTS())); - - /* commands list requested */ - bot->Notice(theClient,"Commands available to this user:"); - string cmdList = ""; - for (ccontrol::constCommandIterator cmdptr = bot->command_begin(); - cmdptr != bot->command_end(); ++cmdptr) - { - int ComLevel = cmdptr->second->getFlags(); - if ((ComLevel & commandLevel::flg_NOLOGIN) || ((tempUser) && (tempUser->gotAccess(cmdptr->second)))) - { - cmdList += (cmdptr->second->getName() + " "); - if (cmdList.size() > 80) - { - bot->Notice(theClient, "%s", cmdList.c_str()); - cmdList.assign(""); - } - } - } - if (!cmdList.empty()) - bot->Notice(theClient, "%s", cmdList.c_str()); - } - bot->Notice(theClient,"-----===== End of userinfo for %s =====-----",Name.c_str()); - } - } -bot->Notice(theClient,"End of userinfo"); -return true; -} +#include +#include +#include +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "commLevels.h" +#include "misc.h" +#include "match.h" +#include "Network.h" +#include "ccontrol_generic.h" +#include "gnuworld_config.h" +namespace gnuworld { + +using std::string; + +namespace uworld { + +bool USERINFOCommand::Exec(iClient* theClient, const string& Message) { + + StringTokenizer st(Message); + + if (st.size() < 2) { + Usage(theClient); + return true; + } + + bot->MsgChanLog("USERINFO %s\n", st.assemble(1).c_str()); + + ccUser* tempUser; + string Name; + string Level; + string Email; + string Server; + bool Suspended; + char GetLogs[4]; + char GetLag[4]; + char NeedOp[4]; + char SSO[4]; + char SSOOO[4]; + char AutoOp[4]; + string SuspendedBy; + string SuspendReason; + time_t SuspendExpires; + unsigned int SuspendLevel; + string SLevel; + ccontrol::usersconstiterator ptr; + for (ptr = bot->usersmap_begin(); ptr != bot->usersmap_end(); ++ptr) { + tempUser = ptr->second; + if (!(match(st[1], tempUser->getUserName())) || !(match(st[1], tempUser->getServer()))) { + Name.assign(tempUser->getUserName()); + Server.assign(tempUser->getServer()); + Email.assign(tempUser->getEmail()); + SuspendExpires = tempUser->getSuspendExpires(); + if ((tempUser->getIsSuspended()) && (SuspendExpires > ::time(0))) { + Suspended = true; + SuspendedBy.assign(tempUser->getSuspendedBy()); + SuspendReason.assign(tempUser->getSuspendReason()); + SuspendLevel = tempUser->getSuspendLevel(); + if (SuspendLevel == operLevel::OPERLEVEL) { + SLevel.assign("OPER"); + } else if (SuspendLevel == operLevel::ADMINLEVEL) { + SLevel.assign("ADMIN"); + } else if (SuspendLevel == operLevel::SMTLEVEL) { + SLevel.assign("SMT"); + } else if (SuspendLevel == operLevel::CODERLEVEL) { + SLevel.assign("CODER"); + } + } else { + Suspended = false; + } + if (tempUser->isUhs()) { + Level.assign("UHS"); + } else if (tempUser->isOper()) { + Level.assign("OPER"); + } else if (tempUser->isAdmin()) { + Level.assign("ADMIN"); + } else if (tempUser->isSmt()) { + Level.assign("SMT"); + } else + Level.assign("CODER"); + + if (tempUser->getLogs()) { + sprintf(GetLogs, "YES"); + } else { + sprintf(GetLogs, "NO"); + } + + if (tempUser->getLag()) { + sprintf(GetLag, "YES"); + } else { + sprintf(GetLag, "NO"); + } + + if (tempUser->getSso()) { + sprintf(SSO, "YES"); + } else { + sprintf(SSO, "NO"); + } + + if (tempUser->getSsooo()) { + sprintf(SSOOO, "YES"); + } else { + sprintf(SSOOO, "NO"); + } + + if (tempUser->getAutoOp()) { + sprintf(AutoOp, "YES"); + } else { + sprintf(AutoOp, "NO"); + } + + if (tempUser->getNeedOp()) { + sprintf(NeedOp, "YES"); + } else { + sprintf(NeedOp, "NO"); + } + if (tempUser->getClients().size() > 0) { + vector Clients = tempUser->getClients(); + vector::iterator Itr; + bot->Notice(theClient, "User Name: %s Currently logged in from:", Name.c_str()); + for (Itr = Clients.begin(); Itr != Clients.end(); Itr++) { + iClient* tClient = *Itr; + StringTokenizer st2(tClient->getServer()->getName(), '.'); + bot->Notice(theClient, " %s (%s.*)", tClient->getRealNickUserHost().c_str(), + st2[0].c_str()); + } + } else + bot->Notice(theClient, "User Name: %s Not logged in", Name.c_str()); + if (Email == "") + Email.assign("Not assigned"); + bot->Notice(theClient, "Level: %s E-mail: %s", Level.c_str(), Email.c_str()); + if (Server == "") + Server.assign("Not assigned"); + bot->Notice(theClient, "Server: %s", Server.c_str()); + if (Suspended) { + bot->Notice(theClient, "User was suspended by: %s until %s", SuspendedBy.c_str(), + bot->convertToAscTime(SuspendExpires)); + bot->Notice(theClient, "Reason: %s", SuspendReason.c_str()); + bot->Notice(theClient, "Level: %s", SLevel.c_str()); + } + bot->Notice(theClient, + "User Flags: GetLogs \002%s\002 NeedOp \002%s\002 GetLag \002%s\002", + GetLogs, NeedOp, GetLag); + bot->Notice( + theClient, + "Single Sign On: \002%s\002 (only if opered: \002%s\002) AutoOp: \002%s\002", + SSO, SSOOO, AutoOp); + std::string Account = tempUser->getAccount(); + if (strcasecmp(Account, "") != 0) + bot->Notice(theClient, "Account associated: %s", Account.c_str()); + if ((st.size() > 2) && (!strcasecmp(st[2], "-cl"))) { + bot->Notice(theClient, "Password last changed: %s ago", + (tempUser->getPassChangeTS() == 0) ? "N/A" + : Ago(tempUser->getPassChangeTS())); + + /* commands list requested */ + bot->Notice(theClient, "Commands available to this user:"); + string cmdList = ""; + for (ccontrol::constCommandIterator cmdptr = bot->command_begin(); + cmdptr != bot->command_end(); ++cmdptr) { + int ComLevel = cmdptr->second->getFlags(); + if ((ComLevel & commandLevel::flg_NOLOGIN) || + ((tempUser) && (tempUser->gotAccess(cmdptr->second)))) { + cmdList += (cmdptr->second->getName() + " "); + if (cmdList.size() > 80) { + bot->Notice(theClient, "%s", cmdList.c_str()); + cmdList.assign(""); + } + } + } + if (!cmdList.empty()) + bot->Notice(theClient, "%s", cmdList.c_str()); + } + bot->Notice(theClient, "-----===== End of userinfo for %s =====-----", Name.c_str()); + } + } + bot->Notice(theClient, "End of userinfo"); + return true; } -} + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/UserFilter.h b/mod.ccontrol/UserFilter.h index b72190b1..11a8eb48 100644 --- a/mod.ccontrol/UserFilter.h +++ b/mod.ccontrol/UserFilter.h @@ -30,45 +30,39 @@ namespace gnuworld { namespace uworld { class UserFilter { -public: - virtual bool filter(ccUser*) = 0; + public: + virtual bool filter(ccUser*) = 0; }; -class UserFilterComposite : public UserFilter{ +class UserFilterComposite : public UserFilter { -private: - vector filters; -public: - void addFilter(UserFilter* filter) { - filters.push_back(filter); - } + private: + vector filters; + + public: + void addFilter(UserFilter* filter) { filters.push_back(filter); } - virtual bool filter(ccUser* user) { - for(unsigned int i=0; i < filters.size();++i) { - if(!filters[i]->filter(user)) { - return false; - } - } - return true; + virtual bool filter(ccUser* user) { + for (unsigned int i = 0; i < filters.size(); ++i) { + if (!filters[i]->filter(user)) { + return false; + } } + return true; + } }; class ByLevelsUserFilter : public UserFilter { -private: - unsigned int levels; -public: - ByLevelsUserFilter() { - this->levels = 0; - } + private: + unsigned int levels; - void addLevel(unsigned int userLevel) { - levels |= (1 << userLevel); - } + public: + ByLevelsUserFilter() { this->levels = 0; } - virtual bool filter(ccUser* user) { - return (levels & (1 << user->getType())) > 0 ; - } + void addLevel(unsigned int userLevel) { levels |= (1 << userLevel); } + + virtual bool filter(ccUser* user) { return (levels & (1 << user->getType())) > 0; } }; -} -} -#endif /* USERFILTER_H */ +} // namespace uworld +} // namespace gnuworld +#endif /* USERFILTER_H */ diff --git a/mod.ccontrol/WHOISCommand.cc b/mod.ccontrol/WHOISCommand.cc index b3662ce4..f6c26c35 100644 --- a/mod.ccontrol/WHOISCommand.cc +++ b/mod.ccontrol/WHOISCommand.cc @@ -19,220 +19,179 @@ * * $Id: WHOISCommand.cc,v 1.25 2005/08/24 13:36:32 kewlio Exp $ */ -#include -#include -#include -#include "Network.h" -#include "ccontrol.h" -#include "CControlCommands.h" -#include "StringTokenizer.h" -#include "ip.h" -#include "ccontrol_generic.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ -using std::endl ; -using std::string ; - -namespace uworld -{ +#include +#include +#include +#include "Network.h" +#include "ccontrol.h" +#include "CControlCommands.h" +#include "StringTokenizer.h" +#include "ip.h" +#include "ccontrol_generic.h" +#include "gnuworld_config.h" + +namespace gnuworld { +using std::endl; +using std::string; + +namespace uworld { // whois nickname -bool WHOISCommand::Exec( iClient* theClient, const string& Message ) -{ -StringTokenizer st( Message ) ; -if( st.size() < 2 ) - { - Usage( theClient ) ; - return true ; - } - -iClient* Target = Network->findNick( st[ 1 ] ) ; -if( NULL == Target ) - { - bot->Notice( theClient, "Unable to find nick: %s", st[ 1 ].c_str() ) ; - return true ; - } -bot->MsgChanLog("WHOIS %s\n",st.assemble(1).c_str()); - -iServer* targetServer = Network->findServer( Target->getIntYY() ) ; -if( NULL == targetServer ) - { - elog << "WHOISCommand> Unable to find server: " - << Target->getIntYY() << endl ; - return false ; - } - -if((Target->isModeX()) && (Target->isModeR())) - { - bot->Notice( theClient, "%s is %s (%s) [%s]", - st[ 1 ].c_str(), - Target->getNickUserHost().c_str(), - Target->getRealNickUserHost().c_str(), - xIP(Target->getIP() ).GetNumericIP().c_str() - ) ; - - } -else - { - bot->Notice( theClient, "%s is %s [%s]", - st[ 1 ].c_str(), - Target->getNickUserHost().c_str(), - xIP(Target->getIP() ).GetNumericIP().c_str() - ) ; - } - -if( Target->getNickTS() != Target->getFirstNickTS() ) - { - bot->Notice(theClient, "%s has used its current nickname for %s [since %ld]", - st[1].c_str(), - Ago(Target->getNickTS()), - Target->getNickTS()); - } - -bot->Notice(theClient, "%s has been connected for %s [since %ld]", - st[1].c_str(), - Ago(Target->getFirstNickTS()), - Target->getFirstNickTS()); - -if (Target->isModeR()) -{ - string accountFlags; - if( Target->getAccountFlag( iClient::X_TOTP_REQ_IPR ) || Target->getAccountFlag(iClient::X_TOTP_ENABLED ) ) - { - accountFlags += ( Target->getAccountFlag( iClient::X_TOTP_REQ_IPR ) ) ? "TOTP_REQ_IPR " : "TOTP "; - - // Check for disabled methods - std::string disabled; - if( Target->getAccountFlag( iClient::X_WEB_DISABLE_TOTP ) ) - disabled += ( disabled.empty() ? "WEB" : ",WEB" ) ; - if( Target->getAccountFlag( iClient::X_CERT_DISABLE_TOTP ) ) - disabled += ( disabled.empty() ? "CERT" : ",CERT" ) ; - if( !disabled.empty() ) - accountFlags += "(DISABLE=" + disabled + ") "; - } - - if(Target->getAccountFlag(iClient::X_GLOBAL_SUSPEND)) - accountFlags += "SUSPENDED "; - if(Target->getAccountFlag(iClient::X_FRAUD)) - accountFlags += "FRAUD "; - if(Target->getAccountFlag(iClient::X_CERTONLY)) - accountFlags += "CERTONLY "; - - /* client is authed - show it here */ - bot->Notice(theClient, "%s is authed as [%s]", - st[1].c_str(), - Target->getAccount().c_str()); - if( !accountFlags.empty()) - bot->Notice(theClient, " Flags: %s", accountFlags.c_str()); -} - -bot->Notice( theClient, "Numeric: %s, UserModes: %s, Server Numeric: %s (%s)", - Target->getCharYYXXX().c_str(), - Target->getStringModes().c_str(), - targetServer->getCharYY().c_str(), - targetServer->getName().c_str() - ) ; - -if( Target->isModeZ() ) - { - bot->Notice( theClient, "%s is connected using TLS", - st[ 1 ].c_str()) ; - if( Target->hasTlsFingerprint() ) - bot->Notice( theClient, " Fingerprint: %s", compactToCanonical( Target->getTlsFingerprint() ).c_str() ) ; - } - -if( Target->isOper() ) - { - bot->Notice( theClient, "%s is an IRCoperator", - st[ 1 ].c_str() ) ; - } - -if(Target->getMode(iClient::MODE_SERVICES)) - { - return true; - } - -vector< string > channels ; -string curChannel ; -string::size_type curPlace; -string tChannel; -char curChar[10]; -gnuworld::Channel* theChannel; -gnuworld::ChannelUser* theChannelUser; -bool hasCC; //Channel has control codes - -for( iClient::const_channelIterator ptr = Target->channels_begin() ; - ptr != Target->channels_end() ; ++ptr ) - { - curChannel = ""; - tChannel = (*ptr)->getName(); +bool WHOISCommand::Exec(iClient* theClient, const string& Message) { + StringTokenizer st(Message); + if (st.size() < 2) { + Usage(theClient); + return true; + } + + iClient* Target = Network->findNick(st[1]); + if (NULL == Target) { + bot->Notice(theClient, "Unable to find nick: %s", st[1].c_str()); + return true; + } + bot->MsgChanLog("WHOIS %s\n", st.assemble(1).c_str()); + + iServer* targetServer = Network->findServer(Target->getIntYY()); + if (NULL == targetServer) { + elog << "WHOISCommand> Unable to find server: " << Target->getIntYY() << endl; + return false; + } + + if ((Target->isModeX()) && (Target->isModeR())) { + bot->Notice(theClient, "%s is %s (%s) [%s]", st[1].c_str(), + Target->getNickUserHost().c_str(), Target->getRealNickUserHost().c_str(), + xIP(Target->getIP()).GetNumericIP().c_str()); + + } else { + bot->Notice(theClient, "%s is %s [%s]", st[1].c_str(), Target->getNickUserHost().c_str(), + xIP(Target->getIP()).GetNumericIP().c_str()); + } + + if (Target->getNickTS() != Target->getFirstNickTS()) { + bot->Notice(theClient, "%s has used its current nickname for %s [since %ld]", st[1].c_str(), + Ago(Target->getNickTS()), Target->getNickTS()); + } + + bot->Notice(theClient, "%s has been connected for %s [since %ld]", st[1].c_str(), + Ago(Target->getFirstNickTS()), Target->getFirstNickTS()); + + if (Target->isModeR()) { + string accountFlags; + if (Target->getAccountFlag(iClient::X_TOTP_REQ_IPR) || + Target->getAccountFlag(iClient::X_TOTP_ENABLED)) { + accountFlags += + (Target->getAccountFlag(iClient::X_TOTP_REQ_IPR)) ? "TOTP_REQ_IPR " : "TOTP "; + + // Check for disabled methods + std::string disabled; + if (Target->getAccountFlag(iClient::X_WEB_DISABLE_TOTP)) + disabled += (disabled.empty() ? "WEB" : ",WEB"); + if (Target->getAccountFlag(iClient::X_CERT_DISABLE_TOTP)) + disabled += (disabled.empty() ? "CERT" : ",CERT"); + if (!disabled.empty()) + accountFlags += "(DISABLE=" + disabled + ") "; + } + + if (Target->getAccountFlag(iClient::X_GLOBAL_SUSPEND)) + accountFlags += "SUSPENDED "; + if (Target->getAccountFlag(iClient::X_FRAUD)) + accountFlags += "FRAUD "; + if (Target->getAccountFlag(iClient::X_CERTONLY)) + accountFlags += "CERTONLY "; + + /* client is authed - show it here */ + bot->Notice(theClient, "%s is authed as [%s]", st[1].c_str(), Target->getAccount().c_str()); + if (!accountFlags.empty()) + bot->Notice(theClient, " Flags: %s", accountFlags.c_str()); + } + + bot->Notice(theClient, "Numeric: %s, UserModes: %s, Server Numeric: %s (%s)", + Target->getCharYYXXX().c_str(), Target->getStringModes().c_str(), + targetServer->getCharYY().c_str(), targetServer->getName().c_str()); + + if (Target->isModeZ()) { + bot->Notice(theClient, "%s is connected using TLS", st[1].c_str()); + if (Target->hasTlsFingerprint()) + bot->Notice(theClient, " Fingerprint: %s", + compactToCanonical(Target->getTlsFingerprint()).c_str()); + } + + if (Target->isOper()) { + bot->Notice(theClient, "%s is an IRCoperator", st[1].c_str()); + } + + if (Target->getMode(iClient::MODE_SERVICES)) { + return true; + } + + vector channels; + string curChannel; + string::size_type curPlace; + string tChannel; + char curChar[10]; + gnuworld::Channel* theChannel; + gnuworld::ChannelUser* theChannelUser; + bool hasCC; // Channel has control codes + + for (iClient::const_channelIterator ptr = Target->channels_begin(); + ptr != Target->channels_end(); ++ptr) { + curChannel = ""; + tChannel = (*ptr)->getName(); theChannel = (*ptr); theChannelUser = theChannel->findUser(Target); tChannel = theChannel->getName(); - if(theChannelUser->getMode(gnuworld::ChannelUser::MODE_V)) tChannel = "+" + tChannel; - if(theChannelUser->getMode(gnuworld::ChannelUser::MODE_O)) tChannel = "@" + tChannel; - if ((theChannel->getMode(Channel::MODE_S)) || (theChannel->getMode(Channel::MODE_P))) - tChannel = "!" + tChannel; - - hasCC = false; - for(curPlace = 0; curPlace < tChannel.size();++curPlace) - { - if(((tChannel[curPlace] > 1) && (tChannel[curPlace] < 4)) - || (tChannel[curPlace] == 15) - || ((tChannel[curPlace] > 27) && (tChannel[curPlace] < 33)) - || (tChannel[curPlace] == 22) - || (tChannel[curPlace] == char(160)) - || ((unsigned(tChannel[curPlace]) > 252) - && (unsigned(tChannel[curPlace]) <= 254))) - { - hasCC = true; - sprintf(curChar,"%d",tChannel[curPlace]); - curChannel += string("\x16^") + curChar + string("\x16"); - } - else - { - curChannel += tChannel[curPlace]; - } - } - - if(hasCC) - { - curChannel = string("*") + curChannel; - } - - channels.push_back( curChannel) ; - } - -if( channels.empty() ) - { - return true ; - } - -string chanNames ; -for( vector< string >::size_type i = 0 ; i < channels.size() ; i++ ) - { - if ((chanNames.size() + channels[i].size()) > 410) - { - /* need to split lines up */ - bot->Notice(theClient, "On channels: %s", chanNames.c_str()); - chanNames = ""; - } - chanNames += channels[ i ] ; - if( (i + 1) < channels.size() ) - { - chanNames += ", " ; - } - } - -bot->Notice( theClient, "On channels: %s", chanNames.c_str() ) ; -bot->Notice( theClient, "* - Channel contains control codes" ); -bot->Notice( theClient, "! - Channel is +s or +p" ); - -return true ; -} - -} + if (theChannelUser->getMode(gnuworld::ChannelUser::MODE_V)) + tChannel = "+" + tChannel; + if (theChannelUser->getMode(gnuworld::ChannelUser::MODE_O)) + tChannel = "@" + tChannel; + if ((theChannel->getMode(Channel::MODE_S)) || (theChannel->getMode(Channel::MODE_P))) + tChannel = "!" + tChannel; + + hasCC = false; + for (curPlace = 0; curPlace < tChannel.size(); ++curPlace) { + if (((tChannel[curPlace] > 1) && (tChannel[curPlace] < 4)) || + (tChannel[curPlace] == 15) || + ((tChannel[curPlace] > 27) && (tChannel[curPlace] < 33)) || + (tChannel[curPlace] == 22) || (tChannel[curPlace] == char(160)) || + ((unsigned(tChannel[curPlace]) > 252) && (unsigned(tChannel[curPlace]) <= 254))) { + hasCC = true; + sprintf(curChar, "%d", tChannel[curPlace]); + curChannel += string("\x16^") + curChar + string("\x16"); + } else { + curChannel += tChannel[curPlace]; + } + } + + if (hasCC) { + curChannel = string("*") + curChannel; + } + + channels.push_back(curChannel); + } + + if (channels.empty()) { + return true; + } + + string chanNames; + for (vector::size_type i = 0; i < channels.size(); i++) { + if ((chanNames.size() + channels[i].size()) > 410) { + /* need to split lines up */ + bot->Notice(theClient, "On channels: %s", chanNames.c_str()); + chanNames = ""; + } + chanNames += channels[i]; + if ((i + 1) < channels.size()) { + chanNames += ", "; + } + } + + bot->Notice(theClient, "On channels: %s", chanNames.c_str()); + bot->Notice(theClient, "* - Channel contains control codes"); + bot->Notice(theClient, "! - Channel is +s or +p"); + + return true; } +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/ccBadChannel.cc b/mod.ccontrol/ccBadChannel.cc index bfed3cfd..144672d0 100644 --- a/mod.ccontrol/ccBadChannel.cc +++ b/mod.ccontrol/ccBadChannel.cc @@ -20,118 +20,90 @@ * $Id: ccBadChannel.cc,v 1.7 2007/08/28 16:10:03 dan_karrels Exp $ */ -#include -#include "dbHandle.h" -#include "ccontrol.h" -#include "ccBadChannel.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ -using std::string ; - -namespace uworld -{ - -ccBadChannel::ccBadChannel(dbHandle* SQLDb, unsigned int Place) -{ -Name = SQLDb->GetValue(Place,0); -Reason = SQLDb->GetValue(Place,1); -AddedBy = SQLDb->GetValue(Place,2); +#include +#include "dbHandle.h" +#include "ccontrol.h" +#include "ccBadChannel.h" +#include "gnuworld_config.h" + +namespace gnuworld { +using std::string; + +namespace uworld { + +ccBadChannel::ccBadChannel(dbHandle* SQLDb, unsigned int Place) { + Name = SQLDb->GetValue(Place, 0); + Reason = SQLDb->GetValue(Place, 1); + AddedBy = SQLDb->GetValue(Place, 2); } -bool ccBadChannel::Update(dbHandle* SQLDb) -{ - -if(!dbConnected) - { +bool ccBadChannel::Update(dbHandle* SQLDb) { + + if (!dbConnected) { return false; - } - -stringstream theQuery; -theQuery << "UPDATE BadChannels SET Reason = '" - << escapeSQLChars(Reason) - << "', AddedBy = '" - << escapeSQLChars(AddedBy) - << "' WHERE lower(Name) = '" - << escapeSQLChars(string_lower(Name)) << "'" - << ends; - -elog << "ccBadChannel::Update> " - << theQuery.str() - << endl; - -if( !SQLDb->Exec( theQuery ) ) -//if (PGRES_COMMAND_OK != status) - { - elog << "ccBadChannel::Update SQL ERROR : " - << SQLDb->ErrorMessage() << endl; - return false; - } -//delete[] theQuery.str() ; -return true; + } + + stringstream theQuery; + theQuery << "UPDATE BadChannels SET Reason = '" << escapeSQLChars(Reason) << "', AddedBy = '" + << escapeSQLChars(AddedBy) << "' WHERE lower(Name) = '" + << escapeSQLChars(string_lower(Name)) << "'" << ends; + + elog << "ccBadChannel::Update> " << theQuery.str() << endl; + + if (!SQLDb->Exec(theQuery)) + // if (PGRES_COMMAND_OK != status) + { + elog << "ccBadChannel::Update SQL ERROR : " << SQLDb->ErrorMessage() << endl; + return false; + } + // delete[] theQuery.str() ; + return true; } -bool ccBadChannel::Delete(dbHandle* SQLDb) -{ - -if(!dbConnected) - { +bool ccBadChannel::Delete(dbHandle* SQLDb) { + + if (!dbConnected) { return false; - } - -stringstream theQuery; -theQuery << "DELETE FROM BadChannels WHERE lower(Name) = '" - << escapeSQLChars(string_lower(Name)) << "'" - << ends; - -elog << "ccBadChannel::Delete> " - << theQuery.str() - << endl; - -if( !SQLDb->Exec( theQuery ) ) -//if (PGRES_COMMAND_OK != status) - { - elog << "ccBadChannel::Delete SQL ERROR : " - << SQLDb->ErrorMessage() << endl; + } + + stringstream theQuery; + theQuery << "DELETE FROM BadChannels WHERE lower(Name) = '" + << escapeSQLChars(string_lower(Name)) << "'" << ends; + + elog << "ccBadChannel::Delete> " << theQuery.str() << endl; + + if (!SQLDb->Exec(theQuery)) + // if (PGRES_COMMAND_OK != status) + { + elog << "ccBadChannel::Delete SQL ERROR : " << SQLDb->ErrorMessage() << endl; return false; - } -return true; + } + return true; } -bool ccBadChannel::Insert(dbHandle* SQLDb) -{ - -if(!dbConnected) - { +bool ccBadChannel::Insert(dbHandle* SQLDb) { + + if (!dbConnected) { return false; - } - -stringstream theQuery; -theQuery << "INSERT INTO BadChannels (Name,Reason,AddedBy) VALUES ('" - << escapeSQLChars(Name) << "','" - << escapeSQLChars(Reason) - << "','" - << escapeSQLChars(AddedBy) - << "')" - << ends; - -elog << "ccBadChannel::Insert> " - << theQuery.str() - << endl; - -if( !SQLDb->Exec( theQuery ) ) -//if (PGRES_COMMAND_OK != status) - { - elog << "ccBadChannel::Insert SQL ERROR : " - << SQLDb->ErrorMessage() << endl; + } + + stringstream theQuery; + theQuery << "INSERT INTO BadChannels (Name,Reason,AddedBy) VALUES ('" << escapeSQLChars(Name) + << "','" << escapeSQLChars(Reason) << "','" << escapeSQLChars(AddedBy) << "')" << ends; + + elog << "ccBadChannel::Insert> " << theQuery.str() << endl; + + if (!SQLDb->Exec(theQuery)) + // if (PGRES_COMMAND_OK != status) + { + elog << "ccBadChannel::Insert SQL ERROR : " << SQLDb->ErrorMessage() << endl; return false; - } + } -return true; + return true; } -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/ccBadChannel.h b/mod.ccontrol/ccBadChannel.h index 6e5d98ac..12c8d39f 100644 --- a/mod.ccontrol/ccBadChannel.h +++ b/mod.ccontrol/ccBadChannel.h @@ -18,72 +18,59 @@ * * $Id: ccBadChannel.h,v 1.3 2007/08/28 16:10:03 dan_karrels Exp $ */ - + #ifndef __CCBADCHANNEL_H_ #define __CCBADCHANNEL_H_ -#include +#include -#include "dbHandle.h" +#include "dbHandle.h" using namespace std; -namespace gnuworld -{ - -namespace uworld -{ - -class ccBadChannel -{ -public: - ccBadChannel() {} - - ccBadChannel(dbHandle* , unsigned int); - - ccBadChannel(const string& _Name, const string& _Reason , - const string& _AddedBy) : Name(_Name), - Reason(_Reason),AddedBy(_AddedBy) {}; - - ~ccBadChannel(){} - - bool Update(dbHandle*); - - bool Insert(dbHandle*); - - bool Delete(dbHandle*); - - const string& getName() const - { return Name; } - - const string& getReason() const - { return Reason; } - - const string& getAddedBy() const - { return AddedBy; } - - void setName(const string& _Name) - { Name = _Name; } - - void setReason(const string& _Reason) - { Reason = _Reason; } - - void setAddedBy(const string& _AddedBy) - { AddedBy = _AddedBy; } - -private: - - string Name; - - string Reason; - - string AddedBy; - - -}; - -} - -} - -#endif +namespace gnuworld { + +namespace uworld { + +class ccBadChannel { + public: + ccBadChannel() {} + + ccBadChannel(dbHandle*, unsigned int); + + ccBadChannel(const string& _Name, const string& _Reason, const string& _AddedBy) + : Name(_Name), Reason(_Reason), AddedBy(_AddedBy) {}; + + ~ccBadChannel() {} + + bool Update(dbHandle*); + + bool Insert(dbHandle*); + + bool Delete(dbHandle*); + + const string& getName() const { return Name; } + + const string& getReason() const { return Reason; } + + const string& getAddedBy() const { return AddedBy; } + + void setName(const string& _Name) { Name = _Name; } + + void setReason(const string& _Reason) { Reason = _Reason; } + + void setAddedBy(const string& _AddedBy) { AddedBy = _AddedBy; } + + private: + string Name; + + string Reason; + + string AddedBy; +}; + +} // namespace uworld + +} // namespace gnuworld + +#endif diff --git a/mod.ccontrol/ccException.cc b/mod.ccontrol/ccException.cc index bccb85a1..ca27d5af 100644 --- a/mod.ccontrol/ccException.cc +++ b/mod.ccontrol/ccException.cc @@ -1,7 +1,7 @@ /** * ccException.cc * Exception class - * + * * 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 @@ -19,336 +19,239 @@ * * $Id: ccException.cc,v 1.17 2008/12/27 23:34:31 hidden1 Exp $ */ - -#include -#include - -#include -#include -#include - -#include "ELog.h" -#include "misc.h" -#include "match.h" -#include "ccException.h" -#include "ccontrol.h" -#include "gnuworld_config.h" -#include "StringTokenizer.h" - -namespace gnuworld -{ - -using std::string ; -using std::endl ; -using std::stringstream ; -using std::ends ; - -namespace uworld -{ - -//extern unsigned int dbConnected; + +#include +#include + +#include +#include +#include + +#include "ELog.h" +#include "misc.h" +#include "match.h" +#include "ccException.h" +#include "ccontrol.h" +#include "gnuworld_config.h" +#include "StringTokenizer.h" + +namespace gnuworld { + +using std::endl; +using std::ends; +using std::string; +using std::stringstream; + +namespace uworld { + +// extern unsigned int dbConnected; unsigned int ccIpLnb::numAllocated = 0; unsigned int ccIpLisp::numAllocated = 0; -void ccIpLnb::setCidr( const string& _cidr ) -{ -cidr = _cidr; -StringTokenizer st(cidr,'/'); -if (st.size() == 2) { - cidr1 = st[0]; - cidr2 = atoi(st[1].c_str()); -} +void ccIpLnb::setCidr(const string& _cidr) { + cidr = _cidr; + StringTokenizer st(cidr, '/'); + if (st.size() == 2) { + cidr1 = st[0]; + cidr2 = atoi(st[1].c_str()); + } } -ccIpLisp::ccIpLisp(dbHandle* _SQLDb) -{ - ++numAllocated; - maxlimit = 0; - maxIdentlimit = 0; - active = 1; - nogline = 0; - v6 = 2; - AddedOn = ::time(0); - ModOn = ::time(0); - SQLDb = _SQLDb; - count = 0; - email = "N/A"; - clonecidr = 64; - forcecount = 0; - glunidented = 0; +ccIpLisp::ccIpLisp(dbHandle* _SQLDb) { + ++numAllocated; + maxlimit = 0; + maxIdentlimit = 0; + active = 1; + nogline = 0; + v6 = 2; + AddedOn = ::time(0); + ModOn = ::time(0); + SQLDb = _SQLDb; + count = 0; + email = "N/A"; + clonecidr = 64; + forcecount = 0; + glunidented = 0; } +ccIpLisp::~ccIpLisp() { --numAllocated; } -ccIpLisp::~ccIpLisp() -{ - --numAllocated; +ccIpLnb::ccIpLnb(dbHandle* _SQLDb) { + ++numAllocated; + ipLisp = 0; + AddedOn = ::time(0); + SQLDb = _SQLDb; + ipLispid = 0; + cidr2 = 128; + count = 0; } -ccIpLnb::ccIpLnb(dbHandle* _SQLDb) -{ - ++numAllocated; - ipLisp = 0; - AddedOn = ::time(0); - SQLDb = _SQLDb; - ipLispid = 0; - cidr2 = 128; - count = 0; +ccIpLnb::~ccIpLnb() { --numAllocated; } + +int ccIpLisp::loadData(const string& Name) { + int i = 0; + static const char Main[] = + "SELECT " + "name,id,AddedBy,AddedOn,lastmodby,lastmodon,maxlimit,active,email,clonecidr,forcecount," + "glunidented,isgroup,maxidentlimit,nogline FROM ipLISPs WHERE name = '"; + + if ((!dbConnected) || !(SQLDb)) { + return false; + } + + stringstream theQuery; + theQuery << Main << escapeSQLChars(Name) << "'" << ends; + + elog << "ccIpLisp::loadData> " << theQuery.str().c_str() << endl; + + // TODO: Isn't this impossible? + if (!SQLDb->Exec(theQuery, true) && (SQLDb->Tuples() > 0)) + // if( (PGRES_TUPLES_OK != status) && (SQLDb->Tuples() > 0) ) + { + return false; + } + + setName(SQLDb->GetValue(i, 0)); + setID(atoi(SQLDb->GetValue(i, 1).c_str())); + setAddedBy(SQLDb->GetValue(i, 2)); + setAddedOn(static_cast(atoi(SQLDb->GetValue(i, 3).c_str()))); + setModBy(SQLDb->GetValue(i, 4)); + setModOn(static_cast(atoi(SQLDb->GetValue(i, 5).c_str()))); + setLimit(atoi(SQLDb->GetValue(i, 6).c_str())); + setActive(atoi(SQLDb->GetValue(i, 7).c_str())); + setEmail(SQLDb->GetValue(i, 8)); + setCloneCidr(atoi(SQLDb->GetValue(i, 9).c_str())); + setForcecount(atoi(SQLDb->GetValue(i, 10).c_str())); + setGlunidented(atoi(SQLDb->GetValue(i, 11).c_str())); + setGroup(atoi(SQLDb->GetValue(i, 12).c_str())); + setIdentLimit(atoi(SQLDb->GetValue(i, 13).c_str())); + setNoGline(atoi(SQLDb->GetValue(i, 14).c_str())); + + theQuery.str(""); + + return true; } +int ccIpLisp::updateData() { + static const char* Main = "UPDATE ipLISPs SET AddedBy = '"; + + if (!dbConnected) { + return false; + } + + stringstream theQuery; + theQuery << Main << escapeSQLChars(AddedBy) << "', maxlimit = " << maxlimit + << ", maxidentlimit = " << maxIdentlimit << ", addedon = " << AddedOn + << ", active = " << active << ", nogline = " << nogline << ", lastmodon = " << ModOn + << ", clonecidr = " << clonecidr << ", forcecount = " << forcecount + << ", glunidented = " << glunidented << ", isgroup = " << group << ", lastmodby = '" + << escapeSQLChars(ModBy) << "', email = '" << escapeSQLChars(email) << "', name = '" + << escapeSQLChars(Name) << "' WHERE id = " << id << ends; + + elog << "ccIpLisp::Update> " << theQuery.str().c_str() << endl; + + if (SQLDb->Exec(theQuery)) + // if( PGRES_COMMAND_OK == status ) + { + return true; + } else { + elog << "ccIpLisp::Update> SQL Failure: " << SQLDb->ErrorMessage() << endl; + return false; + } +} -ccIpLnb::~ccIpLnb() -{ - --numAllocated; +bool ccIpLisp::Insert() { + static const char* quer = "INSERT INTO " + "ipLISPs(name,maxlimit,maxidentlimit,addedby,addedon,lastmodby," + "lastmodon,email,clonecidr,forcecount,glunidented,isgroup) VALUES ('"; + + if (!dbConnected) { + return false; + } + + stringstream query; + query << quer << escapeSQLChars(Name) << "'," << maxlimit << "," << maxIdentlimit << ",'" + << escapeSQLChars(AddedBy) << "'," << AddedOn << ",'" << escapeSQLChars(ModBy) << "'," + << ModOn << ",'" << escapeSQLChars(email) << "'," << clonecidr << "," << forcecount << "," + << glunidented << "," << group << ")" << ends; + + elog << "ccIpLisp::Insert> " << query.str().c_str() << endl; + + if (!SQLDb->Exec(query)) + // if(PGRES_COMMAND_OK != status) + { + elog << "ccIpLisp::Insert> SQL Failure: " << SQLDb->ErrorMessage() << endl; + return false; + } + return true; + // return (PGRES_COMMAND_OK == status) ; } +bool ccIpLnb::Insert() { + static const char* quer = "INSERT INTO ipLNetblocks(cidr,ispid,addedby,addedon) VALUES ('"; -int ccIpLisp::loadData(const string& Name) -{ -int i = 0; -static const char Main[] = "SELECT name,id,AddedBy,AddedOn,lastmodby,lastmodon,maxlimit,active,email,clonecidr,forcecount,glunidented,isgroup,maxidentlimit,nogline FROM ipLISPs WHERE name = '"; - -if((!dbConnected) || !(SQLDb)) - { - return false; - } - -stringstream theQuery; -theQuery << Main - << escapeSQLChars(Name) - << "'" - << ends; - -elog << "ccIpLisp::loadData> " - << theQuery.str().c_str() - << endl; - -// TODO: Isn't this impossible? -if( !SQLDb->Exec( theQuery, true ) && (SQLDb->Tuples() > 0) ) -//if( (PGRES_TUPLES_OK != status) && (SQLDb->Tuples() > 0) ) - { - return false; - } - -setName(SQLDb->GetValue(i,0)); -setID(atoi(SQLDb->GetValue(i,1).c_str())); -setAddedBy(SQLDb->GetValue(i,2)) ; -setAddedOn(static_cast< time_t >( - atoi( SQLDb->GetValue(i,3).c_str() ) )) ; -setModBy(SQLDb->GetValue(i,4)) ; -setModOn(static_cast< time_t >( - atoi( SQLDb->GetValue(i,5).c_str() ) )) ; -setLimit(atoi(SQLDb->GetValue(i,6).c_str())); -setActive(atoi(SQLDb->GetValue(i,7).c_str())); -setEmail(SQLDb->GetValue(i,8)); -setCloneCidr(atoi(SQLDb->GetValue(i,9).c_str())); -setForcecount(atoi(SQLDb->GetValue(i,10).c_str())); -setGlunidented(atoi(SQLDb->GetValue(i,11).c_str())); -setGroup(atoi(SQLDb->GetValue(i,12).c_str())); -setIdentLimit(atoi(SQLDb->GetValue(i,13).c_str())); -setNoGline(atoi(SQLDb->GetValue(i,14).c_str())); - -theQuery.str(""); - -return true; + if (!dbConnected) { + return false; + } + stringstream query; + query << quer << escapeSQLChars(cidr) << "'," << ipLispid << ",'" << escapeSQLChars(AddedBy) + << "'," << AddedOn << ")" << ends; + + elog << "ccIpLnb::Insert> " << query.str().c_str() << endl; + + if (!SQLDb->Exec(query)) + // if(PGRES_COMMAND_OK != status) + { + elog << "ccIpLnb::Insert> SQL Failure: " << SQLDb->ErrorMessage() << endl; + return false; + } + return true; + // return (PGRES_COMMAND_OK == status) ; } +bool ccIpLisp::Delete() { + static const char* quer = "DELETE FROM ipLISPs WHERE name = '"; -int ccIpLisp::updateData() -{ -static const char *Main = "UPDATE ipLISPs SET AddedBy = '"; - -if(!dbConnected) - { - return false; - } - -stringstream theQuery; -theQuery << Main - << escapeSQLChars(AddedBy) - << "', maxlimit = " - << maxlimit - << ", maxidentlimit = " - << maxIdentlimit - << ", addedon = " - << AddedOn - << ", active = " - << active - << ", nogline = " - << nogline - << ", lastmodon = " - << ModOn - << ", clonecidr = " - << clonecidr - << ", forcecount = " - << forcecount - << ", glunidented = " - << glunidented - << ", isgroup = " - << group - << ", lastmodby = '" - << escapeSQLChars(ModBy) - << "', email = '" - << escapeSQLChars(email) - << "', name = '" - << escapeSQLChars(Name) - << "' WHERE id = " - << id - << ends; - -elog << "ccIpLisp::Update> " - << theQuery.str().c_str() - << endl; - -if( SQLDb->Exec( theQuery ) ) -//if( PGRES_COMMAND_OK == status ) - { - return true; - } -else - { - elog << "ccIpLisp::Update> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - return false; - } + if (!dbConnected) { + return false; + } -} + stringstream query; + query << quer << escapeSQLChars(Name) << "'" << ends; -bool ccIpLisp::Insert() -{ -static const char *quer = "INSERT INTO ipLISPs(name,maxlimit,maxidentlimit,addedby,addedon,lastmodby,lastmodon,email,clonecidr,forcecount,glunidented,isgroup) VALUES ('"; - -if(!dbConnected) - { - return false; - } - -stringstream query; -query << quer - << escapeSQLChars(Name) << "'," - << maxlimit - << "," << maxIdentlimit - << ",'" << escapeSQLChars(AddedBy) - << "'," << AddedOn - << ",'" << escapeSQLChars(ModBy) - << "'," << ModOn - << ",'" << escapeSQLChars(email) - << "'," << clonecidr - << "," << forcecount - << "," << glunidented - << "," << group - << ")" << ends; - -elog << "ccIpLisp::Insert> " - << query.str().c_str() - << endl; - -if( !SQLDb->Exec( query ) ) -//if(PGRES_COMMAND_OK != status) - { - elog << "ccIpLisp::Insert> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - return false ; - } -return true ; -//return (PGRES_COMMAND_OK == status) ; -} + elog << "ccIpLisp::delException> " << query.str().c_str() << endl; -bool ccIpLnb::Insert() -{ -static const char *quer = "INSERT INTO ipLNetblocks(cidr,ispid,addedby,addedon) VALUES ('"; - -if(!dbConnected) - { - return false; - } - -stringstream query; -query << quer - << escapeSQLChars(cidr) << "'," - << ipLispid - << ",'" << escapeSQLChars(AddedBy) - << "'," << AddedOn - << ")" << ends; - -elog << "ccIpLnb::Insert> " - << query.str().c_str() - << endl; - -if( !SQLDb->Exec( query ) ) -//if(PGRES_COMMAND_OK != status) - { - elog << "ccIpLnb::Insert> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - return false ; - } -return true ; -//return (PGRES_COMMAND_OK == status) ; + if (!SQLDb->Exec(query)) + // if( PGRES_COMMAND_OK != status ) + { + elog << "ccIpLisp::findException> SQL Failure: " << SQLDb->ErrorMessage() << endl; + return false; + } + return true; } -bool ccIpLisp::Delete() -{ -static const char *quer = "DELETE FROM ipLISPs WHERE name = '"; - -if(!dbConnected) - { - return false; - } - -stringstream query; -query << quer - << escapeSQLChars(Name) << "'" - << ends; - -elog << "ccIpLisp::delException> " - << query.str().c_str() - << endl ; - -if( !SQLDb->Exec( query ) ) -//if( PGRES_COMMAND_OK != status ) - { - elog << "ccIpLisp::findException> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - return false; - } -return true; -} +bool ccIpLnb::Delete() { + static const char* quer = "DELETE FROM ipLNetblocks WHERE cidr = '"; -bool ccIpLnb::Delete() -{ -static const char *quer = "DELETE FROM ipLNetblocks WHERE cidr = '"; - -if(!dbConnected) - { - return false; - } - -stringstream query; -query << quer - << escapeSQLChars(cidr) << "'" - << " and ispid = " - << ipLispid - << ends; - -elog << "ccIpLnb::delException> " - << query.str().c_str() - << endl ; - -if( !SQLDb->Exec( query ) ) -//if( PGRES_COMMAND_OK != status ) - { - elog << "ccIpLnb::findException> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - return false; - } -return true; -} + if (!dbConnected) { + return false; + } + stringstream query; + query << quer << escapeSQLChars(cidr) << "'" + << " and ispid = " << ipLispid << ends; + elog << "ccIpLnb::delException> " << query.str().c_str() << endl; + + if (!SQLDb->Exec(query)) + // if( PGRES_COMMAND_OK != status ) + { + elog << "ccIpLnb::findException> SQL Failure: " << SQLDb->ErrorMessage() << endl; + return false; + } + return true; } -} + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/ccException.h b/mod.ccontrol/ccException.h index 506050a2..4fe816d6 100644 --- a/mod.ccontrol/ccException.h +++ b/mod.ccontrol/ccException.h @@ -22,270 +22,201 @@ #ifndef __CCEXCEPTION_H #define __CCEXCEPTION_H "$Id: ccException.h,v 1.13 2009/07/26 18:30:37 mrbean_ Exp $" -#include - -#include - -#include "dbHandle.h" - -#include "match.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -typedef std::map ipLclonesMapType; - - -class ccIpLisp -{ -public: - ccIpLisp(dbHandle* _SQLDb); - virtual ~ccIpLisp(); - - - inline bool isActive() const - { return (active == 1 ? true : false); } - - inline bool isNoGline() const - { return (nogline == 1 ? true : false); } - - inline bool isGlunidented() const - { return (glunidented == 1 ? true : false); } - - inline bool isForcecount() const - { return (forcecount == 1 ? true : false); } - - inline int isv6() const - { return v6; } - - inline bool isGroup() const - { return (group == 1 ? true : false); } - - inline const string& getName() const - { return Name; } - - inline const int& getID() const - { return id; } - - inline const int& getLimit() const - { return maxlimit; } - - inline const int& getIdentLimit() const - { return maxIdentlimit; } - - inline const string& getEmail() const - { return email; } - - inline const int& getCloneCidr() const - { return clonecidr; } - - inline const string& getAddedBy() const - { return AddedBy; } - - inline time_t getAddedOn() const - { return AddedOn; } - - inline const string& getModBy() const - { return ModBy; } - - inline time_t getModOn() const - { return ModOn; } - - inline const int& getCount() const - { return count; } - - inline void setName( const string& _Name ) - { Name = _Name; } - - inline void setLimit( const int _maxlimit ) - { maxlimit = _maxlimit; } - - inline void setIdentLimit( const int _maxIdentlimit ) - { maxIdentlimit = _maxIdentlimit; } - - inline void setID( const int _id ) - { id = _id; } - - inline void setAddedBy( const string& _AddedBy) - { AddedBy = _AddedBy; } - - inline void setAddedOn( const time_t _AddedOn ) - { AddedOn = _AddedOn; } - - inline void setModBy( const string& _ModBy) - { ModBy = _ModBy; } - - inline void setModOn( const time_t _ModOn ) - { ModOn = _ModOn; } - - inline void setEmail( const string& _email ) - { email = _email; } - - inline void setCloneCidr( const int _clonecidr ) - { clonecidr = _clonecidr; } - - inline void setActive( const int _active) - { active = _active; } - - inline void setNoGline( const int _nogline) - { nogline = _nogline; } - - inline void setGlunidented( const int _glunidented) - { glunidented = _glunidented; } - - inline void setForcecount( const int _forcecount) - { forcecount = _forcecount; } - - inline void setv6( const int _v6) - { v6 = _v6; } - - inline void setGroup( const int _group) - { group = _group; } - - inline void incCount( const int _count ) - { count += _count; } - - inline void setSqldb(dbHandle* _SQLDb) - { SQLDb = _SQLDb; } - - int loadData(const string& Name); - - int updateData(); - - bool Insert(); - - bool Delete(); - - static unsigned int numAllocated; - - ipLclonesMapType ipLidentclonesMap; - - -protected: - - int id; - int forcecount; - int glunidented; - int v6; - int group; - string Name; - string email; - int clonecidr; - int maxlimit; - int maxIdentlimit; - int count; - int active; - int nogline; - string AddedBy; - time_t AddedOn; - string ModBy; - time_t ModOn; - dbHandle* SQLDb; - -}; - -class ccIpLnb -{ -public: - ccIpLnb(dbHandle* _SQLDb); - virtual ~ccIpLnb(); - - inline bool operator==( const string& ExceptionHost ) const - { return (!strcasecmp( cidr, ExceptionHost ) - || !match(cidr.c_str(),ExceptionHost.c_str())) ; } - - inline bool isActive() const - { return ipLisp->isActive(); } - - inline bool isNoGline() const - { return ipLisp->isNoGline(); } - - inline bool isForcecount() const - { return ipLisp->isForcecount(); } - - inline const string& getCidr() const - { return cidr; } - - inline const string& getCidr1() const - { return cidr1; } - - inline const int& getCidr2() const - { return cidr2; } - - inline const int& getIpLispID() const - { return ipLispid; } - - inline const int& getCount() const - { return count; } - - inline const ccIpLisp* getIpLisp() const - { return ipLisp; } - - inline const int& getCloneCidr() const - { return ipLisp->getCloneCidr(); } - - inline const int& getLimit() const - { return ipLisp->getLimit(); } - - inline const int& getIdentLimit() const - { return ipLisp->getIdentLimit(); } - - inline const string& getAddedBy() const - { return AddedBy; } - - inline time_t getAddedOn() const - { return AddedOn; } - - inline void setIpLisp( ccIpLisp* _ipLisp ) - { ipLisp = _ipLisp; } - - inline void setIpLispID( const int _ipLispid ) - { ipLispid = _ipLispid; } - - inline void incCount( const int _count ) - { count += _count; } - - inline void setAddedBy( const string& _AddedBy) - { AddedBy = _AddedBy; } - - inline void setAddedOn( const time_t _AddedOn ) - { AddedOn = _AddedOn; } - - void setCidr( const string& _cidr ); - - inline void setSqldb(dbHandle* _SQLDb) - { SQLDb = _SQLDb; } - - - - bool Insert(); - - bool Delete(); - - ipLclonesMapType ipLclonesMap; - - - ccIpLisp* ipLisp; - - static unsigned int numAllocated; - -protected: - - int ipLispid; - int count; - string cidr; - string cidr1; - int cidr2; - string AddedBy; - time_t AddedOn; - dbHandle* SQLDb; - -}; -} -} +#include + +#include + +#include "dbHandle.h" + +#include "match.h" + +namespace gnuworld { + +using std::string; + +namespace uworld { + +typedef std::map ipLclonesMapType; + +class ccIpLisp { + public: + ccIpLisp(dbHandle* _SQLDb); + virtual ~ccIpLisp(); + + inline bool isActive() const { return (active == 1 ? true : false); } + + inline bool isNoGline() const { return (nogline == 1 ? true : false); } + + inline bool isGlunidented() const { return (glunidented == 1 ? true : false); } + + inline bool isForcecount() const { return (forcecount == 1 ? true : false); } + + inline int isv6() const { return v6; } + + inline bool isGroup() const { return (group == 1 ? true : false); } + + inline const string& getName() const { return Name; } + + inline const int& getID() const { return id; } + + inline const int& getLimit() const { return maxlimit; } + + inline const int& getIdentLimit() const { return maxIdentlimit; } + + inline const string& getEmail() const { return email; } + + inline const int& getCloneCidr() const { return clonecidr; } + + inline const string& getAddedBy() const { return AddedBy; } + + inline time_t getAddedOn() const { return AddedOn; } + + inline const string& getModBy() const { return ModBy; } + + inline time_t getModOn() const { return ModOn; } + + inline const int& getCount() const { return count; } + + inline void setName(const string& _Name) { Name = _Name; } + + inline void setLimit(const int _maxlimit) { maxlimit = _maxlimit; } + + inline void setIdentLimit(const int _maxIdentlimit) { maxIdentlimit = _maxIdentlimit; } + + inline void setID(const int _id) { id = _id; } + + inline void setAddedBy(const string& _AddedBy) { AddedBy = _AddedBy; } + + inline void setAddedOn(const time_t _AddedOn) { AddedOn = _AddedOn; } + + inline void setModBy(const string& _ModBy) { ModBy = _ModBy; } + + inline void setModOn(const time_t _ModOn) { ModOn = _ModOn; } + + inline void setEmail(const string& _email) { email = _email; } + + inline void setCloneCidr(const int _clonecidr) { clonecidr = _clonecidr; } + + inline void setActive(const int _active) { active = _active; } + + inline void setNoGline(const int _nogline) { nogline = _nogline; } + + inline void setGlunidented(const int _glunidented) { glunidented = _glunidented; } + + inline void setForcecount(const int _forcecount) { forcecount = _forcecount; } + + inline void setv6(const int _v6) { v6 = _v6; } + + inline void setGroup(const int _group) { group = _group; } + + inline void incCount(const int _count) { count += _count; } + + inline void setSqldb(dbHandle* _SQLDb) { SQLDb = _SQLDb; } + + int loadData(const string& Name); + + int updateData(); + + bool Insert(); + + bool Delete(); + + static unsigned int numAllocated; + + ipLclonesMapType ipLidentclonesMap; + + protected: + int id; + int forcecount; + int glunidented; + int v6; + int group; + string Name; + string email; + int clonecidr; + int maxlimit; + int maxIdentlimit; + int count; + int active; + int nogline; + string AddedBy; + time_t AddedOn; + string ModBy; + time_t ModOn; + dbHandle* SQLDb; +}; + +class ccIpLnb { + public: + ccIpLnb(dbHandle* _SQLDb); + virtual ~ccIpLnb(); + + inline bool operator==(const string& ExceptionHost) const { + return (!strcasecmp(cidr, ExceptionHost) || !match(cidr.c_str(), ExceptionHost.c_str())); + } + + inline bool isActive() const { return ipLisp->isActive(); } + + inline bool isNoGline() const { return ipLisp->isNoGline(); } + + inline bool isForcecount() const { return ipLisp->isForcecount(); } + + inline const string& getCidr() const { return cidr; } + + inline const string& getCidr1() const { return cidr1; } + + inline const int& getCidr2() const { return cidr2; } + + inline const int& getIpLispID() const { return ipLispid; } + + inline const int& getCount() const { return count; } + + inline const ccIpLisp* getIpLisp() const { return ipLisp; } + + inline const int& getCloneCidr() const { return ipLisp->getCloneCidr(); } + + inline const int& getLimit() const { return ipLisp->getLimit(); } + + inline const int& getIdentLimit() const { return ipLisp->getIdentLimit(); } + + inline const string& getAddedBy() const { return AddedBy; } + + inline time_t getAddedOn() const { return AddedOn; } + + inline void setIpLisp(ccIpLisp* _ipLisp) { ipLisp = _ipLisp; } + + inline void setIpLispID(const int _ipLispid) { ipLispid = _ipLispid; } + + inline void incCount(const int _count) { count += _count; } + + inline void setAddedBy(const string& _AddedBy) { AddedBy = _AddedBy; } + + inline void setAddedOn(const time_t _AddedOn) { AddedOn = _AddedOn; } + + void setCidr(const string& _cidr); + + inline void setSqldb(dbHandle* _SQLDb) { SQLDb = _SQLDb; } + + bool Insert(); + + bool Delete(); + + ipLclonesMapType ipLclonesMap; + + ccIpLisp* ipLisp; + + static unsigned int numAllocated; + + protected: + int ipLispid; + int count; + string cidr; + string cidr1; + int cidr2; + string AddedBy; + time_t AddedOn; + dbHandle* SQLDb; +}; +} // namespace uworld +} // namespace gnuworld #endif // __CCEXCEPTION_H diff --git a/mod.ccontrol/ccFloodData.cc b/mod.ccontrol/ccFloodData.cc index 2a1af00e..e84d1f65 100644 --- a/mod.ccontrol/ccFloodData.cc +++ b/mod.ccontrol/ccFloodData.cc @@ -1,7 +1,7 @@ /** * ccFloodData.cc * flood data class - * + * * 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 @@ -19,59 +19,49 @@ * * $Id: ccFloodData.cc,v 1.8 2005/01/12 03:50:29 dan_karrels Exp $ */ - -#include -#include -#include -#include -#include +#include +#include -#include "ccFloodData.h" -#include "Constants.h" -#include "gnuworld_config.h" +#include +#include +#include -namespace gnuworld -{ +#include "ccFloodData.h" +#include "Constants.h" +#include "gnuworld_config.h" -using std::string ; -using std::endl ; +namespace gnuworld { -namespace uworld -{ +using std::endl; +using std::string; + +namespace uworld { unsigned int ccFloodData::numAllocated = 0; -ccFloodData::ccFloodData(const string &_Numeric) - : Numeric(_Numeric), - Logins(0), - IgnoreExpires( 0 ), - Points(0), - lastMessage(0) +ccFloodData::ccFloodData(const string& _Numeric) + : Numeric(_Numeric), Logins(0), IgnoreExpires(0), Points(0), lastMessage(0) { -++numAllocated; + ++numAllocated; } -ccFloodData::~ccFloodData() -{ ---numAllocated; -} +ccFloodData::~ccFloodData() { --numAllocated; } -bool ccFloodData::addPoints(unsigned int _Points) -{ -//Check if the flood points needs to be reset -if((signed)flood::RESET_TIME < (::time(0) - lastMessage)) - Points = 0; +bool ccFloodData::addPoints(unsigned int _Points) { + // Check if the flood points needs to be reset + if ((signed)flood::RESET_TIME < (::time(0) - lastMessage)) + Points = 0; -//Update the new flood points -Points += _Points; -lastMessage = ::time(0); + // Update the new flood points + Points += _Points; + lastMessage = ::time(0); -//We have updated everything, check if the user needs to be silenced + // We have updated everything, check if the user needs to be silenced -return (Points > flood::FLOOD_POINTS); + return (Points > flood::FLOOD_POINTS); } - -} -} //Namespace Gnuworld + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/ccFloodData.h b/mod.ccontrol/ccFloodData.h index 9b6398ac..7e370624 100644 --- a/mod.ccontrol/ccFloodData.h +++ b/mod.ccontrol/ccFloodData.h @@ -25,86 +25,73 @@ #define IGNORE_NOT_FOUND -1 #define IGNORE_REMOVED -2 -#include - -#include - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -class ccFloodData -{ -public: - ccFloodData(const string &); - - virtual ~ccFloodData(); - //Mehods for getting info - - inline const string getNumeric() const - { return Numeric; } - - inline const int& getLogins() const - { return Logins; } - - inline time_t getIgnoreExpires() const - { return IgnoreExpires; } - inline const string getIgnoredHost() const - { return IgnoredHost; } - - //Methods for setting info - - inline void setNumeric( string _Numeric ) - { Numeric = _Numeric; } - - inline void setLogins( int _Logins ) - { Logins = _Logins; } - - inline void add_Login() - { Logins++; } - - inline void resetIgnore() - { IgnoreExpires = 0; IgnoredHost="" ; } - - inline void resetLogins() - { Logins = 0; } - - inline void setIgnoreExpires(time_t _Expires) - { IgnoreExpires =_Expires; } - - inline void setIgnoredHost(string _Host) - { IgnoredHost =_Host; } - - static unsigned int numAllocated; - - inline unsigned int getPoints() const - { return Points; } - - inline time_t getLastMessage() const - { return lastMessage; } - - bool addPoints(unsigned int ); - -protected: - string Numeric; - - int Logins; - - time_t IgnoreExpires; - - string IgnoredHost; - - //Holds the flood points a user has - unsigned int Points; - - //The last time we got data from this user - time_t lastMessage; +#include + +#include + +namespace gnuworld { + +using std::string; + +namespace uworld { + +class ccFloodData { + public: + ccFloodData(const string&); + + virtual ~ccFloodData(); + // Mehods for getting info + + inline const string getNumeric() const { return Numeric; } + + inline const int& getLogins() const { return Logins; } + + inline time_t getIgnoreExpires() const { return IgnoreExpires; } + inline const string getIgnoredHost() const { return IgnoredHost; } + + // Methods for setting info + + inline void setNumeric(string _Numeric) { Numeric = _Numeric; } + + inline void setLogins(int _Logins) { Logins = _Logins; } + + inline void add_Login() { Logins++; } + + inline void resetIgnore() { + IgnoreExpires = 0; + IgnoredHost = ""; + } + + inline void resetLogins() { Logins = 0; } + + inline void setIgnoreExpires(time_t _Expires) { IgnoreExpires = _Expires; } + + inline void setIgnoredHost(string _Host) { IgnoredHost = _Host; } + + static unsigned int numAllocated; + + inline unsigned int getPoints() const { return Points; } + + inline time_t getLastMessage() const { return lastMessage; } + + bool addPoints(unsigned int); + + protected: + string Numeric; + + int Logins; + + time_t IgnoreExpires; + + string IgnoredHost; + + // Holds the flood points a user has + unsigned int Points; + + // The last time we got data from this user + time_t lastMessage; }; // class ccFloodData -} +} // namespace uworld } // namespace gnuworld #endif // __CCFLOODDATA_H diff --git a/mod.ccontrol/ccGline.cc b/mod.ccontrol/ccGline.cc index cd98ab26..29904532 100644 --- a/mod.ccontrol/ccGline.cc +++ b/mod.ccontrol/ccGline.cc @@ -1,7 +1,7 @@ /** * ccGline.cc * Gline class - * + * * 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 @@ -19,280 +19,202 @@ * * $Id: ccGline.cc,v 1.22 2007/08/28 16:10:06 dan_karrels Exp $ */ - -#include -#include -#include -#include -#include +#include +#include + +#include +#include +#include -#include "dbHandle.h" -#include "ELog.h" -#include "misc.h" -#include "ccGline.h" -#include "ccontrol.h" -#include "gnuworld_config.h" +#include "dbHandle.h" +#include "ELog.h" +#include "misc.h" +#include "ccGline.h" +#include "ccontrol.h" +#include "gnuworld_config.h" -namespace gnuworld -{ +namespace gnuworld { -using std::string ; -using std::endl ; -using std::stringstream ; -using std::ends ; +using std::endl; +using std::ends; +using std::string; +using std::stringstream; -namespace uworld -{ +namespace uworld { unsigned int ccGline::numAllocated = 0; ccGline::ccGline(dbHandle* _SQLDb) - : Id(), - AddedBy(), - AddedOn( 0 ), - Expires( 0 ), - LastUpdated( 0 ), - Reason(), - SQLDb( _SQLDb ) -{ -++numAllocated; + : Id(), AddedBy(), AddedOn(0), Expires(0), LastUpdated(0), Reason(), SQLDb(_SQLDb) { + ++numAllocated; } -ccGline::~ccGline() -{ ---numAllocated; +ccGline::~ccGline() { --numAllocated; } + +bool ccGline::Insert() { + // First we gotta make sure, there is no old gline in the database + static const char* Del = "DELETE FROM glines WHERE lower(host) = '"; + + if (!dbConnected) { + return false; + } + stringstream delQuery; + delQuery << Del << escapeSQLChars(string_lower(Host)) << "'" << ends; + + if (!SQLDb->Exec(delQuery)) + // if( PGRES_COMMAND_OK != status ) + { + elog << "ccGline::DeleteOnInsert> SQL Failure: " << SQLDb->ErrorMessage() << endl; + + return false; + } + // Now insert the new one + static const char* Main = + "INSERT INTO Glines (Host,AddedBy,AddedOn,ExpiresAt,LastUpdated,Reason) VALUES ('"; + + stringstream theQuery; + theQuery << Main << escapeSQLChars(Host) << "','" << escapeSQLChars(AddedBy) << "'," << AddedOn + << "," << Expires << "," << LastUpdated << ",'" << escapeSQLChars(Reason) << "')" + << ends; + + elog << "Gline::Insert::sqlQuery> " << theQuery.str().c_str() << endl; + + if (SQLDb->Exec(theQuery)) + // if( PGRES_COMMAND_OK == status ) + { + return true; + } else { + elog << "ccontrol::Gline::Insert> SQL Failure: " << SQLDb->ErrorMessage() << endl; + return false; + } } -bool ccGline::Insert() -{ -//First we gotta make sure, there is no old gline in the database -static const char *Del = "DELETE FROM glines WHERE lower(host) = '"; - -if(!dbConnected) - { - return false; - } -stringstream delQuery; -delQuery << Del - << escapeSQLChars(string_lower(Host)) << "'" - << ends; - - -if( !SQLDb->Exec( delQuery ) ) -//if( PGRES_COMMAND_OK != status ) - { - elog << "ccGline::DeleteOnInsert> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - - return false ; - } -//Now insert the new one -static const char *Main = "INSERT INTO Glines (Host,AddedBy,AddedOn,ExpiresAt,LastUpdated,Reason) VALUES ('"; - -stringstream theQuery; -theQuery << Main - << escapeSQLChars(Host) << "','" - << escapeSQLChars(AddedBy) << "'," - << AddedOn << "," - << Expires << "," - << LastUpdated << ",'" - << escapeSQLChars(Reason) << "')" - << ends; - -elog << "Gline::Insert::sqlQuery> " - << theQuery.str().c_str() - << endl; - -if( SQLDb->Exec( theQuery ) ) -//if( PGRES_COMMAND_OK == status ) - { - return true; - } -else - { - elog << "ccontrol::Gline::Insert> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - return false; - } - +bool ccGline::Update() { + if (atoi(Id.c_str()) == -1) // saveGlines was false when this gline was added + { + return true; + } + static const char* Main = "UPDATE Glines SET Id = '"; + + if (!dbConnected) { + return false; + } + + stringstream theQuery; + theQuery << Main << Id << "', Host = '" << escapeSQLChars(Host) << "', AddedBy = '" + << escapeSQLChars(AddedBy) << "', AddedOn = " << AddedOn << ",ExpiresAt = " << Expires + << ",LastUpdated = " << LastUpdated << ",Reason = '" << escapeSQLChars(Reason) << "'" + << " WHERE Id = " << Id << ends; + + elog << "ccontrol::Gline::Update> " << theQuery.str().c_str() << endl; + + if (SQLDb->Exec(theQuery)) + // if( PGRES_COMMAND_OK == status ) + { + return true; + } else { + elog << "ccontrol::Gline::Update> SQL Failure: " << SQLDb->ErrorMessage() << endl; + return false; + } } -bool ccGline::Update() -{ -if(atoi(Id.c_str()) == -1) //saveGlines was false when this gline was added - { - return true; - } -static const char *Main = "UPDATE Glines SET Id = '"; - -if(!dbConnected) - { - return false; - } - -stringstream theQuery; -theQuery << Main - << Id - << "', Host = '" - << escapeSQLChars(Host) - << "', AddedBy = '" - << escapeSQLChars(AddedBy) - << "', AddedOn = " - << AddedOn - << ",ExpiresAt = " - << Expires - << ",LastUpdated = " - << LastUpdated - << ",Reason = '" - << escapeSQLChars(Reason) << "'" - << " WHERE Id = " << Id - << ends; - -elog << "ccontrol::Gline::Update> " - << theQuery.str().c_str() - << endl; - -if( SQLDb->Exec( theQuery ) ) -//if( PGRES_COMMAND_OK == status ) - { - return true; - } -else - { - elog << "ccontrol::Gline::Update> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - return false; - } -} +bool ccGline::loadData(int GlineId) { + static const char* Main = + "SELECT Id,Host,AddedBy,AddedOn,ExpiresAt,LastUpdated,Reason FROM glines WHERE Id = "; -bool ccGline::loadData(int GlineId) -{ -static const char *Main = "SELECT Id,Host,AddedBy,AddedOn,ExpiresAt,LastUpdated,Reason FROM glines WHERE Id = "; - -if(!dbConnected) - { - return false; - } - -stringstream theQuery; -theQuery << Main - << GlineId - << ends; - -elog << "ccontrol::glineload> " - << theQuery.str().c_str() - << endl; - -if( !SQLDb->Exec( theQuery, true ) ) -//if( PGRES_TUPLES_OK != status ) - { - elog << "ccGline::load> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - - return false ; - } - -if(SQLDb->Tuples() < 6) - return false; -Id = SQLDb->GetValue(0,0); -Host = SQLDb->GetValue(0,1); -AddedBy = SQLDb->GetValue(0,2) ; -AddedOn = static_cast< time_t >( unsigned( - atoi( SQLDb->GetValue(0,3).c_str() ) )) ; -Expires = static_cast< time_t >( unsigned( - atoi( SQLDb->GetValue(0,4).c_str() ) )) ; -LastUpdated = static_cast< time_t >( unsigned( - atoi( SQLDb->GetValue(0,5).c_str() ) )) ; -Reason = SQLDb->GetValue(0,6); - -return true; -} + if (!dbConnected) { + return false; + } + + stringstream theQuery; + theQuery << Main << GlineId << ends; -bool ccGline::loadData( const string & HostName) -{ -static const char *Main = "SELECT Id,Host,AddedBy,AddedOn,ExpiresAt,LastUpdated,Reason FROM glines WHERE Host = '"; - -if(!dbConnected) - { - return false; - } - -stringstream theQuery; -theQuery << Main - << escapeSQLChars(HostName.c_str()) - << "'" << ends; - -elog << "ccontrol::loadData> " - << theQuery.str().c_str() - << endl; - -if( !SQLDb->Exec( theQuery, true ) ) -//if( PGRES_TUPLES_OK != status ) - { - elog << "ccGline::loadData> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - - return false ; - } - -if(SQLDb->Tuples() == 0) //If no gline was found - return false; -Id = SQLDb->GetValue(0,0); -Host = SQLDb->GetValue(0,1); -AddedBy = SQLDb->GetValue(0,2) ; -AddedOn = static_cast< time_t >( atoi( SQLDb->GetValue(0,3).c_str() ) ) ; -Expires = static_cast< time_t >( atoi( SQLDb->GetValue(0,4).c_str() ) ) ; -LastUpdated = static_cast< time_t >( atoi( SQLDb->GetValue(0,5).c_str() ) ) ; -Reason = SQLDb->GetValue(0,6); - -return true; + elog << "ccontrol::glineload> " << theQuery.str().c_str() << endl; + + if (!SQLDb->Exec(theQuery, true)) + // if( PGRES_TUPLES_OK != status ) + { + elog << "ccGline::load> SQL Failure: " << SQLDb->ErrorMessage() << endl; + + return false; + } + + if (SQLDb->Tuples() < 6) + return false; + Id = SQLDb->GetValue(0, 0); + Host = SQLDb->GetValue(0, 1); + AddedBy = SQLDb->GetValue(0, 2); + AddedOn = static_cast(unsigned(atoi(SQLDb->GetValue(0, 3).c_str()))); + Expires = static_cast(unsigned(atoi(SQLDb->GetValue(0, 4).c_str()))); + LastUpdated = static_cast(unsigned(atoi(SQLDb->GetValue(0, 5).c_str()))); + Reason = SQLDb->GetValue(0, 6); + + return true; } -bool ccGline::Delete() -{ -if(atoi(Id.c_str()) == -1) //saveGlines was false when this gline was added - { - return true; - } - -static const char *Main = "DELETE FROM glines WHERE Id = "; - -if(!dbConnected) - { - return false; - } - -stringstream theQuery; -theQuery << Main - << Id - << ends; - -elog << "ccontrol::glineDelete> " - << theQuery.str().c_str() - << endl; - -if( SQLDb->Exec( theQuery ) ) -//if( PGRES_COMMAND_OK == status ) - { - return true; - } -else - { - elog << "ccGline::ccDelete> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - - return false ; - } -return true; +bool ccGline::loadData(const string& HostName) { + static const char* Main = + "SELECT Id,Host,AddedBy,AddedOn,ExpiresAt,LastUpdated,Reason FROM glines WHERE Host = '"; + + if (!dbConnected) { + return false; + } + + stringstream theQuery; + theQuery << Main << escapeSQLChars(HostName.c_str()) << "'" << ends; + + elog << "ccontrol::loadData> " << theQuery.str().c_str() << endl; + + if (!SQLDb->Exec(theQuery, true)) + // if( PGRES_TUPLES_OK != status ) + { + elog << "ccGline::loadData> SQL Failure: " << SQLDb->ErrorMessage() << endl; + + return false; + } + + if (SQLDb->Tuples() == 0) // If no gline was found + return false; + Id = SQLDb->GetValue(0, 0); + Host = SQLDb->GetValue(0, 1); + AddedBy = SQLDb->GetValue(0, 2); + AddedOn = static_cast(atoi(SQLDb->GetValue(0, 3).c_str())); + Expires = static_cast(atoi(SQLDb->GetValue(0, 4).c_str())); + LastUpdated = static_cast(atoi(SQLDb->GetValue(0, 5).c_str())); + Reason = SQLDb->GetValue(0, 6); + + return true; } +bool ccGline::Delete() { + if (atoi(Id.c_str()) == -1) // saveGlines was false when this gline was added + { + return true; + } + + static const char* Main = "DELETE FROM glines WHERE Id = "; + if (!dbConnected) { + return false; + } + + stringstream theQuery; + theQuery << Main << Id << ends; + + elog << "ccontrol::glineDelete> " << theQuery.str().c_str() << endl; + + if (SQLDb->Exec(theQuery)) + // if( PGRES_COMMAND_OK == status ) + { + return true; + } else { + elog << "ccGline::ccDelete> SQL Failure: " << SQLDb->ErrorMessage() << endl; + + return false; + } + return true; } -} //Namespace Gnuworld + +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/ccGline.h b/mod.ccontrol/ccGline.h index 2077aef6..d3310f39 100644 --- a/mod.ccontrol/ccGline.h +++ b/mod.ccontrol/ccGline.h @@ -22,104 +22,84 @@ #ifndef __CCGLINE_H #define __CCGLINE_H "$Id: ccGline.h,v 1.15 2007/08/28 16:10:07 dan_karrels Exp $" -#include -#include - -#include - -#include "dbHandle.h" - -namespace gnuworld -{ - -using std::string ; -using std::list ; -namespace uworld -{ - -class ccGline -{ -public: - - ccGline(dbHandle*); - - virtual ~ccGline(); - //Mehods for getting info - - inline const string& getId() const - { return Id; } - - inline const string& getHost() const - { return Host; } - - inline const string& getAddedBy() const - { return AddedBy; } - - inline const time_t& getAddedOn() const - { return AddedOn; } - - inline const time_t& getExpires() const - { return Expires; } - - inline const time_t& getLastUpdated() const - { return LastUpdated; } - - inline const string& getReason() const - { return Reason; } - - - //Methods for setting info - - inline void setId( const string& _Id ) - { Id = _Id; } - - inline void setHost( const string& _Host ) - { Host = _Host; } - - inline void setAddedBy( const string& _AddedBy ) - { AddedBy = _AddedBy; } - - inline void setAddedOn( const time_t& _AddedOn ) - { AddedOn = _AddedOn; } - - inline void setExpires( const time_t& _Expires ) - { Expires = _Expires; } - - inline void setLastUpdated( const time_t& _LastUpdated ) - { LastUpdated = _LastUpdated; } - - inline void setReason( const string& _Reason ) - { Reason = _Reason; } - - inline void setSqldb(dbHandle* _SQLDb) - { SQLDb = _SQLDb; } - - //Methods for updating - - bool Insert(); - - bool Update(); - - bool loadData( int ); - - bool loadData( const string & ); - - bool Delete(); - - static unsigned int numAllocated; - -protected: - string Id; - string Host; - string AddedBy; - time_t AddedOn; - time_t Expires; - time_t LastUpdated; - string Reason; - dbHandle* SQLDb; - +#include +#include + +#include + +#include "dbHandle.h" + +namespace gnuworld { + +using std::list; +using std::string; +namespace uworld { + +class ccGline { + public: + ccGline(dbHandle*); + + virtual ~ccGline(); + // Mehods for getting info + + inline const string& getId() const { return Id; } + + inline const string& getHost() const { return Host; } + + inline const string& getAddedBy() const { return AddedBy; } + + inline const time_t& getAddedOn() const { return AddedOn; } + + inline const time_t& getExpires() const { return Expires; } + + inline const time_t& getLastUpdated() const { return LastUpdated; } + + inline const string& getReason() const { return Reason; } + + // Methods for setting info + + inline void setId(const string& _Id) { Id = _Id; } + + inline void setHost(const string& _Host) { Host = _Host; } + + inline void setAddedBy(const string& _AddedBy) { AddedBy = _AddedBy; } + + inline void setAddedOn(const time_t& _AddedOn) { AddedOn = _AddedOn; } + + inline void setExpires(const time_t& _Expires) { Expires = _Expires; } + + inline void setLastUpdated(const time_t& _LastUpdated) { LastUpdated = _LastUpdated; } + + inline void setReason(const string& _Reason) { Reason = _Reason; } + + inline void setSqldb(dbHandle* _SQLDb) { SQLDb = _SQLDb; } + + // Methods for updating + + bool Insert(); + + bool Update(); + + bool loadData(int); + + bool loadData(const string&); + + bool Delete(); + + static unsigned int numAllocated; + + protected: + string Id; + string Host; + string AddedBy; + time_t AddedOn; + time_t Expires; + time_t LastUpdated; + string Reason; + dbHandle* SQLDb; + }; // class ccGline -} +} // namespace uworld } // namespace gnuworld #endif // __CCGLINE_H diff --git a/mod.ccontrol/ccLog.cc b/mod.ccontrol/ccLog.cc index dfbf84cb..8c77b170 100644 --- a/mod.ccontrol/ccLog.cc +++ b/mod.ccontrol/ccLog.cc @@ -18,7 +18,7 @@ * * $Id: ccLog.cc,v 1.10 2007/09/12 13:36:02 kewlio Exp $ */ - + #include "ccLog.h" #include #include "ELog.h" @@ -27,104 +27,81 @@ #include #include "StringTokenizer.h" -#include "gnuworld_config.h" +#include "gnuworld_config.h" using namespace std; -namespace gnuworld -{ - -namespace uworld -{ +namespace gnuworld { -bool ccLog::Save(fstream& out) -{ +namespace uworld { -if(out.bad()) - { - return false; - } +bool ccLog::Save(fstream& out) { -char time[20]; -time[0] = '\0'; -sprintf(time,"%ld",(long)::time(0)); -string Line = time; -Line += " "; -string::size_type pos; -for(pos = 0; pos < User.size();++pos) - { - if(User[pos] != '\\') - { - Line += User[pos]; - } - else - { - Line += "\\\\"; - } - } -Line += ' '; -for(pos = 0; pos < Host.size();++pos) - { - if(Host[pos] != '\\') - { - Line += Host[pos]; - } - else - { - Line += "\\\\"; - } - } -Line += ' '; -for(pos = 0; pos < Desc.size();++pos) - { - if(Desc[pos] != '\\') - { - Line += Desc[pos]; - } - else - { - Line += "\\\\"; - } - } + if (out.bad()) { + return false; + } -/*out << Time - << " " << User.c_str() - << " " << Host.c_str() - << " " << Desc.c_str() - << "\n";*/ -out << Line << "\n"; -return true; + char time[20]; + time[0] = '\0'; + sprintf(time, "%ld", (long)::time(0)); + string Line = time; + Line += " "; + string::size_type pos; + for (pos = 0; pos < User.size(); ++pos) { + if (User[pos] != '\\') { + Line += User[pos]; + } else { + Line += "\\\\"; + } + } + Line += ' '; + for (pos = 0; pos < Host.size(); ++pos) { + if (Host[pos] != '\\') { + Line += Host[pos]; + } else { + Line += "\\\\"; + } + } + Line += ' '; + for (pos = 0; pos < Desc.size(); ++pos) { + if (Desc[pos] != '\\') { + Line += Desc[pos]; + } else { + Line += "\\\\"; + } + } + /*out << Time + << " " << User.c_str() + << " " << Host.c_str() + << " " << Desc.c_str() + << "\n";*/ + out << Line << "\n"; + return true; } -bool ccLog::Load(fstream& in) -{ - -if((in.bad()) || (in.eof())) - { - return false; - } -char read[513]; -if(!in.getline(read,512)) - { - return false; - } -StringTokenizer st(read); -if(st.size() < 4) - { - elog << "invalid number of args in logs!" << endl; - return false; - } -Time = atoi(st[0].c_str()); -User = st[1]; -Host = st[2]; -CommandName = st[3]; -Desc = st.assemble(3); +bool ccLog::Load(fstream& in) { -return true; + if ((in.bad()) || (in.eof())) { + return false; + } + char read[513]; + if (!in.getline(read, 512)) { + return false; + } + StringTokenizer st(read); + if (st.size() < 4) { + elog << "invalid number of args in logs!" << endl; + return false; + } + Time = atoi(st[0].c_str()); + User = st[1]; + Host = st[2]; + CommandName = st[3]; + Desc = st.assemble(3); + return true; } - -} -} +} // namespace uworld +} // namespace gnuworld diff --git a/mod.ccontrol/ccLog.h b/mod.ccontrol/ccLog.h index 814082b7..b4d06c50 100644 --- a/mod.ccontrol/ccLog.h +++ b/mod.ccontrol/ccLog.h @@ -18,7 +18,7 @@ * * $Id: ccLog.h,v 1.5 2003/06/28 01:21:19 dan_karrels Exp $ */ - + #ifndef __CCLOG_H_ #define __CCLOG_H_ @@ -28,48 +28,37 @@ using namespace std; -namespace gnuworld -{ - -namespace uworld -{ - -class ccLog -{ - -public: - ccLog() : Time(0) , User() , Host(), CommandName() , Desc() {} - - ccLog(time_t _Time, string _User, string _Host - ,string _CommName , string _Desc) - : Time(_Time), User(_User) , Host(_Host) - ,CommandName(_CommName), Desc(_Desc) - {} - - ccLog(fstream& in) - { - Load(in); - } - - time_t Time; - - string User; - - string Host; - - string CommandName; - - string Desc; - - bool Save(fstream& out); - - bool Load(fstream& in); - - -}; - -} - -} - -#endif +namespace gnuworld { + +namespace uworld { + +class ccLog { + + public: + ccLog() : Time(0), User(), Host(), CommandName(), Desc() {} + + ccLog(time_t _Time, string _User, string _Host, string _CommName, string _Desc) + : Time(_Time), User(_User), Host(_Host), CommandName(_CommName), Desc(_Desc) {} + + ccLog(fstream& in) { Load(in); } + + time_t Time; + + string User; + + string Host; + + string CommandName; + + string Desc; + + bool Save(fstream& out); + + bool Load(fstream& in); +}; + +} // namespace uworld + +} // namespace gnuworld + +#endif diff --git a/mod.ccontrol/ccServer.cc b/mod.ccontrol/ccServer.cc index 8e5b0e62..c03c75e5 100644 --- a/mod.ccontrol/ccServer.cc +++ b/mod.ccontrol/ccServer.cc @@ -1,7 +1,7 @@ /** * ccServer.cc * Server class - * + * * 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 @@ -19,273 +19,185 @@ * * $Id: ccServer.cc,v 1.18 2009/08/06 02:59:24 hidden1 Exp $ */ - -#include -#include - -#include -#include -#include - -#include "dbHandle.h" -#include "ELog.h" -#include "misc.h" -#include "ccServer.h" -#include "ccontrol.h" -#include "Constants.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ -using std::string ; -using std::endl ; -using std::stringstream ; -using std::ends ; - -namespace uworld -{ + +#include +#include + +#include +#include +#include + +#include "dbHandle.h" +#include "ELog.h" +#include "misc.h" +#include "ccServer.h" +#include "ccontrol.h" +#include "Constants.h" +#include "gnuworld_config.h" + +namespace gnuworld { +using std::endl; +using std::ends; +using std::string; +using std::stringstream; + +namespace uworld { unsigned int ccServer::numAllocated = 0; ccServer::ccServer(dbHandle* _SQLDb) - : Name(), - Uplink(), - Numeric(), - LastConnected( 0 ), - LastSplitted( 0 ), - SplitReason( "" ), - Version( "Unknown" ), - AddedOn( ::time(0) ), - LastUpdated( 0 ), - NetServer(NULL), - ReportMissing(true), - LagTime(0), - LastLagReport(0), - LastLagSent(0), - LastLagRecv(0), - SQLDb( _SQLDb ) -{ -++numAllocated; + : Name(), Uplink(), Numeric(), LastConnected(0), LastSplitted(0), SplitReason(""), + Version("Unknown"), AddedOn(::time(0)), LastUpdated(0), NetServer(NULL), ReportMissing(true), + LagTime(0), LastLagReport(0), LastLagSent(0), LastLagRecv(0), SQLDb(_SQLDb) { + ++numAllocated; } -ccServer::~ccServer() -{ ---numAllocated; +ccServer::~ccServer() { --numAllocated; } + +bool ccServer::Insert() { + static const char* Main = "INSERT INTO servers " + "(Name,LastUplink,LastNumeric,LastConnected,SplitedOn,SplitReason," + "Version,AddedOn,LastUpdated,ReportMissing) VALUES ('"; + + if (!dbConnected) { + return false; + } + stringstream theQuery; + theQuery << Main << escapeSQLChars(Name) << "','" << escapeSQLChars(Uplink) << "','" + << escapeSQLChars(Numeric) << "'," << LastConnected << "," << LastSplitted << ",'" + << escapeSQLChars(SplitReason) << "','" << escapeSQLChars(Version) << "'," << AddedOn + << "," << LastUpdated << "," << (ReportMissing ? "'t'" : "'n'") << ")" << ends; + + elog << "ccontrol::Server::Insert::sqlQuery> " << theQuery.str().c_str() << endl; + + if (SQLDb->Exec(theQuery)) + // if( PGRES_COMMAND_OK == status ) + { + return true; + } else { + elog << "ccontrol::Server::Insert> SQL Failure: " << SQLDb->ErrorMessage() << endl; + return false; + } } -bool ccServer::Insert() -{ -static const char *Main = "INSERT INTO servers (Name,LastUplink,LastNumeric,LastConnected,SplitedOn,SplitReason,Version,AddedOn,LastUpdated,ReportMissing) VALUES ('"; - -if(!dbConnected) - { - return false; - } -stringstream theQuery; -theQuery << Main - << escapeSQLChars(Name) <<"','" - << escapeSQLChars(Uplink) << "','" - << escapeSQLChars(Numeric) << "'," - << LastConnected << "," - << LastSplitted - << ",'" << escapeSQLChars(SplitReason) - << "','" << escapeSQLChars(Version) - << "'," << AddedOn - << "," << LastUpdated - << "," - << (ReportMissing ? "'t'" : "'n'") - << ")" - << ends; - -elog << "ccontrol::Server::Insert::sqlQuery> " - << theQuery.str().c_str() - << endl; - -if( SQLDb->Exec( theQuery ) ) -//if( PGRES_COMMAND_OK == status ) - { - return true; - } -else - { - elog << "ccontrol::Server::Insert> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - return false; - } - +bool ccServer::Update() { + static const char* Main = "UPDATE servers SET Name = '"; + + if (!dbConnected) { + return false; + } + + stringstream theQuery; + theQuery << Main << escapeSQLChars(Name) << "', LastUplink = '" << escapeSQLChars(Uplink) + << "', LastNumeric = '" << escapeSQLChars(Numeric) + << "', LastConnected = " << LastConnected << ",SplitedOn = " << LastSplitted + << ", SplitReason = '" << escapeSQLChars(SplitReason) << "', Version = '" + << escapeSQLChars(Version) << "', AddedOn = " << AddedOn + << ", LastUpdated = " << LastUpdated + << ", ReportMissing = " << (ReportMissing ? "'t'" : "'n'") << " WHERE lower(Name) = '" + << string_lower(Name) << "'" << ends; + + elog << "ccontrol::Server::Update> " << theQuery.str().c_str() << endl; + + if (SQLDb->Exec(theQuery)) + // if( PGRES_COMMAND_OK == status ) + { + return true; + } else { + elog << "ccontrol::Server::Update> SQL Failure: " << SQLDb->ErrorMessage() << endl; + return false; + } } -bool ccServer::Update() -{ -static const char *Main = "UPDATE servers SET Name = '"; - -if(!dbConnected) - { - return false; - } - -stringstream theQuery; -theQuery << Main - << escapeSQLChars(Name) - << "', LastUplink = '" - << escapeSQLChars(Uplink) - << "', LastNumeric = '" - << escapeSQLChars(Numeric) - << "', LastConnected = " - << LastConnected - << ",SplitedOn = " - << LastSplitted - << ", SplitReason = '" - << escapeSQLChars(SplitReason) - << "', Version = '" - << escapeSQLChars(Version) - << "', AddedOn = " - << AddedOn - << ", LastUpdated = " - << LastUpdated - << ", ReportMissing = " - << (ReportMissing ? "'t'" : "'n'") - << " WHERE lower(Name) = '" << string_lower(Name) - << "'" << ends; - -elog << "ccontrol::Server::Update> " - << theQuery.str().c_str() - << endl; - -if( SQLDb->Exec( theQuery ) ) -//if( PGRES_COMMAND_OK == status ) - { - return true; - } -else - { - elog << "ccontrol::Server::Update> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - return false; - } -} +bool ccServer::loadData(string ServerName) { + // static const char *Main = "SELECT + // name,lastuplink,lastconnected,splitedon,lastnumeric,splitreason FROM servers WHERE + // lower(Name) = '"; -bool ccServer::loadData(string ServerName) -{ -//static const char *Main = "SELECT name,lastuplink,lastconnected,splitedon,lastnumeric,splitreason FROM servers WHERE -//lower(Name) = '"; + if (!dbConnected) { + return false; + } -if(!dbConnected) - { - return false; - } + stringstream theQuery; + theQuery << server::Query << "Where lower(Name) = '" << escapeSQLChars(string_lower(ServerName)) + << "'" << ends; -stringstream theQuery; -theQuery << server::Query - << "Where lower(Name) = '" - << escapeSQLChars(string_lower(ServerName)) - << "'" << ends; + elog << "ccontrol::Server::LoadData> " << theQuery.str().c_str() << endl; -elog << "ccontrol::Server::LoadData> " - << theQuery.str().c_str() - << endl; + if (!SQLDb->Exec(theQuery, true)) + // if( PGRES_TUPLES_OK != status ) + { + elog << "ccontrol::Server> SQL Failure: " << SQLDb->ErrorMessage() << endl; -if( !SQLDb->Exec( theQuery, true ) ) -//if( PGRES_TUPLES_OK != status ) - { - elog << "ccontrol::Server> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; + return false; + } - return false ; - } + return loadDataFromDB(); +} -return loadDataFromDB(); +bool ccServer::loadNumericData(string ServNumeric) { + /*static const char *Main = "SELECT + name,lastuplink,lastconnected,splitedon,lastnumeric,SplitReason FROM servers WHERE LastNumeric = + '";*/ -} + if (!dbConnected) { + return false; + } -bool ccServer::loadNumericData(string ServNumeric) -{ -/*static const char *Main = "SELECT name,lastuplink,lastconnected,splitedon,lastnumeric,SplitReason FROM servers WHERE -LastNumeric = '";*/ - -if(!dbConnected) - { - return false; - } - -stringstream theQuery; -theQuery << server::Query - << "Where LastNumeric = '" - << escapeSQLChars(ServNumeric) - << "'" << ends; - -elog << "ccontrol::Server::LoadNumericData> " - << theQuery.str().c_str() - << endl; - -if( !SQLDb->Exec( theQuery, true ) ) -//if( PGRES_TUPLES_OK != status ) - { - elog << "ccontrol::Server> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - - return false ; - } -return loadDataFromDB(); + stringstream theQuery; + theQuery << server::Query << "Where LastNumeric = '" << escapeSQLChars(ServNumeric) << "'" + << ends; -} + elog << "ccontrol::Server::LoadNumericData> " << theQuery.str().c_str() << endl; -bool ccServer::loadDataFromDB(int place) -{ - -if(SQLDb->Tuples() == 0 ) - return false; -Name = SQLDb->GetValue(place,0); -Uplink = SQLDb->GetValue(0,1); -LastConnected = static_cast< time_t >( - atoi( SQLDb->GetValue(place,2).c_str() ) ) ; -LastSplitted = static_cast< time_t >( - atoi( SQLDb->GetValue(place,3).c_str() ) ) ; -Numeric = SQLDb->GetValue(place,4); -SplitReason = SQLDb->GetValue(place,5); -Version = SQLDb->GetValue(place,6); -AddedOn = static_cast< time_t >( - atoi( SQLDb->GetValue(place,7).c_str() ) ) ; -LastUpdated = static_cast< time_t >( - atoi( SQLDb->GetValue(place,8).c_str() ) ) ; -ReportMissing = (!strcasecmp(SQLDb->GetValue(place,9),"t") ? true : false); -return true; + if (!SQLDb->Exec(theQuery, true)) + // if( PGRES_TUPLES_OK != status ) + { + elog << "ccontrol::Server> SQL Failure: " << SQLDb->ErrorMessage() << endl; + return false; + } + return loadDataFromDB(); } -bool ccServer::Delete() -{ -static const char *Main = "DELETE FROM servers WHERE lower(Name) = '"; - -if(!dbConnected) - { - return false; - } - -stringstream theQuery; -theQuery << Main - << escapeSQLChars(string_lower(Name)) - << "'" << ends; - -elog << "ccontrol::Server::Delete> " - << theQuery.str().c_str() - << endl; - -if( !SQLDb->Exec( theQuery ) ) -//if( PGRES_COMMAND_OK != status ) - { - elog << "ccontrol::Server::Delete> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - return false; - } -return true; +bool ccServer::loadDataFromDB(int place) { + + if (SQLDb->Tuples() == 0) + return false; + Name = SQLDb->GetValue(place, 0); + Uplink = SQLDb->GetValue(0, 1); + LastConnected = static_cast(atoi(SQLDb->GetValue(place, 2).c_str())); + LastSplitted = static_cast(atoi(SQLDb->GetValue(place, 3).c_str())); + Numeric = SQLDb->GetValue(place, 4); + SplitReason = SQLDb->GetValue(place, 5); + Version = SQLDb->GetValue(place, 6); + AddedOn = static_cast(atoi(SQLDb->GetValue(place, 7).c_str())); + LastUpdated = static_cast(atoi(SQLDb->GetValue(place, 8).c_str())); + ReportMissing = (!strcasecmp(SQLDb->GetValue(place, 9), "t") ? true : false); + return true; } +bool ccServer::Delete() { + static const char* Main = "DELETE FROM servers WHERE lower(Name) = '"; + + if (!dbConnected) { + return false; + } + + stringstream theQuery; + theQuery << Main << escapeSQLChars(string_lower(Name)) << "'" << ends; + + elog << "ccontrol::Server::Delete> " << theQuery.str().c_str() << endl; + + if (!SQLDb->Exec(theQuery)) + // if( PGRES_COMMAND_OK != status ) + { + elog << "ccontrol::Server::Delete> SQL Failure: " << SQLDb->ErrorMessage() << endl; + return false; + } + return true; } -} //Namespace Gnuworld +} // namespace uworld + +} // namespace gnuworld diff --git a/mod.ccontrol/ccServer.h b/mod.ccontrol/ccServer.h index b6b163cd..42f848d7 100644 --- a/mod.ccontrol/ccServer.h +++ b/mod.ccontrol/ccServer.h @@ -22,160 +22,125 @@ #ifndef __CCSERVER_H #define __CCSERVER_H "$Id: ccServer.h,v 1.11 2009/07/26 18:30:38 mrbean_ Exp $" -#include - -#include - -#include "dbHandle.h" -#include "iServer.h" - -namespace gnuworld -{ - -using std::string ; - -namespace uworld -{ - -class ccServer -{ -public: - ccServer(dbHandle*); - virtual ~ccServer(); - //Mehods for getting info - - inline const string& getName() const - { return Name; } - - inline const string& getUplink() const - { return Uplink; } - - inline const string& getLastNumeric() const - { return Numeric; } - - inline const time_t& getLastConnected() const - { return LastConnected; } - - inline const time_t& getLastSplitted() const - { return LastSplitted; } - - inline const time_t& getLagTime() const - { return LagTime; } - - inline const time_t& getLastLagReport() const - { return LastLagReport; } - - inline const time_t& getLastLagSent() const - { return LastLagSent; } - - inline const time_t& getLastLagRecv() const - { return LastLagRecv; } - - inline const string& getSplitReason() const - { return SplitReason; } - - inline const string& getVersion() const - { return Version; } - - inline const time_t& getAddedOn() const - { return AddedOn; } - - inline const time_t& getLastUpdated() const - { return LastUpdated; } - - inline const iServer* getNetServer() const - { return NetServer; } - - inline const bool& getReportMissing() const - { return ReportMissing; } - - - //Methods for setting info - - inline void setName( const string& _Name ) - { Name = _Name; } - - inline void setUplink( const string& _Uplink ) - { Uplink = _Uplink; } - - inline void setLastNumeric( const string& _LastNumeric ) - { Numeric = _LastNumeric; } - - inline void setLastConnected( const time_t& _LastConnected ) - { LastConnected = _LastConnected; } - - inline void setLastSplitted( const time_t& _LastSplitted ) - { LastSplitted = _LastSplitted; } - - inline void setSplitReason( const string& _Reason) - { SplitReason = _Reason; } - - inline void setLagTime( const time_t& _LagTime ) - { LagTime = _LagTime; } - - inline void setLastLagReport( const time_t& _LastLagReport ) - { LastLagReport = _LastLagReport; } - - inline void setLastLagSent( const time_t& _LastLagSent ) - { LastLagSent = _LastLagSent; } - - inline void setLastLagRecv( const time_t& _LastLagRecv ) - { LastLagRecv = _LastLagRecv; } - - inline void setVersion( const string& _Version ) - { Version = _Version; } - - inline void setAddedOn( const time_t& _AddedOn ) - { AddedOn = _AddedOn; } - - inline void setLastUpdated( const time_t& _LastUpdated ) - { LastUpdated = _LastUpdated; } - - inline void setNetServer(iServer* NewServer) - { NetServer = NewServer; } - - inline void setReportMissing( const bool _ReportMissing ) - { ReportMissing = _ReportMissing; } - - inline void setSqldb(dbHandle* _SQLDb) - { SQLDb = _SQLDb; } - - //Methods for updating - - bool Insert(); - - bool Update(); - - bool loadData( string ); - - bool loadNumericData( string ); - - bool loadDataFromDB(int place = 0 ); - - bool Delete(); - - static unsigned int numAllocated; - -protected: - string Name; - string Uplink; - string Numeric; - time_t LastConnected; - time_t LastSplitted; - string SplitReason; - string Version; - time_t AddedOn; - time_t LastUpdated; - iServer* NetServer; - bool ReportMissing; - time_t LagTime; - time_t LastLagReport; - time_t LastLagSent; - time_t LastLagRecv; - dbHandle* SQLDb; +#include + +#include + +#include "dbHandle.h" +#include "iServer.h" + +namespace gnuworld { + +using std::string; + +namespace uworld { + +class ccServer { + public: + ccServer(dbHandle*); + virtual ~ccServer(); + // Mehods for getting info + + inline const string& getName() const { return Name; } + + inline const string& getUplink() const { return Uplink; } + + inline const string& getLastNumeric() const { return Numeric; } + + inline const time_t& getLastConnected() const { return LastConnected; } + + inline const time_t& getLastSplitted() const { return LastSplitted; } + + inline const time_t& getLagTime() const { return LagTime; } + + inline const time_t& getLastLagReport() const { return LastLagReport; } + + inline const time_t& getLastLagSent() const { return LastLagSent; } + + inline const time_t& getLastLagRecv() const { return LastLagRecv; } + + inline const string& getSplitReason() const { return SplitReason; } + + inline const string& getVersion() const { return Version; } + + inline const time_t& getAddedOn() const { return AddedOn; } + + inline const time_t& getLastUpdated() const { return LastUpdated; } + + inline const iServer* getNetServer() const { return NetServer; } + + inline const bool& getReportMissing() const { return ReportMissing; } + + // Methods for setting info + + inline void setName(const string& _Name) { Name = _Name; } + + inline void setUplink(const string& _Uplink) { Uplink = _Uplink; } + + inline void setLastNumeric(const string& _LastNumeric) { Numeric = _LastNumeric; } + + inline void setLastConnected(const time_t& _LastConnected) { LastConnected = _LastConnected; } + + inline void setLastSplitted(const time_t& _LastSplitted) { LastSplitted = _LastSplitted; } + + inline void setSplitReason(const string& _Reason) { SplitReason = _Reason; } + + inline void setLagTime(const time_t& _LagTime) { LagTime = _LagTime; } + + inline void setLastLagReport(const time_t& _LastLagReport) { LastLagReport = _LastLagReport; } + + inline void setLastLagSent(const time_t& _LastLagSent) { LastLagSent = _LastLagSent; } + + inline void setLastLagRecv(const time_t& _LastLagRecv) { LastLagRecv = _LastLagRecv; } + + inline void setVersion(const string& _Version) { Version = _Version; } + + inline void setAddedOn(const time_t& _AddedOn) { AddedOn = _AddedOn; } + + inline void setLastUpdated(const time_t& _LastUpdated) { LastUpdated = _LastUpdated; } + + inline void setNetServer(iServer* NewServer) { NetServer = NewServer; } + + inline void setReportMissing(const bool _ReportMissing) { ReportMissing = _ReportMissing; } + + inline void setSqldb(dbHandle* _SQLDb) { SQLDb = _SQLDb; } + + // Methods for updating + + bool Insert(); + + bool Update(); + + bool loadData(string); + + bool loadNumericData(string); + + bool loadDataFromDB(int place = 0); + + bool Delete(); + + static unsigned int numAllocated; + + protected: + string Name; + string Uplink; + string Numeric; + time_t LastConnected; + time_t LastSplitted; + string SplitReason; + string Version; + time_t AddedOn; + time_t LastUpdated; + iServer* NetServer; + bool ReportMissing; + time_t LagTime; + time_t LastLagReport; + time_t LastLagSent; + time_t LastLagRecv; + dbHandle* SQLDb; }; // class ccServer -} +} // namespace uworld } // namespace gnuworld #endif // __CCSERVER_H diff --git a/mod.ccontrol/ccUser.cc b/mod.ccontrol/ccUser.cc index 88eecc5c..47df4471 100644 --- a/mod.ccontrol/ccUser.cc +++ b/mod.ccontrol/ccUser.cc @@ -1,7 +1,7 @@ /** * ccUser.cc - * Storage class for accessing user information - * + * Storage class for accessing user information + * * 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 @@ -19,433 +19,325 @@ * * $Id: ccUser.cc,v 1.22 2009/07/26 18:30:38 mrbean_ Exp $ */ - -#include -#include - -#include - -#include "dbHandle.h" -#include "ELog.h" -#include "misc.h" -#include "ccUser.h" -#include "commLevels.h" -#include "ccontrol.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ -using std::string ; -using std::endl ; -using std::stringstream ; -using std::ends ; - -namespace uworld -{ + +#include +#include + +#include + +#include "dbHandle.h" +#include "ELog.h" +#include "misc.h" +#include "ccUser.h" +#include "commLevels.h" +#include "ccontrol.h" +#include "gnuworld_config.h" + +namespace gnuworld { +using std::endl; +using std::ends; +using std::string; +using std::stringstream; + +namespace uworld { unsigned int ccUser::numAllocated = 0; ccUser::ccUser(dbHandle* _SQLDb) - : Id( 0 ), - Server( "" ), - IsSuspended(0), - SuspendExpires(0), - SuspendLevel(0), - SuspendReason(""), - Access( 0 ), - SAccess( 0 ), - Flags( 0 ), - IsUhs(0), - IsOper(0), - IsAdmin(0), - IsSmt(0), - IsCoder(0), - GetLogs(0), - GetLag(0), - Sso(0), - Ssooo(0), - AutoOp(0), - NeedOp(0), - Notice(0), - SQLDb( _SQLDb ), - LastAuthTS(0), - PassChangeTS(0) -{ -++numAllocated; + : Id(0), Server(""), IsSuspended(0), SuspendExpires(0), SuspendLevel(0), SuspendReason(""), + Access(0), SAccess(0), Flags(0), IsUhs(0), IsOper(0), IsAdmin(0), IsSmt(0), IsCoder(0), + GetLogs(0), GetLag(0), Sso(0), Ssooo(0), AutoOp(0), NeedOp(0), Notice(0), SQLDb(_SQLDb), + LastAuthTS(0), PassChangeTS(0) { + ++numAllocated; } -ccUser::~ccUser() -{ ---numAllocated; -} +ccUser::~ccUser() { --numAllocated; } + +bool ccUser::loadData(const string& Name) { + if (!dbConnected) { + return false; + } -bool ccUser::loadData(const string& Name) -{ -if(!dbConnected) - { - return false; - } - -static const char Main[] = "SELECT user_id,user_name,password,access,saccess,flags,suspend_expires,suspended_by,server,isSuspended,IsUhs,IsOper,IsAdmin,IsSmt,IsCoder,GetLogs,NeedOp,Email,Suspend_Level,Suspend_Reason,Notice,GetLag,LastPassChangeTS,Sso,Ssooo,AutoOp,Account,AccountTS FROM opers WHERE lower(user_name) = '"; - -if(!dbConnected) - { - return false; - } - -stringstream theQuery; -theQuery << Main - << escapeSQLChars(string_lower(Name)) - << "'" - << ends; - -elog << "ccUser::loadData> " - << theQuery.str().c_str() - << endl; - -if( SQLDb->Exec( theQuery, true ) && (SQLDb->Tuples() > 0) ) -//if( (PGRES_TUPLES_OK == status) && (SQLDb->Tuples() > 0) ) - { + static const char Main[] = + "SELECT " + "user_id,user_name,password,access,saccess,flags,suspend_expires,suspended_by,server," + "isSuspended,IsUhs,IsOper,IsAdmin,IsSmt,IsCoder,GetLogs,NeedOp,Email,Suspend_Level,Suspend_" + "Reason,Notice,GetLag,LastPassChangeTS,Sso,Ssooo,AutoOp,Account,AccountTS FROM opers WHERE " + "lower(user_name) = '"; + + if (!dbConnected) { + return false; + } + + stringstream theQuery; + theQuery << Main << escapeSQLChars(string_lower(Name)) << "'" << ends; + + elog << "ccUser::loadData> " << theQuery.str().c_str() << endl; + + if (SQLDb->Exec(theQuery, true) && (SQLDb->Tuples() > 0)) + // if( (PGRES_TUPLES_OK == status) && (SQLDb->Tuples() > 0) ) + { GetParm(); - return true; - } + return true; + } -return false; + return false; } -bool ccUser::loadData( const unsigned int Id) -{ +bool ccUser::loadData(const unsigned int Id) { -if(!dbConnected) - { - return false; - } + if (!dbConnected) { + return false; + } -static const char Main[] = "SELECT user_id,user_name,password,access,saccess,flags,suspend_expires,suspended_by,server,isSuspended,IsUhs,IsOper,IsAdmin,IsSmt,IsCoder,GetLogs,NeedOp,Email,Suspend_Level,Suspend_Reason,Notice,GetLag,LastPassChangeTS,Sso,Ssooo,AutoOp,Account,AccountTS FROM opers WHERE user_id = "; -stringstream theQuery; + static const char Main[] = + "SELECT " + "user_id,user_name,password,access,saccess,flags,suspend_expires,suspended_by,server," + "isSuspended,IsUhs,IsOper,IsAdmin,IsSmt,IsCoder,GetLogs,NeedOp,Email,Suspend_Level,Suspend_" + "Reason,Notice,GetLag,LastPassChangeTS,Sso,Ssooo,AutoOp,Account,AccountTS FROM opers WHERE " + "user_id = "; + stringstream theQuery; -if(!dbConnected) - { - return false; - } + if (!dbConnected) { + return false; + } -theQuery << Main - << Id - << ';' - << ends; + theQuery << Main << Id << ';' << ends; -elog << "ccontrol::loadData> " - << theQuery.str().c_str() - << endl; + elog << "ccontrol::loadData> " << theQuery.str().c_str() << endl; -if( SQLDb->Exec( theQuery, true ) && (SQLDb->Tuples() > 0) ) -//if( (PGRES_TUPLES_OK == status) && (SQLDb->Tuples() > 0) ) - { - GetParm(); - return true; - } + if (SQLDb->Exec(theQuery, true) && (SQLDb->Tuples() > 0)) + // if( (PGRES_TUPLES_OK == status) && (SQLDb->Tuples() > 0) ) + { + GetParm(); + return true; + } -return false; + return false; } -void ccUser::GetParm() -{ -Id = atoi(SQLDb->GetValue(0, 0).c_str()); -UserName = SQLDb->GetValue(0, 1); -Password = SQLDb->GetValue(0, 2); -Access = atol(SQLDb->GetValue(0, 3).c_str()); -SAccess = atol(SQLDb->GetValue(0, 4).c_str()); -Flags = atoi(SQLDb->GetValue(0, 5).c_str()); -SuspendExpires = atoi(SQLDb->GetValue(0,6).c_str()); -SuspendedBy = SQLDb->GetValue(0,7); -Server = SQLDb->GetValue(0,8); -IsSuspended = (!strcasecmp(SQLDb->GetValue(0,9),"t") ? 1 : 0 ); -IsUhs = (!strcasecmp(SQLDb->GetValue(0,10),"t") ? 1 : 0 ); -IsOper = (!strcasecmp(SQLDb->GetValue(0,11),"t") ? 1 : 0 ); -IsAdmin = (!strcasecmp(SQLDb->GetValue(0,12),"t") ? 1 : 0 ); -IsSmt = (!strcasecmp(SQLDb->GetValue(0,13),"t") ? 1 : 0 ); -IsCoder = (!strcasecmp(SQLDb->GetValue(0,14),"t") ? 1 : 0 ); -GetLogs = (!strcasecmp(SQLDb->GetValue(0,15),"t") ? 1 : 0 ); -NeedOp = (!strcasecmp(SQLDb->GetValue(0,16),"t") ? 1 : 0 ); -Email = SQLDb->GetValue(0,17); -SuspendLevel = atoi(SQLDb->GetValue(0,18).c_str()); -SuspendReason = SQLDb->GetValue(0,19); -Notice = (!strcasecmp(SQLDb->GetValue(0,20),"t") ? 1 : 0 ); -GetLag = (!strcasecmp(SQLDb->GetValue(0,21),"t") ? 1 : 0 ); -PassChangeTS = atoi(SQLDb->GetValue(0,22).c_str()); -Sso = (!strcasecmp(SQLDb->GetValue(0,23),"t") ? 1 : 0 ); -Ssooo = (!strcasecmp(SQLDb->GetValue(0,24),"t") ? 1 : 0 ); -AutoOp = (!strcasecmp(SQLDb->GetValue(0,25),"t") ? 1 : 0 ); -Account = SQLDb->GetValue(0,26); -AccountTS = atoi(SQLDb->GetValue(0,27).c_str()); +void ccUser::GetParm() { + Id = atoi(SQLDb->GetValue(0, 0).c_str()); + UserName = SQLDb->GetValue(0, 1); + Password = SQLDb->GetValue(0, 2); + Access = atol(SQLDb->GetValue(0, 3).c_str()); + SAccess = atol(SQLDb->GetValue(0, 4).c_str()); + Flags = atoi(SQLDb->GetValue(0, 5).c_str()); + SuspendExpires = atoi(SQLDb->GetValue(0, 6).c_str()); + SuspendedBy = SQLDb->GetValue(0, 7); + Server = SQLDb->GetValue(0, 8); + IsSuspended = (!strcasecmp(SQLDb->GetValue(0, 9), "t") ? 1 : 0); + IsUhs = (!strcasecmp(SQLDb->GetValue(0, 10), "t") ? 1 : 0); + IsOper = (!strcasecmp(SQLDb->GetValue(0, 11), "t") ? 1 : 0); + IsAdmin = (!strcasecmp(SQLDb->GetValue(0, 12), "t") ? 1 : 0); + IsSmt = (!strcasecmp(SQLDb->GetValue(0, 13), "t") ? 1 : 0); + IsCoder = (!strcasecmp(SQLDb->GetValue(0, 14), "t") ? 1 : 0); + GetLogs = (!strcasecmp(SQLDb->GetValue(0, 15), "t") ? 1 : 0); + NeedOp = (!strcasecmp(SQLDb->GetValue(0, 16), "t") ? 1 : 0); + Email = SQLDb->GetValue(0, 17); + SuspendLevel = atoi(SQLDb->GetValue(0, 18).c_str()); + SuspendReason = SQLDb->GetValue(0, 19); + Notice = (!strcasecmp(SQLDb->GetValue(0, 20), "t") ? 1 : 0); + GetLag = (!strcasecmp(SQLDb->GetValue(0, 21), "t") ? 1 : 0); + PassChangeTS = atoi(SQLDb->GetValue(0, 22).c_str()); + Sso = (!strcasecmp(SQLDb->GetValue(0, 23), "t") ? 1 : 0); + Ssooo = (!strcasecmp(SQLDb->GetValue(0, 24), "t") ? 1 : 0); + AutoOp = (!strcasecmp(SQLDb->GetValue(0, 25), "t") ? 1 : 0); + Account = SQLDb->GetValue(0, 26); + AccountTS = atoi(SQLDb->GetValue(0, 27).c_str()); } -bool ccUser::Update() -{ -static const char *Main = "UPDATE opers SET password = '"; - -if(!dbConnected) - { - return false; - } - -stringstream theQuery; -theQuery << Main - << escapeSQLChars(Password) - << "', Access = " - << Access - << ", SAccess = " - << SAccess - << ", last_updated_by = '" - << escapeSQLChars(last_updated_by) - << "',last_updated = date_part('epoch', CURRENT_TIMESTAMP)::int,flags = " - << Flags - << ",suspend_expires = " - << SuspendExpires - << " ,suspended_by = '" - << escapeSQLChars(SuspendedBy) - << "' ,suspend_level = " - << SuspendLevel - << ", suspend_reason = '" - << escapeSQLChars(SuspendReason) - << "' ,server = '" - << escapeSQLChars(Server) - << "' ,isSuspended = " - << (IsSuspended ? "'t'" : "'n'") - << ",isUhs = " - << (IsUhs ? "'t'" : "'n'") - << ",isOper = " - << (IsOper ? "'t'" : "'n'") - << ",isAdmin = " - << (IsAdmin ? "'t'" : "'n'") - << ",isSmt = " - << (IsSmt ? "'t'" : "'n'") - << ",isCoder = " - << (IsCoder ? "'t'" : "'n'") - << ",GetLogs = " - << (GetLogs ? "'t'" : "'n'") - << ",GetLag = " - << (GetLag ? "'t'" : "'n'") - << ",Sso = " - << (Sso ? "'t'" : "'n'") - << ",Ssooo = " - << (Ssooo ? "'t'" : "'n'") - << ",AutoOp = " - << (AutoOp ? "'t'" : "'n'") - << ",LastPassChangeTS = " - << PassChangeTS - << ",AccountTS = " - << AccountTS - << ",NeedOp = " - << (NeedOp ? "'t'" : "'n'") - << ", Email = '" - << escapeSQLChars(Email) - << "', Account = '" - << escapeSQLChars(Account) - << "',Notice = " - << (Notice ? "'t'" : "'n'") - << " WHERE lower(user_name) = '" - << escapeSQLChars( string_lower(UserName)) << "'" - << ends; - -elog << "ccontrol::UpdateOper> " - << theQuery.str().c_str() - << endl; - -if( SQLDb->Exec( theQuery ) ) -//if( PGRES_COMMAND_OK == status ) - { - return true; - } -else - { - elog << "ccontrol::UpdateOper> SQL Failure: " - << SQLDb->ErrorMessage() - << endl ; - return false; - } +bool ccUser::Update() { + static const char* Main = "UPDATE opers SET password = '"; + + if (!dbConnected) { + return false; + } + + stringstream theQuery; + theQuery << Main << escapeSQLChars(Password) << "', Access = " << Access + << ", SAccess = " << SAccess << ", last_updated_by = '" + << escapeSQLChars(last_updated_by) + << "',last_updated = date_part('epoch', CURRENT_TIMESTAMP)::int,flags = " << Flags + << ",suspend_expires = " << SuspendExpires << " ,suspended_by = '" + << escapeSQLChars(SuspendedBy) << "' ,suspend_level = " << SuspendLevel + << ", suspend_reason = '" << escapeSQLChars(SuspendReason) << "' ,server = '" + << escapeSQLChars(Server) << "' ,isSuspended = " << (IsSuspended ? "'t'" : "'n'") + << ",isUhs = " << (IsUhs ? "'t'" : "'n'") << ",isOper = " << (IsOper ? "'t'" : "'n'") + << ",isAdmin = " << (IsAdmin ? "'t'" : "'n'") << ",isSmt = " << (IsSmt ? "'t'" : "'n'") + << ",isCoder = " << (IsCoder ? "'t'" : "'n'") + << ",GetLogs = " << (GetLogs ? "'t'" : "'n'") + << ",GetLag = " << (GetLag ? "'t'" : "'n'") << ",Sso = " << (Sso ? "'t'" : "'n'") + << ",Ssooo = " << (Ssooo ? "'t'" : "'n'") << ",AutoOp = " << (AutoOp ? "'t'" : "'n'") + << ",LastPassChangeTS = " << PassChangeTS << ",AccountTS = " << AccountTS + << ",NeedOp = " << (NeedOp ? "'t'" : "'n'") << ", Email = '" << escapeSQLChars(Email) + << "', Account = '" << escapeSQLChars(Account) + << "',Notice = " << (Notice ? "'t'" : "'n'") << " WHERE lower(user_name) = '" + << escapeSQLChars(string_lower(UserName)) << "'" << ends; + + elog << "ccontrol::UpdateOper> " << theQuery.str().c_str() << endl; + + if (SQLDb->Exec(theQuery)) + // if( PGRES_COMMAND_OK == status ) + { + return true; + } else { + elog << "ccontrol::UpdateOper> SQL Failure: " << SQLDb->ErrorMessage() << endl; + return false; + } } -void ccUser::setUhs() -{ -IsUhs = true; -IsOper = IsAdmin = IsSmt = IsCoder = false; +void ccUser::setUhs() { + IsUhs = true; + IsOper = IsAdmin = IsSmt = IsCoder = false; } -void ccUser::setOper() -{ -IsOper = true; -IsUhs = IsAdmin = IsSmt = IsCoder = false; +void ccUser::setOper() { + IsOper = true; + IsUhs = IsAdmin = IsSmt = IsCoder = false; } -void ccUser::setAdmin() -{ -IsAdmin = true; -IsOper = IsUhs = IsSmt = IsCoder = false; +void ccUser::setAdmin() { + IsAdmin = true; + IsOper = IsUhs = IsSmt = IsCoder = false; } -void ccUser::setSmt() -{ -IsSmt = true; -IsOper = IsAdmin = IsUhs = IsCoder = false; +void ccUser::setSmt() { + IsSmt = true; + IsOper = IsAdmin = IsUhs = IsCoder = false; } -void ccUser::setCoder() -{ -IsCoder = true; -IsOper = IsAdmin = IsSmt = IsUhs = false; +void ccUser::setCoder() { + IsCoder = true; + IsOper = IsAdmin = IsSmt = IsUhs = false; } -void ccUser::addClient(iClient* Client) -{ -vector::iterator Itr; -for (Itr = Clients.begin(); Itr != Clients.end(); Itr++) - { - if (*Itr == Client) - return; - } -Clients.push_back(Client); +void ccUser::addClient(iClient* Client) { + vector::iterator Itr; + for (Itr = Clients.begin(); Itr != Clients.end(); Itr++) { + if (*Itr == Client) + return; + } + Clients.push_back(Client); } -void ccUser::remClient(iClient* Client) -{ -vector::iterator Itr; -for (Itr = Clients.begin(); Itr != Clients.end(); Itr++) - { - iClient* tClient = *Itr; - if (tClient == Client) - { - Clients.erase(Itr); - return; - } - } +void ccUser::remClient(iClient* Client) { + vector::iterator Itr; + for (Itr = Clients.begin(); Itr != Clients.end(); Itr++) { + iClient* tClient = *Itr; + if (tClient == Client) { + Clients.erase(Itr); + return; + } + } } -unsigned int ccUser::getType() -{ -return (operLevel::UHSLEVEL * IsUhs + operLevel::OPERLEVEL * IsOper - + operLevel::ADMINLEVEL * IsAdmin + operLevel::SMTLEVEL * IsSmt - + operLevel::CODERLEVEL * IsCoder); -} - -void ccUser::setType(unsigned int Type) -{ -switch (Type) - { - case operLevel::UHSLEVEL: - IsUhs = true; - IsOper = false; - IsAdmin = false; - IsSmt = false; - IsCoder = false; - break; - case operLevel::OPERLEVEL: - IsUhs = false; - IsOper = true; - IsAdmin = false; - IsSmt = false; - IsCoder = false; - break; - case operLevel::ADMINLEVEL: - IsUhs = false; - IsOper = false; - IsAdmin = true; - IsSmt = false; - IsCoder = false; - break; - case operLevel::SMTLEVEL: - IsUhs = false; - IsOper = false; - IsAdmin = false; - IsSmt = true; - IsCoder = false; - break; - case operLevel::CODERLEVEL: - IsUhs = false; - IsOper = false; - IsAdmin = false; - IsSmt = false; - IsCoder = true; - default:; - } +unsigned int ccUser::getType() { + return (operLevel::UHSLEVEL * IsUhs + operLevel::OPERLEVEL * IsOper + + operLevel::ADMINLEVEL * IsAdmin + operLevel::SMTLEVEL * IsSmt + + operLevel::CODERLEVEL * IsCoder); } -bool ccUser::gotAccess(Command* Comm) -{ -if(Comm->getSecondAccess()) - { - return ((SAccess & Comm->getFlags()) != 0 ? true : false); - } -else - { - return ((Access & Comm->getFlags()) != 0 ? true : false); - } -return false; +void ccUser::setType(unsigned int Type) { + switch (Type) { + case operLevel::UHSLEVEL: + IsUhs = true; + IsOper = false; + IsAdmin = false; + IsSmt = false; + IsCoder = false; + break; + case operLevel::OPERLEVEL: + IsUhs = false; + IsOper = true; + IsAdmin = false; + IsSmt = false; + IsCoder = false; + break; + case operLevel::ADMINLEVEL: + IsUhs = false; + IsOper = false; + IsAdmin = true; + IsSmt = false; + IsCoder = false; + break; + case operLevel::SMTLEVEL: + IsUhs = false; + IsOper = false; + IsAdmin = false; + IsSmt = true; + IsCoder = false; + break; + case operLevel::CODERLEVEL: + IsUhs = false; + IsOper = false; + IsAdmin = false; + IsSmt = false; + IsCoder = true; + default:; + } } -void ccUser::addCommand(Command* Comm) -{ -if(Comm->getSecondAccess()) - SAccess |= Comm->getFlags(); -else - Access |= Comm->getFlags(); +bool ccUser::gotAccess(Command* Comm) { + if (Comm->getSecondAccess()) { + return ((SAccess & Comm->getFlags()) != 0 ? true : false); + } else { + return ((Access & Comm->getFlags()) != 0 ? true : false); + } + return false; } - -void ccUser::removeCommand(Command* Comm) -{ -if(Comm->getSecondAccess()) - SAccess &= ~Comm->getFlags(); -else - Access &= ~Comm->getFlags(); + +void ccUser::addCommand(Command* Comm) { + if (Comm->getSecondAccess()) + SAccess |= Comm->getFlags(); + else + Access |= Comm->getFlags(); } -void ccUser::updateAccessFromFlags() -{ -if(IsOper) - { - Access = commandLevel::OPER; - SAccess = commandLevel::SOPER; - } -else if(IsAdmin) - { - Access = commandLevel::ADMIN; - SAccess = commandLevel::SADMIN; - } -else if(IsSmt) - { - Access = commandLevel::SMT; - SAccess = commandLevel::SSMT; - } -else if(IsCoder) - { - Access = commandLevel::CODER; - SAccess = commandLevel::SCODER; - } +void ccUser::removeCommand(Command* Comm) { + if (Comm->getSecondAccess()) + SAccess &= ~Comm->getFlags(); + else + Access &= ~Comm->getFlags(); } -void ccUser::updateAccess(unsigned int Type) -{ -switch(Type) - { - case operLevel::OPERLEVEL: - Access = commandLevel::OPER; - SAccess = commandLevel::SOPER; - break; - case operLevel::ADMINLEVEL: - Access = commandLevel::ADMIN; - SAccess = commandLevel::SADMIN; - break; - case operLevel::SMTLEVEL: - Access = commandLevel::SMT; - SAccess = commandLevel::SSMT; - break; - case operLevel::CODERLEVEL: - Access = commandLevel::CODER; - SAccess = commandLevel::SCODER; - break; - } +void ccUser::updateAccessFromFlags() { + if (IsOper) { + Access = commandLevel::OPER; + SAccess = commandLevel::SOPER; + } else if (IsAdmin) { + Access = commandLevel::ADMIN; + SAccess = commandLevel::SADMIN; + } else if (IsSmt) { + Access = commandLevel::SMT; + SAccess = commandLevel::SSMT; + } else if (IsCoder) { + Access = commandLevel::CODER; + SAccess = commandLevel::SCODER; + } } +void ccUser::updateAccess(unsigned int Type) { + switch (Type) { + case operLevel::OPERLEVEL: + Access = commandLevel::OPER; + SAccess = commandLevel::SOPER; + break; + case operLevel::ADMINLEVEL: + Access = commandLevel::ADMIN; + SAccess = commandLevel::SADMIN; + break; + case operLevel::SMTLEVEL: + Access = commandLevel::SMT; + SAccess = commandLevel::SSMT; + break; + case operLevel::CODERLEVEL: + Access = commandLevel::CODER; + SAccess = commandLevel::SCODER; + break; + } } - + +} // namespace uworld + } // namespace gnuworld diff --git a/mod.ccontrol/ccUser.h b/mod.ccontrol/ccUser.h index e7b4f46d..f4024ab1 100644 --- a/mod.ccontrol/ccUser.h +++ b/mod.ccontrol/ccUser.h @@ -22,349 +22,275 @@ #ifndef __CCUSER_H #define __CCUSER_H "$Id: ccUser.h,v 1.21 2009/07/26 18:30:38 mrbean_ Exp $" -#include +#include -#include +#include -#include "dbHandle.h" +#include "dbHandle.h" -#include "CControlCommands.h" - -#include "iClient.h" +#include "CControlCommands.h" +#include "iClient.h" #include -//#include "ccontrol.h" -namespace gnuworld -{ +// #include "ccontrol.h" +namespace gnuworld { +using std::pair; using std::string; using std::vector; -using std::pair; -namespace uworld -{ - -namespace operLevel - { - const unsigned int UHSLEVEL = 0x01; - const unsigned int OPERLEVEL = 0x02; - const unsigned int ADMINLEVEL = 0x03; - const unsigned int SMTLEVEL = 0x04; - const unsigned int CODERLEVEL = 0x05; - const string CODERLEVELSTR = "CODER"; - const string SMTLEVELSTR = "SMT"; - const string ADMINLEVELSTR = "ADMIN"; - const string OPERLEVELSTR = "OPER"; - const string UHSLEVELSTR = "UHS"; - - - } - +namespace uworld { + +namespace operLevel { +const unsigned int UHSLEVEL = 0x01; +const unsigned int OPERLEVEL = 0x02; +const unsigned int ADMINLEVEL = 0x03; +const unsigned int SMTLEVEL = 0x04; +const unsigned int CODERLEVEL = 0x05; +const string CODERLEVELSTR = "CODER"; +const string SMTLEVELSTR = "SMT"; +const string ADMINLEVELSTR = "ADMIN"; +const string OPERLEVELSTR = "OPER"; +const string UHSLEVELSTR = "UHS"; + +} // namespace operLevel + /* CLASS ccUser - + Holds all the vital information about a user */ -class ccUser -{ -public: - ccUser(dbHandle*) ; - virtual ~ccUser() ; +class ccUser { + public: + ccUser(dbHandle*); + virtual ~ccUser(); - /* - * Methods to get data atrributes. - */ + /* + * Methods to get data atrributes. + */ - inline const unsigned int& getID() const - { return Id ; } + inline const unsigned int& getID() const { return Id; } - inline const string& getUserName() const - { return UserName ; } + inline const string& getUserName() const { return UserName; } - inline const string& getPassword() const - { return Password ; } + inline const string& getPassword() const { return Password; } - inline const string& getLast_Updated_by() const - { return last_updated_by ; } + inline const string& getLast_Updated_by() const { return last_updated_by; } - inline const string& getNumeric() const - { return Numeric ; } + inline const string& getNumeric() const { return Numeric; } - inline const string& getEmail() const - { return Email ; } + inline const string& getEmail() const { return Email; } - inline const string& getAccount() const - { return Account ; } - - inline const time_t& getAccountTS() const - { return AccountTS ; } + inline const string& getAccount() const { return Account; } - inline const time_t& getAccountID() const - { return AccountTS ; } + inline const time_t& getAccountTS() const { return AccountTS; } - inline const bool& getIsSuspended() const - { return IsSuspended ; } - - inline const time_t& getSuspendExpires() const - { return SuspendExpires ; } + inline const time_t& getAccountID() const { return AccountTS; } - inline const time_t& getPassChangeTS() const - { return PassChangeTS; } + inline const bool& getIsSuspended() const { return IsSuspended; } - inline const time_t& getLastAuthTS() const - { return LastAuthTS; } + inline const time_t& getSuspendExpires() const { return SuspendExpires; } - inline const string& getLastAuthNumeric() const - { return LastAuthNumeric; } + inline const time_t& getPassChangeTS() const { return PassChangeTS; } - inline const unsigned int& getSuspendLevel() const - { return SuspendLevel; } - - inline const string& getSuspendedBy() const - { return SuspendedBy ; } + inline const time_t& getLastAuthTS() const { return LastAuthTS; } - inline const string& getSuspendReason() const - { return SuspendReason ; } - - inline const unsigned long int& getAccess() const - { return Access ; } + inline const string& getLastAuthNumeric() const { return LastAuthNumeric; } - inline const unsigned long int& getSAccess() const - { return SAccess ; } + inline const unsigned int& getSuspendLevel() const { return SuspendLevel; } - inline const unsigned int& getFlags() const - { return Flags ; } - - inline bool gotFlag(unsigned int _flag) const - { return (Flags & _flag ? true : false) ; } + inline const string& getSuspendedBy() const { return SuspendedBy; } - inline const string& getServer() const - { return Server; } + inline const string& getSuspendReason() const { return SuspendReason; } - inline const bool& isUhs() const - { return IsUhs; } + inline const unsigned long int& getAccess() const { return Access; } - inline const bool& isOper() const - { return IsOper; } + inline const unsigned long int& getSAccess() const { return SAccess; } - inline const bool& isAdmin() const - { return IsAdmin; } + inline const unsigned int& getFlags() const { return Flags; } - inline const bool& isSmt() const - { return IsSmt; } + inline bool gotFlag(unsigned int _flag) const { return (Flags & _flag ? true : false); } - inline const bool& isCoder() const - { return IsCoder; } + inline const string& getServer() const { return Server; } - inline const bool& getLogs() const - { return GetLogs; } + inline const bool& isUhs() const { return IsUhs; } - inline const bool& getLag() const - { return GetLag; } + inline const bool& isOper() const { return IsOper; } - inline const bool& getSso() const - { return Sso; } + inline const bool& isAdmin() const { return IsAdmin; } - inline const bool& getSsooo() const - { return Ssooo; } + inline const bool& isSmt() const { return IsSmt; } - inline const bool& getAutoOp() const - { return AutoOp; } + inline const bool& isCoder() const { return IsCoder; } - inline const bool& getNeedOp() const - { return NeedOp; } + inline const bool& getLogs() const { return GetLogs; } - inline const bool& getNotice() const - { return Notice; } + inline const bool& getLag() const { return GetLag; } - inline const vector getClients() const - { return Clients; } + inline const bool& getSso() const { return Sso; } - /* - * Methods to set data attributes - */ + inline const bool& getSsooo() const { return Ssooo; } - inline void setID( const unsigned int _id ) - { Id = _id; } - - inline void setUserName( const string& _username ) - { UserName = _username; } + inline const bool& getAutoOp() const { return AutoOp; } - inline void setPassword( const string& _password ) - { Password = _password; } + inline const bool& getNeedOp() const { return NeedOp; } - inline void setLast_Updated_By( const string& _last_updated_by ) - { last_updated_by = _last_updated_by; } + inline const bool& getNotice() const { return Notice; } - inline void setNumeric( const string& _numeric ) - { Numeric = _numeric; } + inline const vector getClients() const { return Clients; } - inline void setEmail(const string& _Email) - { Email = _Email; } - - inline void setAccount(const string& _Account) - { Account = _Account; } - - inline void setAccountTS(const unsigned int _AccountTS) - { AccountTS = _AccountTS; } + /* + * Methods to set data attributes + */ - inline void setAccountID(const unsigned int _AccountTS) - { AccountTS = _AccountTS; } + inline void setID(const unsigned int _id) { Id = _id; } - inline void setIsSuspended(const bool _suspeneded) - { IsSuspended = _suspeneded; } - - inline void setSuspendExpires( const unsigned int _expire ) - { SuspendExpires = _expire; } + inline void setUserName(const string& _username) { UserName = _username; } - inline void setLastAuthTS(const unsigned int _lastauth) - { LastAuthTS = _lastauth; } + inline void setPassword(const string& _password) { Password = _password; } - inline void setPassChangeTS(const unsigned int _PassChangeTS) - { PassChangeTS = _PassChangeTS; } + inline void setLast_Updated_By(const string& _last_updated_by) { + last_updated_by = _last_updated_by; + } - inline void setLastAuthNumeric(const string& _numeric) - { LastAuthNumeric = _numeric; } + inline void setNumeric(const string& _numeric) { Numeric = _numeric; } - inline void setSuspendLevel( const unsigned int _level ) - { SuspendLevel = _level; } - - inline void setSuspendedBy( const string& _suspendedby ) - { SuspendedBy = _suspendedby; } - - inline void setSuspendReason( const string& _reason ) - { SuspendReason = _reason; } - - inline void setAccess( const unsigned long int _access ) - { Access = _access; } - - inline void setSAccess( const unsigned long int _saccess ) - { SAccess = _saccess; } - - - inline void setFlags( const unsigned int _flags ) - { Flags = _flags; } - - inline void removeFlag( const unsigned int _flag ) - { Flags &= ~_flag; } - - inline void setFlag( const unsigned int _flag ) - { Flags |= _flag; } - - inline void setServer( const string& _server ) - { Server = _server; } - - inline void setLogs( const bool _Logs ) - { GetLogs = _Logs; } - - inline void setLag( const bool _Lag ) - { GetLag = _Lag; } - - inline void setSso( const bool _Sso ) - { Sso = _Sso; } - - inline void setSsooo( const bool _Ssooo ) - { Ssooo = _Ssooo; } - - inline void setAutoOp( const bool _autoOp ) - { AutoOp = _autoOp; } - - inline void setNeedOp( const bool _needOp ) - { NeedOp = _needOp; } - - inline void setNotice( const bool _notice ) - { Notice = _notice; } - - inline void setSqldb(dbHandle* _SQLDb) - { SQLDb = _SQLDb; } - /* - * Methods to load a user and update the - * the database - */ - - bool loadData( const string& Name ); - - bool loadData( const unsigned int Id ); - - bool Update(); - - void GetParm(); - - void setUhs(); - - void setOper(); - - void setAdmin(); - - void setSmt(); - - void setCoder(); - - unsigned int getType(); - - void setType(unsigned int Type); - - bool gotAccess(Command* Comm); - - void addCommand(Command* Comm); - - void removeCommand(Command* Comm); - - void updateAccessFromFlags(); - - void updateAccess(unsigned int Type); - - void addClient(iClient* Client); - - void remClient(iClient* Client); - - static unsigned int numAllocated; - -protected: - unsigned int Id; - string UserName; - string Password; - string last_updated_by; - string Numeric; - string Server; - string Email; - string Account; - time_t AccountTS; - bool IsSuspended; - time_t SuspendExpires; - string SuspendedBy; - unsigned int SuspendLevel; - string SuspendReason; - unsigned long int Access; - unsigned long int SAccess; - unsigned int Flags; - bool IsUhs; - bool IsOper; - bool IsAdmin; - bool IsSmt; - bool IsCoder; - bool GetLogs; - bool GetLag; - bool Sso; - bool Ssooo; - bool AutoOp; - bool NeedOp; - bool Notice; - vector Clients; - dbHandle* SQLDb; - time_t LastAuthTS; - time_t PassChangeTS; - string LastAuthNumeric; - -} ; // class ccUser - -} -} // namespace gnuworld + inline void setEmail(const string& _Email) { Email = _Email; } -#endif // __CCUSER_H + inline void setAccount(const string& _Account) { Account = _Account; } + + inline void setAccountTS(const unsigned int _AccountTS) { AccountTS = _AccountTS; } + + inline void setAccountID(const unsigned int _AccountTS) { AccountTS = _AccountTS; } + + inline void setIsSuspended(const bool _suspeneded) { IsSuspended = _suspeneded; } + + inline void setSuspendExpires(const unsigned int _expire) { SuspendExpires = _expire; } + + inline void setLastAuthTS(const unsigned int _lastauth) { LastAuthTS = _lastauth; } + + inline void setPassChangeTS(const unsigned int _PassChangeTS) { PassChangeTS = _PassChangeTS; } + + inline void setLastAuthNumeric(const string& _numeric) { LastAuthNumeric = _numeric; } + + inline void setSuspendLevel(const unsigned int _level) { SuspendLevel = _level; } + + inline void setSuspendedBy(const string& _suspendedby) { SuspendedBy = _suspendedby; } + + inline void setSuspendReason(const string& _reason) { SuspendReason = _reason; } + + inline void setAccess(const unsigned long int _access) { Access = _access; } + + inline void setSAccess(const unsigned long int _saccess) { SAccess = _saccess; } + + inline void setFlags(const unsigned int _flags) { Flags = _flags; } + + inline void removeFlag(const unsigned int _flag) { Flags &= ~_flag; } + + inline void setFlag(const unsigned int _flag) { Flags |= _flag; } + + inline void setServer(const string& _server) { Server = _server; } + + inline void setLogs(const bool _Logs) { GetLogs = _Logs; } + + inline void setLag(const bool _Lag) { GetLag = _Lag; } + + inline void setSso(const bool _Sso) { Sso = _Sso; } + inline void setSsooo(const bool _Ssooo) { Ssooo = _Ssooo; } + inline void setAutoOp(const bool _autoOp) { AutoOp = _autoOp; } + inline void setNeedOp(const bool _needOp) { NeedOp = _needOp; } + + inline void setNotice(const bool _notice) { Notice = _notice; } + + inline void setSqldb(dbHandle* _SQLDb) { SQLDb = _SQLDb; } + /* + * Methods to load a user and update the + * the database + */ + + bool loadData(const string& Name); + + bool loadData(const unsigned int Id); + + bool Update(); + + void GetParm(); + + void setUhs(); + + void setOper(); + + void setAdmin(); + + void setSmt(); + + void setCoder(); + + unsigned int getType(); + + void setType(unsigned int Type); + + bool gotAccess(Command* Comm); + + void addCommand(Command* Comm); + + void removeCommand(Command* Comm); + + void updateAccessFromFlags(); + + void updateAccess(unsigned int Type); + + void addClient(iClient* Client); + + void remClient(iClient* Client); + + static unsigned int numAllocated; + + protected: + unsigned int Id; + string UserName; + string Password; + string last_updated_by; + string Numeric; + string Server; + string Email; + string Account; + time_t AccountTS; + bool IsSuspended; + time_t SuspendExpires; + string SuspendedBy; + unsigned int SuspendLevel; + string SuspendReason; + unsigned long int Access; + unsigned long int SAccess; + unsigned int Flags; + bool IsUhs; + bool IsOper; + bool IsAdmin; + bool IsSmt; + bool IsCoder; + bool GetLogs; + bool GetLag; + bool Sso; + bool Ssooo; + bool AutoOp; + bool NeedOp; + bool Notice; + vector Clients; + dbHandle* SQLDb; + time_t LastAuthTS; + time_t PassChangeTS; + string LastAuthNumeric; + +}; // class ccUser + +} // namespace uworld +} // namespace gnuworld + +#endif // __CCUSER_H diff --git a/mod.ccontrol/ccUserData.h b/mod.ccontrol/ccUserData.h index c19766f6..f54709f3 100644 --- a/mod.ccontrol/ccUserData.h +++ b/mod.ccontrol/ccUserData.h @@ -26,46 +26,33 @@ #include "ccUser.h" #include "ccFloodData.h" -namespace gnuworld -{ +namespace gnuworld { -namespace uworld -{ +namespace uworld { -class ccUserData -{ +class ccUserData { -public: - - ccUserData(ccFloodData* tFlood = NULL,ccUser* tDbUser = NULL) - : flood(tFlood), - dbUser(tDbUser) - {} - - virtual ~ccUserData(){} - - inline ccUser* getDbUser() const - { return dbUser; } - - inline ccFloodData* getFlood() const - { return flood; } - - inline void setDbUser(ccUser* _dbUser) - { dbUser = _dbUser; } - - inline void setFlood(ccFloodData* _flood) - { flood = _flood; } -protected: + public: + ccUserData(ccFloodData* tFlood = NULL, ccUser* tDbUser = NULL) + : flood(tFlood), dbUser(tDbUser) {} - - ccFloodData* flood; + virtual ~ccUserData() {} - ccUser* dbUser; + inline ccUser* getDbUser() const { return dbUser; } + inline ccFloodData* getFlood() const { return flood; } + inline void setDbUser(ccUser* _dbUser) { dbUser = _dbUser; } + + inline void setFlood(ccFloodData* _flood) { flood = _flood; } + + protected: + ccFloodData* flood; + + ccUser* dbUser; }; -} -} +} // namespace uworld +} // namespace gnuworld #endif diff --git a/mod.ccontrol/ccontrol.cc b/mod.ccontrol/ccontrol.cc index 3e787aee..f5b16a61 100644 --- a/mod.ccontrol/ccontrol.cc +++ b/mod.ccontrol/ccontrol.cc @@ -21,65 +21,63 @@ * USA. * * $Id: ccontrol.cc,v 1.243 2010/09/12 20:28:24 hidden1 Exp $ -*/ + */ #define MAJORVER "2" #define MINORVER "B1" #define RELDATE "11th December, 2013" -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "client.h" -#include "iClient.h" -#include "EConfig.h" -#include "events.h" -#include "StringTokenizer.h" -#include "misc.h" -#include "Network.h" -#include "ELog.h" -#include "ccUser.h" -#include "dbHandle.h" -#include "ccontrol.h" -#include "server.h" -#include "Constants.h" -#include "commLevels.h" -#include "ccFloodData.h" -#include "ccUserData.h" -#include "ip.h" -#include "ccontrol_generic.h" -#include "gnuworld_config.h" - -namespace gnuworld -{ -using std::ends ; -using std::stringstream ; -using std::string ; -using std::vector ; -using std::cout ; -using std::endl ; -using std::count ; - -namespace uworld -{ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "client.h" +#include "iClient.h" +#include "EConfig.h" +#include "events.h" +#include "StringTokenizer.h" +#include "misc.h" +#include "Network.h" +#include "ELog.h" +#include "ccUser.h" +#include "dbHandle.h" +#include "ccontrol.h" +#include "server.h" +#include "Constants.h" +#include "commLevels.h" +#include "ccFloodData.h" +#include "ccUserData.h" +#include "ip.h" +#include "ccontrol_generic.h" +#include "gnuworld_config.h" + +namespace gnuworld { +using std::count; +using std::cout; +using std::endl; +using std::ends; +using std::string; +using std::stringstream; +using std::vector; + +namespace uworld { using namespace std; @@ -87,7380 +85,6104 @@ using namespace std; * Exported function used by moduleLoader to gain an * instance of this module. */ -extern "C" -{ - xClient* _gnuwinit(const string& args) - { - return new ccontrol( args ); - } - -} +extern "C" { +xClient* _gnuwinit(const string& args) { return new ccontrol(args); } +} bool dbConnected = false; - -ccontrol::ccontrol( const string& configFileName ) - : xClient( configFileName ) -{ -elog << "Initializing ccontrol version " - << MAJORVER << "." << MINORVER - << " please standby... " << endl; - -myHub = 0; -ccHub = 0; -// Read the config file -EConfig conf( configFileName ) ; - -sqlHost = conf.Find("sql_host" )->second; -sqlDb = conf.Find( "sql_db" )->second; -sqlPort = conf.Find( "sql_port" )->second; -sqlPass = conf.Require( "sql_pass" )->second; -sqlUser = conf.Require( "sql_user" )->second; - -inBurst = true; -inRefresh = false; - -string Query = "host=" + sqlHost + " dbname=" + sqlDb + " port=" + sqlPort; -if (strcasecmp(sqlUser,"''")) - { - Query += (" user=" + sqlUser); - } - -if (strcasecmp(sqlPass,"''")) - { - Query += (" password=" + sqlPass); - } - -elog << Query - << endl ; -elog << "ccontrol::ccontrol> Attempting to connect to " - << sqlHost - << "; Database: " - << sqlDb - << endl; - -SQLDb = new dbHandle( this, - sqlHost, - ::atoi( sqlPort.c_str() ), - sqlDb, - sqlUser, - sqlPass ) ; -//(std::nothrow) cmDatabase( Query.c_str() ) ; -assert( SQLDb != 0 ) ; - -//-- Make sure we connected to the SQL database; if -// we didn't we exit entirely. -if (SQLDb->ConnectionBad ()) - { - elog << "ccontrol::ccontrol> Unable to connect to SQL server." - << endl - << "ccontrol::ccontrol> PostgreSQL error message: " - << SQLDb->ErrorMessage() - << endl ; - - ::exit( 0 ) ; - } -else - { - elog << "ccontrol::ccontrol> Connection established to SQL " - << endl ; - } -dbConnected = true; - -// operChanReason is the reason used when kicking non-opers from -// oper-only channels -operChanReason = conf.Find( "operchanreason" )->second ; - -// operChanModes are the modes to set when setting up an oper-only -// channel -operChanModes = conf.Find( "operchanmodes" )->second ; - -// gLength is the length of time (in seconds) for default glines -gLength = atoi( conf.Find( "glength" )->second.c_str() ) ; - -// CCEmail is the email ccontrol will post the last com report under -CCEmail = conf.Require( "ccemail" )->second; - -//AbuseMail is the mail that the lastcom report will be post to -AbuseMail = conf.Require( "abuse_mail" )->second; - -//GLInterval is the inteval in which ccontrol will check for expired glines -ExpiredInterval = atoi( conf.Require( "Expired_interval" )->second.c_str() ); - -ExcessConnReportInterval = atoi( conf.Require( "excess_conn_report_interval" )->second.c_str() ); - -//Sendmail is the full path of the sendmail program -Sendmail_Path = conf.Require("SendMail")->second; - -//SendReport flag that tells ccontrol if the user want the report to be mailed -SendReport = atoi(conf.Require("mail_report")->second.c_str()); - -maxThreads = atoi(conf.Require("max_threads")->second.c_str()); - -checkClones = atoi(conf.Require("check_clones")->second.c_str()); - -showCGIpsInLogs = atoi(conf.Require("showCGIpsInLogs")->second.c_str()); - -dbConnectionTimer = atoi(conf.Require("dbinterval")->second.c_str()); - -AnnounceNick = conf.Require("AnnounceNick")->second; - -iauthTimeout = atoi(conf.Require("iauthTimeout")->second.c_str()); - - -// Set up the oper channels -EConfig::const_iterator ptr = conf.Find( "operchan" ) ; -while( ptr != conf.end() && ptr->first == "operchan" ) - { - operChans.push_back( ptr->second ) ; - ++ptr ; - } - -// Read out the client's message channel -limitsChan = conf.Find( "limitschan" )->second ; - -// Make sure that the limitsChan is in the list of operchans -if ((limitsChan != "''") && (operChans.end() == find( operChans.begin(), operChans.end(), limitsChan))) - { - // Not found, add it to the list of operChans - operChans.push_back( limitsChan ) ; - } - -// Read out the client's message channel -msgChan = conf.Find( "msgchan" )->second ; - -// Make sure that the msgChan is in the list of operchans -if( operChans.end() == find( operChans.begin(), operChans.end(), msgChan ) ) - { - // Not found, add it to the list of operChans - operChans.push_back( msgChan ) ; - } - -// Get URL messages for some G-lines -url_excessive_conn = conf.Require( "url_excessive_conn" )->second ; -if (url_excessive_conn == "''") - url_excessive_conn = ""; -url_install_identd = conf.Require( "url_install_identd" )->second ; -if (url_install_identd == "''") - url_install_identd = ""; - -// Be sure to use all capital letters for the command name - -RegisterCommand( new HELPCommand( this, "HELP", "[topic]" - "\t\tObtain general help or help for a specific command", - true, - commandLevel::flg_HELP, - false, - false, - true, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new INVITECommand( this, "INVITE", "<#channel> " - "\t\tRequest an invitation to a channel", - false, - commandLevel::flg_INVITE, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new JUPECommand( this, "JUPE", " " - "Jupe a server for the given reason.", - false, - commandLevel::flg_JUPE, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new MODECommand( this, "MODE", " " - "Change modes on the given channel", - false, - commandLevel::flg_MODE, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new SCHANGLINECommand( this, "SCHANGLINE", - "[-u] <#channel> [time units (s,d,h)] " - "Gline a given channel for the given reason", - true, - commandLevel::flg_SCHANGLINE, - false, - true, - false, - operLevel::CODERLEVEL, - true ) ) ; -RegisterCommand( new FORCECHANGLINECommand( this, "FORCECHANGLINE", - "[-u] <#channel> [time units (s,d,h)] " - "Gline a given channel for the given reason", - true, - commandLevel::flg_FORCECHANGLINE, - false, - true, - false, - operLevel::OPERLEVEL, - true ) ) ; -RegisterCommand( new GLINECommand( this, "GLINE", - " [time units (s,d,h)] " - "Gline a given user@host for the given reason", - true, - commandLevel::flg_GLINE, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new SCANGLINECommand( this, "SCANGLINE", " " - "Search current network glines for glines matching ", - false, - commandLevel::flg_SCGLINE, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new REMGLINECommand( this, "REMGLINE", " " - "Remove the gline matching ", - true, - commandLevel::flg_REMGLINE, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new TOPICCommand( this, "TOPIC", "<#channel> [topic] " - "Change channel topic", - false, - commandLevel::flg_TOPIC, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new TRANSLATECommand( this, "TRANSLATE", " " - "Translate a numeric into user information", - false, - commandLevel::flg_TRANS, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new WHOISCommand( this, "WHOIS", " " - "Obtain information on a given nickname", - false, - commandLevel::flg_WHOIS, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new KICKCommand( this, "KICK", " " - "Kick a user from a channel", - false, - commandLevel::flg_KICK, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; - -// The following commands deals with operchans, if you want operchans -// just uncomment them -/* - -RegisterCommand( new ADDOPERCHANCommand( this, "ADDOPERCHAN", "" - "Add an oper channel", - false, - commandLevel::flg_ADDOPCHN, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new REMOPERCHANCommand( this, "REMOPERCHAN", "" - "Remove an oper channel", - false, - commandLevel::flg_REMOPCHN, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new LISTOPERCHANSCommand( this, "LISTOPERCHANS", - "List current IRCoperator only channels", - false, - commandLevel::flg_LOPCHN, - true, - false, - false,operLevel::OPERLEVEL, - false ) ) ; -*/ - -RegisterCommand( new CHANINFOCommand( this, "CHANINFO", "" - "Obtain information about a given channel", - false, - commandLevel::flg_CHINFO, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new LOGINCommand( this, "LOGIN", " " - "Authenticate with the bot", - true, - commandLevel::flg_LOGIN, - false, - false, - true, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new DEAUTHCommand( this, "DEAUTH", "" - "Deauthenticate with the bot", - false, - commandLevel::flg_DEAUTH, - false, - false, - true, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new DEAUTHCommand( this, "LOGOUT", "" - "Deauthenticate with the bot", - false, - commandLevel::flg_DEAUTH, - false, - false, - true, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new ADDUSERCommand( this, "ADDUSER", - " [SERVER*] " - "Add a new oper", - true, - commandLevel::flg_ADDNOP, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new REMUSERCommand( this, "REMUSER", " " - "Remove an oper", - true, - commandLevel::flg_REMOP, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new ADDCOMMANDCommand( this, "ADDCOMMAND", - " " - "Add a new command to an oper", - true, - commandLevel::flg_ADDCMD, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new REMCOMMANDCommand( this, "REMCOMMAND", - " " - "Remove a command from oper", - true, - commandLevel::flg_DELCMD, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new NEWPASSCommand( this, "NEWPASS", " " - "Change password", - true, - commandLevel::flg_NEWPASS, - false, - false, - true, - operLevel::UHSLEVEL, - false ) ) ; -RegisterCommand( new SUSPENDCommand( this, "SUSPEND", - " [-l level] " - "Suspend an oper", - true, - commandLevel::flg_SUSPEND, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new UNSUSPENDCommand( this, "UNSUSPEND", " " - "UnSuspend an oper", - true, - commandLevel::flg_UNSUSPEND, - false, - true, - false, - operLevel::OPERLEVEL, - false ) ) ; -RegisterCommand( new MODUSERCommand( this, "MODUSER", - "