Use GList in manifest_x structures
[platform/core/appfw/app-installers.git] / src / tpk / step / step_create_symbolic_link.cc
1 /* Copyright 2015 Samsung Electronics, license APACHE-2.0, see LICENSE file */
2 #include "tpk/step/step_create_symbolic_link.h"
3 #include <boost/filesystem.hpp>
4 #include <boost/system/error_code.hpp>
5 #include <pkgmgr-info.h>
6
7 #include <iostream>
8
9 #include "common/step/step.h"
10 #include "common/app_installer.h"
11 #include "common/installer_context.h"
12 #include "common/utils/file_util.h"
13 #include "common/utils/glist_range.h"
14 #include "common/utils/logging.h"
15
16 namespace tpk {
17 namespace filesystem {
18
19 namespace bf = boost::filesystem;
20 using common_installer::InstallerContext;
21 typedef common_installer::Step::Status Status;
22
23 namespace {
24
25 bool CreateSymLink(application_x* app, InstallerContext* context) {
26   boost::system::error_code boost_error;
27   bf::path bindir = context->pkg_path.get() /
28       bf::path("bin");
29   LOG(DEBUG) << "Creating dir: " << bindir;
30   if (!common_installer::CreateDir(bindir)) {
31     LOG(ERROR) << "Directory creation failure: " << bindir;
32     return false;
33   }
34
35   // Exec path
36   // Make a symlink with the name of appid, pointing exec file
37   bf::path symlink_path = bindir / bf::path(app->appid);
38   LOG(DEBUG) << "Creating symlink " << symlink_path << " pointing " <<
39       app->exec;
40   bf::create_symlink(bf::path(app->exec), symlink_path, boost_error);
41   if (boost_error) {
42     LOG(ERROR) << "Symlink creation failure: " << symlink_path;
43     return false;
44   }
45
46   // Give an execution permission to the original executable
47   bf::path exec_path = bindir / bf::path(app->exec);
48   LOG(DEBUG) << "Giving exec permission to " << exec_path;
49   bf::permissions(exec_path, bf::owner_all |
50       bf::group_read | bf::group_exe |
51       bf::others_read | bf::others_exe, boost_error);
52   if (boost_error) {
53     LOG(ERROR) << "Permission change failure";
54     return false;
55   }
56   return true;
57 }
58
59 bool RemoveSymLink(application_x* app, InstallerContext* context) {
60   /* NOTE: Unlike WRT app, tpk apps have bin/ directory by default.
61    * So we don't remove the bin/ directory.
62    */
63   bf::path exec_path = bf::path(context->pkg_path.get()) / bf::path("bin");
64   bf::remove_all(exec_path / bf::path(app->appid));
65   return true;
66 }
67
68 }  // namespace
69
70 Status StepCreateSymbolicLink::precheck() {
71   manifest_x *m = context_->manifest_data.get();
72   if (!m) {
73     LOG(ERROR) << "manifest_data attribute is empty";
74     return Step::Status::INVALID_VALUE;
75   }
76   if (!m->application) {
77     LOG(ERROR) << "No application exists";
78     return Step::Status::ERROR;
79   }
80
81   return Step::Status::OK;
82 }
83
84 Status StepCreateSymbolicLink::process() {
85   manifest_x* m = context_->manifest_data.get();
86   for (application_x* app : GListRange<application_x*>(m->application)) {
87     if (!CreateSymLink(app, context_))
88       return Status::ERROR;
89   }
90   return Status::OK;
91 }
92
93
94 Status StepCreateSymbolicLink::undo() {
95   manifest_x* m = context_->manifest_data.get();
96   Step::Status ret = Status::OK;
97   for (application_x* app : GListRange<application_x*>(m->application)) {
98     if (!CreateSymLink(app, context_))
99       ret = Status::ERROR;
100   }
101   return ret;
102 }
103
104 }  // namespace filesystem
105 }  // namespace tpk