From: Soyoung Kim Date: Fri, 3 May 2013 08:57:59 +0000 (+0900) Subject: Fixed update web app X-Git-Tag: submit/tizen_2.2/20130716.180435~1^2~164 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=db02e4a7d79b7667fc294dc78c412ae866978bd8;p=framework%2Fweb%2Fwrt-installer.git Fixed update web app [Issue#] N/A [Problem] N/A [Cause] N/A [Solution] fixed update web app [SCMRequest] this patch need wrt-commons package. Change-Id: I3c4c52a3566b737124ae06c214b096d24b94ce16 --- diff --git a/packaging/wrt-installer.spec b/packaging/wrt-installer.spec index 3ad8546..e45c3c0 100644 --- a/packaging/wrt-installer.spec +++ b/packaging/wrt-installer.spec @@ -28,6 +28,7 @@ BuildRequires: pkgconfig(libpcrecpp) BuildRequires: pkgconfig(pkgmgr-installer) BuildRequires: pkgconfig(pkgmgr-parser) BuildRequires: pkgconfig(pkgmgr-types) +BuildRequires: pkgconfig(pkgmgr-info) BuildRequires: pkgconfig(pkgmgr) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(cert-svc) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5e33b52..03997c0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -81,6 +81,7 @@ SET(INSTALLER_SOURCES ${INSTALLER_JOBS}/widget_install/task_prepare_reinstall.cpp ${INSTALLER_JOBS}/widget_install/wac_security.cpp ${INSTALLER_JOBS}/widget_install/widget_update_info.cpp + ${INSTALLER_JOBS}/widget_install/directory_api.cpp ${INSTALLER_JOBS}/widget_uninstall/job_widget_uninstall.cpp ${INSTALLER_JOBS}/widget_uninstall/task_check.cpp ${INSTALLER_JOBS}/widget_uninstall/task_remove_files.cpp @@ -122,6 +123,7 @@ PKG_CHECK_MODULES(INSTALLER_STATIC_DEP wrt-plugins-types pkgmgr-installer pkgmgr-parser + pkgmgr-info web-provider osp-appfw REQUIRED diff --git a/src/jobs/widget_install/ace_registration.cpp b/src/jobs/widget_install/ace_registration.cpp index e2077ef..ac266d1 100644 --- a/src/jobs/widget_install/ace_registration.cpp +++ b/src/jobs/widget_install/ace_registration.cpp @@ -137,4 +137,102 @@ bool registerAceWidget(const WrtDB::DbWidgetHandle& widgetHandle, delete[] certData; return retval == ACE_OK; } +bool registerAceWidgetFromDB(const WrtDB::DbWidgetHandle& widgetHandle) +{ + using namespace WrtDB; + LogDebug("Updating Ace database from Widget DB"); + struct widget_info wi; + DPL::OptionalString os; + WrtDB::WidgetCertificateDataList certList; + + Try { + WidgetDAOReadOnly dao(widgetHandle); + + WidgetType type = dao.getWidgetType(); + if (type == WrtDB::APP_TYPE_WAC20) { + wi.type = WAC20; + } else if (type == WrtDB::APP_TYPE_TIZENWEBAPP) { + wi.type = Tizen; + } else { + LogError("Unknown application type"); + return false; + } + + wi.id = toAceString(dao.getGUID()); + wi.version = toAceString(dao.getVersion()); + wi.author = toAceString(dao.getAuthorName()); + wi.shareHerf = strdup(dao.getShareHref().c_str()); + LogDebug("Basic data converted. Certificates begin."); + certList = dao.getCertificateDataList(); + } + Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) { + LogError("Widget does not exist"); + return false; + } + + //one more element for NULL termination + LogDebug("Found: " << certList.size() << " certificates"); + ace_certificate_data** certData = new ace_certificate_data * + [certList.size() + 1]; + certData[certList.size()] = NULL; // last element set to NULL + + int i = 0; + FOREACH(it, certList) + { + certData[i] = new ace_certificate_data; + switch (it->owner) { + case WrtDB::WidgetCertificateData::AUTHOR: + certData[i]->owner = AUTHOR; + break; + case WrtDB::WidgetCertificateData::DISTRIBUTOR: + certData[i]->owner = DISTRIBUTOR; + break; + default: + LogDebug("Unknown owner type of cert"); + certData[i]->owner = UNKNOWN; + break; + } + switch (it->type) { + case WrtDB::WidgetCertificateData::ENDENTITY: + certData[i]->type = ENDENTITY; + break; + case WrtDB::WidgetCertificateData::ROOT: + certData[i]->type = ROOT; + break; + default: + LogError("Unknown type of cert"); + certData[i]->type = ENDENTITY; + break; + } + certData[i]->chain_id = it->chainId; + + certData[i]->md5_fp = toAceString(it->strMD5Fingerprint); + certData[i]->sha1_fp = toAceString(it->strSHA1Fingerprint); + certData[i]->common_name = + toAceString(DPL::ToUTF8String(it->strCommonName)); + ++i; + } + + LogDebug("Registerign widget in ace"); + ace_return_t retval = ace_register_widget( + static_cast(widgetHandle), &wi, certData); + + //clean up - WidgetInfo + free(wi.author); + free(wi.id); + free(wi.shareHerf); + free(wi.version); + + //free cert list + i = 0; + while (certData[i] != NULL) { + free(certData[i]->common_name); + free(certData[i]->md5_fp); + free(certData[i]->sha1_fp); + delete certData[i]; + ++i; + } + delete[] certData; + return retval == ACE_OK; +} } diff --git a/src/jobs/widget_install/ace_registration.h b/src/jobs/widget_install/ace_registration.h index a9e0577..f98c3ce 100644 --- a/src/jobs/widget_install/ace_registration.h +++ b/src/jobs/widget_install/ace_registration.h @@ -28,6 +28,7 @@ namespace AceApi { bool registerAceWidget(const WrtDB::DbWidgetHandle& widgetHandle, const WrtDB::WidgetRegisterInfo& widgetConfig, const WrtDB::WidgetCertificateDataList& certList); +bool registerAceWidgetFromDB(const WrtDB::DbWidgetHandle& widgetHandle); } #endif /* WRT_SRC_INSTALLER_CORE_ACE_REGISTRATION_H_ */ diff --git a/src/jobs/widget_install/directory_api.cpp b/src/jobs/widget_install/directory_api.cpp new file mode 100644 index 0000000..678ec1d --- /dev/null +++ b/src/jobs/widget_install/directory_api.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file directory_api.cpp + * @author Soyoung Kim(sy037.kim@samsung.com) + * @version 1.0 + * @brief directory api - implementation file + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace DirectoryApi { +bool DirectoryCopy(std::string source, std::string dest) +{ + DIR* dir = opendir(source.c_str()); + if (NULL == dir) { + return false; + } + + struct dirent dEntry; + struct dirent *dEntryResult; + int return_code; + + do { + struct stat statInfo; + 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)) { + continue; + } + std::string destFolder = dest + "/" + fileName; + WrtUtilMakeDir(destFolder); + + if (!DirectoryCopy(fullName, destFolder)) { + closedir(dir); + return false; + } + } + + std::string destFile = dest + "/" + fileName; + std::ifstream infile(fullName); + std::ofstream outfile(destFile); + outfile << infile.rdbuf(); + outfile.close(); + infile.close(); + } + } while (dEntryResult != NULL && return_code == 0); + closedir(dir); + return true; +} +} diff --git a/src/jobs/widget_install/directory_api.h b/src/jobs/widget_install/directory_api.h new file mode 100644 index 0000000..1632528 --- /dev/null +++ b/src/jobs/widget_install/directory_api.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file directory_api.h + * @author Soyoung Kim(sy037.kim@samsung.com) + * @version 1.0 + * @brief directory api - header file + */ +#ifndef WRT_SRC_INSTALLER_CORE_DIRECTORY_API_H_ +#define WRT_SRC_INSTALLER_CORE_DIRECTORY_API_H_ + +#include + +namespace DirectoryApi { +bool DirectoryCopy(std::string source, std::string dest); +} + +#endif /* WRT_SRC_INSTALLER_CORE_DIRECTORY_API_H_ */ + diff --git a/src/jobs/widget_install/job_widget_install.cpp b/src/jobs/widget_install/job_widget_install.cpp index 57475e9..cc011ed 100644 --- a/src/jobs/widget_install/job_widget_install.cpp +++ b/src/jobs/widget_install/job_widget_install.cpp @@ -241,6 +241,7 @@ JobWidgetInstall::JobWidgetInstall( WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) { AddTask(new TaskUpdateFiles(m_installerContext)); + AddTask(new TaskFileManipulation(m_installerContext)); } AddTask(new TaskManifestFile(m_installerContext)); @@ -249,17 +250,14 @@ JobWidgetInstall::JobWidgetInstall( { AddTask(new TaskInstallOspsvc(m_installerContext)); } - if (m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) - { - AddTask(new TaskRemoveBackupFiles(m_installerContext)); - } + AddTask(new TaskCertificates(m_installerContext)); AddTask(new TaskDatabase(m_installerContext)); AddTask(new TaskAceCheck(m_installerContext)); //TODO: remove widgetHandle from this task and move before database task // by now widget handle is needed in ace check // Any error in acecheck while update will break widget AddTask(new TaskSmack(m_installerContext)); + AddTask(new TaskRemoveBackupFiles(m_installerContext)); } else if (result == ConfigureResult::Deferred) { // Installation is deferred LogInfo("Configure installation deferred"); diff --git a/src/jobs/widget_install/task_database.cpp b/src/jobs/widget_install/task_database.cpp index 0258359..bfa6271 100644 --- a/src/jobs/widget_install/task_database.cpp +++ b/src/jobs/widget_install/task_database.cpp @@ -65,6 +65,7 @@ TaskDatabase::TaskDatabase(InstallerContext& context) : AddStep(&TaskDatabase::StepLiveboxDBInsert); AddAbortStep(&TaskDatabase::StepAbortDBInsert); + AddAbortStep(&TaskDatabase::StepAbortAceDBInsert); } void TaskDatabase::StepWrtDBInsert() @@ -80,6 +81,11 @@ void TaskDatabase::StepWrtDBInsert() { m_handleToRemove = WidgetDAOReadOnly::getHandle( m_context.widgetConfig.tzAppid); + + std::string makeAppid = + DPL::ToUTF8String(m_context.widgetConfig.tzAppid) + "." + + "backup"; + m_backAppId = DPL::FromUTF8String(makeAppid); } Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) { @@ -88,7 +94,9 @@ void TaskDatabase::StepWrtDBInsert() ThrowMsg(Exceptions::DatabaseFailure, "Given tizenId not found for update installation"); } - WidgetDAO::registerOrUpdateWidget( + + WidgetDAO::backupAndUpdateWidget( + m_backAppId, m_context.widgetConfig.tzAppid, m_context.widgetConfig, m_context.wacSecurity); @@ -280,13 +288,19 @@ void TaskDatabase::StepAbortDBInsert() LogWarning("[DB Update Task] Aborting... (DB Clean)"); Try { - WidgetDAO::unregisterWidget(m_context.widgetConfig.tzAppid); + WidgetDAO::restoreUpdateWidget(m_backAppId, + m_context.widgetConfig.tzAppid); LogDebug("Cleaning DB successful!"); } Catch(DPL::DB::SqlConnection::Exception::Base) { LogError("Failed to handle StepAbortDBClean!"); } +} + +void TaskDatabase::StepAbortAceDBInsert() +{ + LogWarning("[DB Update Task] ACE DB Aborting... (DB Clean)"); ace_unregister_widget(static_cast(m_handle)); // Remove also old one. If it was already updated nothing wrong will happen, @@ -294,6 +308,12 @@ void TaskDatabase::StepAbortDBInsert() if (INVALID_WIDGET_HANDLE != m_handleToRemove) { ace_unregister_widget(static_cast(m_handle)); } + + if (!AceApi::registerAceWidgetFromDB(m_handleToRemove)) + { + LogError("ace database restore failed"); + } + LogDebug("Ace data inserted"); } void TaskDatabase::StepLiveboxDBInsert() diff --git a/src/jobs/widget_install/task_database.h b/src/jobs/widget_install/task_database.h index 3e0beba..88d99e9 100644 --- a/src/jobs/widget_install/task_database.h +++ b/src/jobs/widget_install/task_database.h @@ -43,6 +43,7 @@ class TaskDatabase : //of widget handle WrtDB::DbWidgetHandle m_handleToRemove; WrtDB::DbWidgetHandle m_handle; + WrtDB::TizenAppId m_backAppId; void StepRegisterExternalFiles(); void StepWrtDBInsert(); @@ -53,6 +54,7 @@ class TaskDatabase : void StepLiveboxDBInsert(); void StepAbortDBInsert(); + void StepAbortAceDBInsert(); public: TaskDatabase(InstallerContext& context); diff --git a/src/jobs/widget_install/task_file_manipulation.cpp b/src/jobs/widget_install/task_file_manipulation.cpp index 2203828..e32607b 100644 --- a/src/jobs/widget_install/task_file_manipulation.cpp +++ b/src/jobs/widget_install/task_file_manipulation.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -149,13 +150,13 @@ TaskFileManipulation::TaskFileManipulation(InstallerContext& context) : m_context.locationType) { AddStep(&TaskFileManipulation::StepCreateDirs); - AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir); if (m_context.widgetConfig.packagingType != WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) { AddStep(&TaskFileManipulation::StepRenamePath); AddAbortStep(&TaskFileManipulation::StepAbortRenamePath); } + AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir); AddStep(&TaskFileManipulation::StepLinkForPreload); } else { @@ -202,6 +203,17 @@ void TaskFileManipulation::StepCreatePrivateStorageDir() std::string storagePath = m_context.locations->getPrivateStorageDir(); LogDebug("Create private storage directory : " << m_context.locations->getPrivateStorageDir()); + + if (m_context.isUpdateMode) { //update + std::string backData = m_context.locations->getBackupPrivateDir(); + LogDebug("copy private storage " << backData << " to " << storagePath); + WrtUtilMakeDir(storagePath); + if (!DirectoryApi::DirectoryCopy(backData, storagePath)) { + LogError("Failed to rename " << backData << " to " << storagePath); + ThrowMsg(Exceptions::BackupFailed, + "Error occurs copy private strage files"); + } + } changeOwnerForDirectory(storagePath); } diff --git a/src/jobs/widget_install/task_install_ospsvc.cpp b/src/jobs/widget_install/task_install_ospsvc.cpp index 7909c26..30c8101 100644 --- a/src/jobs/widget_install/task_install_ospsvc.cpp +++ b/src/jobs/widget_install/task_install_ospsvc.cpp @@ -24,6 +24,9 @@ #include #include +#include +#include +#include #include #include #include @@ -48,6 +51,7 @@ TaskInstallOspsvc::TaskInstallOspsvc(InstallerContext& context) : m_context(context) { AddStep(&TaskInstallOspsvc::StepInstallOspService); + AddStep(&TaskInstallOspsvc::StepUpdateManifestFile); } void TaskInstallOspsvc::StepInstallOspService() @@ -93,5 +97,39 @@ void TaskInstallOspsvc::StepInstallOspService() InstallerContext::INSTALL_INSTALL_OSPSVC, "Installed Osp servcie"); } + +void TaskInstallOspsvc::StepUpdateManifestFile() +{ + std::string pkgid = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid); + pkgmgrinfo_pkginfo_h handle; + + int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid.c_str(), &handle); + if (ret != PMINFO_R_OK) { + LogDebug("StepUpdateManifestFile"); + std::ostringstream manifest_file; + if (m_context.mode.rootPath == InstallMode::RootPath::RO) { + manifest_file << "/usr/share/packages/"; //TODO constant with path + } else { + manifest_file << "/opt/share/packages/"; //TODO constant with path + } + manifest_file << pkgid; + manifest_file << ".xml"; + LogDebug("manifest file : " << manifest_file.str()); + + int ret = pkgmgr_parser_parse_manifest_for_uninstallation( + manifest_file.str().c_str(), NULL); + + if (ret != 0) { + LogError("Manifest parser error: " << ret); + } + + int code = pkgmgr_parser_parse_manifest_for_installation( + manifest_file.str().c_str(), NULL); + + if (code != 0) { + LogError("Manifest parser error: " << code); + } + } +} } //namespace WidgetInstall } //namespace Jobs diff --git a/src/jobs/widget_install/task_install_ospsvc.h b/src/jobs/widget_install/task_install_ospsvc.h index 445bfb4..819a1b0 100644 --- a/src/jobs/widget_install/task_install_ospsvc.h +++ b/src/jobs/widget_install/task_install_ospsvc.h @@ -36,6 +36,7 @@ class TaskInstallOspsvc : public DPL::TaskDecl InstallerContext &m_context; void StepInstallOspService(); + void StepUpdateManifestFile(); void StepAbortInstall(); diff --git a/src/jobs/widget_install/task_manifest_file.cpp b/src/jobs/widget_install/task_manifest_file.cpp index 44985ce..7c3e165 100644 --- a/src/jobs/widget_install/task_manifest_file.cpp +++ b/src/jobs/widget_install/task_manifest_file.cpp @@ -111,6 +111,7 @@ TaskManifestFile::TaskManifestFile(InstallerContext &inCont) : // for widget update. AddStep(&TaskManifestFile::stepBackupIconFiles); AddStep(&TaskManifestFile::stepCopyIconFiles); + AddStep(&TaskManifestFile::stepCreateExecFile); AddStep(&TaskManifestFile::stepGenerateManifest); AddStep(&TaskManifestFile::stepParseUpgradedManifest); AddStep(&TaskManifestFile::stepUpdateFinalize); @@ -307,8 +308,7 @@ void TaskManifestFile::stepBackupIconFiles() { LogDebug("Backup Icon Files"); - backup_dir << m_context.locations->getPackageInstallationDir(); - backup_dir << "/" << "backup" << "/"; + backup_dir << m_context.locations->getBackupDir() << "/"; backupIconFiles(); @@ -544,18 +544,22 @@ void TaskManifestFile::stepParseManifest() void TaskManifestFile::stepParseUpgradedManifest() { - int code = pkgmgr_parser_parse_manifest_for_upgrade( - DPL::ToUTF8String(manifest_file).c_str(), NULL); + if (m_context.widgetConfig.packagingType != + PKG_TYPE_HYBRID_WEB_APP) + { + int code = pkgmgr_parser_parse_manifest_for_upgrade( + DPL::ToUTF8String(manifest_file).c_str(), NULL); - if (code != 0) { - LogError("Manifest parser error: " << code); - ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code); - } + if (code != 0) { + LogError("Manifest parser error: " << code); + ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code); + } - m_context.job->UpdateProgress( - InstallerContext::INSTALL_CREATE_MANIFEST, - "Widget Manifest Parsing Finished"); - LogDebug("Manifest parsed"); + m_context.job->UpdateProgress( + InstallerContext::INSTALL_CREATE_MANIFEST, + "Widget Manifest Parsing Finished"); + LogDebug("Manifest parsed"); + } } void TaskManifestFile::commitManifest() diff --git a/src/jobs/widget_install/task_remove_backup.cpp b/src/jobs/widget_install/task_remove_backup.cpp index 8841739..47e9cf4 100644 --- a/src/jobs/widget_install/task_remove_backup.cpp +++ b/src/jobs/widget_install/task_remove_backup.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -41,7 +42,12 @@ TaskRemoveBackupFiles::TaskRemoveBackupFiles(InstallerContext& context) : DPL::TaskDecl(this), m_context(context) { - AddStep(&TaskRemoveBackupFiles::StepRemoveBackupFiles); + if (m_context.widgetConfig.packagingType != + WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) + { + AddStep(&TaskRemoveBackupFiles::StepRemoveBackupFiles); + } + AddStep(&TaskRemoveBackupFiles::StepDeleteBackupDB); } void TaskRemoveBackupFiles::StepRemoveBackupFiles() @@ -62,13 +68,24 @@ void TaskRemoveBackupFiles::StepRemoveBackupFiles() LogDebug("Success to remove temp directory : " << tmp); } else { LogError("Failed to remove temp directory : " << tmp); - ThrowMsg(Exceptions::RemoveBackupFailed, - "Error occurs during removing existing folder"); } +} - m_context.job->UpdateProgress( - InstallerContext::INSTALL_REMOVE_BACKUP_FILE, - "Backup widget file delete Finished"); +void TaskRemoveBackupFiles::StepDeleteBackupDB() +{ + LogDebug("StepDeleteBackupDB"); + std::string oldAppid = + DPL::ToUTF8String(m_context.widgetConfig.tzAppid) + ".backup"; + + Try + { + WidgetDAO::unregisterWidget(DPL::FromUTF8String(oldAppid)); + } + Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) + { + LogError("Fail to delete old version db information"); + } } + } //namespace WidgetInstall } //namespace Jobs diff --git a/src/jobs/widget_install/task_remove_backup.h b/src/jobs/widget_install/task_remove_backup.h index d269435..777f988 100644 --- a/src/jobs/widget_install/task_remove_backup.h +++ b/src/jobs/widget_install/task_remove_backup.h @@ -35,6 +35,7 @@ class TaskRemoveBackupFiles : InstallerContext& m_context; void StepRemoveBackupFiles(); + void StepDeleteBackupDB(); public: TaskRemoveBackupFiles(InstallerContext& context); diff --git a/src/jobs/widget_install/task_update_files.cpp b/src/jobs/widget_install/task_update_files.cpp index eeecb86..69b7053 100644 --- a/src/jobs/widget_install/task_update_files.cpp +++ b/src/jobs/widget_install/task_update_files.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -57,258 +58,48 @@ TaskUpdateFiles::TaskUpdateFiles(InstallerContext& context) : DPL::TaskDecl(this), m_context(context) { - AddStep(&TaskUpdateFiles::StepCreateBackupFolder); - AddStep(&TaskUpdateFiles::StepResourceFilesBackup); - AddStep(&TaskUpdateFiles::StepExecFileBackup); + AddStep(&TaskUpdateFiles::StepBackupDirectory); - AddAbortStep(&TaskUpdateFiles::StepAbortCreateBackupFolder); - AddAbortStep(&TaskUpdateFiles::StepAbortExecFileBackup); - AddAbortStep(&TaskUpdateFiles::StepAbortResourceFilesBackup); + AddAbortStep(&TaskUpdateFiles::StepAbortBackupDirectory); } -void TaskUpdateFiles::StepCreateBackupFolder() +void TaskUpdateFiles::StepBackupDirectory() { LogDebug("StepCreateBackupFolder"); - std::string srcBuPath = m_context.locations->getBackupSourceDir(); - LogDebug("backup resource directory path : " << srcBuPath); - if (!WrtUtilMakeDir(srcBuPath)) { - ThrowMsg( - Exceptions::BackupFailed, - "Error occurs during create \ - backup directory."); - } - - std::string binBuPath = m_context.locations->getBackupBinaryDir(); - LogDebug("backup execution directory path : " << binBuPath); - if (!WrtUtilMakeDir(binBuPath)) { - ThrowMsg( - Exceptions::BackupFailed, - "Error occurs during create backup \ - directory."); - } - - m_context.job->UpdateProgress( - InstallerContext::INSTALL_CREATE_BACKUP_DIR, - "Backup directory created for update"); -} - -void TaskUpdateFiles::ReadDirList(std::string dirPath, ExistFileList &list, - size_t subLen) -{ - DIR* pkgDir = opendir(dirPath.c_str()); - if (!pkgDir) { - LogError("Package directory " << dirPath << " doesn't exist"); - ThrowMsg(Exceptions::BackupFailed, - "Error occurs during read \ - directory"); - } - - struct stat statInfo; - struct dirent dirent; - struct dirent *result; - int return_code; - errno = 0; - for (return_code = readdir_r(pkgDir, &dirent, &result); - result != NULL && return_code == 0; - return_code = readdir_r(pkgDir, &dirent, &result)) - { - std::string dirName = dirent.d_name; - std::string absFileName = dirPath + "/" + dirName; - if (stat(absFileName.c_str(), &statInfo) != 0) { - ThrowMsg(Exceptions::BackupFailed, "Error occurs read file"); - } - - if (S_ISDIR(statInfo.st_mode)) { - if (strcmp(dirent.d_name, ".") == 0 || strcmp(dirent.d_name, - "..") == 0) - { - continue; - } - ReadDirList(absFileName, list, subLen); - } - - list.insert(absFileName.substr(subLen)); - } - if (return_code != 0 || errno != 0) { - LogError("readdir_r() failed with " << DPL::GetErrnoString()); - } - errno = 0; - //closing the directory - if (-1 == TEMP_FAILURE_RETRY(closedir(pkgDir))) { - LogError("Failed to close dir: " << dirPath << " with error: " - << DPL::GetErrnoString()); - } -} - -void TaskUpdateFiles::StepResourceFilesBackup() -{ - LogDebug("StepCopyFiles"); - - ExistFileList resList; - ExistFileList tempList; - - std::string pkgSrc = m_context.locations->getSourceDir(); - ReadDirList(pkgSrc, resList, strlen(pkgSrc.c_str()) + 1); - - std::string tempSrc = m_context.locations->getTemporaryPackageDir(); - ReadDirList(tempSrc, tempList, strlen(tempSrc.c_str()) + 1); - - FOREACH(it, tempList) { - std::set::iterator res; - res = resList.find(*it); - std::string resFile = pkgSrc + "/" + (*it); - std::string newFile = tempSrc + "/" + (*it); - - if (res != resList.end()) { - std::string backupFile = - m_context.locations->getBackupSourceDir() + - "/" + (*it); - - struct stat sInfo; - if (stat(resFile.c_str(), &sInfo) != 0) { - ThrowMsg(Exceptions::BackupFailed, "Error occurs read file"); - } - - if (S_ISDIR(sInfo.st_mode)) { - LogDebug(resFile << " is a directory. so create a folder : " << - backupFile); - WrtUtilMakeDir(backupFile); - } else { - if ((rename(resFile.c_str(), backupFile.c_str())) != 0) { - LogError( - "Failed to rename " << resFile << " to " << - backupFile); - ThrowMsg( - Exceptions::BackupFailed, - "Error occurs during \ - rename file"); - } - - LogDebug("backup : " << resFile << " to " << backupFile); + std::string backPath = m_context.locations->getBackupDir(); + LogDebug("backup resource directory path : " << backPath); + std::string pkgPath = m_context.locations->getPackageInstallationDir(); - if ((rename(newFile.c_str(), resFile.c_str())) != 0) { - LogError( - "Failed to rename " << newFile << " to " << resFile); - ThrowMsg( - Exceptions::BackupFailed, - "Error occurs during \ - rename file"); - } - LogDebug("copy : " << newFile << " to " << resFile); - } - resList.erase(res); - } else { - if ((rename(newFile.c_str(), resFile.c_str())) != 0) { - LogError("Failed to rename " << newFile << " to " << resFile); - ThrowMsg( - Exceptions::BackupFailed, - "Error occurs during \ - rename file"); - } - LogDebug("only copy : " << newFile << " to " << resFile); - } - } - - if (resList.empty() != 0) { - FOREACH(remain, resList) { - std::string pkgFile = pkgSrc + "/" + (*remain); - std::string backFile = tempSrc + "/" + (*remain); - if ((rename(pkgFile.c_str(), backFile.c_str())) != 0) { - LogError("Failed to backup : " << pkgFile << " to " << backFile); - ThrowMsg( - Exceptions::BackupFailed, - "Error occurs during \ - rename file"); - } - LogDebug("only backup : " << pkgFile << " to " << backFile); - } - } - - m_context.job->UpdateProgress( - InstallerContext::INSTALL_BACKUP_RES_FILES, - "Backup resource file for update"); -} - -void TaskUpdateFiles::StepExecFileBackup() -{ - std::string execFile = m_context.locations->getExecFile(); - - LogDebug(" source : " << execFile); - - std::string tempSource = m_context.locations->getBackupExecFile(); - LogDebug(" source : " << tempSource); - - if ((rename(execFile.c_str(), tempSource.c_str())) != 0) { - LogError("Failed to rename " << execFile << " to " << - tempSource); + LogDebug("copy : " << pkgPath << " to " << backPath); + if ((rename(pkgPath.c_str(), backPath.c_str())) != 0) { + LogError("Failed to rename " << pkgPath << " to " << backPath); ThrowMsg(Exceptions::BackupFailed, - "Error occurs during \ - rename file"); + "Error occurs during rename file"); } - LogDebug("Backup : " << execFile << " to " << tempSource); - std::string clientPath = GlobalConfig::GetWrtClientExec(); + WrtUtilMakeDir(pkgPath); - LogInfo("link -s " << clientPath << " " << execFile); - - errno = 0; - if( symlink(clientPath.c_str(), execFile.c_str()) != 0 ) - { - int error = errno; - if(error) - LogPedantic("Failed to make a symbolic name for a file " - << "[" << DPL::GetErrnoString(error) << "]"); - ThrowMsg(Exceptions::BackupFailed, - "Error occurs during rename file"); - } m_context.job->UpdateProgress( - InstallerContext::INSTALL_BACKUP_EXEC, - "Backup execution file for update"); + InstallerContext::INSTALL_CREATE_BACKUP_DIR, + "Backup directory created for update"); } -void TaskUpdateFiles::StepAbortResourceFilesBackup() +void TaskUpdateFiles::StepAbortBackupDirectory() { LogDebug("StepAbortCopyFiles"); - std::string srcPath = m_context.locations->getSourceDir(); - std::string srcBuPath = m_context.locations->getBackupSourceDir(); - - LogDebug("Backup Folder " << srcBuPath << " to " << srcPath); - - if (!WrtUtilRemove(srcPath)) { - LogError("Failed to remove " << srcPath); - } - - if (rename(srcBuPath.c_str(), srcPath.c_str()) != 0) { - LogError("Failed to rename " << srcBuPath << " to " << srcPath); - } -} -void TaskUpdateFiles::StepAbortExecFileBackup() -{ - LogDebug("StepAbortExecFileBackup"); - std::string binPath = m_context.locations->getBinaryDir(); + std::string backPath = m_context.locations->getBackupDir(); + std::string pkgPath = m_context.locations->getPackageInstallationDir(); - if (!WrtUtilRemove(binPath)) { - LogError("Failed to remove " << binPath); - } + LogDebug("Backup Folder " << backPath << " to " << pkgPath); - std::string binBuPath = m_context.locations->getBackupBinaryDir(); - if (rename(binBuPath.c_str(), binPath.c_str()) != 0) { - LogError("Failed to rename " << binBuPath << " to " << binPath); + if (!WrtUtilRemove(pkgPath)) { + LogError("Failed to remove " << pkgPath); } - LogDebug("Backup Folder " << binBuPath << "move to " << binPath); -} - -void TaskUpdateFiles::StepAbortCreateBackupFolder() -{ - LogDebug("StepAbortCreateBackupFolder"); - std::ostringstream path; - path << m_context.locations->getBackupDir(); - LogDebug("Remove backup directory : " << path.str()); - if (!WrtUtilRemove(path.str())) { - LogError("Failed to remove " << path); + if (rename(backPath.c_str(), pkgPath.c_str()) != 0) { + LogError("Failed to rename " << backPath << " to " << pkgPath); } } } //namespace WidgetInstall diff --git a/src/jobs/widget_install/task_update_files.h b/src/jobs/widget_install/task_update_files.h index b95e5c9..4161b13 100644 --- a/src/jobs/widget_install/task_update_files.h +++ b/src/jobs/widget_install/task_update_files.h @@ -40,16 +40,9 @@ class TaskUpdateFiles : private: InstallerContext& m_context; - /* TODO : md5 check */ - void StepCreateBackupFolder(); - void StepResourceFilesBackup(); - void StepExecFileBackup(); + void StepBackupDirectory(); - void ReadDirList(std::string dirPath, ExistFileList &list, size_t subLen); - - void StepAbortResourceFilesBackup(); - void StepAbortCreateBackupFolder(); - void StepAbortExecFileBackup(); + void StepAbortBackupDirectory(); public: TaskUpdateFiles(InstallerContext& context); diff --git a/src/misc/widget_location.cpp b/src/misc/widget_location.cpp index a0ffb58..adfbd44 100644 --- a/src/misc/widget_location.cpp +++ b/src/misc/widget_location.cpp @@ -137,7 +137,7 @@ std::string WidgetLocation::getExecFile() const std::string WidgetLocation::getBackupDir() const { - return getPackageInstallationDir() + "/backup"; + return getPackageInstallationDir() + ".backup"; } std::string WidgetLocation::getBackupSourceDir() const @@ -155,6 +155,12 @@ std::string WidgetLocation::getBackupExecFile() const return getBackupBinaryDir() + "/" + m_appid; } +std::string WidgetLocation::getBackupPrivateDir() const +{ + return getBackupDir() + "/" + + WrtDB::GlobalConfig::GetWidgetPrivateStoragePath(); +} + std::string WidgetLocation::getUserDataRootDir() const { return std::string(WrtDB::GlobalConfig::GetWidgetUserDataPath()) + diff --git a/src/misc/widget_location.h b/src/misc/widget_location.h index 2e5b7c9..0cdcbdd 100644 --- a/src/misc/widget_location.h +++ b/src/misc/widget_location.h @@ -117,10 +117,11 @@ class WidgetLocation std::string getBinaryDir() const; // /opt/apps/[package]/bin or /usr/apps/[package]/bin std::string getUserBinaryDir() const; // /opt/apps/[package]/bin std::string getExecFile() const; // /opt/apps/[package]/bin/[package] - std::string getBackupDir() const; // /opt/apps/[package]/backup - std::string getBackupSourceDir() const; // /opt/apps/[pkg]/backup/res/wgt - std::string getBackupBinaryDir() const; // /opt/apps/[pkg]/backup/bin - std::string getBackupExecFile() const; // /opt/apps/[pkg]/backup/bin/[pkg] + std::string getBackupDir() const; // /opt/apps/[package].backup + std::string getBackupSourceDir() const; // /opt/apps/[pkg].backup/res/wgt + std::string getBackupBinaryDir() const; // /opt/apps/[pkg].backup/bin + std::string getBackupExecFile() const; // /opt/apps/[pkg].backup/bin/[pkg] + std::string getBackupPrivateDir() const; // /opt/apps/[pkg].backup/data std::string getUserDataRootDir() const; // /opt/usr/apps/[package] std::string getPrivateStorageDir() const; // /opt/usr/apps/[package]/data