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_db_update.cpp
18 * @author Lukasz Wrzosek(l.wrzosek@samsung.com)
20 * @brief Implementation file for installer task database updating
23 #include <widget_install/task_file_manipulation.h>
24 #include <widget_install/job_widget_install.h>
25 #include <widget_install/widget_install_errors.h>
26 #include <widget_install/widget_install_context.h>
27 #include <dpl/utils/wrt_utility.h>
28 #include <dpl/foreach.h>
29 #include <dpl/log/log.h>
30 #include <dpl/assert.h>
33 #define WEBAPP_DEFAULT_UID 5000
34 #define WEBAPP_DEFAULT_GID 5000
37 const mode_t PRIVATE_STORAGE_MODE = 0700;
38 const mode_t SHARE_MODE = 0705;
41 using namespace WrtDB;
44 namespace WidgetInstall {
45 TaskFileManipulation::TaskFileManipulation(InstallerContext& context) :
46 DPL::TaskDecl<TaskFileManipulation>(this),
49 AddStep(&TaskFileManipulation::StepCreateDirs);
50 AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir);
51 AddStep(&TaskFileManipulation::StepCreateShareDir);
52 if (m_context.widgetConfig.packagingType !=
53 WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
55 AddStep(&TaskFileManipulation::StepRenamePath);
56 AddAbortStep(&TaskFileManipulation::StepAbortRenamePath);
60 void TaskFileManipulation::StepCreateDirs()
62 std::string widgetPath;
63 DPL::OptionalString pkgname = m_context.widgetConfig.pkgname;
64 if (pkgname.IsNull()) {
65 ThrowMsg(Exceptions::InternalError, "No Package name exists.");
68 widgetPath = m_context.locations->getPackageInstallationDir();
70 std::string widgetBinPath = m_context.locations->getBinaryDir();
71 std::string widgetSrcPath = m_context.locations->getSourceDir();
73 WrtUtilMakeDir(widgetPath);
75 // If package type is widget with osp service, we don't need to make bin
77 if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) {
78 LogDebug("Doesn't need to create resource directory");
80 LogDebug("Create resource directory");
81 WrtUtilMakeDir(widgetBinPath);
82 WrtUtilMakeDir(widgetSrcPath);
85 m_context.job->UpdateProgress(
86 InstallerContext::INSTALL_DIR_CREATE,
87 "Widget Directory Created");
90 void TaskFileManipulation::StepCreatePrivateStorageDir()
92 std::string storagePath = m_context.locations->getPrivateStorageDir();
94 if (euidaccess(storagePath.c_str(), F_OK) != 0) {
95 if(!WrtUtilMakeDir(storagePath, PRIVATE_STORAGE_MODE)){
96 LogError("Failed to create directory for private storage");
97 ThrowMsg(Exceptions::InternalError,
98 "Failed to create directory for private storage");
100 // '5000' is default uid, gid for applications.
101 // So installed applications should be launched as process of uid '5000'.
102 // the process can access private directory 'data' of itself.
103 if(chown(storagePath.c_str(),
105 WEBAPP_DEFAULT_GID) != 0)
107 ThrowMsg(Exceptions::InternalError,
108 "Chown to invaild user");
110 } else if (euidaccess(storagePath.c_str(), W_OK | R_OK | X_OK) == 0) {
111 LogInfo("Private storage already exists.");
112 // Even if private directory already is created, private dircetory
113 // should change owner.
114 if(chown(storagePath.c_str(),
116 WEBAPP_DEFAULT_GID) != 0)
118 ThrowMsg(Exceptions::InternalError,
119 "Chown to invaild user");
121 if(chmod(storagePath.c_str(), PRIVATE_STORAGE_MODE) != 0) {
122 ThrowMsg(Exceptions::InternalError,
127 ThrowMsg(Exceptions::InternalError,
128 "No access to private storage.");
132 void TaskFileManipulation::StepCreateShareDir()
134 std::string sharePath = m_context.locations->getShareDir();
136 if (euidaccess(sharePath.c_str(), F_OK) != 0) {
137 if(!WrtUtilMakeDir(sharePath, SHARE_MODE)){
138 LogError("Failed to create directory for share");
139 ThrowMsg(Exceptions::InternalError,
140 "Failed to create directory for share");
142 // '5000' is default uid, gid for applications.
143 // So installed applications should be launched as process of uid '5000'.
144 // the process can access private directory 'data' of itself.
145 if(chown(sharePath.c_str(),
147 WEBAPP_DEFAULT_GID) != 0)
149 ThrowMsg(Exceptions::InternalError,
150 "Chown to invaild user");
152 } else if (euidaccess(sharePath.c_str(), W_OK | R_OK | X_OK) == 0) {
153 LogInfo("Share directory already exists.");
154 // Even if share directory already is created, share dircetory
155 // should change owner.
156 if(chown(sharePath.c_str(),
158 WEBAPP_DEFAULT_GID) != 0)
160 ThrowMsg(Exceptions::InternalError,
161 "Chown to invaild user");
163 if(chmod(sharePath.c_str(), SHARE_MODE) != 0) {
164 ThrowMsg(Exceptions::InternalError,
169 ThrowMsg(Exceptions::InternalError,
170 "No access to private storage.");
175 void TaskFileManipulation::StepRenamePath()
178 DPL::OptionalString pkgname = m_context.widgetConfig.pkgname;
179 if (pkgname.IsNull()) {
180 ThrowMsg(Exceptions::InternalError, "No Package name exists.");
183 if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) {
184 instDir = m_context.locations->getPackageInstallationDir();
186 instDir = m_context.locations->getSourceDir();
189 LogDebug("Copy file from temp directory to " << instDir);
190 if (!WrtUtilRemove(instDir)) {
191 ThrowMsg(Exceptions::RemovingFolderFailure,
192 "Error occurs during removing existing folder");
195 if (!(rename(m_context.locations->getTemporaryPackageDir().c_str(), instDir.c_str()) == 0)) {
196 ThrowMsg(Exceptions::UnknownError,
197 "Error occurs during renaming widget folder");
199 m_context.job->UpdateProgress(
200 InstallerContext::INSTALL_RENAME_PATH,
201 "Widget Rename path Finished");
204 void TaskFileManipulation::StepAbortRenamePath()
206 LogDebug("[Rename Widget Path] Aborting.... (Rename path)");
207 std::string widgetPath;
208 if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) {
209 widgetPath = m_context.locations->getPackageInstallationDir();
211 widgetPath = m_context.locations->getSourceDir();
213 struct stat fileInfo;
214 if (stat(widgetPath.c_str(), &fileInfo) != 0) {
215 LogError("Failed to get widget file path : " << widgetPath);
219 if (!(rename(widgetPath.c_str(), m_context.locations->getTemporaryPackageDir().c_str()) == 0)) {
220 LogError("Failed to rename");
222 LogDebug("Rename widget path sucessful!");
224 } //namespace WidgetInstall