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

This commit is contained in:
Peter Powell 2019-06-10 13:40:37 +01:00
parent df9ca5115b
commit 6e898936d6
5 changed files with 68 additions and 82 deletions

View File

@ -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.

View File

@ -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

View File

@ -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;
this->NewServices = &servicemap[entry->d_name];
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);
}
}
}
closedir(library);
std::cout << std::endl;
std::cout << "failed!" << std::endl;
ServerInstance->Exit(EXIT_STATUS_MODULE);
}
for (std::vector<std::string>::const_iterator iter = files.begin(); iter != files.end(); ++iter)
{
std::cout << "." << std::flush;
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);
}
}
std::cout << std::endl;
}

View File

@ -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)

View File

@ -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)