Fix a bug regarding category data
[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, *result;
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 (ret = readdir_r(dp, &ep, &result);
132                         ret == 0 && result != NULL;
133                         ret = readdir_r(dp, &ep, &result)) {
134                 if (!strcmp(ep.d_name, ".") ||
135                         !strcmp(ep.d_name, "..")) {
136                         continue;
137                 }
138                 snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
139                          ep.d_name);
140                 if (lstat(abs_filename, &fileinfo) < 0)
141                         perror(abs_filename);
142                 else {
143                         if (S_ISDIR(fileinfo.st_mode)) {
144                                 total += fileinfo.st_size;
145                                 if (strcmp(ep.d_name, ".")
146                                     && strcmp(ep.d_name, "..")) {
147                                         ret = _pkgmgr_calculate_dir_size
148                                             (abs_filename);
149                                         total = total + ret;
150                                 }
151                         } else if (S_ISLNK(fileinfo.st_mode)) {
152                                 continue;
153                         } else {
154                                 /*It is a file. Calculate the actual
155                                 size occupied (in terms of 4096 blocks)*/
156                         q = (fileinfo.st_size / BLOCK_SIZE);
157                         r = (fileinfo.st_size % BLOCK_SIZE);
158                         if (r)
159                                 q = q + 1;
160                         total += q * BLOCK_SIZE;
161                         }
162                 }
163         }
164         (void)closedir(dp);
165         return total;
166
167 }
168
169 static int _pkginfo_add_description_info_into_list(const char *locale,
170                 char *record, GList **description)
171 {
172         description_x *info;
173
174         info = calloc(1, sizeof(description_x));
175         if (info == NULL) {
176                 LOGE("out of memory");
177                 return PMINFO_R_ERROR;
178         }
179         info->lang = strdup(locale);
180         info->text = record;
181         *description = g_list_append(*description, info);
182
183         return PMINFO_R_OK;
184 }
185
186 static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid,
187                 GList **privileges)
188 {
189         static const char query_raw[] =
190                 "SELECT DISTINCT privilege, type FROM package_privilege_info "
191                 "WHERE package=%Q";
192         int ret;
193         char *query;
194         sqlite3_stmt *stmt;
195         privilege_x *privilege;
196
197         query = sqlite3_mprintf(query_raw, pkgid);
198         if (query == NULL) {
199                 LOGE("out of memory");
200                 return PMINFO_R_ERROR;
201         }
202
203         ret = sqlite3_prepare_v2(db, query, strlen(query),
204                         &stmt, NULL);
205         sqlite3_free(query);
206         if (ret != SQLITE_OK) {
207                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
208                 return PMINFO_R_ERROR;
209         }
210
211         while (sqlite3_step(stmt) == SQLITE_ROW) {
212                 privilege = calloc(1, sizeof(privilege_x));
213                 _save_column_str(stmt, 0, &privilege->value);
214                 _save_column_str(stmt, 1, &privilege->type);
215                 *privileges = g_list_append(*privileges,
216                                 (gpointer)privilege);
217         }
218
219         sqlite3_finalize(stmt);
220
221         return PMINFO_R_OK;
222 }
223
224 static const char join_localized_info[] =
225         " LEFT OUTER JOIN package_localized_info"
226         "  ON pi.package=package_localized_info.package"
227         "  AND package_localized_info.package_locale=?";
228 static const char join_privilege_info[] =
229         " LEFT OUTER JOIN package_privilege_info"
230         "  ON pi.package=package_privilege_info.package";
231
232 static int _get_filtered_query(pkgmgrinfo_filter_x *filter,
233                 const char *locale, uid_t uid, char **query, GList **bind_params)
234 {
235         int joined = 0;
236         char buf[MAX_QUERY_LEN] = { '\0' };
237         char buf2[MAX_QUERY_LEN] = { '\0' };
238         char *condition = NULL;
239         size_t len = 0;
240         GSList *list = NULL;
241
242         if (filter == NULL)
243                 return PMINFO_R_OK;
244
245         strncat(buf, " WHERE 1=1 ", MAX_QUERY_LEN - len - 1);
246         len += strlen(" WHERE 1=1 ");
247         for (list = filter->list; list; list = list->next) {
248                 joined |= __get_filter_condition(list->data, uid, &condition,
249                                 bind_params);
250                 if (condition == NULL)
251                         continue;
252
253                 strncat(buf, " AND ", MAX_QUERY_LEN - len - 1);
254                 len += strlen(" AND ");
255
256                 strncat(buf, condition, sizeof(buf) - len - 1);
257                 len += strlen(condition);
258                 free(condition);
259                 condition = NULL;
260         }
261
262         if (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) {
263                 strncat(buf2, join_localized_info, MAX_QUERY_LEN - len - 1);
264                 len += strlen(join_localized_info);
265                 *bind_params = g_list_append(*bind_params, strdup(locale));
266         }
267         if (joined & E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO) {
268                 strncat(buf2, join_privilege_info, MAX_QUERY_LEN - len - 1);
269                 len += strlen(join_privilege_info);
270         }
271         strncat(buf2, buf, MAX_QUERY_LEN - len - 1);
272
273         *query = strdup(buf2);
274         if (*query == NULL)
275                 return PMINFO_R_ERROR;
276
277         return PMINFO_R_OK;
278 }
279
280 static void __free_packages(gpointer data)
281 {
282         pkgmgrinfo_basic_free_package((package_x *)data);
283 }
284
285 static bool __check_disable_filter_exist(pkgmgrinfo_filter_x *filter)
286 {
287         GSList *link;
288
289         if (filter == NULL)
290                 return false;
291
292         link = g_slist_find_custom(filter->list, NULL, __pkg_disable_chk_func);
293         if (link)
294                 return true;
295
296         return false;
297 }
298
299 static int __bind_params(sqlite3_stmt *stmt, GList *params)
300 {
301         GList *tmp_list = NULL;
302         int idx = 0;
303         int ret;
304
305         if (stmt == NULL || params == NULL)
306                 return PMINFO_R_EINVAL;
307
308         tmp_list = params;
309         while (tmp_list) {
310                 ret = sqlite3_bind_text(stmt, ++idx, (char *)tmp_list->data, -1, SQLITE_STATIC);
311                 if (ret != SQLITE_OK)
312                         return PMINFO_R_ERROR;
313                 tmp_list = tmp_list->next;
314         }
315
316         return PMINFO_R_OK;
317 }
318
319 static bool __check_package_storage_status(pkgmgrinfo_filter_x *tmp_filter)
320 {
321         GSList *tmp_list = NULL;
322         pkgmgrinfo_node_x *tmp_node = NULL;
323         int property = -1;
324
325         property = _pminfo_pkginfo_convert_to_prop_bool(PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE);
326         for (tmp_list = tmp_filter->list; tmp_list != NULL;
327                         tmp_list = g_slist_next(tmp_list)) {
328                 tmp_node = (pkgmgrinfo_node_x *)tmp_list->data;
329                 if (property == tmp_node->prop) {
330                         if (strcmp(tmp_node->value, "true") == 0)
331                                 return true;
332                         else
333                                 return false;
334                 }
335         }
336         return true;
337 }
338
339 static int _pkginfo_get_packages(uid_t uid, const char *locale,
340                 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages)
341 {
342         static const char query_raw[] =
343                 "SELECT DISTINCT pi.package, pi.package_version, "
344                 "pi.install_location, pi.package_removable, "
345                 "pi.package_preload, pi.package_readonly, pi.package_update, "
346                 "pi.package_appsetting, pi.package_system, pi.package_type, "
347                 "pi.package_size, pi.installed_time, pi.installed_storage, "
348                 "pi.storeclient_id, pi.mainapp_id, pi.package_url, "
349                 "pi.root_path, pi.csc_path, pi.package_nodisplay, "
350                 "pi.package_api_version, pi.package_support_disable, "
351                 "pi.package_tep_name, pi.package_zip_mount_file, pi.external_path, "
352                 "pi.package_support_mode";
353         static const char query_author[] =
354                 ", pi.author_name, pi.author_email, pi.author_href";
355         static const char query_label[] =
356                 ", COALESCE("
357                 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
358                 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
359         static const char query_icon[] =
360                 ", COALESCE("
361                 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
362                 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
363         static const char query_description[] =
364                 ", COALESCE("
365                 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
366                 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
367         static const char query_from_clause[] = " FROM package_info as pi";
368         int ret = PMINFO_R_ERROR;
369         int idx = 0;
370         int query_len = 0;
371         char *dbpath;
372         char *tmp_record = NULL;
373         char *constraints = NULL;
374         char query[MAX_QUERY_LEN] = { '\0' };
375         package_x *info = NULL;
376         author_x *author = NULL;
377         GList *bind_params = NULL;
378         sqlite3 *db;
379         sqlite3_stmt *stmt;
380         pkgmgrinfo_filter_x *tmp_filter = NULL;
381         bool is_check_storage = true;
382
383         dbpath = getUserPkgParserDBPathUID(uid);
384         if (dbpath == NULL)
385                 return PMINFO_R_ERROR;
386
387         ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
388         if (ret != SQLITE_OK) {
389                 _LOGD("failed to open db: %d", ret);
390                 free(dbpath);
391                 return PMINFO_R_ERROR;
392         }
393         free(dbpath);
394
395         if (filter != NULL) {
396                 tmp_filter = filter;
397         } else {
398                 ret = pkgmgrinfo_pkginfo_filter_create((void *)&tmp_filter);
399                 if (ret != PMINFO_R_OK) {
400                         _LOGE("Failed to create filter");
401                         return PMINFO_R_ERROR;
402                 }
403         }
404
405         is_check_storage = __check_package_storage_status(tmp_filter);
406
407         query_len = strlen(query_raw);
408         snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
409         if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
410                 strncat(query, query_author, MAX_QUERY_LEN - query_len - 1);
411                 query_len += strlen(query_author);
412         }
413         if (flag & PMINFO_PKGINFO_GET_LABEL) {
414                 strncat(query, query_label, MAX_QUERY_LEN - query_len - 1);
415                 query_len += strlen(query_label);
416                 bind_params = g_list_append(bind_params, strdup(locale));
417         }
418         if (flag & PMINFO_PKGINFO_GET_ICON) {
419                 strncat(query, query_icon, MAX_QUERY_LEN - query_len - 1);
420                 query_len += strlen(query_icon);
421                 bind_params = g_list_append(bind_params, strdup(locale));
422         }
423         if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
424                 strncat(query, query_description, MAX_QUERY_LEN - query_len - 1);
425                 query_len += strlen(query_description);
426                 bind_params = g_list_append(bind_params, strdup(locale));
427         }
428
429         strncat(query, query_from_clause, MAX_QUERY_LEN - query_len - 1);
430         query_len += strlen(query_from_clause);
431
432         ret = _get_filtered_query(tmp_filter, locale, uid, &constraints, &bind_params);
433         if (ret != PMINFO_R_OK) {
434                 LOGE("Failed to get WHERE clause");
435                 goto catch;
436         }
437
438         if (constraints)
439                 strncat(query, constraints, MAX_QUERY_LEN - query_len - 1);
440
441         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
442         if (ret != SQLITE_OK) {
443                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
444                 ret = PMINFO_R_ERROR;
445                 goto catch;
446         }
447
448         ret = __bind_params(stmt, bind_params);
449         if (ret != SQLITE_OK) {
450                 LOGE("Failed to bind parameters");
451                 goto catch;
452         }
453
454         while (sqlite3_step(stmt) == SQLITE_ROW) {
455                 info = calloc(1, sizeof(package_x));
456                 if (info == NULL) {
457                         LOGE("out of memory");
458                         ret = PMINFO_R_ERROR;
459                         goto catch;
460                 }
461                 idx = 0;
462                 _save_column_str(stmt, idx++, &info->package);
463                 if (g_hash_table_contains(packages,
464                                         (gconstpointer)info->package)) {
465                         free(info->package);
466                         free(info);
467                         info = NULL;
468                         continue;
469                 }
470                 _save_column_str(stmt, idx++, &info->version);
471                 _save_column_str(stmt, idx++, &info->installlocation);
472                 _save_column_str(stmt, idx++, &info->removable);
473                 _save_column_str(stmt, idx++, &info->preload);
474                 _save_column_str(stmt, idx++, &info->readonly);
475                 _save_column_str(stmt, idx++, &info->update);
476                 _save_column_str(stmt, idx++, &info->appsetting);
477                 _save_column_str(stmt, idx++, &info->system);
478                 _save_column_str(stmt, idx++, &info->type);
479                 _save_column_str(stmt, idx++, &info->package_size);
480                 _save_column_str(stmt, idx++, &info->installed_time);
481                 _save_column_str(stmt, idx++, &info->installed_storage);
482                 _save_column_str(stmt, idx++, &info->storeclient_id);
483                 _save_column_str(stmt, idx++, &info->mainapp_id);
484                 _save_column_str(stmt, idx++, &info->package_url);
485                 _save_column_str(stmt, idx++, &info->root_path);
486                 _save_column_str(stmt, idx++, &info->csc_path);
487                 _save_column_str(stmt, idx++, &info->nodisplay_setting);
488                 _save_column_str(stmt, idx++, &info->api_version);
489                 _save_column_str(stmt, idx++, &info->support_disable);
490                 _save_column_str(stmt, idx++, &info->tep_name);
491                 _save_column_str(stmt, idx++, &info->zip_mount_file);
492                 _save_column_str(stmt, idx++, &info->external_path);
493                 _save_column_str(stmt, idx++, &info->support_mode);
494                 info->for_all_users =
495                         strdup((uid != GLOBAL_USER) ? "false" : "true");
496
497                 if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
498                         /* TODO : author should be retrieved at package_localized_info */
499                         author = calloc(1, sizeof(author_x));
500                         if (author == NULL) {
501                                 ret = PMINFO_R_ERROR;
502                                 goto catch;
503                         }
504                         _save_column_str(stmt, idx++, &author->text);
505                         _save_column_str(stmt, idx++, &author->email);
506                         _save_column_str(stmt, idx++, &author->href);
507                         info->author = g_list_append(info->author, author);
508                 }
509
510                 if (flag & PMINFO_PKGINFO_GET_LABEL) {
511                         tmp_record = NULL;
512                         _save_column_str(stmt, idx++, &tmp_record);
513
514                         if (_add_label_info_into_list(locale, tmp_record, &info->label)) {
515                                 ret = PMINFO_R_ERROR;
516                                 goto catch;
517                         }
518                 }
519
520                 if (flag & PMINFO_PKGINFO_GET_ICON) {
521                         tmp_record = NULL;
522                         _save_column_str(stmt, idx++, &tmp_record);
523                         if (_add_icon_info_into_list(locale, tmp_record, &info->icon)) {
524                                 ret = PMINFO_R_ERROR;
525                                 goto catch;
526                         }
527                 }
528
529                 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
530                         tmp_record = NULL;
531                         _save_column_str(stmt, idx++, &tmp_record);
532                         if (_pkginfo_add_description_info_into_list(locale, tmp_record,
533                                         &info->description)) {
534                                 ret = PMINFO_R_ERROR;
535                                 goto catch;
536                         }
537                 }
538
539                 if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) {
540                         if (_pkginfo_get_privilege(db, info->package,
541                                                 &info->privileges)) {
542                                 ret = PMINFO_R_ERROR;
543                                 goto catch;
544                         }
545                 }
546
547                 if (is_check_storage &&
548                                 __pkginfo_check_installed_storage(info) != PMINFO_R_OK) {
549                         ret = PMINFO_R_ERROR;
550                         pkgmgrinfo_basic_free_package(info);
551                         info = NULL;
552                         continue;
553                 }
554
555                 g_hash_table_insert(packages, (gpointer)info->package,
556                                 (gpointer)info);
557         }
558
559         ret = PMINFO_R_OK;
560
561 catch:
562         if (constraints)
563                 free(constraints);
564
565         if (ret != PMINFO_R_OK && info != NULL)
566                 pkgmgrinfo_basic_free_package(info);
567
568         if (filter == NULL)
569                 pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
570
571         g_list_free_full(bind_params, free);
572         sqlite3_close_v2(db);
573         sqlite3_finalize(stmt);
574
575         return ret;
576 }
577
578 static int _pkginfo_get_filtered_foreach_pkginfo(uid_t uid,
579                 pkgmgrinfo_filter_x *filter, int flag,
580                 pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data)
581 {
582         int ret;
583         char *locale;
584         package_x *pkg;
585         pkgmgr_pkginfo_x info;
586         pkgmgrinfo_filter_x *tmp_filter = NULL;
587         GHashTable *list;
588         GHashTableIter iter;
589         gpointer value;
590
591         locale = _get_system_locale();
592         if (locale == NULL)
593                 return PMINFO_R_ERROR;
594
595         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
596                         __free_packages);
597         if (list == NULL) {
598                 free(locale);
599                 return PMINFO_R_ERROR;
600         }
601
602         if (filter != NULL) {
603                 tmp_filter = (pkgmgrinfo_filter_x *)filter;
604         } else {
605                 ret = pkgmgrinfo_pkginfo_filter_create((void *)&tmp_filter);
606                 if (ret != PMINFO_R_OK) {
607                         _LOGE("Failed to create filter");
608                         g_hash_table_destroy(list);
609                         return PMINFO_R_ERROR;
610                 }
611         }
612
613         if (__check_disable_filter_exist(tmp_filter) == false)
614                 pkgmgrinfo_pkginfo_filter_add_bool(tmp_filter,
615                                 PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
616
617         ret = _pkginfo_get_packages(uid, locale, tmp_filter, flag, list);
618         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
619                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, tmp_filter,
620                                 flag, list);
621
622         if (ret != PMINFO_R_OK) {
623                 g_hash_table_destroy(list);
624                 free(locale);
625                 if (filter == NULL)
626                         pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
627                 return PMINFO_R_ERROR;
628         }
629
630         g_hash_table_iter_init(&iter, list);
631         while (g_hash_table_iter_next(&iter, NULL, &value)) {
632                 pkg = (package_x *)value;
633                 info.uid = uid;
634                 info.pkg_info = pkg;
635                 info.locale = locale;
636                 if (pkg_list_cb(&info, user_data) < 0)
637                         break;
638         }
639
640         g_hash_table_destroy(list);
641         free(locale);
642
643         if (filter == NULL)
644                 pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
645
646         return PMINFO_R_OK;
647 }
648
649 static int _pkgmgrinfo_get_pkginfo(const char *pkgid, uid_t uid,
650         pkgmgrinfo_pkginfo_filter_h filter, pkgmgrinfo_pkginfo_h *handle)
651 {
652         int ret;
653         char *locale;
654         GHashTable *list;
655         pkgmgr_pkginfo_x *info;
656
657         if (pkgid == NULL || filter == NULL || handle == NULL) {
658                         LOGE("invalid parameter");
659                         return PMINFO_R_EINVAL;
660         }
661
662         locale = _get_system_locale();
663         if (locale == NULL)
664                 return PMINFO_R_ERROR;
665
666         list = g_hash_table_new(g_str_hash, g_str_equal);
667         if (list == NULL) {
668                 free(locale);
669                 return PMINFO_R_ERROR;
670         }
671
672         ret = _pkginfo_get_packages(uid, locale, filter,
673                         PMINFO_PKGINFO_GET_ALL, list);
674         if (!g_hash_table_size(list) && uid != GLOBAL_USER)
675                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
676                                 PMINFO_PKGINFO_GET_ALL, list);
677
678         if (!g_hash_table_size(list)) {
679                 _LOGI("pkginfo for [%s] is not existed for user [%d]",
680                                 pkgid, uid);
681                 g_hash_table_destroy(list);
682                 free(locale);
683                 return PMINFO_R_ENOENT;
684         }
685
686         info = calloc(1, sizeof(pkgmgr_pkginfo_x));
687         if (info == NULL) {
688                 _LOGE("out of memory");
689                 g_hash_table_destroy(list);
690                 free(locale);
691                 return PMINFO_R_ERROR;
692         }
693
694         info->uid = uid;
695         info->pkg_info = (package_x *)g_hash_table_lookup(list, pkgid);
696         info->locale = locale;
697
698         /* just free list only */
699         g_hash_table_destroy(list);
700
701         *handle = info;
702
703         return ret;
704 }
705
706 API int pkgmgrinfo_pkginfo_get_usr_pkginfo(const char *pkgid, uid_t uid,
707                 pkgmgrinfo_pkginfo_h *handle)
708 {
709         int ret;
710         pkgmgrinfo_pkginfo_filter_h filter;
711
712         if (pkgid == NULL || handle == NULL) {
713                 LOGE("invalid parameter");
714                 return PMINFO_R_EINVAL;
715         }
716
717         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
718         if (ret != PMINFO_R_OK)
719                 return ret;
720
721         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
722                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
723         if (ret != PMINFO_R_OK) {
724                 pkgmgrinfo_pkginfo_filter_destroy(filter);
725                 return PMINFO_R_ERROR;
726         }
727
728         ret = pkgmgrinfo_pkginfo_filter_add_bool(filter,
729                         PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
730         if (ret != PMINFO_R_OK) {
731                 pkgmgrinfo_pkginfo_filter_destroy(filter);
732                 return PMINFO_R_ERROR;
733         }
734
735         ret = _pkgmgrinfo_get_pkginfo(pkgid, uid, filter, handle);
736         pkgmgrinfo_pkginfo_filter_destroy(filter);
737
738         return ret;
739 }
740
741 API int pkgmgrinfo_pkginfo_get_pkginfo(const char *pkgid,
742                 pkgmgrinfo_pkginfo_h *handle)
743 {
744         return pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, _getuid(), handle);
745 }
746
747 API int pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(const char *pkgid,
748                 uid_t uid, pkgmgrinfo_pkginfo_h *handle)
749 {
750         int ret;
751         char *locale;
752         GHashTable *list;
753         pkgmgrinfo_pkginfo_filter_h filter;
754         pkgmgr_pkginfo_x *info;
755
756         if (pkgid == NULL || handle == NULL) {
757                 LOGE("invalid parameter");
758                 return PMINFO_R_EINVAL;
759         }
760
761         locale = _get_system_locale();
762         if (locale == NULL)
763                 return PMINFO_R_ERROR;
764
765         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
766         if (ret != PMINFO_R_OK) {
767                 free(locale);
768                 return ret;
769         }
770
771         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
772                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
773         if (ret != PMINFO_R_OK) {
774                 pkgmgrinfo_pkginfo_filter_destroy(filter);
775                 free(locale);
776                 return PMINFO_R_ERROR;
777         }
778
779         ret = pkgmgrinfo_pkginfo_filter_add_bool(filter,
780                         PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, true);
781         if (ret != PMINFO_R_OK) {
782                 pkgmgrinfo_pkginfo_filter_destroy(filter);
783                 free(locale);
784                 return PMINFO_R_ERROR;
785         }
786
787         list = g_hash_table_new(g_str_hash, g_str_equal);
788         if (list == NULL) {
789                 pkgmgrinfo_pkginfo_filter_destroy(filter);
790                 free(locale);
791                 return PMINFO_R_ERROR;
792         }
793
794         ret = _pkginfo_get_packages(uid, locale, filter,
795                         PMINFO_PKGINFO_GET_ALL, list);
796         if (!g_hash_table_size(list) && uid != GLOBAL_USER)
797                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
798                                 PMINFO_PKGINFO_GET_ALL, list);
799
800         pkgmgrinfo_pkginfo_filter_destroy(filter);
801         if (ret != PMINFO_R_OK) {
802                 g_hash_table_destroy(list);
803                 free(locale);
804                 return ret;
805         }
806
807         if (!g_hash_table_size(list)) {
808                 _LOGI("disabled pkginfo for [%s] is not existed for user [%d]",
809                                 pkgid, uid);
810                 g_hash_table_destroy(list);
811                 free(locale);
812                 return PMINFO_R_ENOENT;
813         }
814
815         info = calloc(1, sizeof(pkgmgr_pkginfo_x));
816         if (info == NULL) {
817                 _LOGE("out of memory");
818                 g_hash_table_destroy(list);
819                 free(locale);
820                 return PMINFO_R_ERROR;
821         }
822
823         info->uid = uid;
824         info->pkg_info = (package_x *)g_hash_table_lookup(list, pkgid);
825         info->locale = locale;
826
827         /* just free list only */
828         g_hash_table_destroy(list);
829
830         *handle = info;
831
832         return ret;
833 }
834
835 API int pkgmgrinfo_pkginfo_get_usr_all_pkginfo(const char *pkgid, uid_t uid,
836                 pkgmgrinfo_pkginfo_h *handle)
837 {
838
839         int ret;
840         pkgmgrinfo_pkginfo_filter_h filter;
841
842         if (pkgid == NULL || handle == NULL) {
843                 LOGE("invalid parameter");
844                 return PMINFO_R_EINVAL;
845         }
846
847         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
848         if (ret != PMINFO_R_OK)
849                 return ret;
850
851         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
852                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
853         if (ret != PMINFO_R_OK) {
854                 pkgmgrinfo_pkginfo_filter_destroy(filter);
855                 return PMINFO_R_ERROR;
856         }
857
858         ret = pkgmgrinfo_pkginfo_filter_add_bool(filter,
859                         PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE, false);
860         if (ret != PMINFO_R_OK) {
861                 pkgmgrinfo_pkginfo_filter_destroy(filter);
862                 return PMINFO_R_ERROR;
863         }
864
865         ret = _pkgmgrinfo_get_pkginfo(pkgid, uid, filter, handle);
866         pkgmgrinfo_pkginfo_filter_destroy(filter);
867
868         return ret;
869 }
870
871 API int pkgmgrinfo_pkginfo_get_disabled_pkginfo(const char *pkgid,
872                 pkgmgrinfo_pkginfo_h *handle)
873 {
874         return pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(pkgid, _getuid(),
875                         handle);
876 }
877
878 API int pkgmgrinfo_pkginfo_get_all_pkginfo(const char *pkgid,
879                 pkgmgrinfo_pkginfo_h *handle)
880 {
881         return pkgmgrinfo_pkginfo_get_usr_all_pkginfo(pkgid, _getuid(), handle);
882 }
883
884 API int pkgmgrinfo_pkginfo_get_usr_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
885                 int flag, void *user_data, uid_t uid)
886 {
887         int ret;
888         pkgmgrinfo_pkginfo_filter_h filter;
889
890         if (pkg_list_cb == NULL) {
891                 LOGE("invalid parameter");
892                 return PMINFO_R_EINVAL;
893         }
894
895         /* create an empty filter */
896         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
897         if (ret != PMINFO_R_OK)
898                 return ret;
899
900         ret = _pkginfo_get_filtered_foreach_pkginfo(uid, filter, flag,
901                         pkg_list_cb, user_data);
902
903         pkgmgrinfo_pkginfo_filter_destroy(filter);
904
905         return ret;
906 }
907
908 API int pkgmgrinfo_pkginfo_get_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
909                 int flag, void *user_data)
910 {
911         return pkgmgrinfo_pkginfo_get_usr_list_full(pkg_list_cb, flag,
912                         user_data, _getuid());
913 }
914
915 API int pkgmgrinfo_pkginfo_get_usr_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
916                 void *user_data, uid_t uid)
917 {
918         int ret;
919         pkgmgrinfo_pkginfo_filter_h filter;
920
921         if (pkg_list_cb == NULL) {
922                 LOGE("invalid parameter");
923                 return PMINFO_R_EINVAL;
924         }
925
926         /* create an empty filter */
927         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
928         if (ret != PMINFO_R_OK)
929                 return ret;
930
931         ret = _pkginfo_get_filtered_foreach_pkginfo(uid, filter,
932                         PMINFO_PKGINFO_GET_ALL, pkg_list_cb, user_data);
933
934         pkgmgrinfo_pkginfo_filter_destroy(filter);
935
936         return ret;
937 }
938
939 API int pkgmgrinfo_pkginfo_get_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
940                 void *user_data)
941 {
942         return pkgmgrinfo_pkginfo_get_usr_list(pkg_list_cb, user_data,
943                         _getuid());
944 }
945
946 API int pkgmgrinfo_pkginfo_get_usr_disabled_list(
947                 pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data, uid_t uid)
948 {
949         int ret;
950         pkgmgrinfo_pkginfo_filter_h filter;
951
952         if (pkg_list_cb == NULL) {
953                 LOGE("invalid parameter");
954                 return PMINFO_R_EINVAL;
955         }
956
957         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
958         if (ret != PMINFO_R_OK)
959                 return ret;
960
961         ret = pkgmgrinfo_pkginfo_filter_add_bool(filter,
962                         PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, true);
963         if (ret != PMINFO_R_OK) {
964                 pkgmgrinfo_pkginfo_filter_destroy(filter);
965                 return PMINFO_R_ERROR;
966         }
967
968         ret = _pkginfo_get_filtered_foreach_pkginfo(uid, filter,
969                         PMINFO_PKGINFO_GET_ALL, pkg_list_cb, user_data);
970
971         pkgmgrinfo_pkginfo_filter_destroy(filter);
972
973         return ret;
974 }
975
976 API int pkgmgrinfo_pkginfo_get_disabled_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
977                 void *user_data)
978 {
979         return pkgmgrinfo_pkginfo_get_usr_disabled_list(pkg_list_cb, user_data,
980                         _getuid());
981 }
982
983 API int pkgmgrinfo_pkginfo_get_pkgname(pkgmgrinfo_pkginfo_h handle, char **pkg_name)
984 {
985         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
986
987         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
988         retvm_if(pkg_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
989
990         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
991                 return PMINFO_R_ERROR;
992
993         *pkg_name = (char *)info->pkg_info->package;
994
995         return PMINFO_R_OK;
996 }
997
998 API int pkgmgrinfo_pkginfo_get_pkgid(pkgmgrinfo_pkginfo_h handle, char **pkgid)
999 {
1000         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1001
1002         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1003         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1004
1005         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
1006                 return PMINFO_R_ERROR;
1007
1008         *pkgid = (char *)info->pkg_info->package;
1009
1010         return PMINFO_R_OK;
1011 }
1012
1013 API int pkgmgrinfo_pkginfo_get_type(pkgmgrinfo_pkginfo_h handle, char **type)
1014 {
1015         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1016
1017         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1018         retvm_if(type == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1019
1020         if (info->pkg_info == NULL)
1021                 return PMINFO_R_ERROR;
1022
1023         if (info->pkg_info->type == NULL)
1024                 *type = "";
1025         else
1026                 *type = (char *)info->pkg_info->type;
1027
1028         return PMINFO_R_OK;
1029 }
1030
1031 API int pkgmgrinfo_pkginfo_get_version(pkgmgrinfo_pkginfo_h handle, char **version)
1032 {
1033         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1034
1035         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1036         retvm_if(version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1037
1038         if (info->pkg_info == NULL)
1039                 return PMINFO_R_ERROR;
1040
1041         if (info->pkg_info->version == NULL)
1042                 *version = "";
1043         else
1044                 *version = (char *)info->pkg_info->version;
1045
1046         return PMINFO_R_OK;
1047 }
1048
1049 API int pkgmgrinfo_pkginfo_get_api_version(pkgmgrinfo_pkginfo_h handle, char **api_version)
1050 {
1051         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1052
1053         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1054         retvm_if(api_version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1055
1056         if (info->pkg_info == NULL)
1057                 return PMINFO_R_ERROR;
1058
1059         if (info->pkg_info->api_version == NULL)
1060                 *api_version = "";
1061         else
1062                 *api_version = (char *)info->pkg_info->api_version;
1063
1064         return PMINFO_R_OK;
1065 }
1066
1067 API int pkgmgrinfo_pkginfo_get_tep_name(pkgmgrinfo_pkginfo_h handle, char **tep_name)
1068 {
1069         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1070
1071         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1072         retvm_if(tep_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1073
1074         if (info->pkg_info == NULL || info->pkg_info->tep_name == NULL)
1075                 return PMINFO_R_ERROR;
1076
1077         *tep_name = (char *)info->pkg_info->tep_name;
1078
1079         return PMINFO_R_OK;
1080 }
1081
1082 API int pkgmgrinfo_pkginfo_get_zip_mount_file(pkgmgrinfo_pkginfo_h handle, char **zip_mount_file)
1083 {
1084         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1085
1086         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1087         retvm_if(zip_mount_file == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1088
1089         if (info->pkg_info == NULL)
1090                 return PMINFO_R_ERROR;
1091
1092         if (info->pkg_info->zip_mount_file == NULL)
1093                 *zip_mount_file = "";
1094         else
1095                 *zip_mount_file = (char *)info->pkg_info->zip_mount_file;
1096
1097         return PMINFO_R_OK;
1098 }
1099
1100 API int pkgmgrinfo_pkginfo_get_external_image_path(pkgmgrinfo_pkginfo_h handle, char **ext_image_path)
1101 {
1102         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1103
1104         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1105         retvm_if(ext_image_path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1106
1107         if (info->pkg_info == NULL)
1108                 return PMINFO_R_ERROR;
1109
1110         if (info->pkg_info->external_path == NULL)
1111                 return PMINFO_R_ENOENT;
1112
1113         *ext_image_path = (char *)info->pkg_info->external_path;
1114
1115         return PMINFO_R_OK;
1116 }
1117
1118 API int pkgmgrinfo_pkginfo_get_install_location(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_install_location *location)
1119 {
1120         char *val;
1121         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1122
1123         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1124         retvm_if(location == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1125
1126         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
1127                 return PMINFO_R_ERROR;
1128
1129         val = (char *)info->pkg_info->installlocation;
1130         if (strcmp(val, "internal-only") == 0)
1131                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
1132         else if (strcmp(val, "prefer-external") == 0)
1133                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
1134         else
1135                 *location = PMINFO_INSTALL_LOCATION_AUTO;
1136
1137         return PMINFO_R_OK;
1138 }
1139
1140 API int pkgmgrinfo_pkginfo_get_package_size(pkgmgrinfo_pkginfo_h handle, int *size)
1141 {
1142         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1143         char *temp = NULL;
1144
1145         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1146         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1147
1148         if (info->pkg_info == NULL)
1149                 return PMINFO_R_ERROR;
1150
1151         if (info->pkg_info->package_size == NULL) {
1152                 temp = strdup("");
1153                 if (temp == NULL) {
1154                         _LOGE("out of memory");
1155                         return PMINFO_R_ERROR;
1156                 } else {
1157                         info->pkg_info->package_size = temp;
1158                 }
1159         }
1160
1161         *size = atoi((char *)info->pkg_info->package_size);
1162
1163         return PMINFO_R_OK;
1164 }
1165
1166 API int pkgmgrinfo_pkginfo_get_icon(pkgmgrinfo_pkginfo_h handle, char **icon)
1167 {
1168         icon_x *ptr;
1169         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1170
1171         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1172         retvm_if(icon == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1173
1174         if (info->pkg_info == NULL || info->pkg_info->icon == NULL)
1175                 return PMINFO_R_ERROR;
1176
1177         ptr = (icon_x *)info->pkg_info->icon->data;
1178         if (ptr == NULL)
1179                 return PMINFO_R_ERROR;
1180
1181         /* TODO : should we return empty string if there was no icon? */
1182         if (ptr->text == NULL)
1183                 *icon = "";
1184         else
1185                 *icon = ptr->text;
1186
1187         return PMINFO_R_OK;
1188 }
1189
1190 API int pkgmgrinfo_pkginfo_get_label(pkgmgrinfo_pkginfo_h handle, char **label)
1191 {
1192         label_x *ptr;
1193         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1194
1195         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1196         retvm_if(label == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1197
1198         if (info->pkg_info == NULL || info->pkg_info->label == NULL)
1199                 return PMINFO_R_ERROR;
1200
1201         ptr = (label_x *)info->pkg_info->label->data;
1202         if (ptr == NULL)
1203                 return PMINFO_R_ERROR;
1204
1205         /* TODO : should we return empty string if there was no label? */
1206         if (ptr->text == NULL)
1207                 *label = "";
1208         else
1209                 *label = ptr->text;
1210
1211         return PMINFO_R_OK;
1212 }
1213
1214 API int pkgmgrinfo_pkginfo_get_description(pkgmgrinfo_pkginfo_h handle, char **description)
1215 {
1216         description_x *ptr;
1217         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1218
1219         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1220         retvm_if(description == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1221
1222         if (info->pkg_info == NULL || info->pkg_info->description == NULL)
1223                 return PMINFO_R_ERROR;
1224
1225         ptr = (description_x *)info->pkg_info->description->data;
1226         if (ptr == NULL)
1227                 return PMINFO_R_ERROR;
1228
1229         if (ptr->text == NULL)
1230                 *description = "";
1231         else
1232                 *description = (char *)ptr->text;
1233
1234         return PMINFO_R_OK;
1235 }
1236
1237 API int pkgmgrinfo_pkginfo_get_author_name(pkgmgrinfo_pkginfo_h handle, char **author_name)
1238 {
1239         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1240         author_x *author;
1241
1242         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1243         retvm_if(author_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1244
1245         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1246                 return PMINFO_R_ERROR;
1247
1248         author = (author_x *)info->pkg_info->author->data;
1249         if (author == NULL)
1250                 return PMINFO_R_ERROR;
1251
1252         if (author->text == NULL)
1253                 *author_name = "";
1254         else
1255                 *author_name = (char *)author->text;
1256
1257         return PMINFO_R_OK;
1258 }
1259
1260 API int pkgmgrinfo_pkginfo_get_author_email(pkgmgrinfo_pkginfo_h handle, char **author_email)
1261 {
1262         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1263         author_x *author;
1264
1265         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1266         retvm_if(author_email == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1267
1268         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1269                 return PMINFO_R_ERROR;
1270
1271         author = (author_x *)info->pkg_info->author->data;
1272         if (author == NULL)
1273                 return PMINFO_R_ERROR;
1274
1275         if (author->email == NULL)
1276                 *author_email = "";
1277         else
1278                 *author_email = (char *)author->email;
1279
1280         return PMINFO_R_OK;
1281 }
1282
1283 API int pkgmgrinfo_pkginfo_get_author_href(pkgmgrinfo_pkginfo_h handle, char **author_href)
1284 {
1285         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1286         author_x *author;
1287
1288         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1289         retvm_if(author_href == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1290
1291         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1292                 return PMINFO_R_ERROR;
1293
1294         author = (author_x *)info->pkg_info->author->data;
1295         if (author == NULL)
1296                 return PMINFO_R_ERROR;
1297
1298         if (author->href == NULL)
1299                 *author_href = "";
1300         else
1301                 *author_href = (char *)author->href;
1302
1303         return PMINFO_R_OK;
1304 }
1305
1306 API int pkgmgrinfo_pkginfo_get_installed_storage(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_installed_storage *storage)
1307 {
1308         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1309
1310         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1311         retvm_if(storage == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1312
1313         if (info->pkg_info == NULL || info->pkg_info->installed_storage == NULL)
1314                 return PMINFO_R_ERROR;
1315
1316         if (strcmp(info->pkg_info->installed_storage, "installed_internal") == 0)
1317                 *storage = PMINFO_INTERNAL_STORAGE;
1318         else if (strcmp(info->pkg_info->installed_storage, "installed_external") == 0)
1319                 *storage = PMINFO_EXTERNAL_STORAGE;
1320         else
1321                 return PMINFO_R_ERROR;
1322
1323         return PMINFO_R_OK;
1324 }
1325
1326 API int pkgmgrinfo_pkginfo_get_installed_time(pkgmgrinfo_pkginfo_h handle, int *installed_time)
1327 {
1328         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1329
1330         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1331         retvm_if(installed_time == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1332
1333         if (info->pkg_info == NULL || info->pkg_info->installed_time == NULL)
1334                 return PMINFO_R_ERROR;
1335
1336         *installed_time = atoi(info->pkg_info->installed_time);
1337
1338         return PMINFO_R_OK;
1339 }
1340
1341 API int pkgmgrinfo_pkginfo_get_storeclientid(pkgmgrinfo_pkginfo_h handle, char **storeclientid)
1342 {
1343         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1344
1345         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1346         retvm_if(storeclientid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1347
1348         if (info->pkg_info == NULL)
1349                 return PMINFO_R_ERROR;
1350
1351         if (info->pkg_info->storeclient_id == NULL)
1352                 *storeclientid = "";
1353         else
1354                 *storeclientid = (char *)info->pkg_info->storeclient_id;
1355
1356         return PMINFO_R_OK;
1357 }
1358
1359 API int pkgmgrinfo_pkginfo_get_mainappid(pkgmgrinfo_pkginfo_h handle, char **mainappid)
1360 {
1361         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1362
1363         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1364         retvm_if(mainappid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1365
1366         if (info->pkg_info == NULL || info->pkg_info->mainapp_id == NULL)
1367                 return PMINFO_R_ERROR;
1368
1369         *mainappid = (char *)info->pkg_info->mainapp_id;
1370
1371         return PMINFO_R_OK;
1372 }
1373
1374 API int pkgmgrinfo_pkginfo_get_url(pkgmgrinfo_pkginfo_h handle, char **url)
1375 {
1376         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1377
1378         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1379         retvm_if(url == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1380
1381         if (info->pkg_info == NULL)
1382                 return PMINFO_R_ERROR;
1383
1384         if (info->pkg_info->package_url == NULL)
1385                 *url = "";
1386         else
1387                 *url = (char *)info->pkg_info->package_url;
1388
1389         return PMINFO_R_OK;
1390 }
1391
1392 API int pkgmgrinfo_pkginfo_get_root_path(pkgmgrinfo_pkginfo_h handle, char **path)
1393 {
1394         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1395
1396         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1397         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1398
1399         if (info->pkg_info == NULL || info->pkg_info->root_path == NULL)
1400                 return PMINFO_R_ERROR;
1401
1402         *path = (char *)info->pkg_info->root_path;
1403
1404         return PMINFO_R_OK;
1405 }
1406
1407 API int pkgmgrinfo_pkginfo_get_csc_path(pkgmgrinfo_pkginfo_h handle, char **path)
1408 {
1409         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1410
1411         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1412         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1413
1414         if (info->pkg_info == NULL)
1415                 return PMINFO_R_ERROR;
1416
1417         if (info->pkg_info->csc_path == NULL)
1418                 *path = "";
1419         else
1420                 *path = (char *)info->pkg_info->csc_path;
1421
1422         return PMINFO_R_OK;
1423 }
1424
1425 API int pkgmgrinfo_pkginfo_get_support_mode(pkgmgrinfo_pkginfo_h handle, int *support_mode)
1426 {
1427         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1428         retvm_if(support_mode == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1429
1430         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1431         if (info->pkg_info->support_mode)
1432                 *support_mode = atoi(info->pkg_info->support_mode);
1433         else
1434                 *support_mode = 0;
1435
1436         return PMINFO_R_OK;
1437 }
1438
1439 API int pkgmgrinfo_pkginfo_is_accessible(pkgmgrinfo_pkginfo_h handle, bool *accessible)
1440 {
1441         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1442         retvm_if(accessible == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1443
1444 #if 0 /* smack issue occured, check later */
1445         char *pkgid = NULL;
1446         pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
1447         if (pkgid == NULL) {
1448                  _LOGD("invalid func parameters\n");
1449                  return PMINFO_R_ERROR;
1450         }
1451          _LOGD("pkgmgr_get_pkg_external_validation() called\n");
1452
1453         FILE *fp = NULL;
1454         char app_mmc_path[FILENAME_MAX] = { 0, };
1455         char app_dir_path[FILENAME_MAX] = { 0, };
1456         char app_mmc_internal_path[FILENAME_MAX] = { 0, };
1457         snprintf(app_dir_path, FILENAME_MAX, "%s%s", PKG_INSTALLATION_PATH, pkgid);
1458         snprintf(app_mmc_path, FILENAME_MAX, "%s%s", PKG_SD_PATH, pkgid);
1459         snprintf(app_mmc_internal_path, FILENAME_MAX, "%s%s/.mmc", PKG_INSTALLATION_PATH, pkgid);
1460
1461         /*check whether application is in external memory or not */
1462         fp = fopen(app_mmc_path, "r");
1463         if (fp == NULL) {
1464                 _LOGD(" app path in external memory not accesible\n");
1465         } else {
1466                 fclose(fp);
1467                 fp = NULL;
1468                 *accessible = 1;
1469                 _LOGD("pkgmgr_get_pkg_external_validation() : SD_CARD \n");
1470                 return PMINFO_R_OK;
1471         }
1472
1473         /*check whether application is in internal or not */
1474         if (fp == NULL) {
1475                 _LOGD(" app path in internal memory not accesible\n");
1476                 *accessible = 0;
1477                 return PMINFO_R_ERROR;
1478         } else {
1479                 fclose(fp);
1480                 /*check whether the application is installed in SD card
1481                 but SD card is not present*/
1482                 fp = fopen(app_mmc_internal_path, "r");
1483                 if (fp == NULL) {
1484                         *accessible = 1;
1485                         _LOGD("pkgmgr_get_pkg_external_validation() : INTERNAL_MEM \n");
1486                         return PMINFO_R_OK;
1487                 } else {
1488                         *accessible = 0;
1489                         _LOGD("pkgmgr_get_pkg_external_validation() : ERROR_MMC_STATUS \n");
1490                 }
1491                 fclose(fp);
1492         }
1493
1494         _LOGD("pkgmgr_get_pkg_external_validation() end\n");
1495 #endif
1496
1497         *accessible = 1;
1498         return PMINFO_R_OK;
1499 }
1500
1501 API int pkgmgrinfo_pkginfo_is_removable(pkgmgrinfo_pkginfo_h handle, bool *removable)
1502 {
1503         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1504
1505         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1506         retvm_if(removable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1507
1508         if (info->pkg_info == NULL || info->pkg_info->removable == NULL)
1509                 return PMINFO_R_ERROR;
1510
1511         *removable = _get_bool_value(info->pkg_info->removable);
1512
1513         return PMINFO_R_OK;
1514 }
1515
1516 API int pkgmgrinfo_pkginfo_is_movable(pkgmgrinfo_pkginfo_h handle, bool *movable)
1517 {
1518         char *val;
1519         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1520
1521         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1522         retvm_if(movable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1523
1524         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
1525                 return PMINFO_R_ERROR;
1526
1527         val = (char *)info->pkg_info->installlocation;
1528         if (strcmp(val, "internal-only") == 0)
1529                 *movable = 0;
1530         else if (strcmp(val, "prefer-external") == 0)
1531                 *movable = 1;
1532         else
1533                 *movable = 1;
1534
1535         return PMINFO_R_OK;
1536 }
1537
1538 API int pkgmgrinfo_pkginfo_is_preload(pkgmgrinfo_pkginfo_h handle, bool *preload)
1539 {
1540         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1541
1542         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1543         retvm_if(preload == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1544
1545         if (info->pkg_info == NULL || info->pkg_info->preload == NULL)
1546                 return PMINFO_R_ERROR;
1547
1548         *preload = _get_bool_value(info->pkg_info->preload);
1549
1550         return PMINFO_R_OK;
1551 }
1552
1553 API int pkgmgrinfo_pkginfo_is_system(pkgmgrinfo_pkginfo_h handle, bool *system)
1554 {
1555         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1556
1557         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1558         retvm_if(system == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1559
1560         if (info->pkg_info == NULL || info->pkg_info->system == NULL)
1561                 return PMINFO_R_ERROR;
1562
1563         *system = _get_bool_value(info->pkg_info->system);
1564
1565         return PMINFO_R_OK;
1566 }
1567
1568 API int pkgmgrinfo_pkginfo_is_readonly(pkgmgrinfo_pkginfo_h handle, bool *readonly)
1569 {
1570         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1571
1572         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1573         retvm_if(readonly == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1574
1575         if (info->pkg_info == NULL || info->pkg_info->readonly == NULL)
1576                 return PMINFO_R_ERROR;
1577
1578         *readonly = _get_bool_value(info->pkg_info->readonly);
1579
1580         return PMINFO_R_OK;
1581 }
1582
1583 API int pkgmgrinfo_pkginfo_is_update(pkgmgrinfo_pkginfo_h handle, bool *update)
1584 {
1585         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1586
1587         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1588         retvm_if(update == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1589
1590         if (info->pkg_info == NULL || info->pkg_info->update == NULL)
1591                 return PMINFO_R_ERROR;
1592
1593         *update = _get_bool_value(info->pkg_info->update);
1594
1595         return PMINFO_R_OK;
1596 }
1597
1598 API int pkgmgrinfo_pkginfo_is_support_disable(pkgmgrinfo_pkginfo_h handle, bool *support_disable)
1599 {
1600         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1601
1602         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1603         retvm_if(support_disable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1604
1605         if (info->pkg_info == NULL || info->pkg_info->support_disable == NULL)
1606                 return PMINFO_R_ERROR;
1607
1608         *support_disable = _get_bool_value(info->pkg_info->support_disable);
1609
1610         return PMINFO_R_OK;
1611 }
1612
1613 API int pkgmgrinfo_pkginfo_is_global(pkgmgrinfo_pkginfo_h handle, bool *global)
1614 {
1615         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1616
1617         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1618         retvm_if(global == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1619
1620         if (info->pkg_info == NULL || info->pkg_info->for_all_users == NULL)
1621                 return PMINFO_R_ERROR;
1622
1623         *global = _get_bool_value(info->pkg_info->for_all_users);
1624
1625         return PMINFO_R_OK;
1626 }
1627
1628 API int pkgmgrinfo_pkginfo_is_for_all_users(pkgmgrinfo_pkginfo_h handle, bool *for_all_users)
1629 {
1630         return pkgmgrinfo_pkginfo_is_global(handle, for_all_users);
1631 }
1632
1633 API int pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo_h handle)
1634 {
1635         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1636
1637         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1638
1639         __cleanup_pkginfo(info);
1640
1641         return PMINFO_R_OK;
1642 }
1643
1644 API int pkgmgrinfo_pkginfo_filter_create(pkgmgrinfo_pkginfo_filter_h *handle)
1645 {
1646         pkgmgrinfo_filter_x *filter;
1647
1648         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle output parameter is NULL\n");
1649
1650         filter = (pkgmgrinfo_filter_x *)calloc(1, sizeof(pkgmgrinfo_filter_x));
1651         if (filter == NULL) {
1652                 _LOGE("Out of Memory!!!");
1653                 return PMINFO_R_ERROR;
1654         }
1655
1656         *handle = filter;
1657
1658         return PMINFO_R_OK;
1659 }
1660
1661 API int pkgmgrinfo_pkginfo_filter_destroy(pkgmgrinfo_pkginfo_filter_h handle)
1662 {
1663         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1664
1665         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1666
1667         if (filter->list) {
1668                 g_slist_foreach(filter->list, __destroy_each_node, NULL);
1669                 g_slist_free(filter->list);
1670         }
1671
1672         g_slist_free_full(filter->list_metadata, __destroy_metadata_node);
1673
1674         free(filter);
1675
1676         return PMINFO_R_OK;
1677 }
1678
1679 API int pkgmgrinfo_pkginfo_filter_add_int(pkgmgrinfo_pkginfo_filter_h handle,
1680                                 const char *property, const int value)
1681 {
1682         char buf[PKG_VALUE_STRING_LEN_MAX] = {'\0'};
1683         char *val;
1684         GSList *link;
1685         int prop;
1686         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1687         pkgmgrinfo_node_x *node;
1688
1689         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1690         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1691
1692         prop = _pminfo_pkginfo_convert_to_prop_int(property);
1693         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_INT ||
1694                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_INT) {
1695                 _LOGE("Invalid Integer Property\n");
1696                 return PMINFO_R_EINVAL;
1697         }
1698         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1699         if (node == NULL) {
1700                 _LOGE("Out of Memory!!!\n");
1701                 return PMINFO_R_ERROR;
1702         }
1703         snprintf(buf, PKG_VALUE_STRING_LEN_MAX - 1, "%d", value);
1704         val = strndup(buf, PKG_VALUE_STRING_LEN_MAX - 1);
1705         if (val == NULL) {
1706                 _LOGE("Out of Memory\n");
1707                 free(node);
1708                 return PMINFO_R_ERROR;
1709         }
1710         node->prop = prop;
1711         node->value = val;
1712         /*If API is called multiple times for same property, we should override the previous values.
1713         Last value set will be used for filtering.*/
1714         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1715         if (link)
1716                 filter->list = g_slist_delete_link(filter->list, link);
1717         filter->list = g_slist_append(filter->list, (gpointer)node);
1718         return PMINFO_R_OK;
1719
1720 }
1721
1722 API int pkgmgrinfo_pkginfo_filter_add_bool(pkgmgrinfo_pkginfo_filter_h handle,
1723                                 const char *property, const bool value)
1724 {
1725         char *val;
1726         GSList *link;
1727         int prop;
1728         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1729         pkgmgrinfo_node_x *node;
1730
1731         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1732         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1733
1734         prop = _pminfo_pkginfo_convert_to_prop_bool(property);
1735         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_BOOL ||
1736                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_BOOL) {
1737                 _LOGE("Invalid Boolean Property\n");
1738                 return PMINFO_R_EINVAL;
1739         }
1740         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1741         if (node == NULL) {
1742                 _LOGE("Out of Memory!!!\n");
1743                 return PMINFO_R_ERROR;
1744         }
1745         if (value)
1746                 val = strndup("true", 4);
1747         else
1748                 val = strndup("false", 5);
1749         if (val == NULL) {
1750                 _LOGE("Out of Memory\n");
1751                 free(node);
1752                 return PMINFO_R_ERROR;
1753         }
1754         node->prop = prop;
1755         node->value = val;
1756         /*If API is called multiple times for same property, we should override the previous values.
1757         Last value set will be used for filtering.*/
1758         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1759         if (link)
1760                 filter->list = g_slist_delete_link(filter->list, link);
1761         filter->list = g_slist_append(filter->list, (gpointer)node);
1762         return PMINFO_R_OK;
1763
1764 }
1765
1766 API int pkgmgrinfo_pkginfo_filter_add_string(pkgmgrinfo_pkginfo_filter_h handle,
1767                                 const char *property, const char *value)
1768 {
1769         char *val;
1770         GSList *link;
1771         int prop;
1772         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1773         pkgmgrinfo_node_x *node;
1774
1775         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1776         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1777         retvm_if(value == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1778
1779         prop = _pminfo_pkginfo_convert_to_prop_str(property);
1780         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_STR ||
1781                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_STR) {
1782                 _LOGE("Invalid String Property\n");
1783                 return PMINFO_R_EINVAL;
1784         }
1785         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1786         if (node == NULL) {
1787                 _LOGE("Out of Memory!!!\n");
1788                 return PMINFO_R_ERROR;
1789         }
1790         if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_AUTO) == 0)
1791                 val = strndup("auto", PKG_STRING_LEN_MAX - 1);
1792         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_INTERNAL) == 0)
1793                 val = strndup("internal-only", PKG_STRING_LEN_MAX - 1);
1794         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_EXTERNAL) == 0)
1795                 val = strndup("prefer-external", PKG_STRING_LEN_MAX - 1);
1796         else if (strcmp(value, "installed_internal") == 0)
1797                 val = strndup("installed_internal", PKG_STRING_LEN_MAX - 1);
1798         else if (strcmp(value, "installed_external") == 0)
1799                 val = strndup("installed_external", PKG_STRING_LEN_MAX - 1);
1800         else
1801                 val = strndup(value, PKG_STRING_LEN_MAX - 1);
1802         if (val == NULL) {
1803                 _LOGE("Out of Memory\n");
1804                 free(node);
1805                 return PMINFO_R_ERROR;
1806         }
1807         node->prop = prop;
1808         node->value = val;
1809         /*If API is called multiple times for same property, we should override the previous values.
1810         Last value set will be used for filtering.*/
1811         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1812         if (link)
1813                 filter->list = g_slist_delete_link(filter->list, link);
1814         filter->list = g_slist_append(filter->list, (gpointer)node);
1815         return PMINFO_R_OK;
1816
1817 }
1818
1819 API int pkgmgrinfo_pkginfo_usr_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count, uid_t uid)
1820 {
1821         int ret;
1822         char *locale;
1823         GHashTable *list = NULL;
1824
1825         if (handle == NULL || count == NULL) {
1826                 _LOGE("invalid parameter");
1827                 return PMINFO_R_EINVAL;
1828         }
1829
1830         locale = _get_system_locale();
1831         if (locale == NULL)
1832                 return PMINFO_R_ERROR;
1833
1834         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
1835                         __free_packages);
1836         if (list == NULL) {
1837                 free(locale);
1838                 return PMINFO_R_ERROR;
1839         }
1840
1841         if (__check_disable_filter_exist((pkgmgrinfo_filter_x *)handle) == false) {
1842                 ret = pkgmgrinfo_pkginfo_filter_add_bool(handle,
1843                                 PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
1844                 if (ret != PMINFO_R_OK) {
1845                         free(locale);
1846                         g_hash_table_destroy(list);
1847                         return PMINFO_R_ERROR;
1848                 }
1849         }
1850
1851         ret = _pkginfo_get_packages(uid, locale,
1852                         (pkgmgrinfo_filter_x *)handle, 0, list);
1853         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
1854                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, handle, 0,
1855                                 list);
1856
1857         if (ret != PMINFO_R_OK) {
1858                 g_hash_table_destroy(list);
1859                 free(locale);
1860                 return PMINFO_R_ERROR;
1861         }
1862
1863         *count = g_hash_table_size(list);
1864
1865         g_hash_table_destroy(list);
1866         free(locale);
1867
1868         return PMINFO_R_OK;
1869 }
1870
1871 API int pkgmgrinfo_pkginfo_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count)
1872 {
1873         return pkgmgrinfo_pkginfo_usr_filter_count(handle, count, _getuid());
1874 }
1875
1876 API int pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(
1877                 pkgmgrinfo_pkginfo_filter_h handle,
1878                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data, uid_t uid)
1879 {
1880         if (handle == NULL || pkg_cb == NULL) {
1881                 LOGE("invalid parameter");
1882                 return PMINFO_R_EINVAL;
1883         }
1884
1885         return _pkginfo_get_filtered_foreach_pkginfo(uid, handle,
1886                         PMINFO_PKGINFO_GET_ALL, pkg_cb, user_data);
1887 }
1888
1889 API int pkgmgrinfo_pkginfo_filter_foreach_pkginfo(pkgmgrinfo_pkginfo_filter_h handle,
1890                                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data)
1891 {
1892         return pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, pkg_cb, user_data, _getuid());
1893 }
1894
1895 API int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle,
1896                         pkgmgrinfo_pkg_privilege_list_cb privilege_func, void *user_data)
1897 {
1898         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1899         retvm_if(privilege_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
1900         int ret;
1901         privilege_x *privilege;
1902         GList *tmp;
1903         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1904
1905         if (info->pkg_info == NULL)
1906                 return PMINFO_R_ERROR;
1907
1908         for (tmp = info->pkg_info->privileges; tmp; tmp = tmp->next) {
1909                 privilege = (privilege_x *)tmp->data;
1910                 if (privilege == NULL)
1911                         continue;
1912                 ret = privilege_func(privilege->value, user_data);
1913                 if (ret < 0)
1914                         break;
1915         }
1916         return PMINFO_R_OK;
1917 }
1918
1919 int __compare_package_version(const char *version, int *major,
1920                 int *minor, int *macro, int *nano)
1921 {
1922         char *version_temp = NULL;
1923         char *major_str = NULL;
1924         char *minor_str = NULL;
1925         char *macro_str = NULL;
1926         char *nano_str = NULL;
1927         char *save_str = NULL;
1928
1929         if (version == NULL || major == NULL || minor == NULL ||
1930                 macro == NULL || nano == NULL) {
1931                 return PMINFO_R_EINVAL;
1932         }
1933
1934         version_temp = strdup(version);
1935         if (version_temp == NULL) {
1936                 LOGE("Out of memory");
1937                 return PMINFO_R_ERROR;
1938         }
1939
1940         major_str = strtok_r(version_temp, ".", &save_str);
1941         if (major_str == NULL) {
1942                 _LOGE("major version is NULL");
1943                 free(version_temp);
1944                 return PMINFO_R_ERROR;
1945         }
1946
1947         minor_str = strtok_r(NULL, ".", &save_str);
1948         if (minor_str == NULL) {
1949                 _LOGE("minor version is NULL");
1950                 free(version_temp);
1951                 return PMINFO_R_ERROR;
1952         }
1953
1954         *major = atoi(major_str);
1955         *minor = atoi(minor_str);
1956         *macro = 0;
1957         *nano = 0;
1958         macro_str = strtok_r(NULL, ".", &save_str);
1959         if (macro_str == NULL) {
1960                 _LOGD("macro version is NULL");
1961         } else {
1962                 *macro = atoi(macro_str);
1963                 nano_str = strtok_r(NULL, ".", &save_str);
1964                 if (nano_str) {
1965                         *nano = atoi(nano_str);
1966                         _LOGD("nano version exists");
1967                 }
1968         }
1969         _LOGD("version = [%s] -> major = [%d], minor = [%d]," \
1970                 " macro = [%d], nano = [%d]", version, *major,
1971                 *minor, *macro, *nano);
1972
1973         free(version_temp);
1974
1975         return PMINFO_R_OK;
1976 }
1977
1978 API int pkgmgrinfo_compare_package_version(const char *current_version,
1979                 const char *target_version,
1980                 pkgmgrinfo_version_compare_type *res)
1981 {
1982         int ret = 0;
1983         int current_version_major = 0;
1984         int current_version_minor = 0;
1985         int current_version_macro = 0;
1986         int current_version_nano = 0;
1987         int target_version_major = 0;
1988         int target_version_minor = 0;
1989         int target_version_macro = 0;
1990         int target_version_nano = 0;
1991
1992         if (current_version == NULL || target_version == NULL ||
1993                 res == NULL) {
1994                 _LOGE("Invalid parameter");
1995                 return PMINFO_R_EINVAL;
1996         }
1997
1998         ret = __compare_package_version(target_version,
1999                 &target_version_major, &target_version_minor,
2000                 &target_version_macro, &target_version_nano);
2001         if (ret < 0) {
2002                 _LOGE("Failed to compare target version(%d)", ret);
2003                 return PMINFO_R_ERROR;
2004         }
2005
2006         ret = __compare_package_version(current_version,
2007                 &current_version_major, &current_version_minor,
2008                 &current_version_macro, &current_version_nano);
2009         if (ret < 0) {
2010                 _LOGE("Failed to compare current version(%d)", ret);
2011                 return PMINFO_R_ERROR;
2012         }
2013
2014         _LOGD("new[%d.%d.%d.%d] old[%d.%d.%d.%d]", target_version_major,
2015                 target_version_minor, target_version_macro,
2016                 target_version_nano, current_version_major,
2017                 current_version_minor, current_version_macro,
2018                 target_version_nano);
2019
2020         if (target_version_major > current_version_major)
2021                 *res = PMINFO_VERSION_NEW;
2022         else if (target_version_major < current_version_major)
2023                 *res = PMINFO_VERSION_OLD;
2024         else if (target_version_minor > current_version_minor)
2025                 *res = PMINFO_VERSION_NEW;
2026         else if (target_version_minor < current_version_minor)
2027                 *res = PMINFO_VERSION_OLD;
2028         else if (target_version_macro > current_version_macro)
2029                 *res = PMINFO_VERSION_NEW;
2030         else if (target_version_macro < current_version_macro)
2031                 *res = PMINFO_VERSION_OLD;
2032         else if (target_version_nano > current_version_nano)
2033                 *res = PMINFO_VERSION_NEW;
2034         else if (target_version_nano < current_version_nano)
2035                 *res = PMINFO_VERSION_OLD;
2036         else
2037                 *res = PMINFO_VERSION_SAME;
2038
2039         return PMINFO_R_OK;
2040 }