Implement app cert compare internal API
[platform/core/appfw/pkgmgr-info.git] / src / manager / pkginfo_manager.cc
1 /*
2  * Copyright (c) 2021 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 "manager/pkginfo_manager.h"
18
19 #include <sys/types.h>
20
21 #include <map>
22 #include <string>
23
24 #include "sqlite3.h"
25 #include "glib.h"
26
27 #include "pkgmgrinfo_private.h"
28
29 #include "logging.hh"
30 #include "common/database/abstract_db_handler.hh"
31 #include "common/database/pkg_set_db_handler.hh"
32 #include "common/parcel/appinfo_parcelable.hh"
33 #include "common/parcel/certinfo_parcelable.hh"
34 #include "common/parcel/depinfo_parcelable.hh"
35 #include "common/parcel/filter_parcelable.hh"
36 #include "common/parcel/pkginfo_parcelable.hh"
37 #include "common/parcel/query_parcelable.hh"
38 #include "common/parcel/result_parcelable.hh"
39
40 #include "client/pkginfo_client.hh"
41
42 #include <parcel.hh>
43
44 #ifdef LOG_TAG
45 #undef LOG_TAG
46 #endif
47 #define LOG_TAG "PKGMGR_INFO"
48
49 #ifdef EXPORT_API
50 #undef EXPORT_API
51 #endif
52 #define EXPORT_API __attribute__((visibility("default")))
53
54 extern "C" EXPORT_API int _pkginfo_get_packages(uid_t uid,
55             pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
56         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
57                         new pkgmgr_common::parcel::FilterParcelable(uid,
58                                         static_cast<pkgmgrinfo_filter_x*>(filter), flag));
59
60         pkgmgr_client::PkgInfoClient client(parcelable, uid,
61                         pkgmgr_common::ReqType::GET_PKG_INFO);
62         if (!client.SendRequest())
63       return PMINFO_R_ERROR;
64
65         std::shared_ptr<pkgmgr_common::parcel::PkgInfoParcelable> return_parcel(
66                         std::static_pointer_cast<pkgmgr_common::parcel::PkgInfoParcelable>(
67                                         client.GetResultParcel()));
68
69         tizen_base::Parcel parcel;
70         parcel.ReadParcelable(return_parcel.get());
71
72         auto result_list = return_parcel->GetPkgInfo();
73         // TODO: check noentry error has returned if size of result_list is 0
74         for (auto& pkginfo : result_list)
75                 g_hash_table_insert(packages, (gpointer)pkginfo->package,
76                                 (gpointer)pkginfo);
77
78         return PMINFO_R_OK;
79 }
80
81 extern "C" EXPORT_API int _pkginfo_get_depends_on(uid_t uid,
82                 const char *pkgid, GList **dependencies) {
83         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
84                         new pkgmgr_common::parcel::DepInfoParcelable(std::string(pkgid)));
85
86         pkgmgr_client::PkgInfoClient client(parcelable, uid,
87                         pkgmgr_common::ReqType::GET_PKG_DEP_INFO);
88         if (!client.SendRequest())
89       return PMINFO_R_ERROR;
90
91         std::shared_ptr<pkgmgr_common::parcel::DepInfoParcelable> return_parcel(
92                         std::static_pointer_cast<pkgmgr_common::parcel::DepInfoParcelable>(
93                                         client.GetResultParcel()));
94
95         tizen_base::Parcel parcel;
96         parcel.ReadParcelable(return_parcel.get());
97
98         auto dependency_list = return_parcel->GetDependencyInfo();
99         for (auto& dependency : dependency_list)
100                 *dependencies = g_list_prepend(*dependencies, dependency);
101         return PMINFO_R_OK;
102 }
103
104 // TODO: Need to add target db uid to identify which database to be searched
105 extern "C" EXPORT_API int _appinfo_get_applications(uid_t db_uid, uid_t uid,
106                 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages) {
107         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
108                         new pkgmgr_common::parcel::FilterParcelable(uid,
109                                         static_cast<pkgmgrinfo_filter_x*>(filter), flag));
110
111         pkgmgr_client::PkgInfoClient client(parcelable, uid, pkgmgr_common::ReqType::GET_APP_INFO);
112         if (!client.SendRequest())
113       return PMINFO_R_ERROR;
114
115         std::shared_ptr<pkgmgr_common::parcel::AppInfoParcelable> return_parcel(
116                         std::static_pointer_cast<pkgmgr_common::parcel::AppInfoParcelable>(
117                                         client.GetResultParcel()));
118
119         tizen_base::Parcel parcel;
120         parcel.ReadParcelable(return_parcel.get());
121         auto result_list = return_parcel->GetAppInfo();
122         for (auto& appinfo : result_list)
123                 g_hash_table_insert(packages, (gpointer)appinfo->appid,
124                                 (gpointer)appinfo);
125
126         return PMINFO_R_OK;
127 }
128
129 extern "C" EXPORT_API char *_appinfo_get_localed_label(
130                 const char *appid, const char *locale, uid_t uid) {
131         char *query = nullptr;
132     query = sqlite3_mprintf(
133                         "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
134                         "WHERE app_id=%Q AND app_locale=%Q),"
135                         "(SELECT app_label FROM package_app_localized_info WHERE "
136                         "app_id=%Q AND app_locale='No Locale'))", appid, locale, appid);
137         if (query == nullptr) {
138                 LOG(ERROR) << "Out of memory";
139                 return nullptr;
140         }
141
142         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
143                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
144           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
145           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
146
147         pkgmgr_client::PkgInfoClient client(parcelable, uid,
148                         pkgmgr_common::ReqType::QUERY);
149         if (!client.SendRequest()) {
150                 sqlite3_free(query);
151                 return nullptr;
152         }
153
154         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
155                                 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
156                                                 client.GetResultParcel()));
157         tizen_base::Parcel parcel;
158         parcel.ReadParcelable(return_parcel.get());
159         sqlite3_free(query);
160         // result_list is vector of string vector
161         char *label = nullptr;
162         auto result_list = return_parcel->GetResult();
163         for (auto result : result_list) {
164                 // result is string vector
165                 // it only has one string or not.
166                 if (result.front().empty() || result.front().length() == 0)
167                         return nullptr;
168                 label = strdup(result.front().c_str());
169                 if (label == nullptr) {
170                         LOG(ERROR) << "Out of memory";
171                         return nullptr;
172                 }
173                 return label;
174         }
175
176         return label;
177 }
178
179 extern "C" EXPORT_API int _appinfo_get_datacontrol_info(
180                 const char *providerid, const char *type, uid_t uid,
181                 char **appid, char **access) {
182         char *query = nullptr;
183         query = sqlite3_mprintf("SELECT app_id, access FROM "
184                         "package_app_data_control WHERE "
185                         "providerid=%Q AND type=%Q", providerid, type);
186         if (query == nullptr) {
187                 LOG(ERROR) << "Out of memory";
188                 return PMINFO_R_ERROR;
189         }
190
191         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
192                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
193           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
194           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
195
196         pkgmgr_client::PkgInfoClient client(parcelable, uid,
197                         pkgmgr_common::ReqType::QUERY);
198         if (!client.SendRequest()) {
199                 sqlite3_free(query);
200                 return PMINFO_R_ERROR;
201         }
202
203         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
204                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
205                                         client.GetResultParcel()));
206         tizen_base::Parcel parcel;
207         parcel.ReadParcelable(return_parcel.get());
208         sqlite3_free(query);
209         // result_list is vector of string vector
210         auto result_list = return_parcel->GetResult();
211         if (result_list.size() == 0)
212                 return PMINFO_R_ENOENT;
213         for (auto result : result_list) {
214                 if (result.size() != 2)
215                         return PMINFO_R_ERROR;
216                 if (result.front().empty() || result.front().size() == 0 ||
217                                 result.back().empty() || result.back().size() == 0)
218                         return PMINFO_R_ERROR;
219                 *appid = strdup(result.front().c_str());
220                 *access = strdup(result.back().c_str());
221                 if (*appid == nullptr || *access == nullptr) {
222                         LOG(ERROR) << "Out of memory";
223                         return PMINFO_R_ERROR;
224                 }
225         }
226
227         return PMINFO_R_OK;
228 }
229
230 extern "C" EXPORT_API int _appinfo_get_datacontrol_appid(
231                 const char *providerid, uid_t uid, char **appid) {
232         char *query = nullptr;
233
234         query = sqlite3_mprintf("SELECT app_id FROM package_app_data_control "
235                 "WHERE providerid=%Q", providerid);
236         if (query == nullptr) {
237                 LOGE("Out of memory");
238                 return PMINFO_R_ERROR;
239         }
240         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
241                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
242           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
243           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
244
245         pkgmgr_client::PkgInfoClient client(parcelable, uid,
246                         pkgmgr_common::ReqType::QUERY);
247         if (!client.SendRequest()) {
248                 sqlite3_free(query);
249                 return PMINFO_R_ERROR;
250         }
251         // TODO: deliver rawdata to reqhandler directly if server is not working
252
253         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
254                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
255                                         client.GetResultParcel()));
256         tizen_base::Parcel parcel;
257         parcel.ReadParcelable(return_parcel.get());
258         sqlite3_free(query);
259
260         // result_list is vector of string vector
261         auto result_list = return_parcel->GetResult();
262         if (result_list.size() == 0)
263                 return PMINFO_R_ENOENT;
264         for (auto result : result_list) {
265                 if (result.size() != 1)
266                         return PMINFO_R_ERROR;
267                 if (result.front().empty() || result.front().size() == 0)
268                         return PMINFO_R_ERROR;
269                 *appid = strdup(result.front().c_str());
270                 if (*appid == nullptr) {
271                         LOG(ERROR) << "Out of memory";
272                         return PMINFO_R_ERROR;
273                 }
274         }
275
276         return PMINFO_R_OK;
277 }
278
279 extern "C" EXPORT_API int _appinfo_get_datacontrol_trusted_info(
280                 const char *providerid, const char *type, uid_t uid,
281                 char **appid, char **trusted) {
282         char *query = nullptr;
283         query = sqlite3_mprintf(
284                         "SELECT app_id, trusted FROM package_app_data_control "
285                         "WHERE providerid=%Q AND type=%Q", providerid, type);
286         if (query == nullptr) {
287                 LOGE("Out of memory");
288                 return PMINFO_R_ERROR;
289         }
290
291         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
292                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
293           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
294           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
295
296         pkgmgr_client::PkgInfoClient client(parcelable, uid,
297                         pkgmgr_common::ReqType::QUERY);
298         if (!client.SendRequest()) {
299                 sqlite3_free(query);
300                 return PMINFO_R_ERROR;
301         }
302         // TODO: deliver rawdata to reqhandler directly if server is not working
303
304         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
305                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
306                                         client.GetResultParcel()));
307         tizen_base::Parcel parcel;
308         parcel.ReadParcelable(return_parcel.get());
309         sqlite3_free(query);
310         // result_list is vector of string vector
311         auto result_list = return_parcel->GetResult();
312         if (result_list.size() == 0)
313                 return PMINFO_R_ENOENT;
314         for (auto result : result_list) {
315                 if (result.size() != 2)
316                         return PMINFO_R_ERROR;
317                 if (result.front().empty() || result.front().size() == 0 ||
318                                 result.back().empty() || result.back().size() == 0)
319                         return PMINFO_R_ERROR;
320                 *appid = strdup(result.front().c_str());
321                 *trusted = strdup(result.back().c_str());
322                 if (*appid == nullptr || *trusted == nullptr) {
323                         LOG(ERROR) << "Out of memory";
324                         return PMINFO_R_ERROR;
325                 }
326         }
327
328         return PMINFO_R_OK;
329 }
330
331 extern "C" EXPORT_API int _appinfo_get_datacontrol_privileges(
332                 const char *providerid, const char *type, uid_t uid,
333                 GList **privileges) {
334         char *query = nullptr;
335         query = sqlite3_mprintf(
336                         "SELECT privilege FROM package_app_data_control_privilege "
337                         "WHERE providerid=%Q AND type=%Q", providerid, type);
338         if (query == nullptr) {
339                 LOGE("Out of memory");
340                 return PMINFO_R_ERROR;
341         }
342
343         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
344                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
345           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
346           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
347
348         pkgmgr_client::PkgInfoClient client(parcelable, uid,
349                         pkgmgr_common::ReqType::QUERY);
350         if (!client.SendRequest()) {
351                 sqlite3_free(query);
352                 return PMINFO_R_ERROR;
353         }
354         // TODO: deliver rawdata to reqhandler directly if server is not working
355
356         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
357                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
358                                         client.GetResultParcel()));
359         tizen_base::Parcel parcel;
360         parcel.ReadParcelable(return_parcel.get());
361         sqlite3_free(query);
362         // result_list is vector of string vector
363         auto result_list = return_parcel->GetResult();
364         if (result_list.size() == 0)
365                 return PMINFO_R_ENOENT;
366
367         for (auto result : result_list) {
368                 if (result.size() != 1)
369                         return PMINFO_R_ERROR;
370                 if (result.front().empty() || result.front().size() == 0)
371                         return PMINFO_R_ERROR;
372                 char *privilege = strdup(result.front().c_str());
373                 if (privilege == nullptr) {
374                         LOG(ERROR) << "Out of memory";
375                         return PMINFO_R_ERROR;
376                 }
377                 *privileges = g_list_append(*privileges, privilege);
378         }
379
380         return PMINFO_R_OK;
381 }
382
383 extern "C" EXPORT_API int _appinfo_get_appcontrol_privileges(
384                 const char *appid, const char *operation, uid_t uid, GList **privileges) {
385         char *query = nullptr;
386         query = sqlite3_mprintf(
387                 "SELECT app_control, privilege FROM package_app_app_control_privilege "
388                 "WHERE app_id=%Q", appid);
389         if (query == nullptr) {
390                 LOG(ERROR) << "Out of memory";
391                 return PMINFO_R_ERROR;
392         }
393
394         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
395                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
396           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
397           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
398
399         pkgmgr_client::PkgInfoClient client(parcelable, uid,
400                         pkgmgr_common::ReqType::QUERY);
401         if (!client.SendRequest()) {
402                 sqlite3_free(query);
403                 return PMINFO_R_ERROR;
404         }
405         // TODO: deliver rawdata to reqhandler directly if server is not working
406
407         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
408                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
409                                         client.GetResultParcel()));
410         tizen_base::Parcel parcel;
411         parcel.ReadParcelable(return_parcel.get());
412         sqlite3_free(query);
413         // result_list is vector of string vector
414         auto result_list = return_parcel->GetResult();
415         if (result_list.size() == 0)
416                 return PMINFO_R_ENOENT;
417
418         for (auto result : result_list) {
419                 if (result.size() != 2)
420                         return PMINFO_R_ERROR;
421                 if (result.front().empty() || result.front().size() == 0 ||
422                                 result.back().empty() || result.back().size() == 0)
423                         return PMINFO_R_ERROR;
424                 std::string app_control = result.front();
425                 std::stringstream ss(app_control);
426                 std::string token;
427                 while (std::getline(ss, token, '|')) {
428                         if (token.compare(std::string(operation))) {
429                                 char *privilege = strdup(result.back().c_str());
430                                 if (privilege == nullptr) {
431                                         LOG(ERROR) << "Out of memory";
432                                         return PMINFO_R_ERROR;
433                                 }
434                                 *privileges = g_list_append(*privileges, privilege);
435                         }
436                 }
437         }
438         return PMINFO_R_OK;
439 }
440
441 extern "C" EXPORT_API int _plugininfo_get_appids(
442                 const char *pkgid, const char *plugin_type,
443                 const char *plugin_name, GList **list) {
444         if (!pkgid || !plugin_type || !plugin_name || !list) {
445                 LOG(ERROR) << "Invalid parameter";
446                 return PMINFO_R_EINVAL;
447         }
448
449         char *query = nullptr;
450         query = sqlite3_mprintf(
451                         "SELECT appid FROM "
452                         "package_plugin_info WHERE pkgid=%Q AND "
453                         "plugin_type=%Q AND plugin_name=%Q",
454       pkgid, plugin_type, plugin_name);
455         if (query == nullptr) {
456                 LOG(ERROR) << "Out of memory";
457                 return PMINFO_R_ERROR;
458         }
459
460         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
461                         new pkgmgr_common::parcel::QueryParcelable(_getuid(), std::string(query),
462           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
463           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
464         sqlite3_free(query);
465
466         pkgmgr_client::PkgInfoClient client(parcelable, _getuid(),
467                         pkgmgr_common::ReqType::QUERY);
468         if (!client.SendRequest()) {
469                 return PMINFO_R_ERROR;
470         }
471
472         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
473                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
474                                         client.GetResultParcel()));
475   if (return_parcel->GetCol() != 1) {
476     LOG(ERROR) << "Invalid result";
477     return PMINFO_R_ERROR;
478   }
479         // result_list is vector of string vector
480         auto& result_list = return_parcel->GetResult();
481         if (result_list.size() == 0)
482                 return PMINFO_R_ENOENT;
483
484         for (auto result : result_list) {
485     if (result.size() != 1) {
486       LOG(ERROR) << "Invalid result";
487       g_list_free_full(*list, free);
488       return PMINFO_R_ERROR;
489     }
490     *list = g_list_append(*list, strdup(result[0].c_str()));
491   }
492
493   return PMINFO_R_OK;
494 }
495
496 static int __convert_update_type(const char *type, pkgmgrinfo_updateinfo_update_type *convert_type)
497 {
498         if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_NONE,
499                         strlen(PMINFO_UPDATEINFO_TYPE_NONE)) == 0)
500                 *convert_type = PMINFO_UPDATEINFO_NONE;
501         else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_FORCE,
502                         strlen(PMINFO_UPDATEINFO_TYPE_FORCE)) == 0)
503                 *convert_type = PMINFO_UPDATEINFO_FORCE;
504         else if (strncasecmp(type, PMINFO_UPDATEINFO_TYPE_OPTIONAL,
505                         strlen(PMINFO_UPDATEINFO_TYPE_OPTIONAL)) == 0)
506                 *convert_type = PMINFO_UPDATEINFO_OPTIONAL;
507         else
508                 return -1;
509         return 0;
510 }
511
512 static void __free_update_info(gpointer data)
513 {
514         updateinfo_x *update_info = (updateinfo_x *)data;
515         if (update_info == nullptr)
516                 return;
517
518         if (update_info->pkgid)
519                 free((void *)update_info->pkgid);
520         if (update_info->version)
521                 free((void *)update_info->version);
522         free((void *)update_info);
523
524 }
525
526 extern "C" EXPORT_API int _get_pkg_updateinfo(const char *pkgid,
527                 GSList **update_info_list, uid_t uid)
528 {
529         char *query = nullptr;
530         int ret;
531
532         if (pkgid == nullptr)
533                 query = sqlite3_mprintf(
534                                                 "SELECT package, update_version, update_type "
535                                                 "FROM package_update_info");
536         else
537                 query = sqlite3_mprintf(
538                                                 "SELECT package, update_version, update_type "
539                                                 "FROM package_update_info WHERE package=%Q",
540                                                 pkgid);
541         if (query == nullptr) {
542                 LOG(ERROR) << "Out of memory";
543                 return PMINFO_R_ERROR;
544         }
545
546         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
547                         new pkgmgr_common::parcel::QueryParcelable(uid, std::string(query),
548           pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
549           pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
550         sqlite3_free(query);
551
552         pkgmgr_client::PkgInfoClient client(parcelable, uid,
553                         pkgmgr_common::ReqType::QUERY);
554         if (!client.SendRequest()) {
555                 return PMINFO_R_ERROR;
556         }
557
558         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
559                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
560                                         client.GetResultParcel()));
561   if (return_parcel->GetCol() != 3) {
562     LOG(ERROR) << "Invalid result";
563     return PMINFO_R_ERROR;
564   }
565
566         auto result_list = return_parcel->GetResult();
567         if (result_list.size() == 0)
568                 return PMINFO_R_ENOENT;
569
570         for (auto result : result_list) {
571     if (result.size() != 3) {
572       LOG(ERROR) << "Invalid result";
573       g_slist_free_full(*update_info_list, __free_update_info);
574       return PMINFO_R_ERROR;
575     }
576     updateinfo_x *update_info = reinterpret_cast<updateinfo_x *>(calloc(1, sizeof(updateinfo_x)));
577                 if (update_info == nullptr) {
578                         LOG(ERROR) << "Out of memory";
579                         return PMINFO_R_ERROR;
580                 }
581     update_info->pkgid = strdup(result[0].c_str());
582     update_info->version = strdup(result[1].c_str());
583           pkgmgrinfo_updateinfo_update_type convert_type;
584                 ret = __convert_update_type(result[2].c_str(), &convert_type);
585                 if (ret != 0) {
586                         __free_update_info(update_info);
587       g_slist_free_full(*update_info_list, __free_update_info);
588                         return PMINFO_R_ERROR;
589                 }
590                 update_info->type = static_cast<int>(convert_type);
591                 *update_info_list = g_slist_prepend(*update_info_list,
592                                 update_info);
593   }
594
595         return PMINFO_R_OK;
596 }
597
598 extern "C" EXPORT_API int _pkginfo_set_usr_installed_storage(const char *pkgid,
599                 INSTALL_LOCATION location, const char *external_pkg_path,
600                 uid_t uid)
601 {
602         char *query = nullptr;
603         const char *location_str;
604         std::vector<std::string> queries;
605
606         if (location == INSTALL_INTERNAL)
607                 location_str = "installed_internal";
608         else if (location == INSTALL_EXTERNAL)
609                 location_str = "installed_external";
610         else
611                 location_str = "installed_extended";
612         /* pkgcakge_info table */
613         query = sqlite3_mprintf(
614                         "update package_info set installed_storage=%Q, external_path=%Q where package=%Q",
615                         location_str, external_pkg_path, pkgid);
616         queries.emplace_back(query);
617         sqlite3_free(query);
618
619         /* package_app_info table */
620         query = sqlite3_mprintf(
621                         "update package_app_info set app_installed_storage=%Q, app_external_path=%Q where package=%Q",
622                         location_str, external_pkg_path, pkgid);
623         queries.emplace_back(query);
624         sqlite3_free(query);
625
626         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
627                         new pkgmgr_common::parcel::QueryParcelable(uid, queries,
628                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
629                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
630
631         pkgmgr_client::PkgInfoClient client(parcelable, uid,
632                         pkgmgr_common::ReqType::QUERY);
633         if (!client.SendRequest()) {
634                 return PMINFO_R_ERROR;
635         }
636
637         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
638                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
639                                         client.GetResultParcel()));
640
641         auto result_list = return_parcel->GetResult();
642         if (result_list.size() != 1) {
643                 LOG(ERROR) << "Invalid result";
644                 return PMINFO_R_ERROR;
645         }
646
647         if (result_list[0].size() != 1) {
648                 LOG(ERROR) << "Invalid result";
649                 return PMINFO_R_ERROR;
650         }
651
652         LOG(ERROR) << "result : " << result_list[0][0];
653         if (result_list[0][0] != "SUCCESS")
654                 return PMINFO_R_ERROR;
655
656         return PMINFO_R_OK;
657 }
658
659 extern "C" EXPORT_API int _certinfo_compare_pkg_certinfo(const char *l_pkgid,
660                 const char *r_pkgid, pkgmgrinfo_cert_compare_result_type_e *result) {
661         char *query = sqlite3_mprintf("SELECT package, "
662                         "COALESCE(author_signer_cert, -1) FROM package_cert_info WHERE "
663                         "package IN (%Q, %Q)", l_pkgid, r_pkgid);
664         if (query == nullptr) {
665                 LOG(ERROR) << "Out of memory";
666                 return PMINFO_R_ERROR;
667         }
668         std::vector<std::string> queries;
669         queries.emplace_back(query);
670         sqlite3_free(query);
671
672         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
673                 new pkgmgr_common::parcel::QueryParcelable(0, queries,
674                                 pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_CERTDB,
675                                 pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
676         pkgmgr_client::PkgInfoClient client(parcelable, 0,
677                         pkgmgr_common::ReqType::QUERY);
678         if (!client.SendRequest()) {
679                 return PMINFO_R_ERROR;
680         }
681
682         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
683                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
684                                         client.GetResultParcel()));
685
686         auto certinfo_list = return_parcel->GetResult();
687         if (certinfo_list.size() != 2)
688                 return PMINFO_R_ERROR;
689
690         std::map<std::string, std::string> result_map;
691         for (auto& certinfo : certinfo_list)
692                 result_map.insert(make_pair(certinfo.front(), certinfo.back()));
693
694         if (result_map.find(std::string(l_pkgid))->second == "-1" &&
695                         result_map.find(std::string(r_pkgid))->second == "-1")
696                 *result = PMINFO_CERT_COMPARE_BOTH_NO_CERT;
697         else if (result_map.find(std::string(l_pkgid))->second == "-1")
698                 *result = PMINFO_CERT_COMPARE_LHS_NO_CERT;
699         else if (result_map.find(std::string(r_pkgid))->second == "-1")
700                 *result = PMINFO_CERT_COMPARE_RHS_NO_CERT;
701         else if (result_map.find(std::string(l_pkgid))->second ==
702                         result_map.find(std::string(r_pkgid))->second)
703                 *result = PMINFO_CERT_COMPARE_MATCH;
704         else
705                 *result = PMINFO_CERT_COMPARE_MISMATCH;
706
707         return PMINFO_R_OK;
708 }
709
710 extern "C" EXPORT_API int _certinfo_compare_app_certinfo(uid_t uid,
711                 const char *l_appid, const char *r_appid,
712                 pkgmgrinfo_cert_compare_result_type_e *result) {
713         char* query = sqlite3_mprintf("SELECT app_id, package FROM "
714                         "package_app_info WHERE app_id IN (%Q, %Q)", l_appid, r_appid);
715         if (query == nullptr) {
716                 LOG(ERROR) << "Out of memory";
717                 return PMINFO_R_ERROR;
718         }
719         std::vector<std::string> queries;
720         queries.emplace_back(query);
721         sqlite3_free(query);
722
723         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
724                 new pkgmgr_common::parcel::QueryParcelable(uid, queries,
725                                 pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
726                                 pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_READ));
727         pkgmgr_client::PkgInfoClient client(parcelable, uid,
728                         pkgmgr_common::ReqType::QUERY);
729         if (!client.SendRequest()) {
730                 return PMINFO_R_ERROR;
731         }
732
733         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
734                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
735                                         client.GetResultParcel()));
736
737         auto pkgid_list = return_parcel->GetResult();
738         std::map<std::string, std::string> result_map;
739         for (auto& pkgid : pkgid_list)
740                 result_map.insert(make_pair(pkgid.front(), pkgid.back()));
741
742         if (result_map.find(std::string(l_appid)) == result_map.end()) {
743                 LOG(ERROR) << "Cannot find pkgid of app " << l_appid
744                                 << " for uid " << uid;
745                 return PMINFO_R_ENOENT;
746         } else if (result_map.find(std::string(r_appid)) == result_map.end()) {
747                 LOG(ERROR) << "Cannot find pkgid of app " << r_appid
748                                 << " for uid " << uid;
749                 return PMINFO_R_ENOENT;
750         }
751
752         const char* l_pkgid = result_map.find(
753                         std::string(l_appid))->second.c_str();
754         const char* r_pkgid = result_map.find(
755                         std::string(r_appid))->second.c_str();
756
757         return _certinfo_compare_pkg_certinfo(l_pkgid, r_pkgid, result);
758 }
759
760 extern "C" EXPORT_API int _parser_execute_write_query(const char *query, uid_t uid)
761 {
762         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
763                         new pkgmgr_common::parcel::QueryParcelable(uid, query,
764                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
765                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
766
767         pkgmgr_client::PkgInfoClient client(parcelable, uid,
768                         pkgmgr_common::ReqType::QUERY);
769         if (!client.SendRequest()) {
770                 return -1;
771         }
772
773         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
774                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
775                                         client.GetResultParcel()));
776
777         auto result_list = return_parcel->GetResult();
778         if (result_list.size() != 1) {
779                 LOG(ERROR) << "Invalid result";
780                 return -1;
781         }
782
783         if (result_list[0].size() != 1) {
784                 LOG(ERROR) << "Invalid result";
785                 return -1;
786         }
787
788         LOG(ERROR) << "result : " << result_list[0][0];
789         if (result_list[0][0] != "SUCCESS")
790                 return -1;
791
792         return 0;
793 }
794
795 extern "C" EXPORT_API int _parser_execute_write_queries(const char **queries, int len, uid_t uid)
796 {
797         std::vector<std::string> query_vt;
798         for (int i = 0; i < len; ++i)
799                 query_vt.emplace_back(queries[i]);
800
801         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
802                         new pkgmgr_common::parcel::QueryParcelable(uid, query_vt,
803                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
804                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
805
806         pkgmgr_client::PkgInfoClient client(parcelable, uid,
807                         pkgmgr_common::ReqType::QUERY);
808         if (!client.SendRequest()) {
809                 return -1;
810         }
811
812         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
813                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
814                                         client.GetResultParcel()));
815
816         auto result_list = return_parcel->GetResult();
817         if (result_list.size() != 1) {
818                 LOG(ERROR) << "Invalid result";
819                 return -1;
820         }
821
822         if (result_list[0].size() != 1) {
823                 LOG(ERROR) << "Invalid result";
824                 return -1;
825         }
826
827         LOG(ERROR) << "result : " << result_list[0][0];
828         if (result_list[0][0] != "SUCCESS")
829                 return -1;
830
831         return 0;
832 }
833
834 extern "C" EXPORT_API int _parser_insert_manifest_info(manifest_x *mfx, uid_t uid)
835 {
836         std::vector<package_x *> vt { mfx };
837
838         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
839                         new pkgmgr_common::parcel::PkgInfoParcelable(uid, std::move(vt), WriteType::Insert));
840
841         pkgmgr_client::PkgInfoClient client(parcelable, uid,
842                         pkgmgr_common::ReqType::SET_PKG_INFO);
843         if (!client.SendRequest()) {
844                 return -1;
845         }
846
847         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
848                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
849                                         client.GetResultParcel()));
850
851         auto result_list = return_parcel->GetResult();
852         if (result_list.size() != 1) {
853                 LOG(ERROR) << "Invalid result";
854                 return -1;
855         }
856
857         if (result_list[0].size() != 1) {
858                 LOG(ERROR) << "Invalid result";
859                 return -1;
860         }
861
862         LOG(ERROR) << "result : " << result_list[0][0];
863         if (result_list[0][0] != "SUCCESS")
864                 return -1;
865
866         return 0;
867 }
868
869 extern "C" EXPORT_API int _parser_update_manifest_info(manifest_x *mfx, uid_t uid)
870 {
871         std::vector<package_x *> vt { mfx };
872
873         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
874                         new pkgmgr_common::parcel::PkgInfoParcelable(uid, std::move(vt), WriteType::Update));
875
876         pkgmgr_client::PkgInfoClient client(parcelable, uid,
877                         pkgmgr_common::ReqType::SET_PKG_INFO);
878         if (!client.SendRequest()) {
879                 return -1;
880         }
881
882         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
883                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
884                                         client.GetResultParcel()));
885
886         auto result_list = return_parcel->GetResult();
887         if (result_list.size() != 1) {
888                 LOG(ERROR) << "Invalid result";
889                 return -1;
890         }
891
892         if (result_list[0].size() != 1) {
893                 LOG(ERROR) << "Invalid result";
894                 return -1;
895         }
896
897         LOG(ERROR) << "result : " << result_list[0][0];
898         if (result_list[0][0] != "SUCCESS")
899                 return -1;
900
901         return 0;
902 }
903
904 extern "C" EXPORT_API int _parser_delete_manifest_info(manifest_x *mfx, uid_t uid)
905 {
906         std::vector<package_x *> vt { mfx };
907
908         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
909                         new pkgmgr_common::parcel::PkgInfoParcelable(uid, std::move(vt), WriteType::Delete));
910
911         pkgmgr_client::PkgInfoClient client(parcelable, uid,
912                         pkgmgr_common::ReqType::SET_PKG_INFO);
913         if (!client.SendRequest()) {
914                 return -1;
915         }
916
917         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
918                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
919                                         client.GetResultParcel()));
920
921         auto result_list = return_parcel->GetResult();
922         if (result_list.size() != 1) {
923                 LOG(ERROR) << "Invalid result";
924                 return -1;
925         }
926
927         if (result_list[0].size() != 1) {
928                 LOG(ERROR) << "Invalid result";
929                 return -1;
930         }
931
932         LOG(ERROR) << "result : " << result_list[0][0];
933         if (result_list[0][0] != "SUCCESS")
934                 return -1;
935
936         return 0;
937 }
938
939 extern "C" EXPORT_API int _pkginfo_insert_certinfo(const char* pkgid,
940                 pkgmgr_certinfo_x* cert, uid_t uid)
941 {
942         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
943                         new pkgmgr_common::parcel::CertInfoParcelable(uid, cert));
944
945         pkgmgr_client::PkgInfoClient client(parcelable, uid,
946                         pkgmgr_common::ReqType::SET_CERT_INFO);
947         if (!client.SendRequest())
948         return PMINFO_R_ERROR;
949
950         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
951                 std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
952                                 client.GetResultParcel()));
953
954         auto result_list = return_parcel->GetResult();
955         if (result_list.size() != 1) {
956                 LOG(ERROR) << "Invalid result";
957                 return PMINFO_R_ERROR;
958         }
959
960         if (result_list[0].size() != 1) {
961                 LOG(ERROR) << "Invalid result";
962                 return PMINFO_R_ERROR;
963         }
964
965         LOG(ERROR) << "result : " << result_list[0][0];
966         if (result_list[0][0] != "SUCCESS")
967                 return PMINFO_R_ERROR;
968
969         return PMINFO_R_OK;
970 }
971
972 extern "C" EXPORT_API int _pkginfo_get_certinfo(const char *pkgid,
973                 pkgmgr_certinfo_x** cert, uid_t uid)
974 {
975         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
976                         new pkgmgr_common::parcel::CertInfoParcelable(uid,
977                                         std::string(pkgid)));
978
979         pkgmgr_client::PkgInfoClient client(parcelable, uid,
980                         pkgmgr_common::ReqType::GET_CERT_INFO);
981         if (!client.SendRequest())
982         return PMINFO_R_ERROR;
983
984         std::shared_ptr<pkgmgr_common::parcel::CertInfoParcelable> return_parcel(
985                 std::static_pointer_cast<pkgmgr_common::parcel::CertInfoParcelable>(
986                                 client.GetResultParcel()));
987
988         tizen_base::Parcel parcel;
989         parcel.ReadParcelable(return_parcel.get());
990         auto certinfo = return_parcel->GetCertInfo();
991         if (certinfo == nullptr)
992                 return PMINFO_R_ERROR;
993
994         *cert = (pkgmgr_certinfo_x*)certinfo;
995         return PMINFO_R_OK;
996 }
997
998 extern "C" EXPORT_API int _pkginfo_delete_certinfo(const char *pkgid)
999 {
1000         char* query = sqlite3_mprintf("UPDATE package_cert_info SET "
1001                         "package_count = package_count - 1 WHERE package=%Q", pkgid);
1002         if (query == nullptr) {
1003                 LOG(ERROR) << "Out of memory";
1004                 return PMINFO_R_ERROR;
1005         }
1006
1007         std::vector<std::string> queries;
1008         queries.emplace_back(query);
1009         sqlite3_free(query);
1010
1011         std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcelable(
1012                         new pkgmgr_common::parcel::QueryParcelable(0, queries,
1013                                         pkgmgr_common::database::AbstractDBHandler::DBType::DB_TYPE_FILE_CERTDB,
1014                                         pkgmgr_common::database::AbstractDBHandler::OperationType::OPERATION_TYPE_WRITE));
1015
1016         pkgmgr_client::PkgInfoClient client(parcelable, 0,
1017                         pkgmgr_common::ReqType::QUERY);
1018         if (!client.SendRequest()) {
1019                 return PMINFO_R_ERROR;
1020         }
1021
1022         std::shared_ptr<pkgmgr_common::parcel::ResultParcelable> return_parcel(
1023                         std::static_pointer_cast<pkgmgr_common::parcel::ResultParcelable>(
1024                                         client.GetResultParcel()));
1025
1026         auto result_list = return_parcel->GetResult();
1027         if (result_list.size() != 1) {
1028                 LOG(ERROR) << "Invalid result";
1029                 return PMINFO_R_ERROR;
1030         }
1031
1032         if (result_list[0].size() != 1) {
1033                 LOG(ERROR) << "Invalid result";
1034                 return PMINFO_R_ERROR;
1035         }
1036
1037         LOG(ERROR) << "result : " << result_list[0][0];
1038         if (result_list[0][0] != "SUCCESS")
1039                 return PMINFO_R_ERROR;
1040
1041         return PMINFO_R_OK;
1042 }