symlink control for read-only files of global app.
[platform/core/appfw/wgt-backend.git] / src / wgt / wgt_app_query_interface.cc
1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "wgt/wgt_app_query_interface.h"
6
7 #include <unistd.h>
8 #include <sys/types.h>
9
10 #include <boost/filesystem/operations.hpp>
11 #include <boost/filesystem/path.hpp>
12 #include <boost/system/error_code.hpp>
13
14 #include <common/pkgmgr_query.h>
15 #include <common/recovery_file.h>
16 #include <common/request.h>
17 #include <common/utils/file_util.h>
18
19 #include <manifest_parser/manifest_parser.h>
20 #include <manifest_parser/utils/logging.h>
21 #include <wgt_manifest_handlers/application_manifest_constants.h>
22 #include <wgt_manifest_handlers/tizen_application_handler.h>
23 #include <wgt_manifest_handlers/widget_handler.h>
24
25 #include <memory>
26 #include <string>
27 #include <vector>
28
29
30 namespace bf = boost::filesystem;
31 namespace bs = boost::system;
32 namespace ci = common_installer;
33
34 namespace {
35
36 const char kHybridConfigLocation[] = "res/wgt/config.xml";
37 const char kTizenManifestLocation[] = "tizen-manifest.xml";
38
39 uid_t GetUid(int argc, char** argv) {
40   uid_t uid = 0;
41   for (int i = 0; i < argc; ++i) {
42     if (!strcmp(argv[i], "-u")) {
43       if (i + 1 < argc) {
44         uid = atoi(argv[i + 1]);
45         break;
46       }
47     }
48   }
49
50   return uid;
51 }
52
53 std::string GetInstallationRequestInfo(int argc, char** argv) {
54   std::string path;
55   for (int i = 0; i < argc; ++i) {
56     if (!strcmp(argv[i], "-i") || !strcmp(argv[i], "-r") ||
57         !strcmp(argv[i], "-d") || !strcmp(argv[i], "-b") ||
58         !strcmp(argv[i], "-w") || !strcmp(argv[i], "-y")) {
59       if (i + 1 < argc) {
60         path = argv[i + 1];
61         break;
62       }
63     }
64   }
65   return path;
66 }
67
68 std::string GetPkgIdFromPath(const std::string& path) {
69   if (!bf::exists(path))
70     return {};
71   bf::path tmp_path = common_installer::GenerateTmpDir("/tmp");
72   bs::error_code code;
73   bf::create_directories(tmp_path, code);
74   if (code)
75     return {};
76   if (!common_installer::ExtractToTmpDir(path.c_str(), tmp_path,
77       "config.xml")) {
78     bf::remove_all(tmp_path, code);
79     return {};
80   }
81   bf::path config_path = tmp_path / "config.xml";
82   std::vector<std::shared_ptr<parser::ManifestHandler>> handlers = {
83     std::make_shared<wgt::parse::WidgetHandler>(),
84     std::make_shared<wgt::parse::TizenApplicationHandler>()
85   };
86   std::unique_ptr<parser::ManifestHandlerRegistry> registry(
87       new parser::ManifestHandlerRegistry(handlers));
88   std::unique_ptr<parser::ManifestParser> parser(
89       new parser::ManifestParser(std::move(registry)));
90   if (!parser->ParseManifest(config_path)) {
91     bf::remove_all(tmp_path, code);
92     return {};
93   }
94   auto info = std::static_pointer_cast<const wgt::parse::TizenApplicationInfo>(
95       parser->GetManifestData(
96           wgt::application_widget_keys::kTizenApplicationKey));
97   if (!info) {
98     bf::remove_all(tmp_path, code);
99     return {};
100   }
101   std::string pkg_id = info->package();
102
103   bf::remove_all(tmp_path, code);
104   return pkg_id;
105 }
106
107 std::string ReadPkgidFromRecovery(const std::string& recovery_path) {
108   std::unique_ptr<ci::recovery::RecoveryFile> recovery_file =
109       ci::recovery::RecoveryFile::OpenRecoveryFileForPath(recovery_path);
110   recovery_file->Detach();
111   return recovery_file->pkgid();
112 }
113
114 }  // namespace
115
116 namespace wgt {
117
118 bool WgtAppQueryInterface::IsAppInstalledByArgv(int argc, char** argv) {
119   std::string arg = GetInstallationRequestInfo(argc, argv);
120   if (arg.empty())
121     return false;
122
123   uid_t uid = GetUid(argc, argv);
124   // argument from commandline is package id
125   if (ci::QueryIsPackageInstalled(arg, ci::GetRequestMode(uid), uid))
126     return true;
127
128   // argument from commandline is path to file
129   std::string pkg_id = GetPkgIdFromPath(arg);
130   if (pkg_id.empty())
131     return false;
132   return ci::QueryIsPackageInstalled(pkg_id, ci::GetRequestMode(uid), uid);
133 }
134
135 bool WgtAppQueryInterface::IsHybridApplication(int argc, char** argv) {
136   std::string arg = GetInstallationRequestInfo(argc, argv);
137   if (arg.find("apps_rw/recovery-") != std::string::npos)
138     arg = ReadPkgidFromRecovery(arg);
139
140   uid_t uid = GetUid(argc, argv);
141   if (ci::QueryIsPackageInstalled(arg, ci::GetRequestMode(uid), uid)) {
142     bf::path package_directory(ci::GetRootAppPath(false, uid));
143     if (bf::exists(package_directory / arg / kTizenManifestLocation) &&
144         bf::exists(package_directory / arg / kHybridConfigLocation))
145       return true;
146   } else {
147     bool tizen_manifest_found = false;
148     bool config_xml_found = false;
149     if (!ci::CheckPathInZipArchive(arg.c_str(), kTizenManifestLocation,
150                                    &tizen_manifest_found))
151       return false;
152     if (!ci::CheckPathInZipArchive(arg.c_str(), kHybridConfigLocation,
153                                    &config_xml_found))
154       return false;
155     if (tizen_manifest_found && config_xml_found)
156       return true;
157   }
158   return false;
159 }
160
161 }  // namespace wgt