d80006420473a36236e2392460fd8f1f2d60415e
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_pkginfo.c
1 /*
2  * pkgmgr-info
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7  * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #define _GNU_SOURCE
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdbool.h>
28 #include <unistd.h>
29 #include <ctype.h>
30 #include <sys/smack.h>
31 #include <linux/limits.h>
32 #include <libgen.h>
33 #include <sys/stat.h>
34
35 #include <sqlite3.h>
36 #include <glib.h>
37
38 #include "pkgmgrinfo_basic.h"
39 #include "pkgmgrinfo_private.h"
40 #include "pkgmgrinfo_debug.h"
41 #include "pkgmgr-info.h"
42
43 static bool _get_bool_value(const char *str)
44 {
45         if (str && !strcmp(str, "true"))
46                 return true;
47         else
48                 return false;
49 }
50
51 static gint __compare_func(gconstpointer data1, gconstpointer data2)
52 {
53         pkgmgrinfo_node_x *node1 = (pkgmgrinfo_node_x *)data1;
54         pkgmgrinfo_node_x *node2 = (pkgmgrinfo_node_x *)data2;
55         if (node1->prop == node2->prop)
56                 return 0;
57         else if (node1->prop > node2->prop)
58                 return 1;
59         else
60                 return -1;
61 }
62
63 static gint __pkg_disable_chk_func(gconstpointer data1, gconstpointer data2)
64 {
65         pkgmgrinfo_node_x *node = (pkgmgrinfo_node_x *)data1;
66
67         if (node->prop == E_PMINFO_PKGINFO_PROP_PACKAGE_DISABLE)
68                 return 0;
69         else
70                 return 1;
71 }
72
73 static void __destroy_each_node(gpointer data, gpointer user_data)
74 {
75         ret_if(data == NULL);
76         pkgmgrinfo_node_x *node = (pkgmgrinfo_node_x *)data;
77         if (node->value) {
78                 free(node->value);
79                 node->value = NULL;
80         }
81         if (node->key) {
82                 free(node->key);
83                 node->key = NULL;
84         }
85         free(node);
86         node = NULL;
87 }
88
89 static void __destroy_metadata_node(gpointer data)
90 {
91         pkgmgrinfo_metadata_node_x *node = (pkgmgrinfo_metadata_node_x *)data;
92         if (node->key)
93                 free(node->key);
94         if (node->value)
95                 free(node->value);
96         free(node);
97 }
98
99 static void __cleanup_pkginfo(pkgmgr_pkginfo_x *data)
100 {
101         ret_if(data == NULL);
102         if (data->locale) {
103                 free((void *)data->locale);
104                 data->locale = NULL;
105         }
106
107         pkgmgrinfo_basic_free_package(data->pkg_info);
108         free((void *)data);
109         data = NULL;
110         return;
111 }
112
113 long long _pkgmgr_calculate_dir_size(char *dirname)
114 {
115         long long total = 0;
116         long long ret = 0;
117         int q = 0; /*quotient*/
118         int r = 0; /*remainder*/
119         DIR *dp = NULL;
120         struct dirent *ep;
121         struct stat fileinfo;
122         char abs_filename[FILENAME_MAX] = { 0, };
123         retvm_if(dirname == NULL, PMINFO_R_ERROR, "dirname is NULL");
124
125         dp = opendir(dirname);
126         if (dp == NULL) {
127                 _LOGE("Couldn't open the directory\n");
128                 return -1;
129         }
130
131         for (ep = readdir(dp); ep != NULL; ep = readdir(dp)) {
132                 if (!strcmp(ep->d_name, ".") ||
133                         !strcmp(ep->d_name, "..")) {
134                         continue;
135                 }
136                 snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
137                          ep->d_name);
138                 if (lstat(abs_filename, &fileinfo) < 0)
139                         perror(abs_filename);
140                 else {
141                         if (S_ISDIR(fileinfo.st_mode)) {
142                                 total += fileinfo.st_size;
143                                 if (strcmp(ep->d_name, ".")
144                                     && strcmp(ep->d_name, "..")) {
145                                         ret = _pkgmgr_calculate_dir_size
146                                             (abs_filename);
147                                         total = total + ret;
148                                 }
149                         } else if (S_ISLNK(fileinfo.st_mode)) {
150                                 continue;
151                         } else {
152                                 /*It is a file. Calculate the actual
153                                 size occupied (in terms of 4096 blocks)*/
154                         q = (fileinfo.st_size / BLOCK_SIZE);
155                         r = (fileinfo.st_size % BLOCK_SIZE);
156                         if (r)
157                                 q = q + 1;
158                         total += q * BLOCK_SIZE;
159                         }
160                 }
161         }
162         (void)closedir(dp);
163         return total;
164
165 }
166
167 static int _pkginfo_add_description_info_into_list(const char *locale,
168                 char *record, GList **description)
169 {
170         description_x *info;
171
172         info = calloc(1, sizeof(description_x));
173         if (info == NULL) {
174                 LOGE("out of memory");
175                 return PMINFO_R_ERROR;
176         }
177         info->lang = strdup(locale);
178         info->text = record;
179         *description = g_list_append(*description, info);
180
181         return PMINFO_R_OK;
182 }
183
184 static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid,
185                 GList **privileges)
186 {
187         static const char query_raw[] =
188                 "SELECT DISTINCT privilege, type FROM package_privilege_info "
189                 "WHERE package=%Q";
190         int ret;
191         char *query;
192         sqlite3_stmt *stmt;
193         privilege_x *privilege;
194
195         query = sqlite3_mprintf(query_raw, pkgid);
196         if (query == NULL) {
197                 LOGE("out of memory");
198                 return PMINFO_R_ERROR;
199         }
200
201         ret = sqlite3_prepare_v2(db, query, strlen(query),
202                         &stmt, NULL);
203         sqlite3_free(query);
204         if (ret != SQLITE_OK) {
205                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
206                 return PMINFO_R_ERROR;
207         }
208
209         while (sqlite3_step(stmt) == SQLITE_ROW) {
210                 privilege = calloc(1, sizeof(privilege_x));
211                 _save_column_str(stmt, 0, &privilege->value);
212                 _save_column_str(stmt, 1, &privilege->type);
213                 *privileges = g_list_append(*privileges,
214                                 (gpointer)privilege);
215         }
216
217         sqlite3_finalize(stmt);
218
219         return PMINFO_R_OK;
220 }
221
222 static int _pkginfo_get_appdefined_privilege(sqlite3 *db, const char *pkgid,
223                 GList **privileges)
224 {
225         static const char query_raw[] =
226                 "SELECT DISTINCT privilege, license, type FROM "
227                 "package_appdefined_privilege_info WHERE package=%Q";
228         int ret;
229         char *query;
230         sqlite3_stmt *stmt;
231         appdefined_privilege_x *privilege;
232
233         query = sqlite3_mprintf(query_raw, pkgid);
234         if (query == NULL) {
235                 LOGE("out of memory");
236                 return PMINFO_R_ERROR;
237         }
238
239         ret = sqlite3_prepare_v2(db, query, strlen(query),
240                         &stmt, NULL);
241         sqlite3_free(query);
242         if (ret != SQLITE_OK) {
243                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
244                 return PMINFO_R_ERROR;
245         }
246
247         while (sqlite3_step(stmt) == SQLITE_ROW) {
248                 privilege = calloc(1, sizeof(appdefined_privilege_x));
249                 if (!privilege) {
250                         LOGE("failed to alloc memory");
251                         sqlite3_finalize(stmt);
252                         return PMINFO_R_ERROR;
253                 }
254                 _save_column_str(stmt, 0, &privilege->value);
255                 _save_column_str(stmt, 1, &privilege->license);
256                 _save_column_str(stmt, 2, &privilege->type);
257                 *privileges = g_list_append(*privileges,
258                                 (gpointer)privilege);
259         }
260
261         sqlite3_finalize(stmt);
262
263         return PMINFO_R_OK;
264 }
265
266 static int _pkginfo_get_dependency(sqlite3 *db, const char *pkgid,
267                 GList **dependencies)
268 {
269         static const char query[] =
270                 "SELECT DISTINCT depends_on, type, required_version "
271                 "FROM package_dependency_info WHERE package=?";
272         int ret;
273         sqlite3_stmt *stmt;
274         dependency_x *dependency;
275
276         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
277         if (ret != SQLITE_OK) {
278                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
279                 return PMINFO_R_ERROR;
280         }
281
282         while (sqlite3_step(stmt) == SQLITE_ROW) {
283                 dependency = calloc(1, sizeof(dependency_x));
284                 if (!dependency) {
285                         LOGE("failed to alloc memory");
286                         sqlite3_finalize(stmt);
287                         return PMINFO_R_ERROR;
288                 }
289                 _save_column_str(stmt, 0, &dependency->depends_on);
290                 _save_column_str(stmt, 1, &dependency->type);
291                 _save_column_str(stmt, 2, &dependency->required_version);
292                 *dependencies = g_list_append(*dependencies,
293                                 (gpointer)dependency);
294         }
295
296         sqlite3_finalize(stmt);
297
298         return PMINFO_R_OK;
299 }
300
301 static const char join_localized_info[] =
302         " LEFT OUTER JOIN package_localized_info"
303         "  ON pi.package=package_localized_info.package"
304         "  AND package_localized_info.package_locale=?";
305 static const char join_privilege_info[] =
306         " LEFT OUTER JOIN package_privilege_info"
307         "  ON pi.package=package_privilege_info.package";
308
309 static int _get_filtered_query(pkgmgrinfo_filter_x *filter,
310                 const char *locale, uid_t uid, char **query, GList **bind_params)
311 {
312         int joined = 0;
313         char buf[MAX_QUERY_LEN] = { '\0' };
314         char buf2[MAX_QUERY_LEN] = { '\0' };
315         char *condition = NULL;
316         GSList *list = NULL;
317
318         if (filter == NULL)
319                 return PMINFO_R_OK;
320
321         snprintf(buf, sizeof(buf), "%s", " WHERE 1=1 ");
322         for (list = filter->list; list; list = list->next) {
323                 joined |= __get_filter_condition(list->data, uid, &condition,
324                                 bind_params);
325                 if (condition == NULL)
326                         continue;
327
328                 strncat(buf, " AND ", sizeof(buf) - strlen(buf) - 1);
329
330                 strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
331                 free(condition);
332                 condition = NULL;
333         }
334
335         if (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) {
336                 strncat(buf2, join_localized_info, sizeof(buf2) - strlen(buf2) - 1);
337                 *bind_params = g_list_append(*bind_params, strdup(locale));
338         }
339         if (joined & E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO)
340                 strncat(buf2, join_privilege_info, sizeof(buf2) - strlen(buf2) - 1);
341         strncat(buf2, buf, sizeof(buf2) - strlen(buf2) - 1);
342
343         *query = strdup(buf2);
344         if (*query == NULL)
345                 return PMINFO_R_ERROR;
346
347         return PMINFO_R_OK;
348 }
349
350 static void __free_packages(gpointer data)
351 {
352         pkgmgrinfo_basic_free_package((package_x *)data);
353 }
354
355 static bool __check_disable_filter_exist(pkgmgrinfo_filter_x *filter)
356 {
357         GSList *link;
358
359         if (filter == NULL)
360                 return false;
361
362         link = g_slist_find_custom(filter->list, NULL, __pkg_disable_chk_func);
363         if (link)
364                 return true;
365
366         return false;
367 }
368
369 static int __bind_params(sqlite3_stmt *stmt, GList *params)
370 {
371         GList *tmp_list = NULL;
372         int idx = 0;
373         int ret;
374
375         if (stmt == NULL || params == NULL)
376                 return PMINFO_R_EINVAL;
377
378         tmp_list = params;
379         while (tmp_list) {
380                 ret = sqlite3_bind_text(stmt, ++idx, (char *)tmp_list->data, -1, SQLITE_STATIC);
381                 if (ret != SQLITE_OK)
382                         return PMINFO_R_ERROR;
383                 tmp_list = tmp_list->next;
384         }
385
386         return PMINFO_R_OK;
387 }
388
389 static bool __check_package_storage_status(pkgmgrinfo_filter_x *tmp_filter)
390 {
391         GSList *tmp_list = NULL;
392         pkgmgrinfo_node_x *tmp_node = NULL;
393         int property = -1;
394
395         property = _pminfo_pkginfo_convert_to_prop_bool(PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE);
396         for (tmp_list = tmp_filter->list; tmp_list != NULL;
397                         tmp_list = g_slist_next(tmp_list)) {
398                 tmp_node = (pkgmgrinfo_node_x *)tmp_list->data;
399                 if (property == tmp_node->prop) {
400                         if (strcmp(tmp_node->value, "true") == 0)
401                                 return true;
402                         else
403                                 return false;
404                 }
405         }
406         return true;
407 }
408
409 static int _pkginfo_get_packages(uid_t uid, const char *locale,
410                 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages)
411 {
412         static const char query_raw[] =
413                 "SELECT DISTINCT pi.package, pi.installed_storage, pi.external_path";
414         static const char query_basic[] =
415                 ", pi.package_version, pi.install_location, "
416                 "pi.package_removable, pi.package_preload, pi.package_readonly, "
417                 "pi.package_update, pi.package_appsetting, pi.package_system, "
418                 "pi.package_type, pi.package_size, pi.installed_time, "
419                 "pi.storeclient_id, pi.mainapp_id, pi.package_url, pi.root_path, "
420                 "pi.csc_path, pi.package_nodisplay, pi.package_api_version, "
421                 "pi.package_support_disable, pi.package_tep_name, "
422                 "pi.package_zip_mount_file, pi.package_support_mode";
423         static const char query_author[] =
424                 ", pi.author_name, pi.author_email, pi.author_href";
425         static const char query_label[] =
426                 ", COALESCE("
427                 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
428                 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
429         static const char query_icon[] =
430                 ", COALESCE("
431                 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
432                 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
433         static const char query_description[] =
434                 ", COALESCE("
435                 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
436                 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
437         static const char query_from_clause[] = " FROM package_info as pi";
438         int ret = PMINFO_R_ERROR;
439         int idx = 0;
440         char *dbpath;
441         char *tmp_record = NULL;
442         char *constraints = NULL;
443         char query[MAX_QUERY_LEN] = { '\0' };
444         package_x *info = NULL;
445         author_x *author = NULL;
446         GList *bind_params = NULL;
447         sqlite3 *db;
448         sqlite3_stmt *stmt = NULL;
449         pkgmgrinfo_filter_x *tmp_filter = NULL;
450         bool is_check_storage = true;
451         const uid_t global_user_uid = GLOBAL_USER;
452
453         dbpath = getUserPkgParserDBPathUID(uid);
454         if (dbpath == NULL)
455                 return PMINFO_R_ERROR;
456
457         ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
458         if (ret != SQLITE_OK) {
459                 _LOGD("failed to open db(%s): %d", dbpath, ret);
460                 free(dbpath);
461                 return PMINFO_R_ERROR;
462         }
463         free(dbpath);
464
465         if (filter != NULL) {
466                 tmp_filter = filter;
467         } else {
468                 ret = pkgmgrinfo_pkginfo_filter_create((void *)&tmp_filter);
469                 if (ret != PMINFO_R_OK) {
470                         _LOGE("Failed to create filter");
471                         return PMINFO_R_ERROR;
472                 }
473         }
474
475         is_check_storage = __check_package_storage_status(tmp_filter);
476
477         snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
478         if (flag & PMINFO_APPINFO_GET_BASICINFO)
479                 strncat(query, query_basic, sizeof(query) - strlen(query) - 1);
480         if (flag & PMINFO_PKGINFO_GET_AUTHOR)
481                 strncat(query, query_author, sizeof(query) - strlen(query) - 1);
482         if (flag & PMINFO_PKGINFO_GET_LABEL) {
483                 strncat(query, query_label, sizeof(query) - strlen(query) - 1);
484                 bind_params = g_list_append(bind_params, strdup(locale));
485         }
486         if (flag & PMINFO_PKGINFO_GET_ICON) {
487                 strncat(query, query_icon, sizeof(query) - strlen(query) - 1);
488                 bind_params = g_list_append(bind_params, strdup(locale));
489         }
490         if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
491                 strncat(query, query_description, sizeof(query) - strlen(query) - 1);
492                 bind_params = g_list_append(bind_params, strdup(locale));
493         }
494
495         strncat(query, query_from_clause, sizeof(query) - strlen(query) - 1);
496
497         ret = _get_filtered_query(tmp_filter, locale, uid, &constraints, &bind_params);
498         if (ret != PMINFO_R_OK) {
499                 LOGE("Failed to get WHERE clause");
500                 goto catch;
501         }
502
503         if (constraints)
504                 strncat(query, constraints, sizeof(query) - strlen(query) - 1);
505
506         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
507         if (ret != SQLITE_OK) {
508                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
509                 ret = PMINFO_R_ERROR;
510                 goto catch;
511         }
512
513         ret = __bind_params(stmt, bind_params);
514         if (ret != SQLITE_OK) {
515                 LOGE("Failed to bind parameters");
516                 goto catch;
517         }
518
519         while (sqlite3_step(stmt) == SQLITE_ROW) {
520                 info = calloc(1, sizeof(package_x));
521                 if (info == NULL) {
522                         LOGE("out of memory");
523                         ret = PMINFO_R_ERROR;
524                         goto catch;
525                 }
526                 idx = 0;
527                 _save_column_str(stmt, idx++, &info->package);
528                 _save_column_str(stmt, idx++, &info->installed_storage);
529                 _save_column_str(stmt, idx++, &info->external_path);
530
531                 if (flag & PMINFO_APPINFO_GET_BASICINFO) {
532                         _save_column_str(stmt, idx++, &info->version);
533                         _save_column_str(stmt, idx++, &info->installlocation);
534                         _save_column_str(stmt, idx++, &info->removable);
535                         _save_column_str(stmt, idx++, &info->preload);
536                         _save_column_str(stmt, idx++, &info->readonly);
537                         _save_column_str(stmt, idx++, &info->update);
538                         _save_column_str(stmt, idx++, &info->appsetting);
539                         _save_column_str(stmt, idx++, &info->system);
540                         _save_column_str(stmt, idx++, &info->type);
541                         _save_column_str(stmt, idx++, &info->package_size);
542                         _save_column_str(stmt, idx++, &info->installed_time);
543                         _save_column_str(stmt, idx++, &info->storeclient_id);
544                         _save_column_str(stmt, idx++, &info->mainapp_id);
545                         _save_column_str(stmt, idx++, &info->package_url);
546                         _save_column_str(stmt, idx++, &info->root_path);
547                         _save_column_str(stmt, idx++, &info->csc_path);
548                         _save_column_str(stmt, idx++, &info->nodisplay_setting);
549                         _save_column_str(stmt, idx++, &info->api_version);
550                         _save_column_str(stmt, idx++, &info->support_disable);
551                         _save_column_str(stmt, idx++, &info->tep_name);
552                         _save_column_str(stmt, idx++, &info->zip_mount_file);
553                         _save_column_str(stmt, idx++, &info->support_mode);
554                 }
555
556                 info->for_all_users =
557                         strdup((uid != global_user_uid) ? "false" : "true");
558
559                 if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
560                         /* TODO : author should be retrieved at package_localized_info */
561                         author = calloc(1, sizeof(author_x));
562                         if (author == NULL) {
563                                 ret = PMINFO_R_ERROR;
564                                 goto catch;
565                         }
566                         _save_column_str(stmt, idx++, &author->text);
567                         _save_column_str(stmt, idx++, &author->email);
568                         _save_column_str(stmt, idx++, &author->href);
569                         info->author = g_list_append(info->author, author);
570                 }
571
572                 if (flag & PMINFO_PKGINFO_GET_LABEL) {
573                         tmp_record = NULL;
574                         _save_column_str(stmt, idx++, &tmp_record);
575
576                         if (_add_label_info_into_list(locale, tmp_record, &info->label)) {
577                                 ret = PMINFO_R_ERROR;
578                                 goto catch;
579                         }
580                 }
581
582                 if (flag & PMINFO_PKGINFO_GET_ICON) {
583                         tmp_record = NULL;
584                         _save_column_str(stmt, idx++, &tmp_record);
585                         if (_add_icon_info_into_list(locale, tmp_record, &info->icon)) {
586                                 ret = PMINFO_R_ERROR;
587                                 goto catch;
588                         }
589                 }
590
591                 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
592                         tmp_record = NULL;
593                         _save_column_str(stmt, idx++, &tmp_record);
594                         if (_pkginfo_add_description_info_into_list(locale, tmp_record,
595                                         &info->description)) {
596                                 ret = PMINFO_R_ERROR;
597                                 goto catch;
598                         }
599                 }
600
601                 if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) {
602                         if (_pkginfo_get_privilege(db, info->package,
603                                                 &info->privileges)) {
604                                 ret = PMINFO_R_ERROR;
605                                 goto catch;
606                         }
607                 }
608
609                 if (flag & PMINFO_PKGINFO_GET_APPDEFINED_PRIVILEGE) {
610                         if (_pkginfo_get_appdefined_privilege(db, info->package,
611                                                 &info->appdefined_privileges)) {
612                                 ret = PMINFO_R_ERROR;
613                                 goto catch;
614                         }
615                 }
616
617                 if (flag & PMINFO_PKGINFO_GET_DEPENDENCY) {
618                         if (_pkginfo_get_dependency(db, info->package,
619                                                 &info->dependencies)) {
620                                 ret = PMINFO_R_ERROR;
621                                 goto catch;
622                         }
623                 }
624
625                 if (is_check_storage &&
626                                 __pkginfo_check_installed_storage(info) != PMINFO_R_OK) {
627                         ret = PMINFO_R_ERROR;
628                         pkgmgrinfo_basic_free_package(info);
629                         info = NULL;
630                         continue;
631                 }
632
633                 g_hash_table_insert(packages, (gpointer)info->package,
634                                 (gpointer)info);
635         }
636
637         ret = PMINFO_R_OK;
638
639 catch:
640         sqlite3_finalize(stmt);
641         sqlite3_close_v2(db);
642
643         if (constraints)
644                 free(constraints);
645
646         if (ret != PMINFO_R_OK && info != NULL)
647                 pkgmgrinfo_basic_free_package(info);
648
649         if (filter == NULL)
650                 pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
651
652         g_list_free_full(bind_params, free);
653
654         return ret;
655 }
656
657 static int _pkginfo_get_filtered_foreach_pkginfo(uid_t uid,
658                 pkgmgrinfo_filter_x *filter, int flag,
659                 pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data)
660 {
661         int ret;
662         char *locale;
663         package_x *pkg;
664         pkgmgr_pkginfo_x info;
665         pkgmgrinfo_filter_x *tmp_filter = NULL;
666         GHashTable *list;
667         GHashTableIter iter;
668         gpointer value;
669
670         locale = _get_system_locale();
671         if (locale == NULL)
672                 return PMINFO_R_ERROR;
673
674         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
675                         __free_packages);
676         if (list == NULL) {
677                 free(locale);
678                 return PMINFO_R_ERROR;
679         }
680
681         if (filter != NULL) {
682                 tmp_filter = (pkgmgrinfo_filter_x *)filter;
683         } else {
684                 ret = pkgmgrinfo_pkginfo_filter_create((void *)&tmp_filter);
685                 if (ret != PMINFO_R_OK) {
686                         _LOGE("Failed to create filter");
687                         g_hash_table_destroy(list);
688                         free(locale);
689                         return PMINFO_R_ERROR;
690                 }
691         }
692
693         if (__check_disable_filter_exist(tmp_filter) == false) {
694                 ret = pkgmgrinfo_pkginfo_filter_add_bool(tmp_filter,
695                                 PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
696                 if (ret != PMINFO_R_OK) {
697                         _LOGE("Failed to add filter");
698                         g_hash_table_destroy(list);
699                         free(locale);
700                         if (filter == NULL)
701                                 pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
702                         return PMINFO_R_ERROR;
703                 }
704         }
705
706         ret = _pkginfo_get_packages(uid, locale, tmp_filter,
707                         flag | PMINFO_PKGINFO_GET_BASICINFO, list);
708         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
709                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, tmp_filter,
710                                 flag | PMINFO_PKGINFO_GET_BASICINFO, list);
711
712         if (ret != PMINFO_R_OK) {
713                 g_hash_table_destroy(list);
714                 free(locale);
715                 if (filter == NULL)
716                         pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
717                 return PMINFO_R_ERROR;
718         }
719
720         g_hash_table_iter_init(&iter, list);
721         while (g_hash_table_iter_next(&iter, NULL, &value)) {
722                 pkg = (package_x *)value;
723                 info.uid = uid;
724                 info.pkg_info = pkg;
725                 info.locale = locale;
726                 if (pkg_list_cb(&info, user_data) < 0)
727                         break;
728         }
729
730         g_hash_table_destroy(list);
731         free(locale);
732
733         if (filter == NULL)
734                 pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
735
736         return PMINFO_R_OK;
737 }
738
739 static int _pkgmgrinfo_get_pkginfo(const char *pkgid, uid_t uid,
740         pkgmgrinfo_pkginfo_filter_h filter, pkgmgrinfo_pkginfo_h *handle)
741 {
742         int ret;
743         char *locale;
744         GHashTable *list;
745         pkgmgr_pkginfo_x *info;
746
747         if (pkgid == NULL || filter == NULL || handle == NULL) {
748                         LOGE("invalid parameter");
749                         return PMINFO_R_EINVAL;
750         }
751
752         locale = _get_system_locale();
753         if (locale == NULL)
754                 return PMINFO_R_ERROR;
755
756         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
757                         __free_packages);
758         if (list == NULL) {
759                 free(locale);
760                 return PMINFO_R_ERROR;
761         }
762
763         ret = _pkginfo_get_packages(uid, locale, filter,
764                         PMINFO_PKGINFO_GET_ALL, list);
765         if (!g_hash_table_size(list) && uid != GLOBAL_USER)
766                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
767                                 PMINFO_PKGINFO_GET_ALL, list);
768
769         if (ret != PMINFO_R_OK) {
770                 g_hash_table_destroy(list);
771                 free(locale);
772                 return ret;
773         }
774
775         if (!g_hash_table_size(list)) {
776                 _LOGD("pkginfo for [%s] is not existed for user [%d]",
777                                 pkgid, uid);
778                 g_hash_table_destroy(list);
779                 free(locale);
780                 return PMINFO_R_ENOENT;
781         }
782
783         info = calloc(1, sizeof(pkgmgr_pkginfo_x));
784         if (info == NULL) {
785                 _LOGE("out of memory");
786                 g_hash_table_destroy(list);
787                 free(locale);
788                 return PMINFO_R_ERROR;
789         }
790
791         info->uid = uid;
792         info->pkg_info = (package_x *)g_hash_table_lookup(list, pkgid);
793         info->locale = locale;
794
795         /* just free list only */
796         g_hash_table_steal(list, (gconstpointer)pkgid);
797         g_hash_table_destroy(list);
798
799         *handle = info;
800
801         return ret;
802 }
803
804 API int pkgmgrinfo_pkginfo_get_usr_pkginfo(const char *pkgid, uid_t uid,
805                 pkgmgrinfo_pkginfo_h *handle)
806 {
807         int ret;
808         pkgmgrinfo_pkginfo_filter_h filter;
809
810         if (pkgid == NULL || handle == NULL) {
811                 LOGE("invalid parameter");
812                 return PMINFO_R_EINVAL;
813         }
814
815         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
816         if (ret != PMINFO_R_OK)
817                 return ret;
818
819         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
820                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
821         if (ret != PMINFO_R_OK) {
822                 pkgmgrinfo_pkginfo_filter_destroy(filter);
823                 return PMINFO_R_ERROR;
824         }
825
826         ret = pkgmgrinfo_pkginfo_filter_add_bool(filter,
827                         PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
828         if (ret != PMINFO_R_OK) {
829                 pkgmgrinfo_pkginfo_filter_destroy(filter);
830                 return PMINFO_R_ERROR;
831         }
832
833         ret = _pkgmgrinfo_get_pkginfo(pkgid, uid, filter, handle);
834         pkgmgrinfo_pkginfo_filter_destroy(filter);
835
836         return ret;
837 }
838
839 API int pkgmgrinfo_pkginfo_get_pkginfo(const char *pkgid,
840                 pkgmgrinfo_pkginfo_h *handle)
841 {
842         return pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, _getuid(), handle);
843 }
844
845 API int pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(const char *pkgid,
846                 uid_t uid, pkgmgrinfo_pkginfo_h *handle)
847 {
848         int ret;
849         char *locale;
850         GHashTable *list;
851         pkgmgrinfo_pkginfo_filter_h filter;
852         pkgmgr_pkginfo_x *info;
853
854         if (pkgid == NULL || handle == NULL) {
855                 LOGE("invalid parameter");
856                 return PMINFO_R_EINVAL;
857         }
858
859         locale = _get_system_locale();
860         if (locale == NULL)
861                 return PMINFO_R_ERROR;
862
863         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
864         if (ret != PMINFO_R_OK) {
865                 free(locale);
866                 return ret;
867         }
868
869         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
870                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
871         if (ret != PMINFO_R_OK) {
872                 pkgmgrinfo_pkginfo_filter_destroy(filter);
873                 free(locale);
874                 return PMINFO_R_ERROR;
875         }
876
877         ret = pkgmgrinfo_pkginfo_filter_add_bool(filter,
878                         PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, true);
879         if (ret != PMINFO_R_OK) {
880                 pkgmgrinfo_pkginfo_filter_destroy(filter);
881                 free(locale);
882                 return PMINFO_R_ERROR;
883         }
884
885         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
886                         __free_packages);
887         if (list == NULL) {
888                 pkgmgrinfo_pkginfo_filter_destroy(filter);
889                 free(locale);
890                 return PMINFO_R_ERROR;
891         }
892
893         ret = _pkginfo_get_packages(uid, locale, filter,
894                         PMINFO_PKGINFO_GET_ALL, list);
895         if (!g_hash_table_size(list) && uid != GLOBAL_USER)
896                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
897                                 PMINFO_PKGINFO_GET_ALL, list);
898
899         pkgmgrinfo_pkginfo_filter_destroy(filter);
900         if (ret != PMINFO_R_OK) {
901                 g_hash_table_destroy(list);
902                 free(locale);
903                 return ret;
904         }
905
906         if (!g_hash_table_size(list)) {
907                 _LOGD("disabled pkginfo for [%s] is not existed for user [%d]",
908                                 pkgid, uid);
909                 g_hash_table_destroy(list);
910                 free(locale);
911                 return PMINFO_R_ENOENT;
912         }
913
914         info = calloc(1, sizeof(pkgmgr_pkginfo_x));
915         if (info == NULL) {
916                 _LOGE("out of memory");
917                 g_hash_table_destroy(list);
918                 free(locale);
919                 return PMINFO_R_ERROR;
920         }
921
922         info->uid = uid;
923         info->pkg_info = (package_x *)g_hash_table_lookup(list, pkgid);
924         info->locale = locale;
925
926         /* just free list only */
927         g_hash_table_steal(list, (gconstpointer)pkgid);
928         g_hash_table_destroy(list);
929
930         *handle = info;
931
932         return ret;
933 }
934
935 API int pkgmgrinfo_pkginfo_get_usr_all_pkginfo(const char *pkgid, uid_t uid,
936                 pkgmgrinfo_pkginfo_h *handle)
937 {
938
939         int ret;
940         pkgmgrinfo_pkginfo_filter_h filter;
941
942         if (pkgid == NULL || handle == NULL) {
943                 LOGE("invalid parameter");
944                 return PMINFO_R_EINVAL;
945         }
946
947         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
948         if (ret != PMINFO_R_OK)
949                 return ret;
950
951         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
952                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
953         if (ret != PMINFO_R_OK) {
954                 pkgmgrinfo_pkginfo_filter_destroy(filter);
955                 return PMINFO_R_ERROR;
956         }
957
958         ret = pkgmgrinfo_pkginfo_filter_add_bool(filter,
959                         PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE, false);
960         if (ret != PMINFO_R_OK) {
961                 pkgmgrinfo_pkginfo_filter_destroy(filter);
962                 return PMINFO_R_ERROR;
963         }
964
965         ret = _pkgmgrinfo_get_pkginfo(pkgid, uid, filter, handle);
966         pkgmgrinfo_pkginfo_filter_destroy(filter);
967
968         return ret;
969 }
970
971 API int pkgmgrinfo_pkginfo_get_disabled_pkginfo(const char *pkgid,
972                 pkgmgrinfo_pkginfo_h *handle)
973 {
974         return pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(pkgid, _getuid(),
975                         handle);
976 }
977
978 API int pkgmgrinfo_pkginfo_get_all_pkginfo(const char *pkgid,
979                 pkgmgrinfo_pkginfo_h *handle)
980 {
981         return pkgmgrinfo_pkginfo_get_usr_all_pkginfo(pkgid, _getuid(), handle);
982 }
983
984 API int pkgmgrinfo_pkginfo_get_usr_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
985                 int flag, void *user_data, uid_t uid)
986 {
987         int ret;
988         pkgmgrinfo_pkginfo_filter_h filter;
989
990         if (pkg_list_cb == NULL) {
991                 LOGE("invalid parameter");
992                 return PMINFO_R_EINVAL;
993         }
994
995         /* create an empty filter */
996         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
997         if (ret != PMINFO_R_OK)
998                 return ret;
999
1000         ret = _pkginfo_get_filtered_foreach_pkginfo(uid, filter, flag,
1001                         pkg_list_cb, user_data);
1002
1003         pkgmgrinfo_pkginfo_filter_destroy(filter);
1004
1005         return ret;
1006 }
1007
1008 API int pkgmgrinfo_pkginfo_get_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
1009                 int flag, void *user_data)
1010 {
1011         return pkgmgrinfo_pkginfo_get_usr_list_full(pkg_list_cb, flag,
1012                         user_data, _getuid());
1013 }
1014
1015 API int pkgmgrinfo_pkginfo_get_usr_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
1016                 void *user_data, uid_t uid)
1017 {
1018         int ret;
1019         pkgmgrinfo_pkginfo_filter_h filter;
1020
1021         if (pkg_list_cb == NULL) {
1022                 LOGE("invalid parameter");
1023                 return PMINFO_R_EINVAL;
1024         }
1025
1026         /* create an empty filter */
1027         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
1028         if (ret != PMINFO_R_OK)
1029                 return ret;
1030
1031         ret = _pkginfo_get_filtered_foreach_pkginfo(uid, filter,
1032                         PMINFO_PKGINFO_GET_ALL, pkg_list_cb, user_data);
1033
1034         pkgmgrinfo_pkginfo_filter_destroy(filter);
1035
1036         return ret;
1037 }
1038
1039 API int pkgmgrinfo_pkginfo_get_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
1040                 void *user_data)
1041 {
1042         return pkgmgrinfo_pkginfo_get_usr_list(pkg_list_cb, user_data,
1043                         _getuid());
1044 }
1045
1046 API int pkgmgrinfo_pkginfo_get_usr_disabled_list(
1047                 pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data, uid_t uid)
1048 {
1049         int ret;
1050         pkgmgrinfo_pkginfo_filter_h filter;
1051
1052         if (pkg_list_cb == NULL) {
1053                 LOGE("invalid parameter");
1054                 return PMINFO_R_EINVAL;
1055         }
1056
1057         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
1058         if (ret != PMINFO_R_OK)
1059                 return ret;
1060
1061         ret = pkgmgrinfo_pkginfo_filter_add_bool(filter,
1062                         PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, true);
1063         if (ret != PMINFO_R_OK) {
1064                 pkgmgrinfo_pkginfo_filter_destroy(filter);
1065                 return PMINFO_R_ERROR;
1066         }
1067
1068         ret = _pkginfo_get_filtered_foreach_pkginfo(uid, filter,
1069                         PMINFO_PKGINFO_GET_ALL, pkg_list_cb, user_data);
1070
1071         pkgmgrinfo_pkginfo_filter_destroy(filter);
1072
1073         return ret;
1074 }
1075
1076 API int pkgmgrinfo_pkginfo_get_disabled_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
1077                 void *user_data)
1078 {
1079         return pkgmgrinfo_pkginfo_get_usr_disabled_list(pkg_list_cb, user_data,
1080                         _getuid());
1081 }
1082
1083 API int pkgmgrinfo_pkginfo_get_pkgname(pkgmgrinfo_pkginfo_h handle, char **pkg_name)
1084 {
1085         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1086
1087         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1088         retvm_if(pkg_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1089
1090         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
1091                 return PMINFO_R_ERROR;
1092
1093         *pkg_name = (char *)info->pkg_info->package;
1094
1095         return PMINFO_R_OK;
1096 }
1097
1098 API int pkgmgrinfo_pkginfo_get_pkgid(pkgmgrinfo_pkginfo_h handle, char **pkgid)
1099 {
1100         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1101
1102         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1103         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1104
1105         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
1106                 return PMINFO_R_ERROR;
1107
1108         *pkgid = (char *)info->pkg_info->package;
1109
1110         return PMINFO_R_OK;
1111 }
1112
1113 API int pkgmgrinfo_pkginfo_get_type(pkgmgrinfo_pkginfo_h handle, char **type)
1114 {
1115         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1116
1117         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1118         retvm_if(type == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1119
1120         if (info->pkg_info == NULL)
1121                 return PMINFO_R_ERROR;
1122
1123         if (info->pkg_info->type == NULL)
1124                 *type = "";
1125         else
1126                 *type = (char *)info->pkg_info->type;
1127
1128         return PMINFO_R_OK;
1129 }
1130
1131 API int pkgmgrinfo_pkginfo_get_version(pkgmgrinfo_pkginfo_h handle, char **version)
1132 {
1133         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1134
1135         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1136         retvm_if(version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1137
1138         if (info->pkg_info == NULL)
1139                 return PMINFO_R_ERROR;
1140
1141         if (info->pkg_info->version == NULL)
1142                 *version = "";
1143         else
1144                 *version = (char *)info->pkg_info->version;
1145
1146         return PMINFO_R_OK;
1147 }
1148
1149 API int pkgmgrinfo_pkginfo_get_api_version(pkgmgrinfo_pkginfo_h handle, char **api_version)
1150 {
1151         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1152
1153         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1154         retvm_if(api_version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1155
1156         if (info->pkg_info == NULL)
1157                 return PMINFO_R_ERROR;
1158
1159         if (info->pkg_info->api_version == NULL)
1160                 *api_version = "";
1161         else
1162                 *api_version = (char *)info->pkg_info->api_version;
1163
1164         return PMINFO_R_OK;
1165 }
1166
1167 API int pkgmgrinfo_pkginfo_get_tep_name(pkgmgrinfo_pkginfo_h handle, char **tep_name)
1168 {
1169         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1170
1171         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1172         retvm_if(tep_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1173
1174         if (info->pkg_info == NULL || info->pkg_info->tep_name == NULL)
1175                 return PMINFO_R_ERROR;
1176
1177         *tep_name = (char *)info->pkg_info->tep_name;
1178
1179         return PMINFO_R_OK;
1180 }
1181
1182 API int pkgmgrinfo_pkginfo_get_zip_mount_file(pkgmgrinfo_pkginfo_h handle, char **zip_mount_file)
1183 {
1184         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1185
1186         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1187         retvm_if(zip_mount_file == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1188
1189         if (info->pkg_info == NULL)
1190                 return PMINFO_R_ERROR;
1191
1192         if (info->pkg_info->zip_mount_file == NULL)
1193                 *zip_mount_file = "";
1194         else
1195                 *zip_mount_file = (char *)info->pkg_info->zip_mount_file;
1196
1197         return PMINFO_R_OK;
1198 }
1199
1200 API int pkgmgrinfo_pkginfo_get_external_image_path(pkgmgrinfo_pkginfo_h handle, char **ext_image_path)
1201 {
1202         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1203
1204         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1205         retvm_if(ext_image_path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1206
1207         if (info->pkg_info == NULL)
1208                 return PMINFO_R_ERROR;
1209
1210         if (info->pkg_info->external_path == NULL)
1211                 return PMINFO_R_ENOENT;
1212
1213         *ext_image_path = (char *)info->pkg_info->external_path;
1214
1215         return PMINFO_R_OK;
1216 }
1217
1218 API int pkgmgrinfo_pkginfo_get_install_location(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_install_location *location)
1219 {
1220         char *val;
1221         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1222
1223         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1224         retvm_if(location == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1225
1226         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
1227                 return PMINFO_R_ERROR;
1228
1229         val = (char *)info->pkg_info->installlocation;
1230         if (strcmp(val, "internal-only") == 0)
1231                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
1232         else if (strcmp(val, "prefer-external") == 0)
1233                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
1234         else
1235                 *location = PMINFO_INSTALL_LOCATION_AUTO;
1236
1237         return PMINFO_R_OK;
1238 }
1239
1240 API int pkgmgrinfo_pkginfo_get_package_size(pkgmgrinfo_pkginfo_h handle, int *size)
1241 {
1242         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1243         char *temp = NULL;
1244
1245         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1246         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1247
1248         if (info->pkg_info == NULL)
1249                 return PMINFO_R_ERROR;
1250
1251         if (info->pkg_info->package_size == NULL) {
1252                 temp = strdup("");
1253                 if (temp == NULL) {
1254                         _LOGE("out of memory");
1255                         return PMINFO_R_ERROR;
1256                 } else {
1257                         info->pkg_info->package_size = temp;
1258                 }
1259         }
1260
1261         *size = atoi((char *)info->pkg_info->package_size);
1262
1263         return PMINFO_R_OK;
1264 }
1265
1266 API int pkgmgrinfo_pkginfo_get_icon(pkgmgrinfo_pkginfo_h handle, char **icon)
1267 {
1268         icon_x *ptr;
1269         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1270
1271         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1272         retvm_if(icon == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1273
1274         if (info->pkg_info == NULL || info->pkg_info->icon == NULL)
1275                 return PMINFO_R_ERROR;
1276
1277         ptr = (icon_x *)info->pkg_info->icon->data;
1278         if (ptr == NULL)
1279                 return PMINFO_R_ERROR;
1280
1281         /* TODO : should we return empty string if there was no icon? */
1282         if (ptr->text == NULL)
1283                 *icon = "";
1284         else
1285                 *icon = ptr->text;
1286
1287         return PMINFO_R_OK;
1288 }
1289
1290 API int pkgmgrinfo_pkginfo_get_label(pkgmgrinfo_pkginfo_h handle, char **label)
1291 {
1292         label_x *ptr;
1293         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1294
1295         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1296         retvm_if(label == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1297
1298         if (info->pkg_info == NULL || info->pkg_info->label == NULL)
1299                 return PMINFO_R_ERROR;
1300
1301         ptr = (label_x *)info->pkg_info->label->data;
1302         if (ptr == NULL)
1303                 return PMINFO_R_ERROR;
1304
1305         /* TODO : should we return empty string if there was no label? */
1306         if (ptr->text == NULL)
1307                 *label = "";
1308         else
1309                 *label = ptr->text;
1310
1311         return PMINFO_R_OK;
1312 }
1313
1314 API int pkgmgrinfo_pkginfo_get_description(pkgmgrinfo_pkginfo_h handle, char **description)
1315 {
1316         description_x *ptr;
1317         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1318
1319         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1320         retvm_if(description == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1321
1322         if (info->pkg_info == NULL || info->pkg_info->description == NULL)
1323                 return PMINFO_R_ERROR;
1324
1325         ptr = (description_x *)info->pkg_info->description->data;
1326         if (ptr == NULL)
1327                 return PMINFO_R_ERROR;
1328
1329         if (ptr->text == NULL)
1330                 *description = "";
1331         else
1332                 *description = (char *)ptr->text;
1333
1334         return PMINFO_R_OK;
1335 }
1336
1337 API int pkgmgrinfo_pkginfo_get_author_name(pkgmgrinfo_pkginfo_h handle, char **author_name)
1338 {
1339         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1340         author_x *author;
1341
1342         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1343         retvm_if(author_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1344
1345         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1346                 return PMINFO_R_ERROR;
1347
1348         author = (author_x *)info->pkg_info->author->data;
1349         if (author == NULL)
1350                 return PMINFO_R_ERROR;
1351
1352         if (author->text == NULL)
1353                 *author_name = "";
1354         else
1355                 *author_name = (char *)author->text;
1356
1357         return PMINFO_R_OK;
1358 }
1359
1360 API int pkgmgrinfo_pkginfo_get_author_email(pkgmgrinfo_pkginfo_h handle, char **author_email)
1361 {
1362         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1363         author_x *author;
1364
1365         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1366         retvm_if(author_email == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1367
1368         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1369                 return PMINFO_R_ERROR;
1370
1371         author = (author_x *)info->pkg_info->author->data;
1372         if (author == NULL)
1373                 return PMINFO_R_ERROR;
1374
1375         if (author->email == NULL)
1376                 *author_email = "";
1377         else
1378                 *author_email = (char *)author->email;
1379
1380         return PMINFO_R_OK;
1381 }
1382
1383 API int pkgmgrinfo_pkginfo_get_author_href(pkgmgrinfo_pkginfo_h handle, char **author_href)
1384 {
1385         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1386         author_x *author;
1387
1388         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1389         retvm_if(author_href == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1390
1391         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1392                 return PMINFO_R_ERROR;
1393
1394         author = (author_x *)info->pkg_info->author->data;
1395         if (author == NULL)
1396                 return PMINFO_R_ERROR;
1397
1398         if (author->href == NULL)
1399                 *author_href = "";
1400         else
1401                 *author_href = (char *)author->href;
1402
1403         return PMINFO_R_OK;
1404 }
1405
1406 API int pkgmgrinfo_pkginfo_get_installed_storage(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_installed_storage *storage)
1407 {
1408         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1409
1410         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1411         retvm_if(storage == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1412
1413         if (info->pkg_info == NULL || info->pkg_info->installed_storage == NULL)
1414                 return PMINFO_R_ERROR;
1415
1416         if (strcmp(info->pkg_info->installed_storage, "installed_internal") == 0)
1417                 *storage = PMINFO_INTERNAL_STORAGE;
1418         else if (strcmp(info->pkg_info->installed_storage, "installed_external") == 0)
1419                 *storage = PMINFO_EXTERNAL_STORAGE;
1420         else if (strcmp(info->pkg_info->installed_storage, "installed_extended") == 0)
1421                 *storage = PMINFO_EXTENDED_STORAGE;
1422         else
1423                 return PMINFO_R_ERROR;
1424
1425         return PMINFO_R_OK;
1426 }
1427
1428 API int pkgmgrinfo_pkginfo_get_installed_time(pkgmgrinfo_pkginfo_h handle, int *installed_time)
1429 {
1430         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1431
1432         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1433         retvm_if(installed_time == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1434
1435         if (info->pkg_info == NULL || info->pkg_info->installed_time == NULL)
1436                 return PMINFO_R_ERROR;
1437
1438         *installed_time = atoi(info->pkg_info->installed_time);
1439
1440         return PMINFO_R_OK;
1441 }
1442
1443 API int pkgmgrinfo_pkginfo_get_storeclientid(pkgmgrinfo_pkginfo_h handle, char **storeclientid)
1444 {
1445         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1446
1447         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1448         retvm_if(storeclientid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1449
1450         if (info->pkg_info == NULL)
1451                 return PMINFO_R_ERROR;
1452
1453         if (info->pkg_info->storeclient_id == NULL)
1454                 *storeclientid = "";
1455         else
1456                 *storeclientid = (char *)info->pkg_info->storeclient_id;
1457
1458         return PMINFO_R_OK;
1459 }
1460
1461 API int pkgmgrinfo_pkginfo_get_mainappid(pkgmgrinfo_pkginfo_h handle, char **mainappid)
1462 {
1463         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1464
1465         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1466         retvm_if(mainappid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1467
1468         if (info->pkg_info == NULL || info->pkg_info->mainapp_id == NULL)
1469                 return PMINFO_R_ERROR;
1470
1471         *mainappid = (char *)info->pkg_info->mainapp_id;
1472
1473         return PMINFO_R_OK;
1474 }
1475
1476 API int pkgmgrinfo_pkginfo_get_url(pkgmgrinfo_pkginfo_h handle, char **url)
1477 {
1478         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1479
1480         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1481         retvm_if(url == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1482
1483         if (info->pkg_info == NULL)
1484                 return PMINFO_R_ERROR;
1485
1486         if (info->pkg_info->package_url == NULL)
1487                 *url = "";
1488         else
1489                 *url = (char *)info->pkg_info->package_url;
1490
1491         return PMINFO_R_OK;
1492 }
1493
1494 API int pkgmgrinfo_pkginfo_get_root_path(pkgmgrinfo_pkginfo_h handle, char **path)
1495 {
1496         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1497
1498         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1499         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1500
1501         if (info->pkg_info == NULL || info->pkg_info->root_path == NULL)
1502                 return PMINFO_R_ERROR;
1503
1504         *path = (char *)info->pkg_info->root_path;
1505
1506         return PMINFO_R_OK;
1507 }
1508
1509 API int pkgmgrinfo_pkginfo_get_csc_path(pkgmgrinfo_pkginfo_h handle, char **path)
1510 {
1511         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1512
1513         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1514         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1515
1516         if (info->pkg_info == NULL)
1517                 return PMINFO_R_ERROR;
1518
1519         if (info->pkg_info->csc_path == NULL)
1520                 *path = "";
1521         else
1522                 *path = (char *)info->pkg_info->csc_path;
1523
1524         return PMINFO_R_OK;
1525 }
1526
1527 API int pkgmgrinfo_pkginfo_get_support_mode(pkgmgrinfo_pkginfo_h handle, int *support_mode)
1528 {
1529         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1530         retvm_if(support_mode == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1531
1532         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1533         if (info->pkg_info->support_mode)
1534                 *support_mode = atoi(info->pkg_info->support_mode);
1535         else
1536                 *support_mode = 0;
1537
1538         return PMINFO_R_OK;
1539 }
1540
1541 API int pkgmgrinfo_pkginfo_is_accessible(pkgmgrinfo_pkginfo_h handle, bool *accessible)
1542 {
1543         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1544         retvm_if(accessible == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1545
1546 #if 0 /* smack issue occured, check later */
1547         char *pkgid = NULL;
1548         pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
1549         if (pkgid == NULL) {
1550                  _LOGD("invalid func parameters\n");
1551                  return PMINFO_R_ERROR;
1552         }
1553          _LOGD("pkgmgr_get_pkg_external_validation() called\n");
1554
1555         FILE *fp = NULL;
1556         char app_mmc_path[FILENAME_MAX] = { 0, };
1557         char app_dir_path[FILENAME_MAX] = { 0, };
1558         char app_mmc_internal_path[FILENAME_MAX] = { 0, };
1559         snprintf(app_dir_path, FILENAME_MAX, "%s%s", PKG_INSTALLATION_PATH, pkgid);
1560         snprintf(app_mmc_path, FILENAME_MAX, "%s%s", PKG_SD_PATH, pkgid);
1561         snprintf(app_mmc_internal_path, FILENAME_MAX, "%s%s/.mmc", PKG_INSTALLATION_PATH, pkgid);
1562
1563         /*check whether application is in external memory or not */
1564         fp = fopen(app_mmc_path, "r");
1565         if (fp == NULL) {
1566                 _LOGD(" app path in external memory not accesible\n");
1567         } else {
1568                 fclose(fp);
1569                 fp = NULL;
1570                 *accessible = 1;
1571                 _LOGD("pkgmgr_get_pkg_external_validation() : SD_CARD \n");
1572                 return PMINFO_R_OK;
1573         }
1574
1575         /*check whether application is in internal or not */
1576         if (fp == NULL) {
1577                 _LOGD(" app path in internal memory not accesible\n");
1578                 *accessible = 0;
1579                 return PMINFO_R_ERROR;
1580         } else {
1581                 fclose(fp);
1582                 /*check whether the application is installed in SD card
1583                 but SD card is not present*/
1584                 fp = fopen(app_mmc_internal_path, "r");
1585                 if (fp == NULL) {
1586                         *accessible = 1;
1587                         _LOGD("pkgmgr_get_pkg_external_validation() : INTERNAL_MEM \n");
1588                         return PMINFO_R_OK;
1589                 } else {
1590                         *accessible = 0;
1591                         _LOGD("pkgmgr_get_pkg_external_validation() : ERROR_MMC_STATUS \n");
1592                 }
1593                 fclose(fp);
1594         }
1595
1596         _LOGD("pkgmgr_get_pkg_external_validation() end\n");
1597 #endif
1598
1599         *accessible = 1;
1600         return PMINFO_R_OK;
1601 }
1602
1603 API int pkgmgrinfo_pkginfo_is_removable(pkgmgrinfo_pkginfo_h handle, bool *removable)
1604 {
1605         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1606
1607         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1608         retvm_if(removable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1609
1610         if (info->pkg_info == NULL || info->pkg_info->removable == NULL)
1611                 return PMINFO_R_ERROR;
1612
1613         *removable = _get_bool_value(info->pkg_info->removable);
1614
1615         return PMINFO_R_OK;
1616 }
1617
1618 API int pkgmgrinfo_pkginfo_is_movable(pkgmgrinfo_pkginfo_h handle, bool *movable)
1619 {
1620         char *val;
1621         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1622
1623         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1624         retvm_if(movable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1625
1626         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
1627                 return PMINFO_R_ERROR;
1628
1629         val = (char *)info->pkg_info->installlocation;
1630         if (strcmp(val, "internal-only") == 0)
1631                 *movable = 0;
1632         else
1633                 *movable = 1;
1634
1635         return PMINFO_R_OK;
1636 }
1637
1638 API int pkgmgrinfo_pkginfo_is_preload(pkgmgrinfo_pkginfo_h handle, bool *preload)
1639 {
1640         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1641
1642         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1643         retvm_if(preload == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1644
1645         if (info->pkg_info == NULL || info->pkg_info->preload == NULL)
1646                 return PMINFO_R_ERROR;
1647
1648         *preload = _get_bool_value(info->pkg_info->preload);
1649
1650         return PMINFO_R_OK;
1651 }
1652
1653 API int pkgmgrinfo_pkginfo_is_system(pkgmgrinfo_pkginfo_h handle, bool *system)
1654 {
1655         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1656
1657         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1658         retvm_if(system == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1659
1660         if (info->pkg_info == NULL || info->pkg_info->system == NULL)
1661                 return PMINFO_R_ERROR;
1662
1663         *system = _get_bool_value(info->pkg_info->system);
1664
1665         return PMINFO_R_OK;
1666 }
1667
1668 API int pkgmgrinfo_pkginfo_is_readonly(pkgmgrinfo_pkginfo_h handle, bool *readonly)
1669 {
1670         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1671
1672         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1673         retvm_if(readonly == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1674
1675         if (info->pkg_info == NULL || info->pkg_info->readonly == NULL)
1676                 return PMINFO_R_ERROR;
1677
1678         *readonly = _get_bool_value(info->pkg_info->readonly);
1679
1680         return PMINFO_R_OK;
1681 }
1682
1683 API int pkgmgrinfo_pkginfo_is_update(pkgmgrinfo_pkginfo_h handle, bool *update)
1684 {
1685         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1686
1687         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1688         retvm_if(update == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1689
1690         if (info->pkg_info == NULL || info->pkg_info->update == NULL)
1691                 return PMINFO_R_ERROR;
1692
1693         *update = _get_bool_value(info->pkg_info->update);
1694
1695         return PMINFO_R_OK;
1696 }
1697
1698 API int pkgmgrinfo_pkginfo_is_support_disable(pkgmgrinfo_pkginfo_h handle, bool *support_disable)
1699 {
1700         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1701
1702         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1703         retvm_if(support_disable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1704
1705         if (info->pkg_info == NULL || info->pkg_info->support_disable == NULL)
1706                 return PMINFO_R_ERROR;
1707
1708         *support_disable = _get_bool_value(info->pkg_info->support_disable);
1709
1710         return PMINFO_R_OK;
1711 }
1712
1713 API int pkgmgrinfo_pkginfo_is_global(pkgmgrinfo_pkginfo_h handle, bool *global)
1714 {
1715         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1716
1717         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1718         retvm_if(global == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1719
1720         if (info->pkg_info == NULL || info->pkg_info->for_all_users == NULL)
1721                 return PMINFO_R_ERROR;
1722
1723         *global = _get_bool_value(info->pkg_info->for_all_users);
1724
1725         return PMINFO_R_OK;
1726 }
1727
1728 API int pkgmgrinfo_pkginfo_is_for_all_users(pkgmgrinfo_pkginfo_h handle, bool *for_all_users)
1729 {
1730         return pkgmgrinfo_pkginfo_is_global(handle, for_all_users);
1731 }
1732
1733 API int pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo_h handle)
1734 {
1735         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1736
1737         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1738
1739         __cleanup_pkginfo(info);
1740
1741         return PMINFO_R_OK;
1742 }
1743
1744 API int pkgmgrinfo_pkginfo_filter_create(pkgmgrinfo_pkginfo_filter_h *handle)
1745 {
1746         pkgmgrinfo_filter_x *filter;
1747
1748         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle output parameter is NULL\n");
1749
1750         filter = (pkgmgrinfo_filter_x *)calloc(1, sizeof(pkgmgrinfo_filter_x));
1751         if (filter == NULL) {
1752                 _LOGE("Out of Memory!!!");
1753                 return PMINFO_R_ERROR;
1754         }
1755
1756         *handle = filter;
1757
1758         return PMINFO_R_OK;
1759 }
1760
1761 API int pkgmgrinfo_pkginfo_filter_destroy(pkgmgrinfo_pkginfo_filter_h handle)
1762 {
1763         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1764
1765         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1766
1767         if (filter->list) {
1768                 g_slist_foreach(filter->list, __destroy_each_node, NULL);
1769                 g_slist_free(filter->list);
1770         }
1771
1772         g_slist_free_full(filter->list_metadata, __destroy_metadata_node);
1773
1774         free(filter);
1775
1776         return PMINFO_R_OK;
1777 }
1778
1779 API int pkgmgrinfo_pkginfo_filter_add_int(pkgmgrinfo_pkginfo_filter_h handle,
1780                                 const char *property, const int value)
1781 {
1782         char buf[PKG_VALUE_STRING_LEN_MAX] = {'\0'};
1783         char *val;
1784         GSList *link;
1785         int prop;
1786         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1787         pkgmgrinfo_node_x *node;
1788
1789         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1790         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1791
1792         prop = _pminfo_pkginfo_convert_to_prop_int(property);
1793         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_INT ||
1794                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_INT) {
1795                 _LOGE("Invalid Integer Property\n");
1796                 return PMINFO_R_EINVAL;
1797         }
1798         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1799         if (node == NULL) {
1800                 _LOGE("Out of Memory!!!\n");
1801                 return PMINFO_R_ERROR;
1802         }
1803         snprintf(buf, PKG_VALUE_STRING_LEN_MAX - 1, "%d", value);
1804         val = strndup(buf, PKG_VALUE_STRING_LEN_MAX - 1);
1805         if (val == NULL) {
1806                 _LOGE("Out of Memory\n");
1807                 free(node);
1808                 return PMINFO_R_ERROR;
1809         }
1810         node->prop = prop;
1811         node->value = val;
1812         /*If API is called multiple times for same property, we should override the previous values.
1813         Last value set will be used for filtering.*/
1814         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1815         if (link)
1816                 filter->list = g_slist_delete_link(filter->list, link);
1817         filter->list = g_slist_append(filter->list, (gpointer)node);
1818         return PMINFO_R_OK;
1819
1820 }
1821
1822 API int pkgmgrinfo_pkginfo_filter_add_bool(pkgmgrinfo_pkginfo_filter_h handle,
1823                                 const char *property, const bool value)
1824 {
1825         char *val;
1826         GSList *link;
1827         int prop;
1828         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1829         pkgmgrinfo_node_x *node;
1830
1831         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1832         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1833
1834         prop = _pminfo_pkginfo_convert_to_prop_bool(property);
1835         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_BOOL ||
1836                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_BOOL) {
1837                 _LOGE("Invalid Boolean Property\n");
1838                 return PMINFO_R_EINVAL;
1839         }
1840         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1841         if (node == NULL) {
1842                 _LOGE("Out of Memory!!!\n");
1843                 return PMINFO_R_ERROR;
1844         }
1845         if (value)
1846                 val = strndup("true", 4);
1847         else
1848                 val = strndup("false", 5);
1849         if (val == NULL) {
1850                 _LOGE("Out of Memory\n");
1851                 free(node);
1852                 return PMINFO_R_ERROR;
1853         }
1854         node->prop = prop;
1855         node->value = val;
1856         /*If API is called multiple times for same property, we should override the previous values.
1857         Last value set will be used for filtering.*/
1858         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1859         if (link)
1860                 filter->list = g_slist_delete_link(filter->list, link);
1861         filter->list = g_slist_append(filter->list, (gpointer)node);
1862         return PMINFO_R_OK;
1863
1864 }
1865
1866 API int pkgmgrinfo_pkginfo_filter_add_string(pkgmgrinfo_pkginfo_filter_h handle,
1867                                 const char *property, const char *value)
1868 {
1869         char *val;
1870         GSList *link;
1871         int prop;
1872         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1873         pkgmgrinfo_node_x *node;
1874
1875         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1876         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1877         retvm_if(value == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1878
1879         prop = _pminfo_pkginfo_convert_to_prop_str(property);
1880         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_STR ||
1881                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_STR) {
1882                 _LOGE("Invalid String Property\n");
1883                 return PMINFO_R_EINVAL;
1884         }
1885         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1886         if (node == NULL) {
1887                 _LOGE("Out of Memory!!!\n");
1888                 return PMINFO_R_ERROR;
1889         }
1890         if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_AUTO) == 0)
1891                 val = strndup("auto", PKG_STRING_LEN_MAX - 1);
1892         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_INTERNAL) == 0)
1893                 val = strndup("internal-only", PKG_STRING_LEN_MAX - 1);
1894         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_EXTERNAL) == 0)
1895                 val = strndup("prefer-external", PKG_STRING_LEN_MAX - 1);
1896         else if (strcmp(value, "installed_internal") == 0)
1897                 val = strndup("installed_internal", PKG_STRING_LEN_MAX - 1);
1898         else if (strcmp(value, "installed_external") == 0)
1899                 val = strndup("installed_external", PKG_STRING_LEN_MAX - 1);
1900         else
1901                 val = strndup(value, PKG_STRING_LEN_MAX - 1);
1902         if (val == NULL) {
1903                 _LOGE("Out of Memory\n");
1904                 free(node);
1905                 return PMINFO_R_ERROR;
1906         }
1907         node->prop = prop;
1908         node->value = val;
1909         /*If API is called multiple times for same property, we should override the previous values.
1910         Last value set will be used for filtering.*/
1911         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1912         if (link)
1913                 filter->list = g_slist_delete_link(filter->list, link);
1914         filter->list = g_slist_append(filter->list, (gpointer)node);
1915         return PMINFO_R_OK;
1916
1917 }
1918
1919 API int pkgmgrinfo_pkginfo_usr_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count, uid_t uid)
1920 {
1921         int ret;
1922         char *locale;
1923         GHashTable *list = NULL;
1924
1925         if (handle == NULL || count == NULL) {
1926                 _LOGE("invalid parameter");
1927                 return PMINFO_R_EINVAL;
1928         }
1929
1930         locale = _get_system_locale();
1931         if (locale == NULL)
1932                 return PMINFO_R_ERROR;
1933
1934         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
1935                         __free_packages);
1936         if (list == NULL) {
1937                 free(locale);
1938                 return PMINFO_R_ERROR;
1939         }
1940
1941         if (__check_disable_filter_exist((pkgmgrinfo_filter_x *)handle) == false) {
1942                 ret = pkgmgrinfo_pkginfo_filter_add_bool(handle,
1943                                 PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
1944                 if (ret != PMINFO_R_OK) {
1945                         free(locale);
1946                         g_hash_table_destroy(list);
1947                         return PMINFO_R_ERROR;
1948                 }
1949         }
1950
1951         ret = _pkginfo_get_packages(uid, locale,
1952                         (pkgmgrinfo_filter_x *)handle, 0, list);
1953         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
1954                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, handle, 0,
1955                                 list);
1956
1957         if (ret != PMINFO_R_OK) {
1958                 g_hash_table_destroy(list);
1959                 free(locale);
1960                 return PMINFO_R_ERROR;
1961         }
1962
1963         *count = g_hash_table_size(list);
1964
1965         g_hash_table_destroy(list);
1966         free(locale);
1967
1968         return PMINFO_R_OK;
1969 }
1970
1971 API int pkgmgrinfo_pkginfo_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count)
1972 {
1973         return pkgmgrinfo_pkginfo_usr_filter_count(handle, count, _getuid());
1974 }
1975
1976 API int pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(
1977                 pkgmgrinfo_pkginfo_filter_h handle,
1978                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data, uid_t uid)
1979 {
1980         if (handle == NULL || pkg_cb == NULL) {
1981                 LOGE("invalid parameter");
1982                 return PMINFO_R_EINVAL;
1983         }
1984
1985         return _pkginfo_get_filtered_foreach_pkginfo(uid, handle,
1986                         PMINFO_PKGINFO_GET_ALL, pkg_cb, user_data);
1987 }
1988
1989 API int pkgmgrinfo_pkginfo_filter_foreach_pkginfo(pkgmgrinfo_pkginfo_filter_h handle,
1990                                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data)
1991 {
1992         return pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, pkg_cb, user_data, _getuid());
1993 }
1994
1995 API int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle,
1996                         pkgmgrinfo_pkg_privilege_list_cb privilege_func, void *user_data)
1997 {
1998         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1999         retvm_if(privilege_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
2000         int ret;
2001         privilege_x *privilege;
2002         appdefined_privilege_x *appdefined_privilege;
2003         GList *tmp;
2004         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
2005
2006         if (info->pkg_info == NULL)
2007                 return PMINFO_R_ERROR;
2008
2009         for (tmp = info->pkg_info->privileges; tmp; tmp = tmp->next) {
2010                 privilege = (privilege_x *)tmp->data;
2011                 if (privilege == NULL)
2012                         continue;
2013                 ret = privilege_func(privilege->value, user_data);
2014                 if (ret < 0)
2015                         return PMINFO_R_OK;
2016         }
2017
2018         for (tmp = info->pkg_info->appdefined_privileges; tmp;
2019                         tmp = tmp->next) {
2020                 appdefined_privilege = (appdefined_privilege_x *)tmp->data;
2021                 if (appdefined_privilege == NULL)
2022                         continue;
2023                 ret = privilege_func(appdefined_privilege->value, user_data);
2024                 if (ret < 0)
2025                         return PMINFO_R_OK;
2026         }
2027         return PMINFO_R_OK;
2028 }
2029
2030 API int pkgmgrinfo_pkginfo_foreach_appdefined_privilege(
2031                 pkgmgrinfo_pkginfo_h handle,
2032                 pkgmgrinfo_pkg_appdefined_privilege_list_cb privilege_func,
2033                 void *user_data)
2034 {
2035         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
2036         retvm_if(privilege_func == NULL, PMINFO_R_EINVAL,
2037                         "Callback function is NULL");
2038         int ret;
2039         appdefined_privilege_x *privilege;
2040         GList *tmp;
2041         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
2042
2043         if (info->pkg_info == NULL)
2044                 return PMINFO_R_ERROR;
2045
2046         for (tmp = info->pkg_info->appdefined_privileges; tmp;
2047                         tmp = tmp->next) {
2048                 privilege = (appdefined_privilege_x *)tmp->data;
2049                 if (privilege == NULL)
2050                         continue;
2051                 ret = privilege_func(privilege->value, privilege->license,
2052                                 user_data);
2053                 if (ret < 0)
2054                         break;
2055         }
2056         return PMINFO_R_OK;
2057 }
2058
2059 API int pkgmgrinfo_pkginfo_foreach_dependency(pkgmgrinfo_pkginfo_h handle,
2060                 pkgmgrinfo_pkg_dependency_list_cb dependency_cb,
2061                 void *user_data)
2062 {
2063         int ret;
2064         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
2065         GList *tmp;
2066         dependency_x *dependency;
2067
2068         if (handle == NULL || dependency_cb == NULL) {
2069                 LOGE("invalid parameter");
2070                 return PMINFO_R_EINVAL;
2071         }
2072
2073         if (info->pkg_info == NULL)
2074                 return PMINFO_R_ERROR;
2075
2076         for (tmp = info->pkg_info->dependencies; tmp; tmp = tmp->next) {
2077                 dependency = (dependency_x *)tmp->data;
2078                 if (dependency == NULL)
2079                         continue;
2080                 ret = dependency_cb(dependency->depends_on, dependency->type,
2081                                 dependency->required_version, user_data);
2082                 if (ret < 0)
2083                         break;
2084         }
2085
2086         return PMINFO_R_OK;
2087 }
2088
2089 struct required_by {
2090         char *pkgid;
2091         char *type;
2092         char *version;
2093 };
2094
2095 static int _get_required_by(sqlite3 *db, const char *pkgid, GQueue **queue,
2096                 GHashTable **table, GList **pkg_list)
2097 {
2098         static const char query[] =
2099                 "SELECT package, type, required_version "
2100                 "FROM package_dependency_info WHERE depends_on=?";
2101         int ret;
2102         sqlite3_stmt *stmt;
2103         struct required_by *req;
2104
2105         /* already checked */
2106         if (!g_hash_table_insert(*table, strdup(pkgid), GINT_TO_POINTER(1)))
2107                 return PMINFO_R_OK;
2108
2109         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2110         if (ret != SQLITE_OK) {
2111                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
2112                 return PMINFO_R_ERROR;
2113         }
2114
2115         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
2116         if (ret != SQLITE_OK) {
2117                 LOGE("bind failed: %s", sqlite3_errmsg(db));
2118                 sqlite3_finalize(stmt);
2119                 return PMINFO_R_ERROR;
2120         }
2121
2122         while (sqlite3_step(stmt) == SQLITE_ROW) {
2123                 req = calloc(1, sizeof(struct required_by));
2124                 if (req == NULL) {
2125                         LOGE("out of memory");
2126                         sqlite3_finalize(stmt);
2127                         return PMINFO_R_ERROR;
2128                 }
2129                 _save_column_str(stmt, 0, &req->pkgid);
2130                 _save_column_str(stmt, 1, &req->type);
2131                 _save_column_str(stmt, 2, &req->version);
2132
2133                 *pkg_list = g_list_append(*pkg_list, req);
2134                 g_queue_push_tail(*queue, strdup(req->pkgid));
2135         }
2136
2137         sqlite3_finalize(stmt);
2138
2139         return PMINFO_R_OK;
2140 }
2141
2142 static int _pkginfo_foreach_required_by(uid_t uid, const char *pkgid,
2143                 GList **pkg_list)
2144 {
2145         int ret;
2146         char *dbpath;
2147         sqlite3 *db;
2148         GQueue *queue;
2149         GHashTable *table;
2150         char *item;
2151
2152         dbpath = getUserPkgParserDBPathUID(uid);
2153         if (dbpath == NULL)
2154                 return PMINFO_R_ERROR;
2155
2156         ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
2157         if (ret != SQLITE_OK) {
2158                 LOGD("failed to open db(%s): %d", dbpath, ret);
2159                 free(dbpath);
2160                 return PMINFO_R_ERROR;
2161         }
2162         free(dbpath);
2163
2164         queue = g_queue_new();
2165         if (queue == NULL) {
2166                 LOGE("out of memory");
2167                 sqlite3_close_v2(db);
2168                 return PMINFO_R_ERROR;
2169         }
2170
2171         table = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
2172
2173         g_queue_push_tail(queue, strdup(pkgid));
2174         while (!g_queue_is_empty(queue)) {
2175                 item = g_queue_pop_head(queue);
2176                 ret = _get_required_by(db, item, &queue, &table, pkg_list);
2177                 free(item);
2178                 if (ret != PMINFO_R_OK) {
2179                         LOGE("failed to get required by pkgs");
2180                         g_hash_table_destroy(table);
2181                         g_queue_free_full(queue, free);
2182                         sqlite3_close_v2(db);
2183                         return PMINFO_R_ERROR;
2184                 }
2185         }
2186
2187         g_hash_table_destroy(table);
2188         g_queue_free_full(queue, free);
2189         sqlite3_close_v2(db);
2190
2191         return PMINFO_R_OK;
2192 }
2193
2194 static void __free_required_by(gpointer data)
2195 {
2196         struct required_by *req = (struct required_by *)data;
2197
2198         free(req->pkgid);
2199         free(req->type);
2200         free(req->version);
2201         free(req);
2202 }
2203
2204 API int pkgmgrinfo_pkginfo_foreach_required_by(pkgmgrinfo_pkginfo_h handle,
2205                 pkgmgrinfo_pkg_dependency_list_cb dependency_cb,
2206                 void *user_data)
2207 {
2208         int ret;
2209         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
2210         GList *pkg_list = NULL;
2211         GList *l;
2212         struct required_by *req;
2213
2214         if (handle == NULL || dependency_cb == NULL || info->pkg_info == NULL) {
2215                 LOGE("invalid parameter");
2216                 return PMINFO_R_EINVAL;
2217         }
2218
2219         ret = _pkginfo_foreach_required_by(info->uid, info->pkg_info->package,
2220                         &pkg_list);
2221         if (ret == PMINFO_R_OK && info->uid != GLOBAL_USER)
2222                 ret = _pkginfo_foreach_required_by(GLOBAL_USER,
2223                                 info->pkg_info->package, &pkg_list);
2224
2225         if (ret != PMINFO_R_OK) {
2226                 g_list_free_full(pkg_list, __free_required_by);
2227                 return ret;
2228         }
2229
2230         for (l = pkg_list; l != NULL; l = l->next) {
2231                 req = (struct required_by *)l->data;
2232                 ret = dependency_cb(req->pkgid, req->type, req->version,
2233                                 user_data);
2234                 if (ret < 0)
2235                         break;
2236         }
2237
2238         g_list_free_full(pkg_list, __free_required_by);
2239
2240         return PMINFO_R_OK;
2241 }
2242
2243 int __compare_package_version(const char *version, int *major,
2244                 int *minor, int *macro, int *nano)
2245 {
2246         char *version_temp = NULL;
2247         char *major_str = NULL;
2248         char *minor_str = NULL;
2249         char *macro_str = NULL;
2250         char *nano_str = NULL;
2251         char *save_str = NULL;
2252
2253         if (version == NULL || major == NULL || minor == NULL ||
2254                 macro == NULL || nano == NULL) {
2255                 return PMINFO_R_EINVAL;
2256         }
2257
2258         version_temp = strdup(version);
2259         if (version_temp == NULL) {
2260                 LOGE("Out of memory");
2261                 return PMINFO_R_ERROR;
2262         }
2263
2264         major_str = strtok_r(version_temp, ".", &save_str);
2265         if (major_str == NULL) {
2266                 _LOGE("major version is NULL");
2267                 free(version_temp);
2268                 return PMINFO_R_ERROR;
2269         }
2270
2271         minor_str = strtok_r(NULL, ".", &save_str);
2272         if (minor_str == NULL) {
2273                 _LOGE("minor version is NULL");
2274                 free(version_temp);
2275                 return PMINFO_R_ERROR;
2276         }
2277
2278         *major = atoi(major_str);
2279         *minor = atoi(minor_str);
2280         *macro = 0;
2281         *nano = 0;
2282         macro_str = strtok_r(NULL, ".", &save_str);
2283         if (macro_str == NULL) {
2284                 _LOGD("macro version is NULL");
2285         } else {
2286                 *macro = atoi(macro_str);
2287                 nano_str = strtok_r(NULL, ".", &save_str);
2288                 if (nano_str) {
2289                         *nano = atoi(nano_str);
2290                         _LOGD("nano version exists");
2291                 }
2292         }
2293         _LOGD("version = [%s] -> major = [%d], minor = [%d]," \
2294                 " macro = [%d], nano = [%d]", version, *major,
2295                 *minor, *macro, *nano);
2296
2297         free(version_temp);
2298
2299         return PMINFO_R_OK;
2300 }
2301
2302 API int pkgmgrinfo_compare_package_version(const char *current_version,
2303                 const char *target_version,
2304                 pkgmgrinfo_version_compare_type *res)
2305 {
2306         int ret = 0;
2307         int current_version_major = 0;
2308         int current_version_minor = 0;
2309         int current_version_macro = 0;
2310         int current_version_nano = 0;
2311         int target_version_major = 0;
2312         int target_version_minor = 0;
2313         int target_version_macro = 0;
2314         int target_version_nano = 0;
2315
2316         if (current_version == NULL || target_version == NULL ||
2317                 res == NULL) {
2318                 _LOGE("Invalid parameter");
2319                 return PMINFO_R_EINVAL;
2320         }
2321
2322         ret = __compare_package_version(target_version,
2323                 &target_version_major, &target_version_minor,
2324                 &target_version_macro, &target_version_nano);
2325         if (ret < 0) {
2326                 _LOGE("Failed to compare target version(%d)", ret);
2327                 return PMINFO_R_ERROR;
2328         }
2329
2330         ret = __compare_package_version(current_version,
2331                 &current_version_major, &current_version_minor,
2332                 &current_version_macro, &current_version_nano);
2333         if (ret < 0) {
2334                 _LOGE("Failed to compare current version(%d)", ret);
2335                 return PMINFO_R_ERROR;
2336         }
2337
2338         _LOGD("new[%d.%d.%d.%d] old[%d.%d.%d.%d]", target_version_major,
2339                 target_version_minor, target_version_macro,
2340                 target_version_nano, current_version_major,
2341                 current_version_minor, current_version_macro,
2342                 target_version_nano);
2343
2344         if (target_version_major > current_version_major)
2345                 *res = PMINFO_VERSION_NEW;
2346         else if (target_version_major < current_version_major)
2347                 *res = PMINFO_VERSION_OLD;
2348         else if (target_version_minor > current_version_minor)
2349                 *res = PMINFO_VERSION_NEW;
2350         else if (target_version_minor < current_version_minor)
2351                 *res = PMINFO_VERSION_OLD;
2352         else if (target_version_macro > current_version_macro)
2353                 *res = PMINFO_VERSION_NEW;
2354         else if (target_version_macro < current_version_macro)
2355                 *res = PMINFO_VERSION_OLD;
2356         else if (target_version_nano > current_version_nano)
2357                 *res = PMINFO_VERSION_NEW;
2358         else if (target_version_nano < current_version_nano)
2359                 *res = PMINFO_VERSION_OLD;
2360         else
2361                 *res = PMINFO_VERSION_SAME;
2362
2363         return PMINFO_R_OK;
2364 }