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.
5 #include "rpk/step/pkgmgr/step_rpk_manifest_adjustment.h"
7 #include <pkgmgr-info.h>
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>
16 #include <type_traits>
18 #include "common/installer_context.h"
20 namespace bs = boost::system;
21 namespace bf = boost::filesystem;
23 using libxml_char = const unsigned char *;
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;
36 new_path_ = bf::path(getUserManifestPath(context_->uid.get(),
37 context_->is_readonly_package.get())) / bf::path(context_->pkgid.get());
39 if (bf::exists(new_path_)) {
40 backup_path_ = new_path_.string() + ".bck";
42 bf::copy_file(new_path_, backup_path_, error);
44 LOG(WARNING) << "Failed to backup original manifest file " << new_path_
45 << " due to error: " << error;
47 return Step::Status::OK;
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;
59 xmlNodePtr node = xmlDocGetRootElement(doc_auto.get());
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));
66 if (attrib == nullptr) {
67 LOG(ERROR) << "Failed to set attribute pkgtype";
68 return Step::Status::ERROR;
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));
76 if (attrib == nullptr) {
77 LOG(ERROR) << "Failed to set attribute readonly";
78 return Step::Status::ERROR;
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));
86 if (attrib == nullptr) {
87 LOG(ERROR) << "Failed to set attribute preload";
88 return Step::Status::ERROR;
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));
96 if (attrib == nullptr) {
97 LOG(ERROR) << "Failed to set attribute removable";
98 return Step::Status::ERROR;
101 if (xmlSaveFile(new_path_.c_str(), doc_auto.get()) == -1) {
102 LOG(ERROR) << "Failed to modify xml file";
103 return Step::Status::ERROR;
106 return Step::Status::OK;
109 } // namespace pkgmgr