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
|
/*
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
#ifndef FS_H__
#define FS_H__
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <functional>
#ifndef STD_FILESYSTEM
# if (_WIN32 && __GNUG__) // MinGW GCC somehow incorrectly converts paths
# define STD_FILESYSTEM 0
# elif (!TARGET_OS_SIMULATOR && __has_include(<filesystem>)) // supports std::filesystem
# define STD_FILESYSTEM 1
# else
# define STD_FILESYSTEM 0
# endif
#endif
namespace i2p {
namespace fs {
extern std::string dirSep;
/**
* @brief Class to work with NetDb & Router profiles
*
* Usage:
*
* const char alphabet[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
* auto h = HashedStorage("name", "y", "z-", ".txt");
* h.SetPlace("/tmp/hs-test");
* h.GetName() -> gives "name"
* h.GetRoot() -> gives "/tmp/hs-test/name"
* h.Init(alphabet, 8); <- creates needed dirs, 8 is size of alphabet
* h.Path("abcd"); <- returns /tmp/hs-test/name/ya/z-abcd.txt
* h.Remove("abcd"); <- removes /tmp/hs-test/name/ya/z-abcd.txt, if it exists
* std::vector<std::string> files;
* h.Traverse(files); <- finds all files in storage and saves in given vector
*/
class HashedStorage
{
protected:
std::string root; /**< path to storage with it's name included */
std::string name; /**< name of the storage */
std::string prefix1; /**< hashed directory prefix */
std::string prefix2; /**< prefix of file in storage */
std::string suffix; /**< suffix of file in storage (extension) */
public:
typedef std::function<void(const std::string &)> FilenameVisitor;
HashedStorage(const char *n, const char *p1, const char *p2, const char *s):
name(n), prefix1(p1), prefix2(p2), suffix(s) {};
/** create subdirs in storage */
bool Init(const char* chars, size_t cnt);
const std::string & GetRoot() const { return root; }
const std::string & GetName() const { return name; }
/** set directory where to place storage directory */
void SetPlace(const std::string & path);
/** path to file with given ident */
std::string Path(const std::string & ident) const;
/** remove file by ident */
void Remove(const std::string & ident);
/** find all files in storage and store list in provided vector */
void Traverse(std::vector<std::string> & files);
/** visit every file in this storage with a visitor */
void Iterate(FilenameVisitor v);
};
/** @brief Returns current application name, default 'i2pd' */
const std::string & GetAppName ();
/** @brief Set application name, affects autodetection of datadir */
void SetAppName (const std::string& name);
/** @brief Returns datadir path */
const std::string & GetDataDir();
/** @brief Returns certsdir path */
const std::string & GetCertsDir();
/** @brief Returns datadir path in UTF-8 encoding */
const std::string GetUTF8DataDir();
/**
* @brief Set datadir either from cmdline option or using autodetection
* @param cmdline_param Value of cmdline parameter --datadir=<something>
* @param isService Value of cmdline parameter --service
*
* Examples of autodetected paths:
*
* Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\
* Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
*/
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
/**
* @brief Set certsdir either from cmdline option or using autodetection
* @param cmdline_param Value of cmdline parameter --certsdir=<something>
*
* Examples of autodetected paths:
*
* Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\certificates
* Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\certificates
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/certificates
* Unix: /var/lib/i2pd/certificates (system=1) >> ~/.i2pd/ or /tmp/i2pd/certificates
*/
void SetCertsDir(const std::string & cmdline_certsdir);
/**
* @brief Create subdirectories inside datadir
*/
bool Init();
/**
* @brief Get list of files in directory
* @param path Path to directory
* @param files Vector to store found files
* @return true on success and false if directory not exists
*/
bool ReadDir(const std::string & path, std::vector<std::string> & files);
/**
* @brief Remove file with given path
* @param path Absolute path to file
* @return true on success, false if file not exists, throws exception on error
*/
bool Remove(const std::string & path);
/**
* @brief Check existence of file
* @param path Absolute path to file
* @return true if file exists, false otherwise
*/
bool Exists(const std::string & path);
uint32_t GetLastUpdateTime (const std::string & path); // seconds since epoch
bool CreateDirectory (const std::string& path);
template<typename T>
void _ExpandPath(std::stringstream & path, T c) {
path << i2p::fs::dirSep << c;
}
template<typename T, typename ... Other>
void _ExpandPath(std::stringstream & path, T c, Other ... other) {
_ExpandPath(path, c);
_ExpandPath(path, other ...);
}
/**
* @brief Get path relative to datadir
*
* Examples (with datadir = "/tmp/i2pd"):
*
* i2p::fs::Path("test") -> '/tmp/i2pd/test'
* i2p::fs::Path("test", "file.txt") -> '/tmp/i2pd/test/file.txt'
*/
template<typename ... Other>
std::string DataDirPath(Other ... components) {
std::stringstream s("");
s << i2p::fs::GetDataDir();
_ExpandPath(s, components ...);
return s.str();
}
template<typename Storage, typename... Filename>
std::string StorageRootPath (const Storage& storage, Filename... filenames)
{
std::stringstream s("");
s << storage.GetRoot ();
_ExpandPath(s, filenames...);
return s.str();
}
} // fs
} // i2p
#endif // /* FS_H__ */
|