Rename invalid WRT_SMACK_LABEL macro to WRT_SMACK_ENABLED
[platform/framework/web/wrt-installer.git] / src / jobs / widget_install / task_prepare_reinstall.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /**
17  * @file    task_prepare_reinstall.cpp
18  * @author  Jihoon Chung(jihoon.chung@samsung.com)
19  * @version 1.0
20  * @brief   Implementation file for installer task prepare reinstalling
21  */
22
23 #include "task_prepare_reinstall.h"
24
25 #include <stdio.h>
26 #include <fstream>
27 #include <unistd.h>
28
29 #include <dpl/task.h>
30 #include <dpl/string.h>
31 #include <dpl/foreach.h>
32 #include <dpl/utils/wrt_utility.h>
33
34 #include <widget_install/widget_install_context.h>
35 #include <widget_install/widget_install_errors.h>
36 #include <widget_install/job_widget_install.h>
37
38 #include <installer_log.h>
39
40 namespace Jobs {
41 namespace WidgetInstall {
42 namespace {
43 const char* const KEY_DELETE = "#delete";
44 const char* const KEY_ADD = "#add";
45 const char* const KEY_MODIFY = "#modify";
46 std::list<std::string> keyList = {KEY_DELETE, KEY_ADD, KEY_MODIFY};
47
48 void verifyFile(const std::string &filePath)
49 {
50     if (access(filePath.c_str(), F_OK) != 0) {
51         ThrowMsg(Exceptions::RDSDeltaFailure, "File is missed " << filePath);
52     }
53 }
54
55 std::string parseSubPath(const std::string& filePath)
56 {
57     std::string subPath("");
58     size_t pos = filePath.find_last_of('/') + 1;
59
60     if (pos != std::string::npos) {
61         subPath = filePath.substr(0, pos);
62     }
63     return subPath;
64 }
65
66 void createDir(const std::string& path)
67 {
68     if (WrtUtilMakeDir(path)) {
69         _D("Create directory : %s", path.c_str());
70     } else {
71         ThrowMsg(Exceptions::RDSDeltaFailure, "Fail to create dir" << path);
72     }
73 }
74 } // namespace anonymous
75
76 TaskPrepareReinstall::TaskPrepareReinstall(InstallerContext& context) :
77     DPL::TaskDecl<TaskPrepareReinstall>(this),
78     m_context(context)
79 {
80     AddStep(&TaskPrepareReinstall::StartStep);
81     AddStep(&TaskPrepareReinstall::StepPrepare);
82     AddStep(&TaskPrepareReinstall::StepParseRDSDelta);
83     AddStep(&TaskPrepareReinstall::StepVerifyRDSDelta);
84     AddStep(&TaskPrepareReinstall::StepAddFile);
85     AddStep(&TaskPrepareReinstall::StepDeleteFile);
86     AddStep(&TaskPrepareReinstall::StepModifyFile);
87     AddStep(&TaskPrepareReinstall::EndStep);
88 }
89
90 void TaskPrepareReinstall::StepPrepare()
91 {
92     _D("Prepare");
93     m_sourcePath = m_context.locations->getTemporaryPackageDir();
94     m_sourcePath += "/";
95
96     m_installedPath = m_context.locations->getPackageInstallationDir();
97     m_installedPath += "/";
98 }
99
100 void TaskPrepareReinstall::StepParseRDSDelta()
101 {
102     _D("parse RDS delta");
103     std::string rdsDeltaPath = m_sourcePath;
104     rdsDeltaPath += ".rds_delta";
105     std::ifstream delta(rdsDeltaPath);
106
107     if (!delta.is_open()) {
108         ThrowMsg(Exceptions::RDSDeltaFailure, "rds_delta file is missed");
109         return;
110     }
111
112     std::string line;
113     std::string key;
114     while (std::getline(delta, line) &&!delta.eof()) {
115         FOREACH(keyIt, keyList) {
116             if (line == *keyIt) {
117                 _D("find key = [%s]", line.c_str());
118                 key = line;
119                 break;
120             }
121         }
122         if (key == line || line.empty() || line == "\n") {
123             continue;
124         }
125         if (key == KEY_DELETE) {
126             m_deleteFileList.push_back(line);
127             _D("line = [%s]", line.c_str());
128         } else if (key == KEY_ADD) {
129             m_addFileList.push_back(line);
130             _D("line = [%s]", line.c_str());
131         } else if (key == KEY_MODIFY) {
132             m_modifyFileList.push_back(line);
133             _D("line = [%s]", line.c_str());
134         }
135     }
136 }
137
138 void TaskPrepareReinstall::StepVerifyRDSDelta()
139 {
140     _D("verify RDS delta");
141     // Verify ADD file
142     FOREACH(file, m_addFileList) {
143         std::string addFilePath = m_sourcePath;
144         addFilePath += *file;
145         verifyFile(addFilePath);
146     }
147     // Verify DELETE file
148     FOREACH(file, m_deleteFileList) {
149         std::string deleteFilePath = m_installedPath;
150         deleteFilePath += *file;
151         verifyFile(deleteFilePath);
152     }
153     // Verify MODIFY file
154     FOREACH(file, m_modifyFileList) {
155         std::string newFilePath = m_sourcePath;
156         newFilePath += *file;
157         verifyFile(newFilePath);
158
159         std::string existingFilePath = m_installedPath;
160         existingFilePath += *file;
161         verifyFile(existingFilePath);
162     }
163     _D("Finished veify RDS Delta");
164
165     m_context.job->UpdateProgress(
166         InstallerContext::INSTALL_RDS_DELTA_CHECK,
167         "RDS delta verify finished");
168 }
169
170 void TaskPrepareReinstall::StepAddFile()
171 {
172     _D("Add file");
173     FOREACH(file, m_addFileList) {
174         std::string newfile = m_sourcePath;
175         newfile += *file;
176         std::string destPath = m_installedPath;
177         destPath += *file;
178
179         if (WrtUtilDirExists(newfile)) {
180             // In case of a new directory
181             createDir(destPath);
182         } else {
183             // In case of a new file
184
185             // Parse directory and file separately
186             std::string subPath = parseSubPath(destPath);
187             if (subPath.empty()) {
188                 ThrowMsg(Exceptions::RDSDeltaFailure,
189                          "Invalid path given" << destPath);
190             }
191
192             // Create a new directory
193             createDir(subPath);
194
195             // Add file
196             if (rename(newfile.c_str(), destPath.c_str()) != 0) {
197                 ThrowMsg(Exceptions::RDSDeltaFailure,
198                         "Fail to add file " << newfile);
199             }
200             _D("Add %s to %s", newfile.c_str(), destPath.c_str());
201         }
202     }
203 }
204
205 void TaskPrepareReinstall::StepDeleteFile()
206 {
207     _D("Delete file");
208     FOREACH(file, m_deleteFileList) {
209         std::string deleteFilePath = m_installedPath;
210         deleteFilePath += *file;
211         if (remove(deleteFilePath.c_str()) != 0) {
212             ThrowMsg(Exceptions::RDSDeltaFailure,
213                 "Fail to DELETE file " << deleteFilePath);
214         }
215         _D("Delete %s", deleteFilePath.c_str());
216     }
217 }
218
219 void TaskPrepareReinstall::StepModifyFile()
220 {
221     _D("Modify  file");
222     FOREACH(file, m_modifyFileList) {
223         std::string destPath = m_installedPath;
224         destPath += *file;
225         if (remove(destPath.c_str()) != 0) {
226             ThrowMsg(Exceptions::RDSDeltaFailure,
227                 "Fail to delete existing file " << destPath);
228         }
229
230         std::string newfile = m_sourcePath;
231         newfile += *file;
232         if (rename(newfile.c_str(), destPath.c_str()) != 0) {
233             ThrowMsg(Exceptions::RDSDeltaFailure,
234                 "Fail to move new file" << destPath);
235         }
236         _D("Replace %s to %s", newfile.c_str(), destPath.c_str());
237     }
238 }
239
240 void TaskPrepareReinstall::StartStep()
241 {
242     _D("---------- <TaskPrepareReinstall> : START ----------");
243 }
244
245 void TaskPrepareReinstall::EndStep()
246 {
247     m_context.job->UpdateProgress(
248         InstallerContext::INSTALL_RDS_PREPARE,
249         "RDS prepare finished");
250
251     _D("---------- <TaskPrepareReinstall> : END ----------");
252 }
253
254 } //namespace WidgetInstall
255 } //namespace Jobs