diff options
author | Peter Powell <petpow@saberuk.com> | 2013-10-05 04:55:11 +0100 |
---|---|---|
committer | Peter Powell <petpow@saberuk.com> | 2013-12-15 06:46:35 +0000 |
commit | 02830985a18950497003f3392cf8d6cc30c15c50 (patch) | |
tree | 77fb47c2a9274221bcaba0cd82d6c08daf207878 | |
parent | 357d190074ee58809b31ea0c08543566168bddf6 (diff) |
Move stuff around a bit:
- Create FileSystem class:
* Move ServerConfig::CleanFilename to FileSystem::GetFileName and rewrite.
* Move ServerConfig::ExpandPath to FileSystem.
* Move ServerConfig::FileExists to FileSystem.
* Move ServerConfig::StartsWithWindowsDriveLetter to FileSystem.
- Move FileReader to fileutils.cpp and fix documentation.
- Move UserManager::DoBackgroundUserStuff to usermanager.cpp.
-rw-r--r-- | include/configreader.h | 30 | ||||
-rw-r--r-- | include/fileutils.h | 87 | ||||
-rw-r--r-- | include/inspircd.h | 1 | ||||
-rw-r--r-- | include/modules.h | 38 | ||||
-rw-r--r-- | src/commands/cmd_rehash.cpp | 8 | ||||
-rw-r--r-- | src/configreader.cpp | 33 | ||||
-rw-r--r-- | src/fileutils.cpp | 102 | ||||
-rw-r--r-- | src/inspircd.cpp | 4 | ||||
-rw-r--r-- | src/modmanager_dynamic.cpp | 2 | ||||
-rw-r--r-- | src/modules.cpp | 45 | ||||
-rw-r--r-- | src/modules/m_xline_db.cpp | 2 | ||||
-rw-r--r-- | src/usermanager.cpp | 68 | ||||
-rw-r--r-- | src/userprocess.cpp | 95 |
13 files changed, 269 insertions, 246 deletions
diff --git a/include/configreader.h b/include/configreader.h index 0fbf234c3..a46f9cf95 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -225,10 +225,10 @@ class CoreExport ServerConfig , Log(LOG_PATH) , Module(MOD_PATH) { } - std::string PrependConfig(const std::string& fn) const { return ServerConfig::ExpandPath(Config, fn); } - std::string PrependData(const std::string& fn) const { return ServerConfig::ExpandPath(Data, fn); } - std::string PrependLog(const std::string& fn) const { return ServerConfig::ExpandPath(Log, fn); } - std::string PrependModule(const std::string& fn) const { return ServerConfig::ExpandPath(Module, fn); } + std::string PrependConfig(const std::string& fn) const { return FileSystem::ExpandPath(Config, fn); } + std::string PrependData(const std::string& fn) const { return FileSystem::ExpandPath(Data, fn); } + std::string PrependLog(const std::string& fn) const { return FileSystem::ExpandPath(Log, fn); } + std::string PrependModule(const std::string& fn) const { return FileSystem::ExpandPath(Module, fn); } }; /** Get a configuration tag @@ -551,30 +551,8 @@ class CoreExport ServerConfig void Fill(); - /** Returns true if the given string starts with a windows drive letter - */ - static bool StartsWithWindowsDriveLetter(const std::string& path); - bool ApplyDisabledCommands(const std::string& data); - /** Clean a filename, stripping the directories (and drives) from string. - * @param name Directory to tidy - * @return The cleaned filename - */ - static const char* CleanFilename(const char* name); - - /** Check if a file exists. - * @param file The full path to a file - * @return True if the file exists and is readable. - */ - static bool FileExists(const char* file); - - /** Expands a path fragment to a full path. - * @param base The base path to expand from - * @param fragment The path fragment to expand on top of base. - */ - static std::string ExpandPath(const std::string& base, const std::string& fragment); - /** Escapes a value for storage in a configuration key. * @param str The string to escape. * @param xml Are we using the XML config format? diff --git a/include/fileutils.h b/include/fileutils.h new file mode 100644 index 000000000..45865bbb0 --- /dev/null +++ b/include/fileutils.h @@ -0,0 +1,87 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2013 Peter Powell <petpow@saberuk.com> + * + * This file is part of InspIRCd. InspIRCd is free software: you can + * redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#pragma once + +/** Provides an easy method of reading a text file into memory. */ +class CoreExport FileReader : public classbase +{ + /** The lines of text in the file. */ + std::vector<std::string> lines; + + /** File size in bytes. */ + unsigned long totalSize; + + public: + /** Initializes a new file reader. */ + FileReader() : totalSize(0) { } + + /** Initializes a new file reader and reads the specified file. + * @param filename The file to read into memory. + */ + FileReader(const std::string& filename); + + /** Loads a text file from disk. + * @param filename The file to read into memory. + * @throw CoreException The file can not be loaded. + */ + void Load(const std::string& filename); + + /** Retrieves the entire contents of the file cache as a single string. */ + std::string GetString() const; + + /** Retrieves the entire contents of the file cache as a vector of strings. */ + const std::vector<std::string>& GetVector() const { return lines; } + + /** Retrieves the total size in bytes of the file. */ + unsigned long TotalSize() const { return totalSize; } +}; + +/** Implements methods for file system access */ +class CoreExport FileSystem +{ +private: + FileSystem() { } + +public: + /** Expands a path fragment to a full path. + * @param base The base path to expand from + * @param fragment The path fragment to expand on top of base. + */ + static std::string ExpandPath(const std::string& base, const std::string& fragment); + + /** + * Checks whether a file with the specified name exists on the filesystem. + * @param path The path to a file. + * @return True if the file exists; otherwise, false. + */ + static bool FileExists(const std::string& path); + + /** Gets the file name segment of a path. + * @param path The path to extract the file name from. + * @return The file name segment of a path. + */ + static std::string GetFileName(const std::string& path); + + /** Determines whether the given path starts with a Windows drive letter. + * @param path The path to validate. + * @returns True if the path begins with a Windows drive letter; otherwise, false. + */ + static bool StartsWithWindowsDriveLetter(const std::string& path); +}; diff --git a/include/inspircd.h b/include/inspircd.h index f43141c38..e02a5deb5 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -54,6 +54,7 @@ CoreExport extern InspIRCd* ServerInstance; #include "caller.h" #include "cull_list.h" #include "extensible.h" +#include "fileutils.h" #include "numerics.h" #include "uid.h" #include "users.h" diff --git a/include/modules.h b/include/modules.h index 931d85032..b7cffd1a0 100644 --- a/include/modules.h +++ b/include/modules.h @@ -1078,44 +1078,6 @@ class CoreExport Module : public classbase, public usecountbase virtual void OnSetUserIP(LocalUser* user); }; -/** Provides an easy method of reading a text file into memory. */ -class CoreExport FileReader : public classbase -{ - /** The lines of text in the file. - */ - std::vector<std::string> lines; - - /** Content size in bytes - */ - unsigned long totalSize; - - public: - /** Initializes a new file reader. - */ - FileReader() : totalSize(0) { } - - /** Initializes a new file reader and reads the specified file. - * @param filename The file to read into memory. - */ - FileReader(const std::string& filename); - - /** Loads a text file from disk. - * @param filename The file to read into memory. - * @throw CoreException The file can not be loaded. - */ - void Load(const std::string& filename); - - /** Retrieves the entire contents of the file cache as a single string. - */ - std::string GetString(); - - /** Retrieves the entire contents of the file cache as a vector of strings. - */ - const std::vector<std::string>& GetVector() { return lines; } - - unsigned long TotalSize() { return totalSize; } -}; - /** A list of modules */ typedef std::vector<Module*> IntModuleList; diff --git a/src/commands/cmd_rehash.cpp b/src/commands/cmd_rehash.cpp index 1fa726962..07183ec7d 100644 --- a/src/commands/cmd_rehash.cpp +++ b/src/commands/cmd_rehash.cpp @@ -75,15 +75,13 @@ CmdResult CommandRehash::Handle (const std::vector<std::string>& parameters, Use // Rehash for me. Try to start the rehash thread if (!ServerInstance->ConfigThread) { - std::string m = user->nick + " is rehashing config file " + ServerConfig::CleanFilename(ServerInstance->ConfigFileName.c_str()) + " on " + ServerInstance->Config->ServerName; + std::string m = user->nick + " is rehashing config file " + FileSystem::GetFileName(ServerInstance->ConfigFileName) + " on " + ServerInstance->Config->ServerName; ServerInstance->SNO->WriteGlobalSno('a', m); if (IS_LOCAL(user)) - user->WriteNumeric(RPL_REHASHING, "%s :Rehashing", - ServerConfig::CleanFilename(ServerInstance->ConfigFileName.c_str())); + user->WriteNumeric(RPL_REHASHING, "%s :Rehashing", FileSystem::GetFileName(ServerInstance->ConfigFileName).c_str()); else - ServerInstance->PI->SendUserNotice(user, std::string("*** Rehashing server ") + - ServerConfig::CleanFilename(ServerInstance->ConfigFileName.c_str())); + ServerInstance->PI->SendUserNotice(user, "*** Rehashing server " + FileSystem::GetFileName(ServerInstance->ConfigFileName)); /* Don't do anything with the logs here -- logs are restarted * after the config thread has completed. diff --git a/src/configreader.cpp b/src/configreader.cpp index 7493d980c..341414e0d 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -734,11 +734,6 @@ void ServerConfig::ApplyModules(User* user) } } -bool ServerConfig::StartsWithWindowsDriveLetter(const std::string &path) -{ - return (path.length() > 2 && isalpha(path[0]) && path[1] == ':'); -} - ConfigTag* ServerConfig::ConfValue(const std::string &tag) { ConfigTagList found = config_data.equal_range(tag); @@ -757,18 +752,6 @@ ConfigTagList ServerConfig::ConfTags(const std::string& tag) return config_data.equal_range(tag); } -bool ServerConfig::FileExists(const char* file) -{ - struct stat sb; - if (stat(file, &sb) == -1) - return false; - - if ((sb.st_mode & S_IFDIR) > 0) - return false; - - return !access(file, F_OK); -} - std::string ServerConfig::Escape(const std::string& str, bool xml) { std::string escaped; @@ -793,22 +776,6 @@ std::string ServerConfig::Escape(const std::string& str, bool xml) return escaped; } -std::string ServerConfig::ExpandPath(const std::string& base, const std::string& fragment) -{ - // The fragment is an absolute path, don't modify it. - if (fragment[0] == '/' || ServerConfig::StartsWithWindowsDriveLetter(fragment)) - return fragment; - - return base + '/' + fragment; -} - -const char* ServerConfig::CleanFilename(const char* name) -{ - const char* p = name + strlen(name); - while ((p != name) && (*p != '/') && (*p != '\\')) p--; - return (p != name ? ++p : p); -} - void ConfigReaderThread::Run() { Config->Read(); diff --git a/src/fileutils.cpp b/src/fileutils.cpp new file mode 100644 index 000000000..ee89cca1c --- /dev/null +++ b/src/fileutils.cpp @@ -0,0 +1,102 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2013 Peter Powell <petpow@saberuk.com> + * + * This file is part of InspIRCd. InspIRCd is free software: you can + * redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "inspircd.h" + +#include <fstream> + +FileReader::FileReader(const std::string& filename) +{ + Load(filename); +} + +void FileReader::Load(const std::string& filename) +{ + // If the file is stored in the file cache then we used that version instead. + std::string realName = ServerInstance->Config->Paths.PrependConfig(filename); + ConfigFileCache::iterator it = ServerInstance->Config->Files.find(realName); + if (it != ServerInstance->Config->Files.end()) + { + this->lines = it->second; + } + else + { + lines.clear(); + + std::ifstream stream(realName.c_str()); + if (!stream.is_open()) + throw CoreException(filename + " does not exist or is not readable!"); + + std::string line; + while (std::getline(stream, line)) + { + lines.push_back(line); + totalSize += line.size() + 2; + } + + stream.close(); + } +} + +std::string FileReader::GetString() const +{ + std::string buffer; + for (file_cache::const_iterator it = this->lines.begin(); it != this->lines.end(); ++it) + { + buffer.append(*it); + buffer.append("\r\n"); + } + return buffer; +} + +std::string FileSystem::ExpandPath(const std::string& base, const std::string& fragment) +{ + // The fragment is an absolute path, don't modify it. + if (fragment[0] == '/' || FileSystem::StartsWithWindowsDriveLetter(fragment)) + return fragment; + + return base + '/' + fragment; +} + +bool FileSystem::FileExists(const std::string& file) +{ + struct stat sb; + if (stat(file.c_str(), &sb) == -1) + return false; + + if ((sb.st_mode & S_IFDIR) > 0) + return false; + + return !access(file.c_str(), F_OK); +} + +std::string FileSystem::GetFileName(const std::string& name) +{ +#ifdef _WIN32 + size_t pos = name.find_last_of("\\/"); +#else + size_t pos = name.rfind('/'); +#endif + return pos == std::string::npos ? name : name.substr(++pos); +} + +bool FileSystem::StartsWithWindowsDriveLetter(const std::string& path) +{ + return (path.length() > 2 && isalpha(path[0]) && path[1] == ':'); +} diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 368ca6e8b..de9287270 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -380,14 +380,14 @@ InspIRCd::InspIRCd(int argc, char** argv) : Logs->AddLogTypes("*", fls, true); } - if (!ServerConfig::FileExists(ConfigFileName.c_str())) + if (!FileSystem::FileExists(ConfigFileName)) { #ifdef _WIN32 /* Windows can (and defaults to) hide file extensions, so let's play a bit nice for windows users. */ std::string txtconf = this->ConfigFileName; txtconf.append(".txt"); - if (ServerConfig::FileExists(txtconf.c_str())) + if (FileSystem::FileExists(txtconf)) { ConfigFileName = txtconf; } diff --git a/src/modmanager_dynamic.cpp b/src/modmanager_dynamic.cpp index de2593d72..0d0042cab 100644 --- a/src/modmanager_dynamic.cpp +++ b/src/modmanager_dynamic.cpp @@ -39,7 +39,7 @@ bool ModuleManager::Load(const std::string& filename, bool defer) const std::string moduleFile = ServerInstance->Config->Paths.PrependModule(filename); - if (!ServerConfig::FileExists(moduleFile.c_str())) + if (!FileSystem::FileExists(moduleFile)) { LastModuleError = "Module file could not be found: " + filename; ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, LastModuleError); diff --git a/src/modules.cpp b/src/modules.cpp index 487bc4ea0..92f619743 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -25,7 +25,6 @@ #include <iostream> -#include <fstream> #include "inspircd.h" #include "xline.h" #include "socket.h" @@ -708,47 +707,3 @@ Module* ModuleManager::Find(const std::string &name) else return modfind->second; } - -FileReader::FileReader(const std::string& filename) -{ - Load(filename); -} - -void FileReader::Load(const std::string& filename) -{ - // If the file is stored in the file cache then we used that version instead. - std::string realName = ServerInstance->Config->Paths.PrependConfig(filename); - ConfigFileCache::iterator it = ServerInstance->Config->Files.find(realName); - if (it != ServerInstance->Config->Files.end()) - { - this->lines = it->second; - } - else - { - lines.clear(); - - std::ifstream stream(realName.c_str()); - if (!stream.is_open()) - throw CoreException(filename + " does not exist or is not readable!"); - - std::string line; - while (std::getline(stream, line)) - { - lines.push_back(line); - totalSize += line.size() + 2; - } - - stream.close(); - } -} - -std::string FileReader::GetString() -{ - std::string buffer; - for (file_cache::iterator it = this->lines.begin(); it != this->lines.end(); ++it) - { - buffer.append(*it); - buffer.append("\r\n"); - } - return buffer; -} diff --git a/src/modules/m_xline_db.cpp b/src/modules/m_xline_db.cpp index d482dca2b..222bbe17b 100644 --- a/src/modules/m_xline_db.cpp +++ b/src/modules/m_xline_db.cpp @@ -156,7 +156,7 @@ class ModuleXLineDB : public Module bool ReadDatabase() { // If the xline database doesn't exist then we don't need to load it. - if (!ServerConfig::FileExists(xlinedbpath.c_str())) + if (!FileSystem::FileExists(xlinedbpath)) return true; std::ifstream stream(xlinedbpath.c_str()); diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 538feaade..191760686 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -337,3 +337,71 @@ bool UserManager::AllModulesReportReady(LocalUser* user) FIRST_MOD_RESULT(OnCheckReady, res, (user)); return (res == MOD_RES_PASSTHRU); } + +/** + * This function is called once a second from the mainloop. + * It is intended to do background checking on all the user structs, e.g. + * stuff like ping checks, registration timeouts, etc. + */ +void UserManager::DoBackgroundUserStuff() +{ + /* + * loop over all local users.. + */ + for (LocalUserList::iterator i = local_users.begin(); i != local_users.end(); ++i) + { + LocalUser* curr = *i; + + if (curr->quitting) + continue; + + if (curr->CommandFloodPenalty || curr->eh.getSendQSize()) + { + unsigned int rate = curr->MyClass->GetCommandRate(); + if (curr->CommandFloodPenalty > rate) + curr->CommandFloodPenalty -= rate; + else + curr->CommandFloodPenalty = 0; + curr->eh.OnDataReady(); + } + + switch (curr->registered) + { + case REG_ALL: + if (ServerInstance->Time() > curr->nping) + { + // This user didn't answer the last ping, remove them + if (!curr->lastping) + { + time_t time = ServerInstance->Time() - (curr->nping - curr->MyClass->GetPingTime()); + const std::string message = "Ping timeout: " + ConvToStr(time) + (time == 1 ? " seconds" : " second"); + this->QuitUser(curr, message); + continue; + } + + curr->Write("PING :" + ServerInstance->Config->ServerName); + curr->lastping = 0; + curr->nping = ServerInstance->Time() + curr->MyClass->GetPingTime(); + } + break; + case REG_NICKUSER: + if (AllModulesReportReady(curr)) + { + /* User has sent NICK/USER, modules are okay, DNS finished. */ + curr->FullConnect(); + continue; + } + break; + } + + if (curr->registered != REG_ALL && (ServerInstance->Time() > (curr->age + curr->MyClass->GetRegTimeout()))) + { + /* + * registration timeout -- didnt send USER/NICK/HOST + * in the time specified in their connection class. + */ + this->QuitUser(curr, "Registration timeout"); + continue; + } + } +} diff --git a/src/userprocess.cpp b/src/userprocess.cpp deleted file mode 100644 index fe55fb3f7..000000000 --- a/src/userprocess.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * InspIRCd -- Internet Relay Chat Daemon - * - * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org> - * Copyright (C) 2006-2008 Robin Burchell <robin+git@viroteck.net> - * Copyright (C) 2005-2007 Craig Edwards <craigedwards@brainbox.cc> - * Copyright (C) 2007 Dennis Friis <peavey@inspircd.org> - * Copyright (C) 2006 Craig McLure <craig@chatspike.net> - * - * This file is part of InspIRCd. InspIRCd is free software: you can - * redistribute it and/or modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation, version 2. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "inspircd.h" -#include "xline.h" -#include "socketengine.h" -#include "command_parse.h" - -/** - * This function is called once a second from the mainloop. - * It is intended to do background checking on all the user structs, e.g. - * stuff like ping checks, registration timeouts, etc. - */ -void UserManager::DoBackgroundUserStuff() -{ - /* - * loop over all local users.. - */ - for (LocalUserList::iterator i = local_users.begin(); i != local_users.end(); ++i) - { - LocalUser* curr = *i; - - if (curr->quitting) - continue; - - if (curr->CommandFloodPenalty || curr->eh.getSendQSize()) - { - unsigned int rate = curr->MyClass->GetCommandRate(); - if (curr->CommandFloodPenalty > rate) - curr->CommandFloodPenalty -= rate; - else - curr->CommandFloodPenalty = 0; - curr->eh.OnDataReady(); - } - - switch (curr->registered) - { - case REG_ALL: - if (ServerInstance->Time() > curr->nping) - { - // This user didn't answer the last ping, remove them - if (!curr->lastping) - { - time_t time = ServerInstance->Time() - (curr->nping - curr->MyClass->GetPingTime()); - const std::string message = "Ping timeout: " + ConvToStr(time) + (time == 1 ? " seconds" : " second"); - this->QuitUser(curr, message); - continue; - } - - curr->Write("PING :" + ServerInstance->Config->ServerName); - curr->lastping = 0; - curr->nping = ServerInstance->Time() + curr->MyClass->GetPingTime(); - } - break; - case REG_NICKUSER: - if (AllModulesReportReady(curr)) - { - /* User has sent NICK/USER, modules are okay, DNS finished. */ - curr->FullConnect(); - continue; - } - break; - } - - if (curr->registered != REG_ALL && (ServerInstance->Time() > (curr->age + curr->MyClass->GetRegTimeout()))) - { - /* - * registration timeout -- didnt send USER/NICK/HOST - * in the time specified in their connection class. - */ - this->QuitUser(curr, "Registration timeout"); - continue; - } - } -} |