Update wrt-installer_0.0.54
[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 <sys/stat.h>
27 #include <dirent.h>
28
29 #include <widget_install/task_update_files.h>
30 #include <dpl/assert.h>
31 #include <dpl/log/log.h>
32 #include <dpl/foreach.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 <dpl/wrt-dao-rw/widget_dao.h>
39 #include <dpl/wrt-dao-ro/global_config.h>
40 #include <dpl/utils/wrt_utility.h>
41 #include <dpl/exception.h>
42
43 using namespace WrtDB;
44
45 namespace {
46
47 inline const char* GetWidgetBackupDirPath()
48 {
49     return "backup";
50 }
51 }
52
53 namespace Jobs {
54 namespace WidgetInstall {
55
56 TaskUpdateFiles::TaskUpdateFiles(InstallerContext& context) :
57     DPL::TaskDecl<TaskUpdateFiles>(this),
58     m_context(context)
59 {
60     AddStep(&TaskUpdateFiles::StepCreateBackupFolder);
61     AddStep(&TaskUpdateFiles::StepResourceFilesBackup);
62     AddStep(&TaskUpdateFiles::StepExecFileBackup);
63
64     AddAbortStep(&TaskUpdateFiles::StepAbortCreateBackupFolder);
65     AddAbortStep(&TaskUpdateFiles::StepAbortExecFileBackup);
66     AddAbortStep(&TaskUpdateFiles::StepAbortResourceFilesBackup);
67 }
68
69 void TaskUpdateFiles::StepCreateBackupFolder()
70 {
71     LogDebug("StepCreateBackupFolder");
72     std::ostringstream backDirPath;
73
74     backDirPath << m_context.locations->getBackupDir();
75     m_srcBuPath = backDirPath.str() + GlobalConfig::GetWidgetSrcPath();
76     LogDebug("backup resource directory path : " << m_srcBuPath);
77     if(!_WrtMakeDir(m_srcBuPath.c_str(), 0755, WRT_FILEUTILS_RECUR)) {
78         ThrowMsg(Exceptions::BackupFailed, "Error occurs during create \
79                 backup directory.");
80     }
81
82     m_binBuPath = backDirPath.str() + GlobalConfig::GetUserWidgetExecPath();
83     LogDebug("backup execution directory path : " << m_binBuPath);
84     if(!_WrtMakeDir(m_binBuPath.c_str(), 0755, WRT_FILEUTILS_RECUR)) {
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         LogDebug("Package directory 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 }
127
128 void TaskUpdateFiles::StepResourceFilesBackup()
129 {
130     LogDebug("StepCopyFiles");
131
132     ExistFileList resList;
133     ExistFileList tempList;
134
135     std::string pkgSrc = m_pkgPath + "/" + GlobalConfig::GetWidgetSrcPath();
136     ReadDirList(pkgSrc, resList, strlen(pkgSrc.c_str())+1);
137
138
139     std::string tempSrc = m_context.locations->getTemporaryPackageDir();
140     ReadDirList(tempSrc, tempList, strlen(tempSrc.c_str())+1);
141
142     FOREACH(it, tempList) {
143         std::set<std::string>::iterator res;
144         res = resList.find(*it);
145         std::string resFile = pkgSrc + "/" + (*it);
146         std::string newFile = tempSrc + "/" +(*it);
147
148         if (res != resList.end()) {
149             std::string backupFile = m_srcBuPath + "/"+ (*it);
150
151             struct stat sInfo;
152             if (stat(resFile.c_str(), &sInfo) != 0) {
153                 ThrowMsg(Exceptions::InternalError, "Error occurs read file");
154             }
155
156             if (S_ISDIR(sInfo.st_mode)) {
157                 LogDebug(resFile << " is a directory. so create a folder : " <<
158                         backupFile);
159                 _WrtMakeDir(backupFile.c_str(), 0755, WRT_FILEUTILS_RECUR);
160             } else {
161                 if ((rename(resFile.c_str(), backupFile.c_str())) != 0) {
162                     LogError("Failed to rename " << resFile << " to " << backupFile);
163                     ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
164                             rename file");
165                 }
166
167                 LogDebug("backup : " << resFile << " to " << backupFile);
168
169                 if ((rename(newFile.c_str(), resFile.c_str())) != 0) {
170                     LogError("Failed to rename " << newFile << " to " << resFile);
171                     ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
172                             rename file");
173                 }
174                 LogDebug("copy : " << newFile << " to " << resFile);
175             }
176             resList.erase(res);
177         } else {
178             if ((rename(newFile.c_str(), resFile.c_str())) != 0) {
179                 LogError("Failed to rename " << newFile << " to " << resFile);
180                 ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
181                         rename file");
182             }
183             LogDebug("only copy : " << newFile << " to " << resFile);
184         }
185     }
186
187     if (resList.empty() != 0) {
188         FOREACH(remain, resList) {
189             std::string pkgFile = pkgSrc + "/" + (*remain);
190             std::string backFile = tempSrc + "/" + (*remain);
191             if ((rename(pkgFile.c_str(), backFile.c_str())) != 0) {
192                 LogError("Failed to backup : " << pkgFile << " to " << backFile);
193                 ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
194                         rename file");
195             }
196             LogDebug("only backup : " << pkgFile << " to " << backFile);
197         }
198     }
199
200     m_context.job->UpdateProgress(
201         InstallerContext::INSTALL_BACKUP_RES_FILES,
202         "Backup resource file for update");
203 }
204
205 void TaskUpdateFiles::StepExecFileBackup()
206 {
207     std::ostringstream source;
208     source << m_pkgPath << "/" << GlobalConfig::GetUserWidgetExecPath();
209     source << "/" << m_context.existingWidgetInfo.existingHandle;
210
211     LogDebug(" source : " << source.str());
212
213     std::ostringstream tempSource;
214     tempSource << m_binBuPath << "/" <<
215         m_context.existingWidgetInfo.existingHandle;
216     LogDebug(" source : " << tempSource.str());
217
218     if ((rename(source.str().c_str(), tempSource.str().c_str())) != 0) {
219         LogError("Failed to rename " << source.str() << " to " <<
220                 tempSource.str());
221         ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
222                 rename file");
223     }
224     LogDebug("Backup : " << source.str() << " to " << tempSource.str());
225
226     std::ostringstream newClient;
227     newClient << m_pkgPath << "/" << GlobalConfig::GetUserWidgetExecPath();
228     newClient << "/" << m_context.widgetHandle;
229
230     std::string clientPath = GlobalConfig::GetWrtClientExec();
231
232     LogInfo("link -s " << clientPath << " " << newClient.str());
233     symlink(clientPath.c_str(), newClient.str().c_str());
234
235     m_context.job->UpdateProgress(
236         InstallerContext::INSTALL_BACKUP_EXEC,
237         "Backup execution file for update");
238 }
239
240 void TaskUpdateFiles::StepAbortResourceFilesBackup()
241 {
242     LogDebug("StepAbortCopyFiles");
243     std::string srcPath = m_pkgPath + "/" + GlobalConfig::GetWidgetSrcPath();
244
245     LogDebug("Backup Folder " << m_srcBuPath << " to " << srcPath);
246
247     if(!_WrtUtilRemoveDir(srcPath.c_str())) {
248         LogError("Failed to remove " << srcPath);
249     }
250
251     if (rename(m_srcBuPath.c_str(), srcPath.c_str()) != 0) {
252         LogError("Failed to rename " << m_srcBuPath << " to " << srcPath);
253     }
254 }
255
256 void TaskUpdateFiles::StepAbortExecFileBackup()
257 {
258     LogDebug("StepAbortExecFileBackup");
259     std::string binPath = m_pkgPath + "/" +
260         GlobalConfig::GetUserWidgetExecPath();
261
262     if(!_WrtUtilRemoveDir(binPath.c_str())) {
263         LogError("Failed to remove " << binPath);
264     }
265
266     if (rename(m_binBuPath.c_str(), binPath.c_str()) != 0) {
267         LogError("Failed to rename " << m_binBuPath << " to " << binPath);
268     }
269     LogDebug("Backup Folder " << m_binBuPath << "move to " << binPath);
270 }
271
272 void TaskUpdateFiles::StepAbortCreateBackupFolder()
273 {
274     LogDebug("StepAbortCreateBackupFolder");
275     std::ostringstream path;
276     path << m_context.locations->getBackupDir();
277     LogDebug("Remove backup directory : " << path.str());
278
279     if(!_WrtUtilRemoveDir(path.str().c_str())) {
280         LogError("Failed to remove " << path);
281     }
282 }
283 } //namespace WidgetInstall
284 } //namespace Jobs