6792e1f6aed17e15f4b7fc071a6957addd7fe96b
[platform/core/appfw/rpk-installer.git] / src / rpk / step / pkgmgr / step_rpk_manifest_adjustment.cc
1 // Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "rpk/step/pkgmgr/step_rpk_manifest_adjustment.h"
6
7 #include <pkgmgr-info.h>
8
9 #include <boost/filesystem/path.hpp>
10 #include <boost/filesystem/operations.hpp>
11 #include <libxml/parser.h>
12 #include <libxml/tree.h>
13 #include <libxml/xpath.h>
14 #include <libxml/xpathInternals.h>
15 #include <string>
16 #include <type_traits>
17
18 #include "common/installer_context.h"
19
20 namespace bs = boost::system;
21 namespace bf = boost::filesystem;
22
23 using libxml_char = const unsigned char *;
24
25 namespace rpk {
26 namespace pkgmgr {
27
28 common_installer::Step::Status StepRpkManifestAdjustment::precheck() {
29   xml_path_ = context_->GetPkgPath();
30   xml_path_ /= "tizen-manifest.xml";
31   if (!bf::exists(xml_path_)) {
32     LOG(ERROR) << "Could not find manifest";
33     return Step::Status::ERROR;
34   }
35
36   new_path_ = bf::path(getUserManifestPath(context_->uid.get(),
37       context_->is_readonly_package.get())) / bf::path(context_->pkgid.get());
38   new_path_ += ".xml";
39   if (bf::exists(new_path_)) {
40     backup_path_ = new_path_.string() + ".bck";
41     bs::error_code error;
42     bf::copy_file(new_path_, backup_path_, error);
43     if (error)
44       LOG(WARNING) << "Failed to backup original manifest file " << new_path_
45                    << " due to error: " << error;
46   }
47   return Step::Status::OK;
48 }
49
50 common_installer::Step::Status StepRpkManifestAdjustment::process() {
51   std::unique_ptr<std::remove_pointer<xmlDocPtr>::type,
52       decltype(xmlFreeDoc)*> doc_auto(
53           xmlParseFile(xml_path_.c_str()), xmlFreeDoc);
54   if (doc_auto == nullptr) {
55     LOG(ERROR) << "Could not parse file";
56     return Step::Status::ERROR;
57   }
58
59   xmlNodePtr node = xmlDocGetRootElement(doc_auto.get());
60
61   std::string pkgtype_attrib = "type";
62   auto attrib = xmlSetProp(node,
63       reinterpret_cast<libxml_char>(pkgtype_attrib.c_str()),
64       reinterpret_cast<libxml_char>(context_->manifest_data.get()->type));
65
66   if (attrib == nullptr) {
67     LOG(ERROR) << "Failed to set attribute pkgtype";
68     return Step::Status::ERROR;
69   }
70
71   std::string readonly_attrib = "readonly";
72   attrib = xmlSetProp(node,
73       reinterpret_cast<libxml_char>(readonly_attrib.c_str()),
74       reinterpret_cast<libxml_char>(context_->manifest_data.get()->readonly));
75
76   if (attrib == nullptr) {
77     LOG(ERROR) << "Failed to set attribute readonly";
78     return Step::Status::ERROR;
79   }
80
81   std::string preload_attrib = "preload";
82   attrib = xmlSetProp(node,
83       reinterpret_cast<libxml_char>(preload_attrib.c_str()),
84       reinterpret_cast<libxml_char>(context_->manifest_data.get()->preload));
85
86   if (attrib == nullptr) {
87     LOG(ERROR) << "Failed to set attribute preload";
88     return Step::Status::ERROR;
89   }
90
91   std::string removable_attrib = "removable";
92   attrib = xmlSetProp(node,
93       reinterpret_cast<libxml_char>(removable_attrib.c_str()),
94       reinterpret_cast<libxml_char>(context_->manifest_data.get()->removable));
95
96   if (attrib == nullptr) {
97     LOG(ERROR) << "Failed to set attribute removable";
98     return Step::Status::ERROR;
99   }
100
101   if (xmlSaveFile(new_path_.c_str(), doc_auto.get()) == -1) {
102     LOG(ERROR) << "Failed to modify xml file";
103     return Step::Status::ERROR;
104   }
105
106   return Step::Status::OK;
107 }
108
109 }  // namespace pkgmgr
110 }  // namespace rpk