2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file task_prepare_reinstall.cpp
18 * @author Jihoon Chung(jihoon.chung@samsung.com)
20 * @brief Implementation file for installer task prepare reinstalling
23 #include "task_prepare_reinstall.h"
29 #include <privilege-control.h>
32 #include <dpl/string.h>
33 #include <dpl/foreach.h>
34 #include <boost/filesystem.hpp>
36 #include <widget_install/widget_install_context.h>
37 #include <widget_install/widget_install_errors.h>
38 #include <dpl/log/secure_log.h>
40 namespace bf = boost::filesystem;
43 namespace WidgetInstall {
45 const char* const KEY_DELETE = "#delete";
46 const char* const KEY_ADD = "#add";
47 const char* const KEY_MODIFY = "#modify";
48 std::list<std::string> keyList = {KEY_DELETE, KEY_ADD, KEY_MODIFY};
50 void verifyFile(const std::string &filePath)
52 if (access(filePath.c_str(), F_OK) != 0) {
53 ThrowMsg(Exceptions::RDSDeltaFailure, "File is missed " << filePath);
57 std::string parseSubPath(const std::string& filePath)
59 std::string subPath("");
60 size_t pos = filePath.find_last_of('/') + 1;
62 if (pos != std::string::npos) {
63 subPath = filePath.substr(0, pos);
68 void createDir(const std::string& path)
73 bf::create_directories(p);
74 bf::permissions(p, bf::owner_all | bf::group_read | bf::group_exe
75 | bf::others_read | bf::others_exe);
76 _D("Create directory : %s", path.c_str());
78 } catch (const bf::filesystem_error& ex) {
79 _E("boost::filesystem::error; %s", ex.what());
80 ThrowMsg(Exceptions::RDSDeltaFailure, "Fail to create dir" << path);
83 } // namespace anonymous
85 TaskPrepareReinstall::TaskPrepareReinstall(JobWidgetInstall * const &jobContext) :
86 DPL::TaskDecl<TaskPrepareReinstall>(this),
87 m_jobContext(jobContext)
89 AddStep(&TaskPrepareReinstall::StartStep);
90 AddStep(&TaskPrepareReinstall::StepPrepare);
91 AddStep(&TaskPrepareReinstall::StepParseRDSDelta);
92 AddStep(&TaskPrepareReinstall::StepVerifyRDSDelta);
93 AddStep(&TaskPrepareReinstall::StepAddFile);
94 AddStep(&TaskPrepareReinstall::StepDeleteFile);
95 AddStep(&TaskPrepareReinstall::StepModifyFile);
96 AddStep(&TaskPrepareReinstall::StepUpdateSmackLabel);
97 AddStep(&TaskPrepareReinstall::EndStep);
100 void TaskPrepareReinstall::StepPrepare()
103 m_sourcePath = m_jobContext->m_installerContext.locations->getTemporaryPackageDir();
106 m_installedPath = m_jobContext->m_installerContext.locations->getPackageInstallationDir();
107 m_installedPath += "/";
110 void TaskPrepareReinstall::StepParseRDSDelta()
112 _D("parse RDS delta");
113 std::string rdsDeltaPath = m_sourcePath;
114 rdsDeltaPath += ".rds_delta";
115 std::ifstream delta(rdsDeltaPath);
117 if (!delta.is_open()) {
118 ThrowMsg(Exceptions::RDSDeltaFailure, "rds_delta file is missed");
124 while (std::getline(delta, line) &&!delta.eof()) {
125 FOREACH(keyIt, keyList) {
126 if (line == *keyIt) {
127 _D("find key = [%s]", line.c_str());
132 if (key == line || line.empty() || line == "\n") {
135 if (key == KEY_DELETE) {
136 m_deleteFileList.push_back(line);
137 _D("line = [%s]", line.c_str());
138 } else if (key == KEY_ADD) {
139 m_addFileList.push_back(line);
140 _D("line = [%s]", line.c_str());
141 } else if (key == KEY_MODIFY) {
142 m_modifyFileList.push_back(line);
143 _D("line = [%s]", line.c_str());
148 void TaskPrepareReinstall::StepVerifyRDSDelta()
150 _D("verify RDS delta");
152 FOREACH(file, m_addFileList) {
153 std::string addFilePath = m_sourcePath;
154 addFilePath += *file;
155 verifyFile(addFilePath);
157 // Verify DELETE file
158 FOREACH(file, m_deleteFileList) {
159 std::string deleteFilePath = m_installedPath;
160 deleteFilePath += *file;
161 verifyFile(deleteFilePath);
163 // Verify MODIFY file
164 FOREACH(file, m_modifyFileList) {
165 std::string newFilePath = m_sourcePath;
166 newFilePath += *file;
167 verifyFile(newFilePath);
169 std::string existingFilePath = m_installedPath;
170 existingFilePath += *file;
171 verifyFile(existingFilePath);
173 _D("Finished veify RDS Delta");
175 m_jobContext->UpdateProgress(
176 InstallerContext::INSTALL_RDS_DELTA_CHECK,
177 "RDS delta verify finished");
180 void TaskPrepareReinstall::StepAddFile()
183 FOREACH(file, m_addFileList) {
184 std::string newfile = m_sourcePath;
186 std::string destPath = m_installedPath;
190 if (bf::is_directory(bf::path(newfile))) {
191 // In case of a new directory
194 // In case of a new file
196 // Parse directory and file separately
197 std::string subPath = parseSubPath(destPath);
198 if (subPath.empty()) {
199 ThrowMsg(Exceptions::RDSDeltaFailure,
200 "Invalid path given" << destPath);
203 // Create a new directory
207 if (rename(newfile.c_str(), destPath.c_str()) != 0) {
208 ThrowMsg(Exceptions::RDSDeltaFailure,
209 "Fail to add file " << newfile);
211 _D("Add %s to %s", newfile.c_str(), destPath.c_str());
213 } catch (const bf::filesystem_error& ex) {
214 _E("boost::filesystem::error: %s", ex.what());
219 void TaskPrepareReinstall::StepDeleteFile()
222 FOREACH(file, m_deleteFileList) {
223 std::string deleteFilePath = m_installedPath;
224 deleteFilePath += *file;
225 if (remove(deleteFilePath.c_str()) != 0) {
226 ThrowMsg(Exceptions::RDSDeltaFailure,
227 "Fail to DELETE file " << deleteFilePath);
229 _D("Delete %s", deleteFilePath.c_str());
233 void TaskPrepareReinstall::StepModifyFile()
236 FOREACH(file, m_modifyFileList) {
237 std::string destPath = m_installedPath;
239 if (remove(destPath.c_str()) != 0) {
240 ThrowMsg(Exceptions::RDSDeltaFailure,
241 "Fail to delete existing file " << destPath);
244 std::string newfile = m_sourcePath;
246 if (rename(newfile.c_str(), destPath.c_str()) != 0) {
247 ThrowMsg(Exceptions::RDSDeltaFailure,
248 "Fail to move new file" << destPath);
250 _D("Replace %s to %s", newfile.c_str(), destPath.c_str());
253 m_jobContext->UpdateProgress(
254 InstallerContext::INSTALL_RDS_PREPARE,
255 "RDS prepare finished");
258 void TaskPrepareReinstall::StepUpdateSmackLabel()
261 std::string resDir = m_installedPath + "res";
262 std::string pkgId = DPL::ToUTF8String(m_jobContext->m_installerContext.widgetConfig.tzPkgid);
263 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId.c_str(), resDir.c_str(),
265 _W("Add label to %s", resDir.c_str());
269 void TaskPrepareReinstall::StartStep()
271 LOGI("---------- <TaskPrepareReinstall> : START ----------");
274 void TaskPrepareReinstall::EndStep()
276 LOGI("---------- <TaskPrepareReinstall> : END ----------");
277 m_jobContext->UpdateProgress(
278 InstallerContext::INSTALL_END,
282 } //namespace WidgetInstall