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;
}