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