Refactor slp-pkgmgr with tidl
[platform/core/appfw/slp-pkgmgr.git] / client / src / internal.cc
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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 #include "client/src/internal.hh"
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <dlfcn.h>
23 #include <unzip.h>
24
25 #include <map>
26 #include <string>
27
28 #include "include/package-manager-plugin.h"
29 #include "log.hh"
30
31 namespace {
32
33 // TODO: Add rpk type
34 const std::map<std::string, std::string> kTypeMap = {
35   {"res/wgt/config.xml", "wgt"},
36   {"config.xml", "wgt"},
37   {"tizen-manifest.xml", "tpk"},
38 };
39 const char kPkgLibPath[] = "/etc/package-manager/backendlib/";
40
41 static pkg_plugin_set* plugin_set_list[24] = { 0, };
42
43 }  // namespace
44
45 namespace pkgmgr {
46 namespace client {
47
48 std::string GetTypeFromPath(const std::string& path) {
49   unzFile uf = unzOpen(path.c_str());
50   if (uf == nullptr) {
51     _E("failed to open zip file %s", path.c_str());
52     return "";
53   }
54
55   std::string type;
56   for (const auto& kv : kTypeMap) {
57     if (unzLocateFile(uf, kv.first.c_str(), 0) == UNZ_OK) {
58       _D("pkgtype of %s: [%s]", path.c_str(), kv.first.c_str());
59       type = kv.second;
60       break;
61     }
62   }
63   unzClose(uf);
64
65   return type;
66 }
67
68 pkg_plugin_set* LoadPluginSet(const std::string& type) {
69   int i;
70   for (i = 0; plugin_set_list[i]; i++) {
71     if (strcmp(plugin_set_list[i]->pkg_type, type.c_str()) == 0) {
72       _D("already loaded for [%s]", type.c_str());
73       return plugin_set_list[i];
74     }
75   }
76
77   std::string lib_path = kPkgLibPath + type + ".so";
78   void* handle = dlopen(lib_path.c_str(), RTLD_LAZY);
79   if (!handle) {
80     _E("failed to load library %s", lib_path.c_str());
81     return nullptr;
82   }
83
84   bool (*on_load)(pkg_plugin_set* plugin);
85   on_load = reinterpret_cast<bool(*)(pkg_plugin_set*)>(
86       dlsym(handle, "pkg_plugin_on_load"));
87   if (!on_load || dlerror()) {
88     _E("can not find symbol");
89     dlclose(handle);
90     return nullptr;
91   }
92
93   if (on_load(plugin_set_list[i]) != 0) {
94     _E("pkg_plugin_on_load failed");
95     free(plugin_set_list[i]);
96     dlclose(handle);
97     plugin_set_list[i] = nullptr;
98     return nullptr;
99   }
100
101   plugin_set_list[i]->plugin_handle = handle;
102   snprintf(plugin_set_list[i]->pkg_type, sizeof(plugin_set_list[i]->pkg_type),
103       "%s", type.c_str());
104
105   _D("library [%s] is loaded", lib_path.c_str());
106
107   return plugin_set_list[i];
108 }
109
110 }  // namespace pkgmgr
111 }  // namespace client