From: Janusz Majnert Date: Wed, 24 Oct 2012 10:56:11 +0000 (+0200) Subject: Fixes for recursive opendir X-Git-Tag: accepted/tizen_2.1/20130425.023916~20^2~48 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1636fbd95f8a6aa0c3eb2885829a553311f7485b;p=framework%2Fweb%2Fwrt-installer.git Fixes for recursive opendir [Issue#] N/A [Feature] Replacing recursive opendir with safe fts_ functions [Cause] Recursive opendir may reach limit of open dirs for process [Solution] Replace with standard fts_* functions for traversing directories [Verification] Install an encrypted widget and verify that encryption works Major rewrite to resource encryption functions was done - verify by installing an encrypted widget and checking that eligible resources are really encrypted. Minor fixes added, mainly to close directories that are no longer used. Change-Id: I51e36f225d49cd46b5454c0cf7cbda09d9e7c1c1 --- diff --git a/src/jobs/widget_install/task_encrypt_resource.cpp b/src/jobs/widget_install/task_encrypt_resource.cpp index 77172eb..dcec387 100644 --- a/src/jobs/widget_install/task_encrypt_resource.cpp +++ b/src/jobs/widget_install/task_encrypt_resource.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -50,7 +50,7 @@ std::set& getSupportedForEncryption() return encryptSet; } -bool isSupportedForEncryption(std::string file) +bool isSupportedForEncryption(const std::string &file) { size_t foundKey = file.rfind("."); if (std::string::npos != foundKey) { @@ -82,39 +82,54 @@ void TaskEncryptResource::StepEncryptResource() void TaskEncryptResource::EncryptDirectory(std::string path) { - DIR* pkgDir = opendir(path.c_str()); - if (!pkgDir) { - LogDebug("Package directory doesn't exist"); - ThrowMsg(Exceptions::InternalError, "Error occurs during read \ - directory"); + FTS *fts; + FTSENT *ftsent; + char * const paths[] = {const_cast(path.c_str()), NULL}; + + if ((fts = fts_open(paths, FTS_PHYSICAL|FTS_NOCHDIR, NULL)) == NULL) { + //ERROR + int error = errno; + LogWarning(__PRETTY_FUNCTION__ << ": fts_open failed with error: " + << strerror(error)); + ThrowMsg(Exceptions::InternalError, "Error reading directory: " + << path); } - struct dirent* dirent; - struct stat statInfo; - do { - if ((dirent = readdir(pkgDir))) { - std::string dirName = dirent->d_name; - std::string absFileName = path + "/" + dirName; - if (stat(absFileName.c_str(), &statInfo) != 0) { - ThrowMsg(Exceptions::InternalError, "Error occurs read file"); - } - - if (S_ISDIR(statInfo.st_mode)) { - if(strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, - "..") == 0) { - continue; - } - EncryptDirectory(absFileName); - } else { - if (isSupportedForEncryption(absFileName)) { - EncryptFile(absFileName); + while ((ftsent = fts_read(fts)) != NULL) { + switch (ftsent->fts_info) { + case FTS_DP: + case FTS_DC: + case FTS_D: + case FTS_DEFAULT: + case FTS_SLNONE: + //directories, non-regular files, dangling symbolic links + break; + case FTS_F: + case FTS_NSOK: + case FTS_SL: + //regular files and other objects that can be counted + if (isSupportedForEncryption(ftsent->fts_path)) { + EncryptFile(ftsent->fts_path); } - } + break; + case FTS_NS: + case FTS_DOT: + case FTS_DNR: + case FTS_ERR: + default: + LogWarning(__PRETTY_FUNCTION__ + << ": traversal failed on file: " + << ftsent->fts_path + << " with error: " + << strerror(ftsent->fts_errno)); + ThrowMsg(Exceptions::InternalError, "Error reading file"); } } - while(dirent); - if (closedir(pkgDir)) { - LogError("Fail to close directory : " << path); + + if (fts_close(fts) == -1) { + int error = errno; + LogWarning(__PRETTY_FUNCTION__ << ": fts_close failed with error: " + << strerror(error)); } } diff --git a/src/jobs/widget_install/task_manifest_file.cpp b/src/jobs/widget_install/task_manifest_file.cpp index edd18f1..7951e2e 100644 --- a/src/jobs/widget_install/task_manifest_file.cpp +++ b/src/jobs/widget_install/task_manifest_file.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -450,6 +451,10 @@ void TaskManifestFile::getFileList(const char* path, list.push_back(file_name); } }while(d_ent); + if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) { + LogError("Failed to close dir: " << path << " with error: " + << DPL::GetErrnoString()); + } } void TaskManifestFile::stepGenerateManifest() diff --git a/src/jobs/widget_install/task_plugins_copy.cpp b/src/jobs/widget_install/task_plugins_copy.cpp index 7860797..a0fbecc 100644 --- a/src/jobs/widget_install/task_plugins_copy.cpp +++ b/src/jobs/widget_install/task_plugins_copy.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -95,15 +96,21 @@ void TaskPluginsCopy::StepFindPlugins() while ((entry = readdir(dir)) != NULL){ tempname = m_npsource + "/" + entry->d_name; if(lstat(tempname.c_str(), &st) != 0) { - LogDebug("Failed to call \"lstat\" (errno:" <d_name, "..", 2)!=0 && strncmp(entry->d_name, ".", 1)!=0) { - LogError("Directory detected instead of plugin file: " << entry->d_name); + if(strncmp(entry->d_name, "..", 2)!=0 + && strncmp(entry->d_name, ".", 1)!=0) { + LogError("Directory detected instead of plugin file: " + << entry->d_name); /* Subdirectories inside plugins/ARCH are not supported */ - closedir(dir); + if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) { + LogError("Failed to close dir: " << m_npsource + << " with error: " << DPL::GetErrnoString()); + } ThrowMsg(Exceptions::PluginsSubdirectory, "Subdirectories inside plugins directory are not supported"); } @@ -124,7 +131,10 @@ void TaskPluginsCopy::StepFindPlugins() LogWarning("Non-plugin file found: " < #include -#include #include +#include using namespace WrtDB; @@ -125,6 +125,11 @@ void TaskUpdateFiles::ReadDirList(std::string dirPath, ExistFileList &list, } } while(dirent); + //closing the directory + if (-1 == TEMP_FAILURE_RETRY(closedir(pkgDir))) { + LogError("Failed to close dir: " << dirPath << " with error: " + << DPL::GetErrnoString()); + } } void TaskUpdateFiles::StepResourceFilesBackup() diff --git a/src/jobs/widget_install/task_widget_config.cpp b/src/jobs/widget_install/task_widget_config.cpp old mode 100755 new mode 100644 index f7c9c9f..dc0d3f9 --- a/src/jobs/widget_install/task_widget_config.cpp +++ b/src/jobs/widget_install/task_widget_config.cpp @@ -164,8 +164,9 @@ void TaskWidgetConfig::ReadLocaleFolders() LogError("readdir() failed with " << DPL::GetErrnoString()); } - if (closedir(localeDir)) { - LogError("closedir() failed with " << DPL::GetErrnoString()); + if (-1 == TEMP_FAILURE_RETRY(closedir(localeDir))) { + LogError("Failed to close dir: " << localePath << " with error: " + << DPL::GetErrnoString()); } } @@ -715,7 +716,10 @@ bool TaskWidgetConfig::parseConfigurationFileWidget(WrtDB::ConfigParserData& con LogDebug("Invalid widget configuration file!"); // _rethrown_exception.Dump(); *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE; - closedir(dir); + if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) { + LogError("Failed to close dir: " << _currentPath << " with error: " + << DPL::GetErrnoString()); + } return false; } @@ -724,7 +728,10 @@ bool TaskWidgetConfig::parseConfigurationFileWidget(WrtDB::ConfigParserData& con } } } - closedir(dir); + if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) { + LogError("Failed to close dir: " << _currentPath << " with error: " + << DPL::GetErrnoString()); + } //We must have config.xml so leaveing if we doesn't if (!has_config_xml) { diff --git a/src/wrt-installer/wrt_installer.cpp b/src/wrt-installer/wrt_installer.cpp index b02a2dc..11dcb57 100644 --- a/src/wrt-installer/wrt_installer.cpp +++ b/src/wrt-installer/wrt_installer.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include "option_parser.h" #include @@ -416,7 +417,8 @@ void WrtInstaller::installPluginsStep() ::PostEvent(WRTInstallerNS::InstallPluginEvent()); if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) { - LogError("Failed to close dir: " << dir); + LogError("Failed to close dir: " << PLUGIN_PATH << " with error: " + << DPL::GetErrnoString()); } } diff --git a/src/wrt-installer/wrt_installer_api.cpp b/src/wrt-installer/wrt_installer_api.cpp index 9921fdf..2a3d48c 100755 --- a/src/wrt-installer/wrt_installer_api.cpp +++ b/src/wrt-installer/wrt_installer_api.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -486,7 +487,8 @@ extern "C" } if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) { - LogError("Failed to close dir: " << dir); + LogError("Failed to close dir: " << PLUGIN_PATH << " with error: " + << DPL::GetErrnoString()); } if (0 != unlink(installRequest.c_str())) {