Fixed can not install to sdcard
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_file_manipulation.cpp
index a41239e..f044af9 100644 (file)
@@ -19,6 +19,7 @@
  * @version 1.0
  * @brief   Implementation file for installer task database updating
  */
+#include <unistd.h>
 #include <sys/stat.h>
 #include <dirent.h>
 #include <widget_install/task_file_manipulation.h>
@@ -46,7 +47,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,25 +55,31 @@ 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) {
+                closedir(dir);
                 return false;
             }
 
             if (S_ISDIR(statInfo.st_mode)) {
-                if(("." == fileName) || (".." == fileName)) {
+                if (("." == fileName) || (".." == fileName)) {
                     continue;
                 }
                 std::string destFolder = dest + "/" + fileName;
                 WrtUtilMakeDir(destFolder);
 
                 if (!_FolderCopy(fullName, destFolder)) {
+                    closedir(dir);
                     return false;
                 }
             }
@@ -85,7 +91,7 @@ bool _FolderCopy(std::string source, std::string dest)
             outfile.close();
             infile.close();
         }
-    } while(dEntry);
+    } while (dEntryResult != NULL && return_code == 0);
     closedir(dir);
     return true;
 }
@@ -95,15 +101,16 @@ namespace Jobs {
 namespace WidgetInstall {
 TaskFileManipulation::TaskFileManipulation(InstallerContext& context) :
     DPL::TaskDecl<TaskFileManipulation>(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);
@@ -112,7 +119,6 @@ TaskFileManipulation::TaskFileManipulation(InstallerContext& context) :
         AddStep(&TaskFileManipulation::StepPrepareExternalDir);
         AddStep(&TaskFileManipulation::StepInstallToExternal);
         AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir);
-        AddStep(&TaskFileManipulation::StepCreateShareDir);
 
         AddAbortStep(&TaskFileManipulation::StepAbortCreateExternalDir);
     }
@@ -121,10 +127,6 @@ TaskFileManipulation::TaskFileManipulation(InstallerContext& context) :
 void TaskFileManipulation::StepCreateDirs()
 {
     std::string widgetPath;
-    DPL::OptionalString pkgname = m_context.widgetConfig.pkgname;
-    if (pkgname.IsNull()) {
-        ThrowMsg(Exceptions::InternalError, "No Package name exists.");
-    }
 
     widgetPath = m_context.locations->getPackageInstallationDir();
 
@@ -153,93 +155,46 @@ void TaskFileManipulation::StepCreatePrivateStorageDir()
     std::string storagePath = m_context.locations->getPrivateStorageDir();
 
     if (euidaccess(storagePath.c_str(), F_OK) != 0) {
-        if(!WrtUtilMakeDir(storagePath, PRIVATE_STORAGE_MODE)){
+        if (!WrtUtilMakeDir(storagePath, PRIVATE_STORAGE_MODE)) {
             LogError("Failed to create directory for private storage");
-            ThrowMsg(Exceptions::InternalError,
-                    "Failed to create directory for private storage");
+            ThrowMsg(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'.
+        // 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)
+        if (chown(storagePath.c_str(),
+                  WEBAPP_DEFAULT_UID,
+                  WEBAPP_DEFAULT_GID) != 0)
         {
-            ThrowMsg(Exceptions::InternalError,
-                 "Chown to invaild user");
+            ThrowMsg(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(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)
+        if (chown(storagePath.c_str(),
+                  WEBAPP_DEFAULT_UID,
+                  WEBAPP_DEFAULT_GID) != 0)
         {
-            ThrowMsg(Exceptions::InternalError,
-                 "Chown to invaild user");
+            ThrowMsg(Exceptions::FileOperationFailed,
+                     "Chown to invaild user");
         }
-        if(chmod(sharePath.c_str(), SHARE_MODE) != 0) {
-            ThrowMsg(Exceptions::InternalError,
-                 "chmod to 0700");
+        if (chmod(storagePath.c_str(), PRIVATE_STORAGE_MODE) != 0) {
+            ThrowMsg(Exceptions::FileOperationFailed,
+                     "chmod to 0700");
         }
-
     } else {
-        ThrowMsg(Exceptions::InternalError,
+        ThrowMsg(Exceptions::FileOperationFailed,
                  "No access to private storage.");
     }
-
 }
 
 void TaskFileManipulation::StepRenamePath()
 {
     std::string instDir;
-    DPL::OptionalString pkgname = m_context.widgetConfig.pkgname;
-    if (pkgname.IsNull()) {
-        ThrowMsg(Exceptions::InternalError, "No Package name exists.");
-    }
 
     if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) {
         instDir = m_context.locations->getPackageInstallationDir();
@@ -250,12 +205,14 @@ 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,
@@ -270,7 +227,7 @@ 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");
         }
     }
     LogDebug("Rename widget path sucessful!");
@@ -280,10 +237,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());
@@ -293,32 +250,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 ");
     }
 }
@@ -327,27 +287,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();
 }