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_update_files.cpp
18 * @author Soyoung Kim (sy037.kim@samsung.com)
20 * @brief Implementation file for installer task update files
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>
36 #include <widget_install/widget_install_context.h>
37 #include <widget_install/widget_install_errors.h>
38 #include <widget_install/job_widget_install.h>
40 #include <dpl/wrt-dao-rw/widget_dao.h>
41 #include <dpl/wrt-dao-ro/global_config.h>
42 #include <dpl/exception.h>
43 #include <dpl/errno_string.h>
45 using namespace WrtDB;
49 inline const char* GetWidgetBackupDirPath()
56 namespace WidgetInstall {
58 TaskUpdateFiles::TaskUpdateFiles(InstallerContext& context) :
59 DPL::TaskDecl<TaskUpdateFiles>(this),
62 AddStep(&TaskUpdateFiles::StepCreateBackupFolder);
63 AddStep(&TaskUpdateFiles::StepResourceFilesBackup);
64 AddStep(&TaskUpdateFiles::StepExecFileBackup);
65 AddStep(&TaskUpdateFiles::StepUpdateExternalFiles);
67 AddAbortStep(&TaskUpdateFiles::StepAbortCreateBackupFolder);
68 AddAbortStep(&TaskUpdateFiles::StepAbortExecFileBackup);
69 AddAbortStep(&TaskUpdateFiles::StepAbortResourceFilesBackup);
72 void TaskUpdateFiles::StepCreateBackupFolder()
74 LogDebug("StepCreateBackupFolder");
75 std::ostringstream backDirPath;
77 std::string srcBuPath = m_context.locations->getBackupSourceDir();
78 LogDebug("backup resource directory path : " << srcBuPath);
79 if(!WrtUtilMakeDir(srcBuPath)) {
80 ThrowMsg(Exceptions::BackupFailed, "Error occurs during create \
84 std::string binBuPath = m_context.locations->getBackupBinaryDir();
85 LogDebug("backup execution directory path : " << binBuPath);
86 if(!WrtUtilMakeDir(binBuPath)) {
87 ThrowMsg(Exceptions::BackupFailed, "Error occurs during create backup \
91 m_context.job->UpdateProgress(
92 InstallerContext::INSTALL_CREATE_BACKUP_DIR,
93 "Backup directory created for update");
96 void TaskUpdateFiles::ReadDirList(std::string dirPath, ExistFileList &list,
99 DIR* pkgDir = opendir(dirPath.c_str());
101 LogError("Package directory " << dirPath << " doesn't exist");
102 ThrowMsg(Exceptions::InternalError, "Error occurs during read \
106 struct dirent* dirent;
107 struct stat statInfo;
109 if ((dirent = readdir(pkgDir))) {
110 std::string dirName = dirent->d_name;
111 std::string absFileName = dirPath + "/" + dirName;
112 if (stat(absFileName.c_str(), &statInfo) != 0) {
113 ThrowMsg(Exceptions::InternalError, "Error occurs read file");
116 if (S_ISDIR(statInfo.st_mode)) {
117 if(strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name,
121 ReadDirList(absFileName, list, subLen);
124 list.insert(absFileName.substr(subLen));
128 //closing the directory
129 if (-1 == TEMP_FAILURE_RETRY(closedir(pkgDir))) {
130 LogError("Failed to close dir: " << dirPath << " with error: "
131 << DPL::GetErrnoString());
135 void TaskUpdateFiles::StepResourceFilesBackup()
137 LogDebug("StepCopyFiles");
139 ExistFileList resList;
140 ExistFileList tempList;
142 std::string pkgSrc = m_context.locations->getSourceDir();
143 ReadDirList(pkgSrc, resList, strlen(pkgSrc.c_str())+1);
146 std::string tempSrc = m_context.locations->getTemporaryPackageDir();
147 ReadDirList(tempSrc, tempList, strlen(tempSrc.c_str())+1);
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);
155 if (res != resList.end()) {
156 std::string backupFile = m_context.locations->getBackupSourceDir() +
160 if (stat(resFile.c_str(), &sInfo) != 0) {
161 ThrowMsg(Exceptions::InternalError, "Error occurs read file");
164 if (S_ISDIR(sInfo.st_mode)) {
165 LogDebug(resFile << " is a directory. so create a folder : " <<
167 WrtUtilMakeDir(backupFile);
169 if ((rename(resFile.c_str(), backupFile.c_str())) != 0) {
170 LogError("Failed to rename " << resFile << " to " << backupFile);
171 ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
175 LogDebug("backup : " << resFile << " to " << backupFile);
177 if ((rename(newFile.c_str(), resFile.c_str())) != 0) {
178 LogError("Failed to rename " << newFile << " to " << resFile);
179 ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
182 LogDebug("copy : " << newFile << " to " << resFile);
186 if ((rename(newFile.c_str(), resFile.c_str())) != 0) {
187 LogError("Failed to rename " << newFile << " to " << resFile);
188 ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
191 LogDebug("only copy : " << newFile << " to " << resFile);
195 if (resList.empty() != 0) {
196 FOREACH(remain, resList) {
197 std::string pkgFile = pkgSrc + "/" + (*remain);
198 std::string backFile = tempSrc + "/" + (*remain);
199 if ((rename(pkgFile.c_str(), backFile.c_str())) != 0) {
200 LogError("Failed to backup : " << pkgFile << " to " << backFile);
201 ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
204 LogDebug("only backup : " << pkgFile << " to " << backFile);
208 m_context.job->UpdateProgress(
209 InstallerContext::INSTALL_BACKUP_RES_FILES,
210 "Backup resource file for update");
213 void TaskUpdateFiles::StepExecFileBackup()
215 std::string execFile = m_context.locations->getExecFile();
217 LogDebug(" source : " << execFile);
219 std::string tempSource= m_context.locations->getBackupExecFile();
220 LogDebug(" source : " << tempSource);
222 if ((rename(execFile.c_str(), tempSource.c_str())) != 0) {
223 LogError("Failed to rename " << execFile << " to " <<
225 ThrowMsg(Exceptions::BackupFailed, "Error occurs during \
228 LogDebug("Backup : " << execFile << " to " << tempSource);
230 std::string clientPath = GlobalConfig::GetWrtClientExec();
232 LogInfo("link -s " << clientPath << " " << execFile);
233 symlink(clientPath.c_str(), execFile.c_str());
235 m_context.job->UpdateProgress(
236 InstallerContext::INSTALL_BACKUP_EXEC,
237 "Backup execution file for update");
240 void TaskUpdateFiles::StepAbortResourceFilesBackup()
242 LogDebug("StepAbortCopyFiles");
243 std::string srcPath = m_context.locations->getSourceDir();
244 std::string srcBuPath = m_context.locations->getBackupSourceDir();
246 LogDebug("Backup Folder " << srcBuPath << " to " << srcPath);
248 if(!WrtUtilRemove(srcPath)) {
249 LogError("Failed to remove " << srcPath);
252 if (rename(srcBuPath.c_str(), srcPath.c_str()) != 0) {
253 LogError("Failed to rename " << srcBuPath << " to " << srcPath);
257 void TaskUpdateFiles::StepAbortExecFileBackup()
259 LogDebug("StepAbortExecFileBackup");
260 std::string binPath = m_context.locations->getBinaryDir();
262 if(!WrtUtilRemove(binPath)) {
263 LogError("Failed to remove " << binPath);
266 std::string binBuPath = m_context.locations->getBackupBinaryDir();
267 if (rename(binBuPath.c_str(), binPath.c_str()) != 0) {
268 LogError("Failed to rename " << binBuPath << " to " << binPath);
270 LogDebug("Backup Folder " << binBuPath << "move to " << binPath);
273 void TaskUpdateFiles::StepAbortCreateBackupFolder()
275 LogDebug("StepAbortCreateBackupFolder");
276 std::ostringstream path;
277 path << m_context.locations->getBackupDir();
278 LogDebug("Remove backup directory : " << path.str());
280 if(!WrtUtilRemove(path.str())) {
281 LogError("Failed to remove " << path);
285 void TaskUpdateFiles::StepUpdateExternalFiles()
287 WidgetDAO dao(m_context.locations->getPkgname());
288 WrtDB::ExternalLocationList externalLocationsUpdate = m_context.locations->listExternalLocations();
289 WrtDB::ExternalLocationList externalLocationsDB = dao.getWidgetExternalLocations();
290 LogDebug("Removing external files:");
291 FOREACH(file, externalLocationsDB)
293 if(std::find(externalLocationsUpdate.begin(), externalLocationsUpdate.end(), *file) == externalLocationsUpdate.end())
295 if(WrtUtilFileExists(*file))
297 LogDebug(" -> " << *file);
298 remove(file->c_str());
300 else if(WrtUtilDirExists(*file))
302 LogDebug(" -> " << *file);
303 if(!WrtUtilRemove(*file)){
304 ThrowMsg(Exceptions::RemovingFolderFailure,
305 "Failed to remove external directory");
310 LogWarning(" -> " << *file << "(no such a path)");
314 dao.unregisterAllExternalLocations();
315 LogDebug("Registering(update) external files:");
316 FOREACH(file, externalLocationsUpdate)
318 LogDebug(" -> " << *file);
320 dao.registerExternalLocations(externalLocationsUpdate);
323 } //namespace WidgetInstall