X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fjobs%2Fwidget_install%2Ftask_file_manipulation.cpp;h=4e257803b9f8b20d59ce2c07c78bf189dad661f7;hb=c7b504b2506c5718e1611c2258b3e345363e0a8c;hp=830679943887034b197a0bec8033b36b8082cd0b;hpb=fd1c15588ac1d18fd5d6117fdb86016cd490e5be;p=framework%2Fweb%2Fwrt-installer.git diff --git a/src/jobs/widget_install/task_file_manipulation.cpp b/src/jobs/widget_install/task_file_manipulation.cpp index 8306799..4e25780 100644 --- a/src/jobs/widget_install/task_file_manipulation.cpp +++ b/src/jobs/widget_install/task_file_manipulation.cpp @@ -19,6 +19,7 @@ * @version 1.0 * @brief Implementation file for installer task database updating */ +#include #include #include #include @@ -29,7 +30,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -46,7 +49,6 @@ using namespace WrtDB; namespace { const char* GLIST_RES_DIR = "res"; -const char* GLIST_BIN_DIR = "bin"; bool _FolderCopy(std::string source, std::string dest) { @@ -55,11 +57,15 @@ bool _FolderCopy(std::string source, std::string dest) return false; } - struct dirent* dEntry = NULL; + struct dirent dEntry; + struct dirent *dEntryResult; + int return_code; + do { struct stat statInfo; - if (dEntry = readdir(dir)) { - std::string fileName = dEntry->d_name; + return_code = readdir_r(dir, &dEntry, &dEntryResult); + if (dEntryResult != NULL && return_code == 0) { + std::string fileName = dEntry.d_name; std::string fullName = source + "/" + fileName; if (stat(fullName.c_str(), &statInfo) != 0) { @@ -68,7 +74,7 @@ bool _FolderCopy(std::string source, std::string dest) } if (S_ISDIR(statInfo.st_mode)) { - if(("." == fileName) || (".." == fileName)) { + if (("." == fileName) || (".." == fileName)) { continue; } std::string destFolder = dest + "/" + fileName; @@ -87,34 +93,75 @@ bool _FolderCopy(std::string source, std::string dest) outfile.close(); infile.close(); } - } while(dEntry); + } while (dEntryResult != NULL && return_code == 0); closedir(dir); return true; } + +void changeOwnerForDirectory(std::string storagePath) { + if (euidaccess(storagePath.c_str(), F_OK) != 0) { + if (!WrtUtilMakeDir(storagePath, PRIVATE_STORAGE_MODE)) { + LogError("Failed to create directory for private storage"); + ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, + "Failed to create directory for private storage"); + } + // '5000' is default uid, gid for applications. + // So installed applications should be launched as process of uid + // '5000'. + // the process can access private directory 'data' of itself. + if (chown(storagePath.c_str(), + WEBAPP_DEFAULT_UID, + WEBAPP_DEFAULT_GID) != 0) + { + ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, + "Chown to invaild user"); + } + } else if (euidaccess(storagePath.c_str(), W_OK | R_OK | X_OK) == 0) { + LogInfo("Private storage already exists."); + // Even if private directory already is created, private dircetory + // should change owner. + if (chown(storagePath.c_str(), + WEBAPP_DEFAULT_UID, + WEBAPP_DEFAULT_GID) != 0) + { + ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, + "Chown to invaild user"); + } + if (chmod(storagePath.c_str(), PRIVATE_STORAGE_MODE) != 0) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, + "chmod to 0700"); + } + } else { + ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, + "No access to private storage."); + } +} } namespace Jobs { namespace WidgetInstall { TaskFileManipulation::TaskFileManipulation(InstallerContext& context) : DPL::TaskDecl(this), - m_context(context) + m_context(context), + m_extHandle(NULL) { if (INSTALL_LOCATION_TYPE_EXTERNAL != - m_context.locationType) { + m_context.locationType) + { AddStep(&TaskFileManipulation::StepCreateDirs); AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir); - AddStep(&TaskFileManipulation::StepCreateShareDir); if (m_context.widgetConfig.packagingType != - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) + WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) { AddStep(&TaskFileManipulation::StepRenamePath); AddAbortStep(&TaskFileManipulation::StepAbortRenamePath); } + AddStep(&TaskFileManipulation::StepLinkForPreload); + } else { AddStep(&TaskFileManipulation::StepPrepareExternalDir); AddStep(&TaskFileManipulation::StepInstallToExternal); AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir); - AddStep(&TaskFileManipulation::StepCreateShareDir); AddAbortStep(&TaskFileManipulation::StepAbortCreateExternalDir); } @@ -139,6 +186,12 @@ void TaskFileManipulation::StepCreateDirs() LogDebug("Create resource directory"); WrtUtilMakeDir(widgetBinPath); WrtUtilMakeDir(widgetSrcPath); + if (m_context.job->getInstallerStruct().m_installMode + == InstallMode::INSTALL_MODE_PRELOAD) + { + std::string userWidgetDir = m_context.locations->getUserDataRootDir(); + WrtUtilMakeDir(userWidgetDir); + } } m_context.job->UpdateProgress( @@ -149,86 +202,9 @@ void TaskFileManipulation::StepCreateDirs() void TaskFileManipulation::StepCreatePrivateStorageDir() { std::string storagePath = m_context.locations->getPrivateStorageDir(); - - if (euidaccess(storagePath.c_str(), F_OK) != 0) { - if(!WrtUtilMakeDir(storagePath, PRIVATE_STORAGE_MODE)){ - LogError("Failed to create directory for private storage"); - ThrowMsg(Exceptions::InternalError, - "Failed to create directory for private storage"); - } - // '5000' is default uid, gid for applications. - // So installed applications should be launched as process of uid '5000'. - // the process can access private directory 'data' of itself. - if(chown(storagePath.c_str(), - WEBAPP_DEFAULT_UID, - WEBAPP_DEFAULT_GID) != 0) - { - ThrowMsg(Exceptions::InternalError, - "Chown to invaild user"); - } - } else if (euidaccess(storagePath.c_str(), W_OK | R_OK | X_OK) == 0) { - LogInfo("Private storage already exists."); - // Even if private directory already is created, private dircetory - // should change owner. - if(chown(storagePath.c_str(), - WEBAPP_DEFAULT_UID, - WEBAPP_DEFAULT_GID) != 0) - { - ThrowMsg(Exceptions::InternalError, - "Chown to invaild user"); - } - if(chmod(storagePath.c_str(), PRIVATE_STORAGE_MODE) != 0) { - ThrowMsg(Exceptions::InternalError, - "chmod to 0700"); - } - - } else { - ThrowMsg(Exceptions::InternalError, - "No access to private storage."); - } -} - -void TaskFileManipulation::StepCreateShareDir() -{ - std::string sharePath = m_context.locations->getShareDir(); - - if (euidaccess(sharePath.c_str(), F_OK) != 0) { - if(!WrtUtilMakeDir(sharePath, SHARE_MODE)){ - LogError("Failed to create directory for share"); - ThrowMsg(Exceptions::InternalError, - "Failed to create directory for share"); - } - // '5000' is default uid, gid for applications. - // So installed applications should be launched as process of uid '5000'. - // the process can access private directory 'data' of itself. - if(chown(sharePath.c_str(), - WEBAPP_DEFAULT_UID, - WEBAPP_DEFAULT_GID) != 0) - { - ThrowMsg(Exceptions::InternalError, - "Chown to invaild user"); - } - } else if (euidaccess(sharePath.c_str(), W_OK | R_OK | X_OK) == 0) { - LogInfo("Share directory already exists."); - // Even if share directory already is created, share dircetory - // should change owner. - if(chown(sharePath.c_str(), - WEBAPP_DEFAULT_UID, - WEBAPP_DEFAULT_GID) != 0) - { - ThrowMsg(Exceptions::InternalError, - "Chown to invaild user"); - } - if(chmod(sharePath.c_str(), SHARE_MODE) != 0) { - ThrowMsg(Exceptions::InternalError, - "chmod to 0700"); - } - - } else { - ThrowMsg(Exceptions::InternalError, - "No access to private storage."); - } - + LogDebug("Create private storage directory : " << + m_context.locations->getPrivateStorageDir()); + changeOwnerForDirectory(storagePath); } void TaskFileManipulation::StepRenamePath() @@ -244,18 +220,85 @@ void TaskFileManipulation::StepRenamePath() LogDebug("Copy file from temp directory to " << instDir); if (!WrtUtilRemove(instDir)) { ThrowMsg(Exceptions::RemovingFolderFailure, - "Error occurs during removing existing folder"); + "Error occurs during removing existing folder"); } - if (!(rename(m_context.locations->getTemporaryPackageDir().c_str(), instDir.c_str()) == 0)) { - ThrowMsg(Exceptions::UnknownError, - "Error occurs during renaming widget folder"); + if (!(rename(m_context.locations->getTemporaryPackageDir().c_str(), + instDir.c_str()) == 0)) + { + ThrowMsg(Exceptions::FileOperationFailed, + "Error occurs during renaming widget folder"); } m_context.job->UpdateProgress( InstallerContext::INSTALL_RENAME_PATH, "Widget Rename path Finished"); } +void TaskFileManipulation::StepLinkForPreload() +{ + if (m_context.job->getInstallerStruct().m_installMode + == InstallMode::INSTALL_MODE_PRELOAD) + { + std::string srcDir = m_context.locations->getUserDataRootDir() + + WrtDB::GlobalConfig::GetWidgetSrcPath(); + + if (0 != access(srcDir.c_str(), F_OK)) { + LogDebug("Make symbolic name for preaload app" << + m_context.locations->getSourceDir() << " to " << srcDir); + std::string resDir = m_context.locations->getUserDataRootDir() + + "/res"; + + WrtUtilMakeDir(resDir); + if (symlink(m_context.locations->getSourceDir().c_str(), srcDir.c_str()) != 0) + { + int error = errno; + if (error) + LogPedantic("Failed to make a symbolic name for a file " + << "[" << DPL::GetErrnoString(error) << "]"); + ThrowMsg(Exceptions::FileOperationFailed, + "Symbolic link creating is not done."); + } + } + + /* link for data directory */ + std::string storagePath = m_context.locations->getPrivateStorageDir(); + std::string dataDir = m_context.locations->getPackageInstallationDir() + + "/" + WrtDB::GlobalConfig::GetWidgetPrivateStoragePath(); + if (0 != access(dataDir.c_str(), F_OK)) { + LogDebug("Make symbolic name for preaload app " << + storagePath << " to " << dataDir); + + if (symlink(storagePath.c_str(), dataDir.c_str()) != 0) + { + int error = errno; + if (error) + LogPedantic("Failed to make a symbolic name for a file " + << "[" << DPL::GetErrnoString(error) << "]"); + ThrowMsg(Exceptions::FileOperationFailed, + "Symbolic link creating is not done."); + } + changeOwnerForDirectory(dataDir); + } + + if (m_context.widgetConfig.packagingType != PKG_TYPE_HYBRID_WEB_APP) { + std::string widgetBinPath = m_context.locations->getBinaryDir(); + std::string userBinPath = m_context.locations->getUserBinaryDir(); + LogDebug("Make symbolic link for preload app " << widgetBinPath << + " to " << userBinPath); + if (symlink(widgetBinPath.c_str(), userBinPath.c_str()) != 0) + { + int error = errno; + if (error) + LogPedantic("Failed to make a symbolic name for a file " + << "[" << DPL::GetErrnoString(error) << "]"); + ThrowMsg(Exceptions::FileOperationFailed, + "Symbolic link creating is not done."); + } + + } + } +} + void TaskFileManipulation::StepAbortRenamePath() { LogDebug("[Rename Widget Path] Aborting.... (Rename path)"); @@ -264,8 +307,14 @@ void TaskFileManipulation::StepAbortRenamePath() widgetPath = m_context.locations->getPackageInstallationDir(); if (!WrtUtilRemove(widgetPath)) { ThrowMsg(Exceptions::RemovingFolderFailure, - "Error occurs during removing existing folder"); + "Error occurs during removing existing folder"); + } + // Remove user data directory if preload web app. + std::string userData = m_context.locations->getUserDataRootDir(); + if (0 == access(userData.c_str(), F_OK)) { + WrtUtilRemove(userData); } + } LogDebug("Rename widget path sucessful!"); } @@ -274,10 +323,10 @@ void TaskFileManipulation::StepPrepareExternalDir() { LogDebug("Step prepare to install in exernal directory"); Try { - std::string pkgname = - DPL::ToUTF8String(*m_context.widgetConfig.pkgname); + std::string pkgid = + DPL::ToUTF8String(m_context.widgetConfig.tzPkgid); - WidgetInstallToExtSingleton::Instance().initialize(pkgname); + WidgetInstallToExtSingleton::Instance().initialize(pkgid); size_t totalSize = Utils::getFolderSize(m_context.locations->getTemporaryPackageDir()); @@ -287,32 +336,35 @@ void TaskFileManipulation::StepPrepareExternalDir() GList *list = NULL; app2ext_dir_details* dirDetail = NULL; - std::string dirNames[2] = {GLIST_RES_DIR, GLIST_BIN_DIR}; - - for (int i = 0; i < 2; i++) { - dirDetail = (app2ext_dir_details*) calloc(1, - sizeof(app2ext_dir_details)); - if (NULL == dirDetail) { - ThrowMsg(Exceptions::ErrorExternalInstallingFailure, "error in app2ext"); - } - dirDetail->name = strdup(dirNames[i].c_str()); - dirDetail->type = APP2EXT_DIR_RO; - list = g_list_append(list, dirDetail); + dirDetail = (app2ext_dir_details*) calloc(1, + sizeof( + app2ext_dir_details)); + if (NULL == dirDetail) { + ThrowMsg(Exceptions::ErrorExternalInstallingFailure, + "error in app2ext"); } + dirDetail->name = strdup(GLIST_RES_DIR); + dirDetail->type = APP2EXT_DIR_RO; + list = g_list_append(list, dirDetail); - if (false == m_context.existingWidgetInfo.isExist) { - WidgetInstallToExtSingleton::Instance().preInstallation(list, - folderSize); - } else { + if (m_context.isUpdateMode) { WidgetInstallToExtSingleton::Instance().preUpgrade(list, - folderSize); + folderSize); + } else { + WidgetInstallToExtSingleton::Instance().preInstallation(list, + folderSize); } free(dirDetail); g_list_free(list); + + /* make bin directory */ + std::string widgetBinPath = m_context.locations->getBinaryDir(); + WrtUtilMakeDir(widgetBinPath); } - Catch (WidgetInstallToExt::Exception::ErrorInstallToExt) + Catch(WidgetInstallToExt::Exception::ErrorInstallToExt) { - ReThrowMsg(Exceptions::ErrorExternalInstallingFailure, "Error during \ + ReThrowMsg(Exceptions::ErrorExternalInstallingFailure, + "Error during \ create external folder "); } } @@ -321,27 +373,28 @@ void TaskFileManipulation::StepInstallToExternal() { LogDebug("StepInstallExternal"); if (!WrtUtilMakeDir(m_context.locations->getSourceDir())) { - ThrowMsg(Exceptions::ErrorExternalInstallingFailure, "To make src \ + ThrowMsg(Exceptions::ErrorExternalInstallingFailure, + "To make src \ directory failed"); } LogDebug("Resource move to external storage " << - m_context.locations->getSourceDir()); + m_context.locations->getSourceDir()); if (!_FolderCopy(m_context.locations->getTemporaryPackageDir(), - m_context.locations->getSourceDir())) + m_context.locations->getSourceDir())) { - ThrowMsg(Exceptions::UnknownError, - "Error occurs during renaming widget folder"); + ThrowMsg(Exceptions::ErrorExternalInstallingFailure, + "Error occurs during renaming widget folder"); } } void TaskFileManipulation::StepAbortCreateExternalDir() { LogError("Abort StepAbortCreateExternalDir"); - if (false == m_context.existingWidgetInfo.isExist) { - WidgetInstallToExtSingleton::Instance().postInstallation(false); - } else { + if (m_context.isUpdateMode) { WidgetInstallToExtSingleton::Instance().postUpgrade(false); + } else { + WidgetInstallToExtSingleton::Instance().postInstallation(false); } WidgetInstallToExtSingleton::Instance().deinitialize(); }