inspircd

A modular C++ IRC daemon (ircd). https://www.inspircd.org/
Log | Files | Refs | README

commit 6e898936d6e0f44da0992ad09139f0e8e6d141af
parent df9ca5115b64bc5b7888dee3123d0bf6527c496d
Author: Peter Powell <petpow@saberuk.com>
Date:   Mon, 10 Jun 2019 13:40:37 +0100

Add a method for getting a list of files in a directory.

Diffstat:
Minclude/fileutils.h | 12++++++++++++
Msrc/fileutils.cpp | 34++++++++++++++++++++++++++++++++++
Msrc/modulemanager.cpp | 42+++++++++++++++++++-----------------------
Mwin/inspircd_win32wrapper.cpp | 39---------------------------------------
Mwin/inspircd_win32wrapper.h | 17-----------------
5 files changed, 65 insertions(+), 79 deletions(-)

diff --git a/include/fileutils.h b/include/fileutils.h @@ -19,6 +19,10 @@ #pragma once +#ifndef _WIN32 +# include <dirent.h> +#endif + /** Provides an easy method of reading a text file into memory. */ class CoreExport FileReader { @@ -79,6 +83,14 @@ public: */ static std::string GetFileName(const std::string& path); + /** Gets a list of files which exist in the specified directory. + * @param directory The directory to retrieve files from. + * @param entries A vector which entries will be added to. + * @param match If defined then a glob match for files to be matched against. + * @return True if the directory could be opened; otherwise false. + */ + static bool GetFileList(const std::string& directory, std::vector<std::string>& entries, const std::string& match = "*"); + /** 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. diff --git a/src/fileutils.cpp b/src/fileutils.cpp @@ -86,6 +86,40 @@ bool FileSystem::FileExists(const std::string& file) return !access(file.c_str(), F_OK); } +bool FileSystem::GetFileList(const std::string& directory, std::vector<std::string>& entries, const std::string& match) +{ +#ifdef _WIN32 + const std::string search_path = directory + "\\" + match; + + WIN32_FIND_DATAA wfd; + HANDLE fh = FindFirstFileA(search_path.c_str(), &wfd); + if (fh == INVALID_HANDLE_VALUE) + return false; + + do + { + entries.push_back(wfd.cFileName); + } while (FindNextFile(fh, &wfd) != 0); + + FindClose(fh); + return true; +#else + DIR* library = opendir(directory.c_str()); + if (!library) + return false; + + dirent* entry = NULL; + while ((entry = readdir(library))) + { + if (InspIRCd::Match(entry->d_name, match, ascii_case_insensitive_map)) + entries.push_back(entry->d_name); + } + closedir(library); + return true; +#endif +} + + std::string FileSystem::GetFileName(const std::string& name) { #ifdef _WIN32 diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp @@ -21,10 +21,6 @@ #include "exitcodes.h" #include <iostream> -#ifndef _WIN32 -#include <dirent.h> -#endif - bool ModuleManager::Load(const std::string& modname, bool defer) { /* Don't allow people to specify paths for modules, it doesn't work as expected */ @@ -126,29 +122,29 @@ bool ModuleManager::Load(const std::string& modname, bool defer) /* We must load the modules AFTER initializing the socket engine, now */ void ModuleManager::LoadCoreModules(std::map<std::string, ServiceList>& servicemap) { - std::cout << std::endl << "Loading core commands" << std::flush; + std::cout << "Loading core modules " << std::flush; - DIR* library = opendir(ServerInstance->Config->Paths.Module.c_str()); - if (library) + std::vector<std::string> files; + if (!FileSystem::GetFileList(ServerInstance->Config->Paths.Module, files, "core_*.so")) { - dirent* entry = NULL; - while (0 != (entry = readdir(library))) - { - if (InspIRCd::Match(entry->d_name, "core_*.so", ascii_case_insensitive_map)) - { - std::cout << "." << std::flush; + std::cout << "failed!" << std::endl; + ServerInstance->Exit(EXIT_STATUS_MODULE); + } - this->NewServices = &servicemap[entry->d_name]; + for (std::vector<std::string>::const_iterator iter = files.begin(); iter != files.end(); ++iter) + { + std::cout << "." << std::flush; - if (!Load(entry->d_name, true)) - { - ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, this->LastError()); - std::cout << std::endl << "[" << con_red << "*" << con_reset << "] " << this->LastError() << std::endl << std::endl; - ServerInstance->Exit(EXIT_STATUS_MODULE); - } - } + const std::string& name = *iter; + this->NewServices = &servicemap[name]; + + if (!Load(name, true)) + { + ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, this->LastError()); + std::cout << std::endl << "[" << con_red << "*" << con_reset << "] " << this->LastError() << std::endl << std::endl; + ServerInstance->Exit(EXIT_STATUS_MODULE); } - closedir(library); - std::cout << std::endl; } + + std::cout << std::endl; } diff --git a/win/inspircd_win32wrapper.cpp b/win/inspircd_win32wrapper.cpp @@ -30,45 +30,6 @@ #include <errno.h> #include <assert.h> -CoreExport DIR * opendir(const char * path) -{ - std::string search_path = std::string(path) + "\\*.*"; - WIN32_FIND_DATAA fd; - HANDLE f = FindFirstFileA(search_path.c_str(), &fd); - if (f != INVALID_HANDLE_VALUE) - { - DIR * d = new DIR; - memcpy(&d->find_data, &fd, sizeof(WIN32_FIND_DATA)); - d->find_handle = f; - d->first = true; - return d; - } - else - { - return 0; - } -} - -CoreExport dirent * readdir(DIR * handle) -{ - if (handle->first) - handle->first = false; - else - { - if (!FindNextFileA(handle->find_handle, &handle->find_data)) - return 0; - } - - strncpy(handle->dirent_pointer.d_name, handle->find_data.cFileName, MAX_PATH); - return &handle->dirent_pointer; -} - -CoreExport void closedir(DIR * handle) -{ - FindClose(handle->find_handle); - delete handle; -} - int optind = 1; char optarg[514]; int getopt_long(int ___argc, char *const *___argv, const char *__shortopts, const struct option *__longopts, int *__longind) diff --git a/win/inspircd_win32wrapper.h b/win/inspircd_win32wrapper.h @@ -106,23 +106,6 @@ extern int optind; extern char optarg[514]; int getopt_long(int ___argc, char *const *___argv, const char *__shortopts, const struct option *__longopts, int *__longind); -struct dirent -{ - char d_name[MAX_PATH]; -}; - -struct DIR -{ - dirent dirent_pointer; - HANDLE find_handle; - WIN32_FIND_DATAA find_data; - bool first; -}; - -CoreExport DIR * opendir(const char * path); -CoreExport dirent * readdir(DIR * handle); -CoreExport void closedir(DIR * handle); - // warning: 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' // Normally, this is a huge problem, but due to our new/delete remap, we can ignore it. #pragma warning(disable:4251)