X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fframework%2Fservice%2Ffile-system.cpp;h=c08f345a8990298402ed7c5f5f89126230492df1;hb=ac6c55df2708be332f5cacc6fc2eba9a7be29a6f;hp=a87ce29163dbd3ce511d0355e98a11ba45e26110;hpb=f2b05fff28ce613a4be37ea984accbcd6a195e00;p=platform%2Fupstream%2Fcsr-framework.git diff --git a/src/framework/service/file-system.cpp b/src/framework/service/file-system.cpp index a87ce29..c08f345 100644 --- a/src/framework/service/file-system.cpp +++ b/src/framework/service/file-system.cpp @@ -100,35 +100,6 @@ int File::getPkgTypes(const std::string &user, 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(Type::Package)) && - (!(type & static_cast(Type::PreLoaded))); - } - - return false; -} - std::string File::getPkgPath(const std::string &path) { std::smatch matched; @@ -161,8 +132,28 @@ std::string File::getPkgPath(const std::string &path) 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 &&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(File::Type::Package); + + if (parentdir->isPreloaded()) + this->m_type |= static_cast(File::Type::PreLoaded); + + return; + } else if (!this->isDir()) { + this->m_type &= ~(static_cast(File::Type::Package) | + static_cast(File::Type::PreLoaded)); + } + } + std::smatch matched; for (const auto ®e : g_regexprs) { @@ -187,42 +178,6 @@ File::File(const std::string &fpath, int type) : m_path(fpath), m_type(type) } } -const std::string &File::getPath() const noexcept -{ - return this->m_path; -} - -bool File::isInApp() const noexcept -{ - return (this->m_type & static_cast(Type::Package)) && - (!(this->m_type & static_cast(Type::PreLoaded))); -} - -bool File::isDir() const noexcept -{ - return this->m_type & static_cast(Type::Directory); -} - -bool File::isModified() const noexcept -{ - return this->m_type & static_cast(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()) { @@ -236,18 +191,18 @@ void File::remove() const } } -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); @@ -267,7 +222,7 @@ FilePtr File::createInternal(const std::string &fpath, time_t modifiedSince, if (isModifiedOnly && !(type & static_cast(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) @@ -275,7 +230,7 @@ FsVisitor::DirPtr FsVisitor::openDir(const std::string &dir) return std::unique_ptr(::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) @@ -284,19 +239,18 @@ FsVisitorPtr FsVisitor::create(const std::string &dirpath, time_t modifiedSince) 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(::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(::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() @@ -306,63 +260,83 @@ 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; }