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