Source code formating unification
[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 inline const char* GetWidgetBackupDirPath()
48 {
49     return "backup";
50 }
51 }
52
53 namespace Jobs {
54 namespace WidgetInstall {
55 TaskUpdateFiles::TaskUpdateFiles(InstallerContext& context) :
56     DPL::TaskDecl<TaskUpdateFiles>(this),
57     m_context(context)
58 {
59     AddStep(&TaskUpdateFiles::StepCreateBackupFolder);
60     AddStep(&TaskUpdateFiles::StepResourceFilesBackup);
61     AddStep(&TaskUpdateFiles::StepExecFileBackup);
62
63     AddAbortStep(&TaskUpdateFiles::StepAbortCreateBackupFolder);
64     AddAbortStep(&TaskUpdateFiles::StepAbortExecFileBackup);
65     AddAbortStep(&TaskUpdateFiles::StepAbortResourceFilesBackup);
66 }
67
68 void TaskUpdateFiles::StepCreateBackupFolder()
69 {
70     LogDebug("StepCreateBackupFolder");
71     std::ostringstream backDirPath;
72
73     std::string srcBuPath = m_context.locations->getBackupSourceDir();
74     LogDebug("backup resource directory path : " << srcBuPath);
75     if (!WrtUtilMakeDir(srcBuPath)) {
76         ThrowMsg(
77             Exceptions::BackupFailed,
78             "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(
86             Exceptions::BackupFailed,
87             "Error occurs during create backup \
88                 directory.");
89     }
90
91     m_context.job->UpdateProgress(
92         InstallerContext::INSTALL_CREATE_BACKUP_DIR,
93         "Backup directory created for update");
94 }
95
96 void TaskUpdateFiles::ReadDirList(std::string dirPath, ExistFileList &list,
97                                   size_t subLen)
98 {
99     DIR* pkgDir = opendir(dirPath.c_str());
100     if (!pkgDir) {
101         LogError("Package directory " << dirPath << " doesn't exist");
102         ThrowMsg(Exceptions::InternalError,
103                  "Error occurs during read \
104                 directory");
105     }
106
107     struct dirent* dirent;
108     struct stat statInfo;
109     do {
110         if ((dirent = readdir(pkgDir))) {
111             std::string dirName = dirent->d_name;
112             std::string absFileName = dirPath + "/" + dirName;
113             if (stat(absFileName.c_str(), &statInfo) != 0) {
114                 ThrowMsg(Exceptions::InternalError, "Error occurs read file");
115             }
116
117             if (S_ISDIR(statInfo.st_mode)) {
118                 if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name,
119                                                                "..") == 0)
120                 {
121                     continue;
122                 }
123                 ReadDirList(absFileName, list, subLen);
124             }
125
126             list.insert(absFileName.substr(subLen));
127         }
128     } while (dirent);
129     //closing the directory
130     if (-1 == TEMP_FAILURE_RETRY(closedir(pkgDir))) {
131         LogError("Failed to close dir: " << dirPath << " with error: "
132                                          << DPL::GetErrnoString());
133     }
134 }
135
136 void TaskUpdateFiles::StepResourceFilesBackup()
137 {
138     LogDebug("StepCopyFiles");
139
140     ExistFileList resList;
141     ExistFileList tempList;
142
143     std::string pkgSrc = m_context.locations->getSourceDir();
144     ReadDirList(pkgSrc, resList, strlen(pkgSrc.c_str()) + 1);
145
146     std::string tempSrc = m_context.locations->getTemporaryPackageDir();
147     ReadDirList(tempSrc, tempList, strlen(tempSrc.c_str()) + 1);
148
149     FOREACH(it, tempList) {
150         std::set<std::string>::iterator res;
151         res = resList.find(*it);
152         std::string resFile = pkgSrc + "/" + (*it);
153         std::string newFile = tempSrc + "/" + (*it);
154
155         if (res != resList.end()) {
156             std::string backupFile =
157                 m_context.locations->getBackupSourceDir() +
158                 "/" + (*it);
159
160             struct stat sInfo;
161             if (stat(resFile.c_str(), &sInfo) != 0) {
162                 ThrowMsg(Exceptions::InternalError, "Error occurs read file");
163             }
164
165             if (S_ISDIR(sInfo.st_mode)) {
166                 LogDebug(resFile << " is a directory. so create a folder : " <<
167                          backupFile);
168                 WrtUtilMakeDir(backupFile);
169             } else {
170                 if ((rename(resFile.c_str(), backupFile.c_str())) != 0) {
171                     LogError(
172                         "Failed to rename " << resFile << " to " <<
173                         backupFile);
174                     ThrowMsg(
175                         Exceptions::BackupFailed,
176                         "Error occurs during \
177                             rename file");
178                 }
179
180                 LogDebug("backup : " << resFile << " to " << backupFile);
181
182                 if ((rename(newFile.c_str(), resFile.c_str())) != 0) {
183                     LogError(
184                         "Failed to rename " << newFile << " to " << resFile);
185                     ThrowMsg(
186                         Exceptions::BackupFailed,
187                         "Error occurs during \
188                             rename file");
189                 }
190                 LogDebug("copy : " << newFile << " to " << resFile);
191             }
192             resList.erase(res);
193         } else {
194             if ((rename(newFile.c_str(), resFile.c_str())) != 0) {
195                 LogError("Failed to rename " << newFile << " to " << resFile);
196                 ThrowMsg(
197                     Exceptions::BackupFailed,
198                     "Error occurs during \
199                         rename file");
200             }
201             LogDebug("only copy : " << newFile << " to " << resFile);
202         }
203     }
204
205     if (resList.empty() != 0) {
206         FOREACH(remain, resList) {
207             std::string pkgFile = pkgSrc + "/" + (*remain);
208             std::string backFile = tempSrc + "/" + (*remain);
209             if ((rename(pkgFile.c_str(), backFile.c_str())) != 0) {
210                 LogError("Failed to backup : " << pkgFile << " to " << backFile);
211                 ThrowMsg(
212                     Exceptions::BackupFailed,
213                     "Error occurs during \
214                         rename file");
215             }
216             LogDebug("only backup : " << pkgFile << " to " << backFile);
217         }
218     }
219
220     m_context.job->UpdateProgress(
221         InstallerContext::INSTALL_BACKUP_RES_FILES,
222         "Backup resource file for update");
223 }
224
225 void TaskUpdateFiles::StepExecFileBackup()
226 {
227     std::string execFile = m_context.locations->getExecFile();
228
229     LogDebug(" source : " << execFile);
230
231     std::string tempSource = m_context.locations->getBackupExecFile();
232     LogDebug(" source : " << tempSource);
233
234     if ((rename(execFile.c_str(), tempSource.c_str())) != 0) {
235         LogError("Failed to rename " << execFile << " to " <<
236                  tempSource);
237         ThrowMsg(Exceptions::BackupFailed,
238                  "Error occurs during \
239                 rename file");
240     }
241     LogDebug("Backup : " << execFile << " to " << tempSource);
242
243     std::string clientPath = GlobalConfig::GetWrtClientExec();
244
245     LogInfo("link -s " << clientPath << " " << execFile);
246     symlink(clientPath.c_str(), execFile.c_str());
247
248     m_context.job->UpdateProgress(
249         InstallerContext::INSTALL_BACKUP_EXEC,
250         "Backup execution file for update");
251 }
252
253 void TaskUpdateFiles::StepAbortResourceFilesBackup()
254 {
255     LogDebug("StepAbortCopyFiles");
256     std::string srcPath = m_context.locations->getSourceDir();
257     std::string srcBuPath = m_context.locations->getBackupSourceDir();
258
259     LogDebug("Backup Folder " << srcBuPath << " to " << srcPath);
260
261     if (!WrtUtilRemove(srcPath)) {
262         LogError("Failed to remove " << srcPath);
263     }
264
265     if (rename(srcBuPath.c_str(), srcPath.c_str()) != 0) {
266         LogError("Failed to rename " << srcBuPath << " to " << srcPath);
267     }
268 }
269
270 void TaskUpdateFiles::StepAbortExecFileBackup()
271 {
272     LogDebug("StepAbortExecFileBackup");
273     std::string binPath = m_context.locations->getBinaryDir();
274
275     if (!WrtUtilRemove(binPath)) {
276         LogError("Failed to remove " << binPath);
277     }
278
279     std::string binBuPath = m_context.locations->getBackupBinaryDir();
280     if (rename(binBuPath.c_str(), binPath.c_str()) != 0) {
281         LogError("Failed to rename " << binBuPath << " to " << binPath);
282     }
283     LogDebug("Backup Folder " << binBuPath << "move to " << binPath);
284 }
285
286 void TaskUpdateFiles::StepAbortCreateBackupFolder()
287 {
288     LogDebug("StepAbortCreateBackupFolder");
289     std::ostringstream path;
290     path << m_context.locations->getBackupDir();
291     LogDebug("Remove backup directory : " << path.str());
292
293     if (!WrtUtilRemove(path.str())) {
294         LogError("Failed to remove " << path);
295     }
296 }
297 } //namespace WidgetInstall
298 } //namespace Jobs