0ab5ee32182b7ec86bdb320b28301c8a3d3ea00d
[framework/web/wrt-installer.git] / src / jobs / widget_install / task_file_manipulation.cpp
1 /*
2  * Copyright (c) 2010 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_db_update.cpp
18  * @author  Lukasz Wrzosek(l.wrzosek@samsung.com)
19  * @version 1.0
20  * @brief   Implementation file for installer task database updating
21  */
22 #include <unistd.h>
23 #include <sys/stat.h>
24 #include <dirent.h>
25 #include <widget_install/task_file_manipulation.h>
26 #include <widget_install/job_widget_install.h>
27 #include <widget_install/widget_install_errors.h>
28 #include <widget_install/widget_install_context.h>
29 #include <widget_install/directory_api.h>
30 #include <dpl/utils/wrt_utility.h>
31 #include <dpl/foreach.h>
32 #include <dpl/assert.h>
33 #include <dpl/errno_string.h>
34 #include <dpl/utils/folder_size.h>
35 #include <dpl/wrt-dao-ro/global_config.h>
36 #include <string>
37 #include <fstream>
38 #include <widget_install_to_external.h>
39 #include <installer_log.h>
40 #include <widget_unzip.h>
41
42 #define WEBAPP_DEFAULT_UID  5000
43 #define WEBAPP_DEFAULT_GID  5000
44
45 namespace {
46 const mode_t PRIVATE_STORAGE_MODE = 0700;
47 const mode_t SHARED_STORAGE_MODE = 0755;
48 }
49
50 using namespace WrtDB;
51
52 namespace {
53 const char* GLIST_RES_DIR = "res";
54
55 bool _FolderCopy(std::string source, std::string dest)
56 {
57     DIR* dir = opendir(source.c_str());
58     if (NULL == dir) {
59         return false;
60     }
61
62     struct dirent dEntry;
63     struct dirent *dEntryResult;
64     int return_code;
65
66     do {
67         struct stat statInfo;
68         return_code = readdir_r(dir, &dEntry, &dEntryResult);
69         if (dEntryResult != NULL && return_code == 0) {
70             std::string fileName = dEntry.d_name;
71             std::string fullName = source + "/" + fileName;
72
73             if (stat(fullName.c_str(), &statInfo) != 0) {
74                 closedir(dir);
75                 return false;
76             }
77
78             if (S_ISDIR(statInfo.st_mode)) {
79                 if (("." == fileName) || (".." == fileName)) {
80                     continue;
81                 }
82                 std::string destFolder = dest + "/" + fileName;
83                 WrtUtilMakeDir(destFolder);
84
85                 if (!_FolderCopy(fullName, destFolder)) {
86                     closedir(dir);
87                     return false;
88                 }
89             }
90
91             std::string destFile = dest + "/" + fileName;
92             std::ifstream infile(fullName);
93             std::ofstream outfile(destFile);
94             outfile << infile.rdbuf();
95             outfile.close();
96             infile.close();
97         }
98     } while (dEntryResult != NULL && return_code == 0);
99     closedir(dir);
100     return true;
101 }
102 }
103
104 namespace Jobs {
105 namespace WidgetInstall {
106 TaskFileManipulation::TaskFileManipulation(InstallerContext& context) :
107     DPL::TaskDecl<TaskFileManipulation>(this),
108     m_context(context),
109     m_extHandle(NULL)
110 {
111     AddStep(&TaskFileManipulation::StartStep);
112     if (INSTALL_LOCATION_TYPE_EXTERNAL !=
113             m_context.locationType)
114     {
115         AddStep(&TaskFileManipulation::StepCreateDirs);
116         if (m_context.mode.extension != InstallMode::ExtensionType::DIR)
117         {
118             AddStep(&TaskFileManipulation::StepUnzipWgtFile);
119             AddAbortStep(&TaskFileManipulation::StepAbortRenamePath);
120         }
121     } else {
122         AddStep(&TaskFileManipulation::StepPrepareExternalDir);
123         AddStep(&TaskFileManipulation::StepInstallToExternal);
124
125         AddAbortStep(&TaskFileManipulation::StepAbortCreateExternalDir);
126     }
127     AddStep(&TaskFileManipulation::EndStep);
128 }
129
130 void TaskFileManipulation::StepCreateDirs()
131 {
132     std::string widgetPath;
133
134     widgetPath = m_context.locations->getPackageInstallationDir();
135
136     std::string widgetBinPath = m_context.locations->getBinaryDir();
137     std::string widgetSrcPath = m_context.locations->getSourceDir();
138
139     WrtUtilMakeDir(widgetPath);
140
141     // If package type is widget with osp service, we don't need to make bin
142     // and src directory
143     if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) {
144         _D("Doesn't need to create resource directory");
145     } else {
146         _D("Create resource directory");
147         WrtUtilMakeDir(widgetBinPath);
148         WrtUtilMakeDir(widgetSrcPath);
149         if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD) {
150             std::string userWidgetDir = m_context.locations->getUserDataRootDir();
151             WrtUtilMakeDir(userWidgetDir);
152         }
153     }
154
155     m_context.job->UpdateProgress(
156         InstallerContext::INSTALL_DIR_CREATE,
157         "Widget Directory Created");
158 }
159
160 void TaskFileManipulation::StepUnzipWgtFile()
161 {
162     if (m_context.widgetConfig.packagingType != PKG_TYPE_HOSTED_WEB_APP) {
163         std::string instDir;
164         if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) {
165             instDir = m_context.locations->getPackageInstallationDir();
166         } else {
167             instDir = m_context.locations->getSourceDir();
168         }
169
170         _D("unzip file to %s", instDir.c_str());
171
172         WidgetUnzip wgtUnzip;
173         wgtUnzip.unzipWgtFile(m_context.requestedPath, instDir);
174     } else {
175         _D("From browser installation - unzip is not done");
176     }
177
178     m_context.job->UpdateProgress(
179         InstallerContext::INSTALL_UNZIP_WGT,
180         "Unzip WGT File");
181 }
182
183 /* TODO :  modify name */
184 void TaskFileManipulation::StepAbortRenamePath()
185 {
186     _D("[Rename Widget Path] Aborting.... (Rename path)");
187     std::string widgetPath;
188     widgetPath = m_context.locations->getPackageInstallationDir();
189     if (!WrtUtilRemove(widgetPath)) {
190         _E("Error occurs during removing existing folder");
191     }
192     // Remove user data directory if preload web app.
193     std::string userData = m_context.locations->getUserDataRootDir();
194     if (0 == access(userData.c_str(), F_OK)) {
195         if (!WrtUtilRemove(userData)) {
196             _E("Error occurs during removing user data directory");
197         }
198     }
199
200     _D("Rename widget path sucessful!");
201 }
202
203 void TaskFileManipulation::StepPrepareExternalDir()
204 {
205     _D("Step prepare to install in exernal directory");
206     Try {
207         std::string pkgid =
208             DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
209
210         WidgetInstallToExtSingleton::Instance().initialize(pkgid);
211
212         size_t totalSize =
213             Utils::getFolderSize(m_context.locations->getTemporaryPackageDir());
214
215         int folderSize = (int)(totalSize / (1024 * 1024)) + 1;
216
217         GList *list = NULL;
218         app2ext_dir_details* dirDetail = NULL;
219
220         dirDetail = (app2ext_dir_details*) calloc(1,
221                 sizeof(
222                     app2ext_dir_details));
223         if (NULL == dirDetail) {
224             ThrowMsg(Exceptions::ErrorExternalInstallingFailure,
225                     "error in app2ext");
226         }
227         dirDetail->name = strdup(GLIST_RES_DIR);
228         dirDetail->type = APP2EXT_DIR_RO;
229         list = g_list_append(list, dirDetail);
230
231         if (m_context.isUpdateMode) {
232             WidgetInstallToExtSingleton::Instance().preUpgrade(list,
233                                                                folderSize);
234         } else {
235             WidgetInstallToExtSingleton::Instance().preInstallation(list,
236                                                                     folderSize);
237         }
238         free(dirDetail);
239         g_list_free(list);
240
241         /* make bin directory */
242         std::string widgetBinPath = m_context.locations->getBinaryDir();
243         WrtUtilMakeDir(widgetBinPath);
244     }
245     Catch(WidgetInstallToExt::Exception::ErrorInstallToExt)
246     {
247         ReThrowMsg(Exceptions::ErrorExternalInstallingFailure,
248                    "Error during \
249                 create external folder ");
250     }
251 }
252
253 void TaskFileManipulation::StepInstallToExternal()
254 {
255     _D("StepInstallExternal");
256     if (!WrtUtilMakeDir(m_context.locations->getSourceDir())) {
257         ThrowMsg(Exceptions::ErrorExternalInstallingFailure,
258                  "To make src \
259                 directory failed");
260     }
261
262     _D("Resource move to external storage %s", m_context.locations->getSourceDir().c_str());
263     if (!_FolderCopy(m_context.locations->getTemporaryPackageDir(),
264                      m_context.locations->getSourceDir()))
265     {
266         ThrowMsg(Exceptions::ErrorExternalInstallingFailure,
267                  "Error occurs during renaming widget folder");
268     }
269 }
270
271 void TaskFileManipulation::StepAbortCreateExternalDir()
272 {
273     _E("Abort StepAbortCreateExternalDir");
274     if (m_context.isUpdateMode) {
275         WidgetInstallToExtSingleton::Instance().postUpgrade(false);
276     } else {
277         WidgetInstallToExtSingleton::Instance().postInstallation(false);
278     }
279     WidgetInstallToExtSingleton::Instance().deinitialize();
280 }
281
282 void TaskFileManipulation::StartStep()
283 {
284     _D("--------- <TaskFileManipulation> : START ----------");
285 }
286
287 void TaskFileManipulation::EndStep()
288 {
289     _D("--------- <TaskFileManipulation> : END ----------");
290 }
291 } //namespace WidgetInstall
292 } //namespace Jobs