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_remove_files.cpp
18 * @author Lukasz Wrzosek(l.wrzosek@samsung.com)
20 * @brief Implementation file for uninstaller task for removing widget files
23 #include <widget_uninstall/task_remove_files.h>
24 #include <widget_uninstall/job_widget_uninstall.h>
25 #include <widget_uninstall/uninstaller_context.h>
26 #include <dpl/wrt-dao-rw/widget_dao.h>
27 #include <dpl/wrt-dao-ro/widget_config.h>
29 #include <dpl/assert.h>
30 #include <dpl/utils/wrt_utility.h>
31 #include <sys/types.h>
36 #include <dpl/utils/wrt_utility.h>
37 #include <pkgmgr/pkgmgr_parser.h>
40 namespace WidgetUninstall {
42 using namespace WrtDB;
44 void TaskRemoveFiles::ReadDir(const std::string& path,
45 std::list<std::string>& filesList)
47 LogInfo("Reading directory " << path);
49 struct dirent* ptr = NULL;
50 dir = opendir(path.c_str());
51 std::string delim = "";
53 // adding / for path to directory to build a proper path to file under directory
54 if (path[path.size() - 1] != '/') {
59 while ((ptr = readdir(dir)) != NULL) {
60 if ((!strcmp(ptr->d_name, ".")) || (!strcmp(ptr->d_name, ".."))) {
61 LogPedantic("Omiting " << ptr->d_name);
64 std::string childPath = path + delim + ptr->d_name;
67 if (0 != lstat(childPath.c_str(), &st)) {
71 "EACCESS Error occured during lstat with path: " <<
76 "EBADF Error occured during lstat with path: " <<
81 "ENOENT Error occured during lstat with path: " <<
86 "ENOTDIR Error occured during lstat with path: " <<
91 "Unknown Error occured during lstat with path: " <<
96 if (S_ISDIR(st.st_mode)) {
98 "Calling ReadDir in recursive way " << childPath);
99 ReadDir(childPath, filesList);
100 } else if (S_ISREG(st.st_mode) ||
101 S_ISCHR(st.st_mode) ||
102 S_ISBLK(st.st_mode) ||
103 S_ISFIFO(st.st_mode) ||
104 S_ISLNK(st.st_mode) ||
105 S_ISSOCK(st.st_mode)) {
106 LogPedantic("Adding to list " << childPath);
107 filesList.push_front(childPath);
109 LogWarning("Uknown file type ??");
114 } else if (errno == ENOTDIR) {
115 LogDebug("Adding to list " << path);
116 filesList.push_front(path);
118 LogWarning("Unknown error");
122 TaskRemoveFiles::TaskRemoveFiles(UninstallerContext& context) :
123 DPL::TaskDecl<TaskRemoveFiles>(this),
126 AddStep(&TaskRemoveFiles::StepPrepare);
127 AddStep(&TaskRemoveFiles::StepRemoveOneFile);
128 AddStep(&TaskRemoveFiles::StepRemoveDirectories);
129 //AddStep(&TaskRemoveFiles::StepRemoveDesktop);
130 AddStep(&TaskRemoveFiles::StepRemoveManifest);
131 AddStep(&TaskRemoveFiles::StepRemoveExternalLocations);
132 AddStep(&TaskRemoveFiles::StepRemoveFinished);
135 TaskRemoveFiles::~TaskRemoveFiles()
139 void TaskRemoveFiles::StepPrepare()
141 LogInfo("StepPrepare started");
143 std::ostringstream widgetDir;
145 widgetDir << m_context.locations->getPackageInstallationDir() << "/";
147 uninstRootDir = widgetDir.str();
148 ReadDir(uninstRootDir, filesList);
150 LogInfo("StepPrepare finished");
152 m_context.job->UpdateProgress(
153 UninstallerContext::UNINSTALL_REMOVE_PREPARE,
154 "Widget remove prepare Finished");
155 m_context.removeStarted = true;
158 void TaskRemoveFiles::StepRemoveOneFile()
160 if (filesList.size() > 0) {
161 LogDebug("Removing " << filesList.front());
162 if (0 != unlink(filesList.front().c_str())) {
163 LogWarning("Failed to remove file" << filesList.front());
165 filesList.pop_front();
166 SwitchToStep(&TaskRemoveFiles::StepRemoveOneFile);
168 m_context.removeFinished = true;
171 m_context.job->UpdateProgress(
172 UninstallerContext::UNINSTALL_REMOVE_ONEFILE,
173 "Widget remove onefile Finished");
176 void TaskRemoveFiles::StepRemoveDirectories()
178 using namespace WrtDB;
179 LogInfo("StepRemoveDirectories started");
181 if (!WrtUtilRemove(uninstRootDir)) {
182 LogWarning("Failed to remove directory" << uninstRootDir);
184 LogInfo("StepRemoveDirectories finished");
186 m_context.job->UpdateProgress(
187 UninstallerContext::UNINSTALL_REMOVE_DIRECTORIES,
188 "Widget remove directories Finished");
191 void TaskRemoveFiles::StepRemoveFinished()
193 LogInfo("StepRemoveFinished finished");
195 m_context.job->UpdateProgress(
196 UninstallerContext::UNINSTALL_REMOVE_FINISHED,
197 "Widget remove steps Finished");
200 void TaskRemoveFiles::StepRemoveDesktop()
202 std::ostringstream desktopFile;
204 desktopFile << GlobalConfig::GetUserWidgetDesktopPath() << "/";
205 desktopFile << m_context.pkgname << ".desktop";
207 unlink(desktopFile.str().c_str());
209 ail_appinfo_h ai = NULL;
212 const char* package = m_context.pkgname.c_str();
213 LogDebug("ail delete : " << package);
215 ret = ail_package_get_appinfo(package, &ai);
217 ail_package_destroy_appinfo(ai);
220 if (AIL_ERROR_OK == ret) {
221 if ( 0 > ail_desktop_remove(package)) {
222 LogWarning("Failed to remove ail information : " << package);
226 m_context.job->UpdateProgress(
227 UninstallerContext::UNINSTALL_REMOVE_DESKTOP,
228 "Widget remove desktop Finished");
231 void TaskRemoveFiles::StepRemoveManifest()
233 std::ostringstream manifest_name;
234 manifest_name << m_context.pkgname << ".xml";
235 std::ostringstream destFile;
236 destFile << "/opt/share/packages" << "/"; //TODO constant with path
237 destFile << manifest_name.str();
238 int ret1 = pkgmgr_parser_parse_manifest_for_uninstallation(destFile.str().c_str(), NULL);
239 int ret2 = unlink(destFile.str().c_str());
242 LogWarning("Manifest file failed to parse for uninstallation");
246 LogWarning("No manifest file found: " << destFile.str());
250 LogDebug("Manifest file removed: " << destFile.str());
254 void TaskRemoveFiles::StepRemoveExternalLocations()
256 WidgetDAO dao(m_context.widgetHandle);
257 LogDebug("Removing external locations:");
258 WrtDB::ExternalLocationList externalPaths = dao.getWidgetExternalLocations();
259 FOREACH(path, externalPaths)
261 if(WrtUtilFileExists(*path))
263 LogDebug(" -> " << *path);
264 remove(path->c_str());
266 else if(WrtUtilDirExists(*path))
268 LogDebug(" -> " << *path);
269 if(!WrtUtilRemove(*path)){
270 Throw(Jobs::WidgetUninstall::TaskRemoveFiles::Exception::RemoveFilesFailed);
275 LogWarning(" -> " << *path << "(no such a path)");
278 dao.unregisterAllExternalLocations();
281 } //namespace WidgetUninstall