std::string canonicalizePath(const std::string &path, bool checkAccess)
{
auto resolved = resolvePath(path);
+
auto target = File::getPkgPath(resolved);
if (checkAccess && !isReadable(path)) {
return target;
}
+FilePtr canonicalizePathWithFile(const std::string &path)
+{
+ auto resolved = resolvePath(path);
+
+ auto fileptr = File::create(path, nullptr);
+
+ if (!isReadable(fileptr->getName()))
+ ThrowExcWarn(CSR_ERROR_FILE_DO_NOT_EXIST, "File is not readable: " << fileptr->getName());
+
+ return fileptr;
+}
+
} // namespace anonymous
CsLogic::CsLogic(const std::shared_ptr<CsLoader> &loader,
auto lastScanTime = this->m_db->getLastScanTime(pkgPath, t);
// traverse files in app and take which is more danger than riskiest
- auto visitor = FsVisitor::create(pkgPath, lastScanTime);
+ auto visitor = FsVisitor::create(pkgPath, false, lastScanTime);
CsDetectedPtr riskiest;
return riskiest;
}
-RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &pkgPath)
+RawBuffer CsLogic::scanApp(const CsContext &context, const FilePtr &pkgPtr)
{
- auto fileptr = File::create(pkgPath);
-
- if (!fileptr)
- ThrowExc(CSR_ERROR_SERVER, "fileptr shouldn't be empty because didn't check modified");
- if (!fileptr->isInApp())
- ThrowExc(CSR_ERROR_SERVER, "fileptr should be in app.");
-
- const auto &pkgId = fileptr->getAppPkgId();
+ const auto &pkgPath = pkgPtr->getName();
+ const auto &pkgId = pkgPtr->getAppPkgId();
if (context.isScanOnCloud && this->m_loader->scanAppOnCloudSupported())
return this->scanAppOnCloud(context, pkgPath, pkgId);
this->m_db->insertDetectedFile(d.targetName, d, this->m_dataVersion);
- return this->handleAskUser(context, d, std::forward<FilePtr>(fileptr));
+ return this->handleAskUser(context, d, std::move(fileptr));
}
RawBuffer CsLogic::scanFile(const CsContext &context, const std::string &filepath)
setCoreUsage(context.coreUsage);
- auto target = canonicalizePath(filepath, true);
+ auto target = canonicalizePathWithFile(filepath);
- if (File::isInApp(target))
+ if (target->isInApp())
return this->scanApp(context, target);
- DEBUG("Scan request on file: " << target);
-
- CsEngineContext engineContext(this->m_loader);
- auto since = this->m_loader->getEngineLatestUpdateTime(engineContext.get());
-
- auto history = this->m_db->getDetectedAllByNameOnPath(target, since);
+ const auto &name = target->getName();
- FilePtr fileptr;
+ if (target->isDir())
+ ThrowExc(CSR_ERROR_FILE_SYSTEM, "file type shouldn't be directory: " << name);
- // if history exist, fileptr can be null because of modified since value
- // from history.
- if (history)
- fileptr = File::createIfModified(target, static_cast<time_t>(history->ts));
- else
- fileptr = File::create(target);
-
- // non-null fileptr means the file is modified since the last history
- // OR there's no history at all.
- if (fileptr) {
- if (history)
- this->m_db->deleteDetectedByNameOnPath(target);
+ DEBUG("Scan request on file: " << name);
- if (fileptr->isDir())
- ThrowExc(CSR_ERROR_FILE_SYSTEM,
- "file type shouldn't be directory: " << target);
+ CsEngineContext engineContext(this->m_loader);
+ auto since = this->m_loader->getEngineLatestUpdateTime(engineContext.get());
+ auto history = this->m_db->getDetectedAllByNameOnPath(name, since);
- DEBUG("file[" << target << "] is modified since the detected time. "
+ if (history == nullptr) {
+ DEBUG("No history exist on target. Newly scan needed: " << name);
+ return this->scanFileWithoutDelta(context, name, std::move(target));
+ } else if (target->isModifiedSince(history->ts)) {
+ DEBUG("file[" << name << "] is modified since the detected time. "
"let's remove history and re-scan");
- return this->scanFileWithoutDelta(context, target, std::move(fileptr));
+ this->m_db->deleteDetectedByNameOnPath(name);
+ return this->scanFileWithoutDelta(context, name, std::move(target));
}
- DEBUG("Usable scan history exist on file: " << target);
+ DEBUG("Usable scan history exist on file: " << name);
if (history->isIgnored)
return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
if (this->m_db->getEngineState(CSR_ENGINE_CS) != CSR_STATE_ENABLE)
ThrowExc(CSR_ERROR_ENGINE_DISABLED, "engine is disabled");
+ auto targetdir = canonicalizePath(dir, true);
+
CsEngineContext csEngineContext(this->m_loader);
auto since = this->m_loader->getEngineLatestUpdateTime(csEngineContext.get());
- auto lastScanTime = this->m_db->getLastScanTime(dir, since);
+ auto lastScanTime = this->m_db->getLastScanTime(targetdir, since);
- auto visitor = FsVisitor::create(dir, lastScanTime);
+ auto visitor = FsVisitor::create(targetdir, true, lastScanTime);
isCancelled();
while (auto file = visitor->next()) {
isCancelled();
- if (file->isInApp()) {
- DEBUG("Scannable app: " << file->getAppPkgPath());
- fileset.insert(file->getAppPkgPath());
- } else {
- DEBUG("Scannable file: " << file->getPath());
- fileset.insert(file->getPath());
- }
+ DEBUG("Scannable item: " << file->getName());
+ fileset.insert(file->getName());
}
if (lastScanTime != -1) {
// for case: scan history exist and not modified.
- for (auto &row : this->m_db->getDetectedAllByNameOnDir(File::getPkgPath(dir), since)) {
+ for (auto &row : this->m_db->getDetectedAllByNameOnDir(targetdir, since)) {
isCancelled();
try {
- auto fileptr = File::create(row->targetName);
+ auto fileptr = File::create(row->targetName, nullptr);
- fileset.insert(fileptr->isInApp() ?
- fileptr->getAppPkgPath() : fileptr->getPath());
+ fileset.insert(fileptr->getName());
} catch (const Exception &e) {
if (e.error() == CSR_ERROR_FILE_DO_NOT_EXIST ||
e.error() == CSR_ERROR_FILE_SYSTEM)
// for file existence / status check. exception thrown.
FilePtr file;
try {
- file = File::create(filepath);
+ file = File::create(filepath, nullptr);
} catch (const Exception &e) {
ERROR("file system related exception occured on file: " << filepath <<
" This case might be file not exist or type invalid,"
throw;
}
- const auto &targetName = (file->isInApp() ? file->getAppPkgPath() : filepath);
+ const auto &targetName = file->getName();
CsEngineContext csEngineContext(this->m_loader);
auto since = this->m_loader->getEngineLatestUpdateTime(csEngineContext.get());
}
// file create based on fileInAppPath(for app target, it is worst detected)
- if (!isCloudHistory && File::createIfModified(history->fileInAppPath,
- static_cast<time_t>(history->ts)))
+ if (!isCloudHistory && file->isModifiedSince(history->ts))
ThrowExc(CSR_ERROR_FILE_CHANGED,
"File[" << history->fileInAppPath << "] modified since db delta inserted."
" Don't refresh detected history to know that it's changed since the"
if (d.response == CSR_CS_USER_RESPONSE_REMOVE && !d.targetName.empty()) {
try {
FilePtr _fileptr;
-
if (fileptr)
- _fileptr = std::forward<FilePtr>(fileptr);
+ _fileptr = std::move(fileptr);
else
- _fileptr = File::create(d.targetName);
+ _fileptr = File::create(d.targetName, nullptr);
_fileptr->remove();
} catch (const Exception &e) {
throw;
}
- this->m_db->deleteDetectedByNameOnPath(File::getPkgPath(d.targetName));
+ this->m_db->deleteDetectedByNameOnPath(d.targetName);
}
return BinaryQueue::Serialize(CSR_ERROR_NONE, d).pop();
RawBuffer getIgnoredList(const StrSet &dirSet);
private:
- RawBuffer scanApp(const CsContext &context, const std::string &pkgPath);
+ RawBuffer scanApp(const CsContext &context, const FilePtr &pkgPtr);
RawBuffer scanAppOnCloud(const CsContext &context, const std::string &pkgPath,
const std::string &pkgId);
CsDetectedPtr scanAppDelta(const std::string &pkgPath, const std::string &pkgId,
return type;
}
-bool File::isInApp(const std::string &path)
-{
- std::smatch matched;
-
- for (const auto ®e : g_regexprs) {
- if (!std::regex_search(path, matched, rege))
- continue;
-
- std::string pkgUser;
- std::string pkgId;
-
- if (matched.size() == 3) {
- pkgId = matched[2];
- } else if (matched.size() == 4) {
- pkgUser = matched[2];
- pkgId = matched[3];
- } else {
- continue;
- }
-
- auto type = File::getPkgTypes(pkgUser, pkgId);
-
- return (type & static_cast<int>(Type::Package)) &&
- (!(type & static_cast<int>(Type::PreLoaded)));
- }
-
- return false;
-}
-
std::string File::getPkgPath(const std::string &path)
{
std::smatch matched;
return path;
}
-File::File(const std::string &fpath, int type) : m_path(fpath), m_type(type)
+File::File(const std::string &fpath, const FilePtr &parentdir, int type,
+ std::unique_ptr<struct stat> &&statptr) :
+ m_path(fpath), m_type(type), m_statptr(std::move(statptr))
{
+ if (parentdir != nullptr) {
+ if (parentdir->isPackage()) {
+ this->m_appPkgPath = parentdir->getAppPkgPath();
+ this->m_appPkgId = parentdir->getAppPkgId();
+ this->m_appUser = parentdir->getAppUser();
+
+ this->m_type |= static_cast<int>(File::Type::Package);
+
+ if (parentdir->isPreloaded())
+ this->m_type |= static_cast<int>(File::Type::PreLoaded);
+
+ return;
+ } else if (!this->isDir()) {
+ this->m_type &= ~(static_cast<int>(File::Type::Package) |
+ static_cast<int>(File::Type::PreLoaded));
+ }
+ }
+
std::smatch matched;
for (const auto ®e : g_regexprs) {
}
}
-const std::string &File::getPath() const noexcept
-{
- return this->m_path;
-}
-
-bool File::isInApp() const noexcept
-{
- return (this->m_type & static_cast<int>(Type::Package)) &&
- (!(this->m_type & static_cast<int>(Type::PreLoaded)));
-}
-
-bool File::isDir() const noexcept
-{
- return this->m_type & static_cast<int>(Type::Directory);
-}
-
-bool File::isModified() const noexcept
-{
- return this->m_type & static_cast<int>(Type::Modified);
-}
-
-const std::string &File::getAppPkgId() const noexcept
-{
- return this->m_appPkgId;
-}
-
-const std::string &File::getAppUser() const noexcept
-{
- return this->m_appUser;
-}
-
-const std::string &File::getAppPkgPath() const noexcept
-{
- return this->m_appPkgPath;
-}
-
void File::remove() const
{
if (this->isInApp()) {
}
}
-FilePtr File::createIfModified(const std::string &fpath, time_t modifiedSince)
+FilePtr File::createIfModified(const std::string &fpath, const FilePtr &parentdir, time_t modifiedSince)
{
- return File::createInternal(fpath, modifiedSince, true);
+ return File::createInternal(fpath, parentdir, modifiedSince, true);
}
-FilePtr File::create(const std::string &fpath, time_t modifiedSince)
+FilePtr File::create(const std::string &fpath, const FilePtr &parentdir, time_t modifiedSince)
{
- return File::createInternal(fpath, modifiedSince, false);
+ return File::createInternal(fpath, parentdir, modifiedSince, false);
}
-FilePtr File::createInternal(const std::string &fpath, time_t modifiedSince,
- bool isModifiedOnly)
+FilePtr File::createInternal(const std::string &fpath, const FilePtr &parentdir,
+ time_t modifiedSince, bool isModifiedOnly)
{
auto statptr = getStat(fpath);
if (isModifiedOnly && !(type & static_cast<int>(Type::Modified)))
return nullptr;
else
- return FilePtr(new File(fpath, type));
+ return FilePtr(new File(fpath, parentdir, type, std::move(statptr)));
}
FsVisitor::DirPtr FsVisitor::openDir(const std::string &dir)
return std::unique_ptr<DIR, int(*)(DIR *)>(::opendir(dir.c_str()), ::closedir);
}
-FsVisitorPtr FsVisitor::create(const std::string &dirpath, time_t modifiedSince)
+FsVisitorPtr FsVisitor::create(const std::string &dirpath, bool isBasedOnName, time_t modifiedSince)
{
auto statptr = getStat(dirpath);
if (statptr == nullptr)
else if (!S_ISDIR(statptr->st_mode))
ThrowExc(CSR_ERROR_FILE_SYSTEM, "file type is not directory: " << dirpath);
else
- return FsVisitorPtr(new FsVisitor(dirpath, modifiedSince));
+ return FsVisitorPtr(new FsVisitor(dirpath, isBasedOnName, modifiedSince));
}
-FsVisitor::FsVisitor(const std::string &dirpath, time_t modifiedSince) :
- m_since(modifiedSince), m_dirptr(openDir(dirpath)),
- m_entryBuf(static_cast<struct dirent *>(::malloc(
- offsetof(struct dirent, d_name) + NAME_MAX + 1)))
+FsVisitor::FsVisitor(const std::string &dirpath, bool isBasedOnName, time_t modifiedSince) :
+ m_since(modifiedSince), m_dirptr(nullptr, ::closedir),
+ m_entryBuf(static_cast<struct dirent *>(::malloc(offsetof(struct dirent, d_name) + NAME_MAX + 1))),
+ m_isDone(true), m_isBasedOnName(isBasedOnName)
{
- if (!this->m_dirptr)
- ThrowExc(CSR_ERROR_SERVER, "Failed to open dir: " << dirpath);
+ if (this->m_entryBuf == nullptr)
+ throw std::bad_alloc();
- DEBUG("dir opened: " << dirpath);
- this->m_dirs.push((dirpath.back() == '/') ? dirpath : (dirpath + '/'));
+ this->m_dirs.emplace(File::create(dirpath, nullptr));
}
FsVisitor::~FsVisitor()
FilePtr FsVisitor::next()
{
- struct dirent *result = nullptr;
while (true) {
- bool isDone = false;
-
- if (readdir_r(this->m_dirptr.get(), this->m_entryBuf, &result) != 0) {
- ERROR("readdir_r error on dir: " << this->m_dirs.front() <<
- " with errno: " << errno << ". Silently ignore this error & dir stream"
- " to reduce side-effect of traversing all the other file systems.");
- isDone = true;
- } else if (result == nullptr) {
- DEBUG("End of stream of dir: " << this->m_dirs.front());
- isDone = true;
- } else if (isInBlackList(this->m_dirs.front())) {
- DEBUG("dir[" << this->m_dirs.front() << "] is in black list.");
- isDone = true;
- }
-
- if (isDone) {
- this->m_dirs.pop();
+ if (this->m_isDone) {
while (!this->m_dirs.empty() &&
- !(this->m_dirptr = openDir(this->m_dirs.front())))
+ !(this->m_dirptr = openDir(this->m_dirs.front()->getPath())) &&
+ isInBlackList(this->m_dirs.front()->getPath()))
this->m_dirs.pop();
- if (this->m_dirs.empty())
+ if (this->m_dirs.empty()) {
+ this->m_currentdir.reset();
+ this->m_isDone = true;
return nullptr;
+ } else {
+ this->m_currentdir = std::move(this->m_dirs.front());
+ this->m_dirs.pop();
+ this->m_isDone = false;
+ DEBUG("dir opened: " << this->m_currentdir->getPath());
+ }
+ }
- DEBUG("dir opened: " << this->m_dirs.front());
+ struct dirent *result = nullptr;
+ const auto &parent_dirpath = this->m_currentdir->getPath();
+ if (::readdir_r(this->m_dirptr.get(), this->m_entryBuf, &result) != 0) {
+ ERROR("readdir_r error on dir: " << parent_dirpath <<
+ " with errno: " << errno << ". Silently ignore this error & dir stream"
+ " to reduce side-effect of traversing all the other file systems.");
+ this->m_isDone = true;
+ continue;
+ } else if (result == nullptr) {
+ DEBUG("End of stream of dir: " << parent_dirpath);
+ this->m_isDone = true;
continue;
}
- auto &dir = this->m_dirs.front();
const auto &name = result->d_name;
auto name_size = ::strlen(name);
if (name_size == 0)
continue;
+ auto fullpath = (parent_dirpath.back() == '/') ?
+ (parent_dirpath + name) : (parent_dirpath + "/" + name);
+
if (result->d_type == DT_DIR) {
- if (name_size == 1 && ::strcmp(name, ".") == 0)
- continue;
- else if (name_size == 2 && ::strcmp(name, "..") == 0)
+ if ((name_size == 1 && name[0] == '.') ||
+ (name_size == 2 && name[0] == '.' && name[1] == '.'))
continue;
- DEBUG("push dir to dirs: " << (dir + name + '/'));
- this->m_dirs.emplace(dir + name + '/');
+ FilePtr dirptr;
+ try {
+ dirptr = File::create(fullpath, this->m_currentdir);
+ } catch (const Exception &e) {
+ if (e.error() == CSR_ERROR_FILE_DO_NOT_EXIST) {
+ WARN("Perm denied to create file on pkg path: " << fullpath);
+ continue;
+ } else {
+ throw;
+ }
+ }
+
+ if (this->m_isBasedOnName && dirptr->isInApp())
+ return dirptr;
+
+ DEBUG("push dir to dirs queue: " << fullpath);
+ this->m_dirs.emplace(std::move(dirptr));
} else if (result->d_type == DT_REG) {
try {
- auto fileptr = File::createIfModified(dir + name, this->m_since);
+ auto fileptr = File::createIfModified(
+ fullpath, this->m_currentdir, this->m_since);
if (fileptr)
return fileptr;
} catch (const Exception &e) {
if (e.error() == CSR_ERROR_FILE_DO_NOT_EXIST)
- WARN("file not exist: " << dir << name << " msg: " << e.what());
+ WARN("file not exist: " << fullpath << " msg: " << e.what());
else if (e.error() == CSR_ERROR_FILE_SYSTEM)
WARN("file type is not regular...? can it be happened?"
- " :" << dir << name << " msg: " << e.what());
+ " :" << fullpath << " msg: " << e.what());
else
throw;
}
#include <cstddef>
#include <ctime>
#include <dirent.h>
+#include <sys/stat.h>
namespace Csr {
public:
File() = delete;
- const std::string &getPath() const noexcept;
- bool isInApp() const noexcept;
- bool isDir() const noexcept;
- bool isModified() const noexcept;
- const std::string &getAppPkgId() const noexcept;
- const std::string &getAppUser() const noexcept;
- const std::string &getAppPkgPath() const noexcept;
+ inline bool isInApp() const noexcept
+ {
+ return this->isPackage() && !this->isPreloaded();
+ }
+
+ inline bool isPackage() const noexcept
+ {
+ return this->m_type & static_cast<int>(Type::Package);
+ }
+
+ inline bool isPreloaded() const noexcept
+ {
+ return this->m_type & static_cast<int>(Type::PreLoaded);
+ }
+
+ inline bool isModified() const noexcept
+ {
+ return this->m_type & static_cast<int>(Type::Modified);
+ }
+
+ inline bool isModifiedSince(time_t since) const noexcept
+ {
+ return this->m_statptr->st_ctime > since;
+ }
+
+ inline bool isDir() const noexcept
+ {
+ return this->m_type & static_cast<int>(Type::Directory);
+ }
+
+ inline const std::string &getName() const noexcept
+ {
+ return (this->isInApp()) ? this->m_appPkgPath : this->m_path;
+ }
+
+ inline const std::string &getPath() const noexcept
+ {
+ return this->m_path;
+ }
+
+ inline const std::string &getAppPkgId() const noexcept
+ {
+ return this->m_appPkgId;
+ }
+
+ inline const std::string &getAppUser() const noexcept
+ {
+ return this->m_appUser;
+ }
+
+ inline const std::string &getAppPkgPath() const noexcept
+ {
+ return this->m_appPkgPath;
+ }
void remove() const;
// throws FileNotExist and FileSystemError
- static FilePtr create(const std::string &fpath, time_t modifiedSince = -1);
- static FilePtr createIfModified(const std::string &fpath, time_t modifiedSince = -1);
+ static FilePtr create(const std::string &fpath, const FilePtr &parentdir,
+ time_t modifiedSince = -1);
+ static FilePtr createIfModified(const std::string &fpath, const FilePtr &parentdir,
+ time_t modifiedSince = -1);
- static bool isInApp(const std::string &path);
static std::string getPkgPath(const std::string &path);
private:
Directory = (1 << 4)
};
- static FilePtr createInternal(const std::string &fpath, time_t modifiedSince,
- bool isModifiedOnly);
+ static FilePtr createInternal(const std::string &fpath, const FilePtr &parentdir,
+ time_t modifiedSince, bool isModifiedOnly);
static int getPkgTypes(const std::string &user, const std::string &pkgid);
- explicit File(const std::string &fpath, int type);
+ explicit File(const std::string &fpath, const FilePtr &parentdir, int type,
+ std::unique_ptr<struct stat> &&statptr);
std::string m_path;
int m_type;
+ std::unique_ptr<struct stat> m_statptr;
std::string m_appPkgId; // meaningful only if inApp == true
std::string m_appUser; // meaningful only if inApp == true
std::string m_appPkgPath; // meaningful only if inApp == true
FilePtr next();
// throws FileNotExist and FileSystemError
- static FsVisitorPtr create(const std::string &dirpath, time_t modifiedSince = -1);
+ static FsVisitorPtr create(const std::string &dirpath, bool isBasedOnName,
+ time_t modifiedSince = -1);
private:
using DirPtr = std::unique_ptr<DIR, int(*)(DIR *)>;
static DirPtr openDir(const std::string &);
- FsVisitor(const std::string &dirpath, time_t modifiedSince = -1);
+ FsVisitor(const std::string &dirpath, bool isBasedOnName, time_t modifiedSince = -1);
time_t m_since;
- std::queue<std::string> m_dirs;
+ std::queue<FilePtr> m_dirs;
DirPtr m_dirptr;
struct dirent *m_entryBuf;
+ FilePtr m_currentdir;
+ bool m_isDone;
+ bool m_isBasedOnName;
};
} // namespace Csr
ASSERT_IF(file.getPath(), path);
ASSERT_IF(file.getAppUser(), user);
ASSERT_IF(file.getAppPkgId(), pkgId);
- ASSERT_IF(file.getAppPkgPath(), pkgPath);
+ ASSERT_IF(file.getName(), pkgPath);
ASSERT_IF(file.isInApp(), inApp);
}
__createFile(fpath);
- auto file = File::create(fpath);
+ auto file = File::create(fpath, nullptr);
BOOST_REQUIRE_NO_THROW(file->remove());
bool isRemoved = access(fpath.c_str(), F_OK) != 0 && errno == ENOENT;
Test::uninstall_app(TEST_TPK_PKG_ID);
ASSERT_INSTALL_APP(TEST_TPK_PATH, TEST_TPK_TYPE);
- auto app = File::create(TEST_TPK_MAL_FILE());
+ auto app = File::create(TEST_TPK_MAL_FILE(), nullptr);
CHECK_IS_NOT_NULL(app);
app->remove();
BOOST_AUTO_TEST_CASE(file_visitor_positive_existing)
{
- CHECK_IS_NOT_NULL(File::create(TEST_WRITE_FILE));
+ CHECK_IS_NOT_NULL(File::create(TEST_WRITE_FILE, nullptr));
}
BOOST_AUTO_TEST_CASE(file_visitor_positive_modified)
// if modifiedSince is same to modified time in file stat,
// the file will be regarded as ''not modified'' no File::create returns null.
- CHECK_IS_NOT_NULL(File::create(file, beforeWrite));
- CHECK_IS_NULL(File::create(file, afterWrite));
+ CHECK_IS_NOT_NULL(File::create(file, nullptr, beforeWrite));
+ CHECK_IS_NULL(File::create(file, nullptr, afterWrite));
}
BOOST_AUTO_TEST_CASE(file_visitor_negative_non_existing)
{
- BOOST_REQUIRE_THROW(File::create(TEST_DIR "/non_existing_file"), Csr::Exception);
+ BOOST_REQUIRE_THROW(File::create(TEST_DIR "/non_existing_file", nullptr), Csr::Exception);
}
BOOST_AUTO_TEST_CASE(directory_visitor_positive_existing)
std::string dir(TEST_DIR_VISIT);
// test for existing dir
- auto visitor = FsVisitor::create(dir);
+ auto visitor = FsVisitor::create(dir, true);
CHECK_IS_NOT_NULL(visitor);
int cnt = 0;
__writeFile(file);
- auto visitor = FsVisitor::create(dir, beforeWrite);
+ auto visitor = FsVisitor::create(dir, true, beforeWrite);
CHECK_IS_NOT_NULL(visitor);
int cnt = 0;
ASSERT_IF(cnt, 1);
}
+BOOST_AUTO_TEST_CASE(app_directory_visitor_positive)
+{
+ auto visitor = FsVisitor::create(TEST_DIR_APPS(), true);
+ CHECK_IS_NOT_NULL(visitor);
+
+ while (auto file = visitor->next())
+ BOOST_MESSAGE("visit target name: " << file->getPath());
+}
+
BOOST_AUTO_TEST_SUITE_END()