From 244a65e8556328642350575c4a94ee8fc1b676b4 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Fri, 17 May 2013 05:46:51 +0100 Subject: [PATCH] Clean up the FileReader class and all of the modules that use it. - Modules which use this class will now have to catch a CoreException when opening files if they wish to ignore the failed loading of a file. - m_randquote has been cleaned up massively and the RANDQUOTE command has been removed as it was pretty much useless. --- include/modules.h | 70 ++++++----------------- src/configreader.cpp | 1 - src/modules.cpp | 92 +++++++++--------------------- src/modules/extra/m_ssl_gnutls.cpp | 12 ++-- src/modules/m_opermotd.cpp | 12 +++- src/modules/m_randquote.cpp | 63 +++++--------------- 6 files changed, 75 insertions(+), 175 deletions(-) diff --git a/include/modules.h b/include/modules.h index 176bdda34..89961a6f5 100644 --- a/include/modules.h +++ b/include/modules.h @@ -1281,76 +1281,42 @@ class CoreExport Module : public classbase, public usecountbase virtual void OnSetUserIP(LocalUser* user); }; -/** Caches a text file into memory and can be used to retrieve lines from it. - * This class contains methods for read-only manipulation of a text file in memory. - * Either use the constructor type with one parameter to load a file into memory - * at construction, or use the LoadFile method to load a file. - */ +/** Provides an easy method of reading a text file into memory. */ class CoreExport FileReader : public classbase { - /** The file contents + /** The lines of text in the file. */ - std::vector fc; + std::vector lines; /** Content size in bytes */ - unsigned long contentsize; - - /** Calculate content size in bytes - */ - void CalcSize(); + unsigned long totalSize; public: - /** Default constructor. - * This method does not load any file into memory, you must use the LoadFile method - * after constructing the class this way. - */ - FileReader(); - - /** Secondary constructor. - * This method initialises the class with a file loaded into it ready for GetLine and - * and other methods to be called. If the file could not be loaded, FileReader::FileSize - * returns 0. + /** Initializes a new file reader. */ - FileReader(const std::string &filename); + FileReader() : totalSize(0) { } - /** Default destructor. - * This deletes the memory allocated to the file. - */ - ~FileReader(); - - /** Used to load a file. - * This method loads a file into the class ready for GetLine and - * and other methods to be called. If the file could not be loaded, FileReader::FileSize - * returns 0. + /** Initializes a new file reader and reads the specified file. + * @param file The file to read into memory. */ - void LoadFile(const std::string &filename); + FileReader(const std::string& filename); - /** Returns the whole content of the file as std::string + /** Loads a text file from disk. + * @param filename The file to read into memory. + * @throw CoreException The file can not be loaded. */ - std::string Contents(); + void Load(const std::string& filename); - /** Returns the entire size of the file as std::string + /** Retrieves the entire contents of the file cache as a single string. */ - unsigned long ContentSize(); + std::string GetString(); - /** Returns true if the file exists - * This function will return false if the file could not be opened. + /** Retrieves the entire contents of the file cache as a vector of strings. */ - bool Exists(); + const std::vector& GetVector() { return lines; } - /** Retrieve one line from the file. - * This method retrieves one line from the text file. If an empty non-NULL string is returned, - * the index was out of bounds, or the line had no data on it. - */ - std::string GetLine(int x); - - /** Returns the size of the file in lines. - * This method returns the number of lines in the read file. If it is 0, no lines have been - * read into memory, either because the file is empty or it does not exist, or cannot be - * opened due to permission problems. - */ - int FileSize(); + unsigned long TotalSize() { return totalSize; } }; /** A list of modules diff --git a/src/configreader.cpp b/src/configreader.cpp index 8951ec0ee..0016fccaf 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -23,7 +23,6 @@ #include "inspircd.h" -#include #include "xline.h" #include "listmode.h" #include "exitcodes.h" diff --git a/src/modules.cpp b/src/modules.cpp index b01b1b5c2..dfbe1358e 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -24,6 +24,7 @@ */ +#include #include "inspircd.h" #include "xline.h" #include "socket.h" @@ -583,82 +584,45 @@ const std::vector ModuleManager::GetAllModuleNames(int filter) return retval; } -FileReader::FileReader(const std::string &filename) +FileReader::FileReader(const std::string& filename) { - LoadFile(filename); + Load(filename); } -FileReader::FileReader() +void FileReader::Load(const std::string& filename) { -} - -std::string FileReader::Contents() -{ - std::string x; - for (file_cache::iterator a = this->fc.begin(); a != this->fc.end(); a++) + // If the file is stored in the file cache then we used that version instead. + ConfigFileCache::iterator it = ServerInstance->Config->Files.find(filename); + if (it != ServerInstance->Config->Files.end()) { - x.append(*a); - x.append("\r\n"); - } - return x; -} - -unsigned long FileReader::ContentSize() -{ - return this->contentsize; -} - -void FileReader::CalcSize() -{ - unsigned long n = 0; - for (file_cache::iterator a = this->fc.begin(); a != this->fc.end(); a++) - n += (a->length() + 2); - this->contentsize = n; -} - -void FileReader::LoadFile(const std::string &filename) -{ - std::map::iterator file = ServerInstance->Config->Files.find(filename); - if (file != ServerInstance->Config->Files.end()) - { - this->fc = file->second; + this->lines = it->second; } else { - fc.clear(); - FILE* f = fopen(filename.c_str(), "r"); - if (!f) - return; - char linebuf[MAXBUF*10]; - while (fgets(linebuf, sizeof(linebuf), f)) - { - int len = strlen(linebuf); - if (len) - fc.push_back(std::string(linebuf, len - 1)); - } - fclose(f); - } - CalcSize(); -} + lines.clear(); + std::ifstream stream(filename.c_str()); + if (!stream.is_open()) + throw CoreException(filename + " does not exist or is not readable!"); -FileReader::~FileReader() -{ -} - -bool FileReader::Exists() -{ - return (!(fc.size() == 0)); -} + std::string line; + while (std::getline(stream, line)) + { + lines.push_back(line); + totalSize += line.size() + 2; + } -std::string FileReader::GetLine(int x) -{ - if ((x<0) || ((unsigned)x>fc.size())) - return ""; - return fc[x]; + stream.close(); + } } -int FileReader::FileSize() +std::string FileReader::GetString() { - return fc.size(); + 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/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 5ae530608..0659f631c 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -360,12 +360,12 @@ class ModuleSSLGnuTLS : public Module FileReader reader; - reader.LoadFile(certfile); - std::string cert_string = reader.Contents(); + reader.Load(certfile); + std::string cert_string = reader.GetString(); gnutls_datum_t cert_datum = { (unsigned char*)cert_string.data(), static_cast(cert_string.length()) }; - reader.LoadFile(keyfile); - std::string key_string = reader.Contents(); + reader.Load(keyfile); + std::string key_string = reader.GetString(); gnutls_datum_t key_datum = { (unsigned char*)key_string.data(), static_cast(key_string.length()) }; // If this fails, no SSL port will work. At all. So, do the smart thing - throw a ModuleException @@ -431,8 +431,8 @@ class ModuleSSLGnuTLS : public Module if (!dhfile.empty()) { // Try to load DH params from file - reader.LoadFile(dhfile); - std::string dhstring = reader.Contents(); + reader.Load(dhfile); + std::string dhstring = reader.GetString(); gnutls_datum_t dh_datum = { (unsigned char*)dhstring.data(), static_cast(dhstring.length()) }; if ((ret = gnutls_dh_params_import_pkcs3(dh_params, &dh_datum, GNUTLS_X509_FMT_PEM)) < 0) diff --git a/src/modules/m_opermotd.cpp b/src/modules/m_opermotd.cpp index b228dc8b7..aa5767b4c 100644 --- a/src/modules/m_opermotd.cpp +++ b/src/modules/m_opermotd.cpp @@ -107,9 +107,15 @@ class ModuleOpermotd : public Module ConfigTag* conf = ServerInstance->Config->ConfValue("opermotd"); onoper = conf->getBool("onoper", true); - FileReader f(conf->getString("file", "opermotd")); - for (int i=0, filesize = f.FileSize(); i < filesize; i++) - cmd.opermotd.push_back(f.GetLine(i)); + try + { + FileReader reader(conf->getString("file", "opermotd")); + cmd.opermotd = reader.GetVector(); + } + catch (CoreException&) + { + // Nothing happens here as we do the error handling in ShowOperMOTD. + } if (conf->getBool("processcolors")) InspIRCd::ProcessColors(cmd.opermotd); diff --git a/src/modules/m_randquote.cpp b/src/modules/m_randquote.cpp index 62d3022cf..8b9ffd6e9 100644 --- a/src/modules/m_randquote.cpp +++ b/src/modules/m_randquote.cpp @@ -25,73 +25,38 @@ #include "inspircd.h" -static FileReader *quotes = NULL; - -std::string prefix; -std::string suffix; - -/** Handle /RANDQUOTE - */ -class CommandRandquote : public Command -{ - public: - CommandRandquote(Module* Creator) : Command(Creator,"RANDQUOTE", 0) - { - } - - CmdResult Handle (const std::vector& parameters, User *user) - { - std::string str; - int fsize; - - fsize = quotes->FileSize(); - str = quotes->GetLine(ServerInstance->GenRandomInt(fsize)); - user->WriteNotice(prefix + str + suffix); - - return CMD_SUCCESS; - } -}; - class ModuleRandQuote : public Module { - CommandRandquote cmd; - public: - ModuleRandQuote() - : cmd(this) - { - } + private: + std::string prefix; + std::string suffix; + std::vector quotes; + public: void init() CXX11_OVERRIDE { ConfigTag* conf = ServerInstance->Config->ConfValue("randquote"); - - std::string q_file = conf->getString("file","quotes"); prefix = conf->getString("prefix"); suffix = conf->getString("suffix"); + FileReader reader(conf->getString("file", "quotes")); + quotes = reader.GetVector(); - quotes = new FileReader(q_file); - if (!quotes->Exists()) - { - throw ModuleException("m_randquote: QuoteFile not Found!! Please check your config - module will not function."); - } - ServerInstance->Modules->AddService(cmd); Implementation eventlist[] = { I_OnUserConnect }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); } - ~ModuleRandQuote() + void OnUserConnect(LocalUser* user) CXX11_OVERRIDE { - delete quotes; + if (!quotes.empty()) + { + unsigned long random = ServerInstance->GenRandomInt(quotes.size()); + user->WriteNotice(prefix + quotes[random] + suffix); + } } Version GetVersion() CXX11_OVERRIDE { - return Version("Provides random quotes on connect.",VF_VENDOR); - } - - void OnUserConnect(LocalUser* user) CXX11_OVERRIDE - { - cmd.Handle(std::vector(), user); + return Version("Provides random quotes on connect.", VF_VENDOR); } }; -- 2.39.5