WidgetHandle removal - part 2. Task order change
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_update_files.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_update_files.cpp
18  * @author  Soyoung Kim (sy037.kim@samsung.com)
19  * @version 1.0
20  * @brief   Implementation file for installer task update files
21  */
22
23 #include <utility>
24 #include <vector>
25 #include <string>
26 #include <algorithm>
27 #include <sys/stat.h>
28 #include <dirent.h>
29
30 #include <widget_install/task_update_files.h>
31 #include <dpl/assert.h>
32 #include <dpl/log/log.h>
33 #include <dpl/foreach.h>
34 #include <dpl/utils/wrt_utility.h>
35
36 #include <widget_install/widget_install_context.h>
37 #include <widget_install/widget_install_errors.h>
38 #include <widget_install/job_widget_install.h>
39
40 #include <dpl/wrt-dao-ro/global_config.h>
41 #include <dpl/exception.h>
42 #include <dpl/errno_string.h>
43
44 using namespace WrtDB;
45
46 namespace {
47
48 inline const char* GetWidgetBackupDirPath()
49 {
50     return "backup";
51 }
52 }
53
54 namespace Jobs {
55 namespace WidgetInstall {
56
57 TaskUpdateFiles::TaskUpdateFiles(InstallerContext& context) :
58     DPL::TaskDecl<TaskUpdateFiles>(this),
59     m_context(context)
60 {
61     AddStep(&TaskUpdateFiles::StepCreateBackupFolder);
62     AddStep(&TaskUpdateFiles::StepResourceFilesBackup);
63     AddStep(&TaskUpdateFiles::StepExecFileBackup);
64
65     AddAbortStep(&TaskUpdateFiles::StepAbortCreateBackupFolder);
66     AddAbortStep(&TaskUpdateFiles::StepAbortExecFileBackup);
67     AddAbortStep(&TaskUpdateFiles::StepAbortResourceFilesBackup);
68 }
69
70 void TaskUpdateFiles::StepCreateBackupFolder()
71 {
72     LogDebug("StepCreateBackupFolder");
73     std::ostringstream backDirPath;
74
75     std::string srcBuPath = m_context.locations->getBackupSourceDir();
76     LogDebug("backup resource directory path : " << srcBuPath);
77     if(!WrtUtilMakeDir(srcBuPath)) {
78         ThrowMsg(Exceptions::BackupFailed, "Error occurs during create \
79                 backup directory.");
80     }
81
82     std::string binBuPath = m_context.locations->getBackupBinaryDir();
83     LogDebug("backup execution directory path : " << binBuPath);
84     if(!WrtUtilMakeDir(binBuPath)) {
85         ThrowMsg(Exceptions::BackupFailed, "Error occurs during create backup \
86                 directory.");
87     }
88
89     m_context.job->UpdateProgress(
90         InstallerContext::INSTALL_CREATE_BACKUP_DIR,
91         "Backup directory created for update");
92 }
93
94 void TaskUpdateFiles::ReadDirList(std::string dirPath, ExistFileList &list,
95         size_t subLen)
96 {
97     DIR* pkgDir = opendir(dirPath.c_str());
98     if (!pkgDir) {
99         LogError("Package directory " << dirPath << " doesn't exist");
100         ThrowMsg(Exceptions::InternalError, "Error occurs during read \
101                 directory");
102     }
103
104     struct dirent* dirent;
105     struct stat statInfo;
106     do {
107         if ((dirent = readdir(pkgDir))) {
108             std::string dirName = dirent->d_name;
109             std::string absFileName = dirPath + "/" + dirName;
110             if (stat(absFileName.c_str(), &statInfo) != 0) {
111                 ThrowMsg(Exceptions::InternalError, "Error occurs read file");
112             }
113
114             if (S_ISDIR(statInfo.st_mode)) {
115                 if(strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name,
116                             "..") == 0) {
117                     continue;
118                 }
119                 ReadDirList(absFileName, list, subLen);
120             }
121
122             list.insert(absFileName.substr(subLen));
123         }
124     }
125     while(dirent);
126     //closing the directory
127     if (-1 == TEMP_FAILURE_RETRY(closedir(pkgDir))) {
128         LogError("Failed to close dir: " << dirPath << " with error: "
129                 << DPL::GetErrnoString());
130     }
131 }
132
133 void TaskUpdateFiles::StepResourceFilesBackup()
134 {
135     LogDebug("StepCopyFiles");
136
137     ExistFileList resList;
138     ExistFileList tempList;
139
140     std::string pkgSrc = m_context.locations->getSourceDir();
141     ReadDirList(pkgSrc, resList, strlen(pkgSrc.c_str())+1);
142
143
144     std::string tempSrc = m_context.locations->getTemporaryPackageDir();
145     ReadDirList(tempSrc, tempList, strlen(tempSrc.c_str())+1);
146
147     FOREACH(it, tempList) {
148         std::set<std::string>::iterator res;
149         res = resList.find(*it);
150         std::string resFile = pkgSrc + "/" + (*it);
151         std::string newFile = tempSrc + "/" +(*it);
152
153         if (res != resList.end()) {
154             std::string backupFile = m_context.locations->getBackupSourceDir() +
155                     "/"+ (*it);
156
157             struct stat sInfo;
158             if (stat(resFile.c_str(), &sInfo) != 0) {
159                 ThrowMsg(Exceptions::InternalError, "Error occurs read file");
160             }
161
162             if (S_ISDIR(sInfo.st_mode)) {
163                 LogDebug(resFile << " is a directory. so create a folder : " <<
164                         backupFile);
165                 WrtUtilMakeDir(backupFile);
166             } else {
167                 if ((rename(resFile.c_str(), backupFile.c_str())) != 0) {
168                     LogError("Failed to rename " << resFile << " to " << backupFile);
169                     ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
170                             rename file");
171                 }
172
173                 LogDebug("backup : " << resFile << " to " << backupFile);
174
175                 if ((rename(newFile.c_str(), resFile.c_str())) != 0) {
176                     LogError("Failed to rename " << newFile << " to " << resFile);
177                     ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
178                             rename file");
179                 }
180                 LogDebug("copy : " << newFile << " to " << resFile);
181             }
182             resList.erase(res);
183         } else {
184             if ((rename(newFile.c_str(), resFile.c_str())) != 0) {
185                 LogError("Failed to rename " << newFile << " to " << resFile);
186                 ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
187                         rename file");
188             }
189             LogDebug("only copy : " << newFile << " to " << resFile);
190         }
191     }
192
193     if (resList.empty() != 0) {
194         FOREACH(remain, resList) {
195             std::string pkgFile = pkgSrc + "/" + (*remain);
196             std::string backFile = tempSrc + "/" + (*remain);
197             if ((rename(pkgFile.c_str(), backFile.c_str())) != 0) {
198                 LogError("Failed to backup : " << pkgFile << " to " << backFile);
199                 ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
200                         rename file");
201             }
202             LogDebug("only backup : " << pkgFile << " to " << backFile);
203         }
204     }
205
206     m_context.job->UpdateProgress(
207         InstallerContext::INSTALL_BACKUP_RES_FILES,
208         "Backup resource file for update");
209 }
210
211 void TaskUpdateFiles::StepExecFileBackup()
212 {
213     std::string execFile = m_context.locations->getExecFile();
214
215     LogDebug(" source : " << execFile);
216
217     std::string tempSource= m_context.locations->getBackupExecFile();
218     LogDebug(" source : " << tempSource);
219
220     if ((rename(execFile.c_str(), tempSource.c_str())) != 0) {
221         LogError("Failed to rename " << execFile << " to " <<
222                 tempSource);
223         ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
224                 rename file");
225     }
226     LogDebug("Backup : " << execFile << " to " << tempSource);
227
228     std::string clientPath = GlobalConfig::GetWrtClientExec();
229
230     LogInfo("link -s " << clientPath << " " << execFile);
231     symlink(clientPath.c_str(), execFile.c_str());
232
233     m_context.job->UpdateProgress(
234         InstallerContext::INSTALL_BACKUP_EXEC,
235         "Backup execution file for update");
236 }
237
238 void TaskUpdateFiles::StepAbortResourceFilesBackup()
239 {
240     LogDebug("StepAbortCopyFiles");
241     std::string srcPath = m_context.locations->getSourceDir();
242     std::string srcBuPath = m_context.locations->getBackupSourceDir();
243
244     LogDebug("Backup Folder " << srcBuPath << " to " << srcPath);
245
246     if(!WrtUtilRemove(srcPath)) {
247         LogError("Failed to remove " << srcPath);
248     }
249
250     if (rename(srcBuPath.c_str(), srcPath.c_str()) != 0) {
251         LogError("Failed to rename " << srcBuPath << " to " << srcPath);
252     }
253 }
254
255 void TaskUpdateFiles::StepAbortExecFileBackup()
256 {
257     LogDebug("StepAbortExecFileBackup");
258     std::string binPath = m_context.locations->getBinaryDir();
259
260     if(!WrtUtilRemove(binPath)) {
261         LogError("Failed to remove " << binPath);
262     }
263
264     std::string binBuPath = m_context.locations->getBackupBinaryDir();
265     if (rename(binBuPath.c_str(), binPath.c_str()) != 0) {
266         LogError("Failed to rename " << binBuPath << " to " << binPath);
267     }
268     LogDebug("Backup Folder " << binBuPath << "move to " << binPath);
269 }
270
271 void TaskUpdateFiles::StepAbortCreateBackupFolder()
272 {
273     LogDebug("StepAbortCreateBackupFolder");
274     std::ostringstream path;
275     path << m_context.locations->getBackupDir();
276     LogDebug("Remove backup directory : " << path.str());
277
278     if(!WrtUtilRemove(path.str())) {
279         LogError("Failed to remove " << path);
280     }
281 }
282
283 } //namespace WidgetInstall
284 } //namespace Jobs