c47d1ccbb7ed032405fa86c8a414dae6e9989d51
[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         const 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                 return PMINFO_R_ERROR;
490         }
491
492         if (filter != NULL) {
493                 tmp_filter = filter;
494         } else {
495                 ret = pkgmgrinfo_pkginfo_filter_create((void *)&tmp_filter);
496                 if (ret != PMINFO_R_OK) {
497                         _LOGE("Failed to create filter");
498                         return PMINFO_R_ERROR;
499                 }
500         }
501
502         /* add package_disable='false' clause by default */
503         pkgmgrinfo_pkginfo_filter_add_bool(tmp_filter, PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
504
505         ret = _get_filtered_query(tmp_filter, locale, &constraints, &bind_params);
506         if (ret != PMINFO_R_OK) {
507                 LOGE("Failed to get WHERE clause");
508                 goto catch;
509         }
510
511         if (constraints)
512                 snprintf(query, MAX_QUERY_LEN - 1, "%s%s", query_raw, constraints);
513         else
514                 snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
515
516         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
517         if (ret != SQLITE_OK) {
518                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
519                 ret = PMINFO_R_ERROR;
520                 goto catch;
521         }
522
523         ret = __bind_params(stmt, bind_params);
524         if (ret != SQLITE_OK) {
525                 LOGE("Failed to bind parameters");
526                 goto catch;
527         }
528
529         while (sqlite3_step(stmt) == SQLITE_ROW) {
530                 info = calloc(1, sizeof(package_x));
531                 if (info == NULL) {
532                         LOGE("out of memory");
533                         sqlite3_finalize(stmt);
534                         sqlite3_close_v2(db);
535                         return PMINFO_R_ERROR;
536                 }
537                 idx = 0;
538                 _save_column_str(stmt, idx++, &info->package);
539                 if (g_hash_table_contains(packages,
540                                         (gconstpointer)info->package)) {
541                         free(info->package);
542                         free(info);
543                         continue;
544                 }
545                 _save_column_str(stmt, idx++, &info->version);
546                 _save_column_str(stmt, idx++, &info->installlocation);
547                 _save_column_str(stmt, idx++, &info->removable);
548                 _save_column_str(stmt, idx++, &info->preload);
549                 _save_column_str(stmt, idx++, &info->readonly);
550                 _save_column_str(stmt, idx++, &info->update);
551                 _save_column_str(stmt, idx++, &info->appsetting);
552                 _save_column_str(stmt, idx++, &info->system);
553                 _save_column_str(stmt, idx++, &info->type);
554                 _save_column_str(stmt, idx++, &info->package_size);
555                 _save_column_str(stmt, idx++, &info->installed_time);
556                 _save_column_str(stmt, idx++, &info->installed_storage);
557                 _save_column_str(stmt, idx++, &info->storeclient_id);
558                 _save_column_str(stmt, idx++, &info->mainapp_id);
559                 _save_column_str(stmt, idx++, &info->package_url);
560                 _save_column_str(stmt, idx++, &info->root_path);
561                 _save_column_str(stmt, idx++, &info->csc_path);
562                 _save_column_str(stmt, idx++, &info->nodisplay_setting);
563                 _save_column_str(stmt, idx++, &info->api_version);
564                 _save_column_str(stmt, idx++, &info->support_disable);
565                 _save_column_str(stmt, idx++, &info->tep_name);
566                 _save_column_str(stmt, idx++, &info->zip_mount_file);
567                 info->for_all_users =
568                         strdup((uid != GLOBAL_USER) ? "false" : "true");
569
570                 if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
571                         if (_pkginfo_get_author(db, info->package,
572                                                 &info->author)) {
573                                 pkgmgrinfo_basic_free_package(info);
574                                 sqlite3_finalize(stmt);
575                                 sqlite3_close_v2(db);
576                                 return PMINFO_R_ERROR;
577                         }
578                 }
579
580                 if (flag & PMINFO_PKGINFO_GET_LABEL) {
581                         if (_pkginfo_get_label(db, info->package, locale,
582                                                 &info->label)) {
583                                 pkgmgrinfo_basic_free_package(info);
584                                 sqlite3_finalize(stmt);
585                                 sqlite3_close_v2(db);
586                                 return PMINFO_R_ERROR;
587                         }
588                 }
589
590                 if (flag & PMINFO_PKGINFO_GET_ICON) {
591                         if (_pkginfo_get_icon(db, info->package, locale,
592                                                 &info->icon)) {
593                                 pkgmgrinfo_basic_free_package(info);
594                                 sqlite3_finalize(stmt);
595                                 sqlite3_close_v2(db);
596                                 return PMINFO_R_ERROR;
597                         }
598                 }
599
600                 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
601                         if (_pkginfo_get_description(db, info->package, locale,
602                                                 &info->description)) {
603                                 pkgmgrinfo_basic_free_package(info);
604                                 sqlite3_finalize(stmt);
605                                 sqlite3_close_v2(db);
606                                 return PMINFO_R_ERROR;
607                         }
608                 }
609
610                 if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) {
611                         if (_pkginfo_get_privilege(db, info->package,
612                                                 &info->privileges)) {
613                                 pkgmgrinfo_basic_free_package(info);
614                                 sqlite3_finalize(stmt);
615                                 sqlite3_close_v2(db);
616                                 return PMINFO_R_ERROR;
617                         }
618                 }
619
620                 g_hash_table_insert(packages, (gpointer)info->package,
621                                 (gpointer)info);
622         }
623
624         ret = PMINFO_R_OK;
625
626 catch:
627         if (constraints)
628                 free(constraints);
629
630         if (ret != PMINFO_R_OK && info != NULL)
631                 pkgmgrinfo_basic_free_package(info);
632
633         if (filter == NULL)
634                 pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
635
636         g_list_free_full(bind_params, free);
637         sqlite3_close_v2(db);
638         sqlite3_finalize(stmt);
639
640         return ret;
641 }
642
643 static int _pkginfo_get_filtered_foreach_pkginfo(uid_t uid,
644                 pkgmgrinfo_filter_x *filter, int flag,
645                 pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data)
646 {
647         int ret;
648         char *locale;
649         package_x *pkg;
650         pkgmgr_pkginfo_x info;
651         GHashTable *list;
652         GHashTableIter iter;
653         gpointer value;
654
655         locale = _get_system_locale();
656         if (locale == NULL)
657                 return PMINFO_R_ERROR;
658
659         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
660                         __free_packages);
661         if (list == NULL) {
662                 free(locale);
663                 return PMINFO_R_ERROR;
664         }
665
666         ret = _pkginfo_get_packages(uid, locale, filter, flag, list);
667         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
668                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
669                                 flag, list);
670
671         if (ret != PMINFO_R_OK) {
672                 g_hash_table_destroy(list);
673                 free(locale);
674                 return PMINFO_R_ERROR;
675         }
676
677         g_hash_table_iter_init(&iter, list);
678         while (g_hash_table_iter_next(&iter, NULL, &value)) {
679                 pkg = (package_x *)value;
680                 info.uid = uid;
681                 info.pkg_info = pkg;
682                 info.locale = locale;
683                 if (pkg_list_cb(&info, user_data) < 0)
684                         break;
685         }
686
687         g_hash_table_destroy(list);
688         free(locale);
689
690         return PMINFO_R_OK;
691 }
692
693 API int pkgmgrinfo_pkginfo_get_usr_pkginfo(const char *pkgid, uid_t uid,
694                 pkgmgrinfo_pkginfo_h *handle)
695 {
696         int ret;
697         char *locale;
698         GHashTable *list;
699         pkgmgrinfo_pkginfo_filter_h filter;
700         pkgmgr_pkginfo_x *info;
701
702         if (pkgid == NULL || handle == NULL) {
703                 LOGE("invalid parameter");
704                 return PMINFO_R_EINVAL;
705         }
706
707         locale = _get_system_locale();
708         if (locale == NULL)
709                 return PMINFO_R_ERROR;
710
711         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
712         if (ret != PMINFO_R_OK) {
713                 free(locale);
714                 return ret;
715         }
716
717         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
718                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
719         if (ret != PMINFO_R_OK) {
720                 pkgmgrinfo_pkginfo_filter_destroy(filter);
721                 free(locale);
722                 return PMINFO_R_ERROR;
723         }
724
725         list = g_hash_table_new(g_str_hash, g_str_equal);
726         if (list == NULL) {
727                 pkgmgrinfo_pkginfo_filter_destroy(filter);
728                 free(locale);
729                 return PMINFO_R_ERROR;
730         }
731
732         ret = _pkginfo_get_packages(uid, locale, filter,
733                         PMINFO_PKGINFO_GET_ALL, list);
734         if (!g_hash_table_size(list) && uid != GLOBAL_USER)
735                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
736                                 PMINFO_PKGINFO_GET_ALL, list);
737
738         pkgmgrinfo_pkginfo_filter_destroy(filter);
739         if (ret != PMINFO_R_OK) {
740                 g_hash_table_destroy(list);
741                 free(locale);
742                 return ret;
743         }
744
745         if (!g_hash_table_size(list)) {
746                 _LOGI("pkginfo for [%s] is not existed for user [%d]",
747                                 pkgid, uid);
748                 g_hash_table_destroy(list);
749                 free(locale);
750                 return PMINFO_R_ENOENT;
751         }
752
753         info = calloc(1, sizeof(pkgmgr_pkginfo_x));
754         if (info == NULL) {
755                 _LOGE("out of memory");
756                 g_hash_table_destroy(list);
757                 free(locale);
758                 return PMINFO_R_ERROR;
759         }
760
761         info->uid = uid;
762         info->pkg_info = (package_x *)g_hash_table_lookup(list, pkgid);
763         info->locale = locale;
764
765         /* just free list only */
766         g_hash_table_destroy(list);
767
768         *handle = info;
769
770         return ret;
771 }
772
773 API int pkgmgrinfo_pkginfo_get_pkginfo(const char *pkgid,
774                 pkgmgrinfo_pkginfo_h *handle)
775 {
776         return pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, _getuid(), handle);
777 }
778
779 API int pkgmgrinfo_pkginfo_get_usr_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
780                 int flag, void *user_data, uid_t uid)
781 {
782         if (pkg_list_cb == NULL) {
783                 LOGE("invalid parameter");
784                 return PMINFO_R_EINVAL;
785         }
786
787         return _pkginfo_get_filtered_foreach_pkginfo(uid, NULL, flag,
788                         pkg_list_cb, user_data);
789 }
790
791 API int pkgmgrinfo_pkginfo_get_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
792                 int flag, void *user_data)
793 {
794         return pkgmgrinfo_pkginfo_get_usr_list_full(pkg_list_cb, flag,
795                         user_data, _getuid());
796 }
797
798 API int pkgmgrinfo_pkginfo_get_usr_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
799                 void *user_data, uid_t uid)
800 {
801         if (pkg_list_cb == NULL) {
802                 LOGE("invalid parameter");
803                 return PMINFO_R_EINVAL;
804         }
805
806         return _pkginfo_get_filtered_foreach_pkginfo(uid, NULL,
807                         PMINFO_PKGINFO_GET_ALL, pkg_list_cb, user_data);
808 }
809
810 API int pkgmgrinfo_pkginfo_get_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
811                 void *user_data)
812 {
813         return pkgmgrinfo_pkginfo_get_usr_list(pkg_list_cb, user_data,
814                         _getuid());
815 }
816
817 API int pkgmgrinfo_pkginfo_get_pkgname(pkgmgrinfo_pkginfo_h handle, char **pkg_name)
818 {
819         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
820
821         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
822         retvm_if(pkg_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
823
824         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
825                 return PMINFO_R_ERROR;
826
827         *pkg_name = (char *)info->pkg_info->package;
828
829         return PMINFO_R_OK;
830 }
831
832 API int pkgmgrinfo_pkginfo_get_pkgid(pkgmgrinfo_pkginfo_h handle, char **pkgid)
833 {
834         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
835
836         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
837         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
838
839         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
840                 return PMINFO_R_ERROR;
841
842         *pkgid = (char *)info->pkg_info->package;
843
844         return PMINFO_R_OK;
845 }
846
847 API int pkgmgrinfo_pkginfo_get_type(pkgmgrinfo_pkginfo_h handle, char **type)
848 {
849         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
850
851         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
852         retvm_if(type == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
853
854         if (info->pkg_info == NULL)
855                 return PMINFO_R_ERROR;
856         if (info->pkg_info->type == NULL)
857                 info->pkg_info->type = strdup("");
858
859         *type = (char *)info->pkg_info->type;
860
861         return PMINFO_R_OK;
862 }
863
864 API int pkgmgrinfo_pkginfo_get_version(pkgmgrinfo_pkginfo_h handle, char **version)
865 {
866         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
867
868         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
869         retvm_if(version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
870
871         if (info->pkg_info == NULL)
872                 return PMINFO_R_ERROR;
873         if (info->pkg_info->version == NULL)
874                 info->pkg_info->version = strdup("");
875
876         *version = (char *)info->pkg_info->version;
877
878         return PMINFO_R_OK;
879 }
880
881 API int pkgmgrinfo_pkginfo_get_api_version(pkgmgrinfo_pkginfo_h handle, char **api_version)
882 {
883         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
884
885         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
886         retvm_if(api_version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
887
888         if (info->pkg_info == NULL)
889                 return PMINFO_R_ERROR;
890         if (info->pkg_info->api_version == NULL)
891                 info->pkg_info->api_version = strdup("");
892
893         *api_version = (char *)info->pkg_info->api_version;
894
895         return PMINFO_R_OK;
896 }
897
898 API int pkgmgrinfo_pkginfo_get_tep_name(pkgmgrinfo_pkginfo_h handle, char **tep_name)
899 {
900         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
901
902         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
903         retvm_if(tep_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
904
905         if (info->pkg_info == NULL || info->pkg_info->tep_name == NULL)
906                 return PMINFO_R_ERROR;
907
908         *tep_name = (char *)info->pkg_info->tep_name;
909
910         return PMINFO_R_OK;
911 }
912
913 API int pkgmgrinfo_pkginfo_get_zip_mount_file(pkgmgrinfo_pkginfo_h handle, char **zip_mount_file)
914 {
915         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
916
917         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
918         retvm_if(zip_mount_file == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
919
920         if (info->pkg_info == NULL)
921                 return PMINFO_R_ERROR;
922         if (info->pkg_info->zip_mount_file == NULL)
923                 info->pkg_info->zip_mount_file = strdup("");
924
925         *zip_mount_file = (char *)info->pkg_info->zip_mount_file;
926
927         return PMINFO_R_OK;
928 }
929
930 API int pkgmgrinfo_pkginfo_get_install_location(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_install_location *location)
931 {
932         char *val;
933         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
934
935         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
936         retvm_if(location == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
937
938         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
939                 return PMINFO_R_ERROR;
940
941         val = (char *)info->pkg_info->installlocation;
942         if (strcmp(val, "internal-only") == 0)
943                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
944         else if (strcmp(val, "prefer-external") == 0)
945                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
946         else
947                 *location = PMINFO_INSTALL_LOCATION_AUTO;
948
949         return PMINFO_R_OK;
950 }
951
952 API int pkgmgrinfo_pkginfo_get_package_size(pkgmgrinfo_pkginfo_h handle, int *size)
953 {
954         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
955         char *temp = NULL;
956
957         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
958         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
959
960         if (info->pkg_info == NULL)
961                 return PMINFO_R_ERROR;
962
963         if (info->pkg_info->package_size == NULL) {
964                 temp = strdup("");
965                 if (temp == NULL) {
966                         _LOGE("out of memory");
967                         return PMINFO_R_ERROR;
968                 } else {
969                         info->pkg_info->package_size = temp;
970                 }
971         }
972
973         *size = atoi((char *)info->pkg_info->package_size);
974
975         return PMINFO_R_OK;
976 }
977
978 API int pkgmgrinfo_pkginfo_get_icon(pkgmgrinfo_pkginfo_h handle, char **icon)
979 {
980         const char *locale;
981         icon_x *ptr;
982         GList *tmp;
983         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
984
985         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
986         retvm_if(icon == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
987
988         locale = info->locale;
989         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
990
991         if (info->pkg_info == NULL || info->pkg_info->icon == NULL)
992                 return PMINFO_R_ERROR;
993
994         for (tmp = info->pkg_info->icon; tmp; tmp = tmp->next) {
995                 ptr = (icon_x *)tmp->data;
996                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
997                                 strcmp(ptr->lang, locale))
998                         continue;
999                 *icon = (char *)ptr->text;
1000                 return PMINFO_R_OK;
1001         }
1002
1003         locale = DEFAULT_LOCALE;
1004         for (tmp = info->pkg_info->icon; tmp; tmp = tmp->next) {
1005                 ptr = (icon_x *)tmp->data;
1006                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1007                                 strcmp(ptr->lang, locale))
1008                         continue;
1009                 *icon = (char *)ptr->text;
1010                 return PMINFO_R_OK;
1011         }
1012
1013         *icon = "";
1014
1015         return PMINFO_R_OK;
1016 }
1017
1018 API int pkgmgrinfo_pkginfo_get_label(pkgmgrinfo_pkginfo_h handle, char **label)
1019 {
1020         const char *locale;
1021         label_x *ptr;
1022         GList *tmp;
1023         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1024
1025         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1026         retvm_if(label == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1027
1028         locale = info->locale;
1029         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1030
1031         if (info->pkg_info == NULL || info->pkg_info->label == NULL)
1032                 return PMINFO_R_ERROR;
1033
1034         for (tmp = info->pkg_info->label; tmp != NULL; tmp = tmp->next) {
1035                 ptr = (label_x *)tmp->data;
1036                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1037                                 strcmp(ptr->lang, locale))
1038                         continue;
1039                 *label = (char *)ptr->text;
1040                 return PMINFO_R_OK;
1041         }
1042
1043         locale = DEFAULT_LOCALE;
1044         for (tmp = info->pkg_info->label; tmp != NULL; tmp = tmp->next) {
1045                 ptr = (label_x *)tmp->data;
1046                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1047                                 strcmp(ptr->lang, locale))
1048                         continue;
1049                 *label = (char *)ptr->text;
1050                 return PMINFO_R_OK;
1051         }
1052
1053         *label = "";
1054
1055         return PMINFO_R_OK;
1056 }
1057
1058 API int pkgmgrinfo_pkginfo_get_description(pkgmgrinfo_pkginfo_h handle, char **description)
1059 {
1060         const char *locale;
1061         description_x *ptr;
1062         GList *tmp;
1063         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1064
1065         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1066         retvm_if(description == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1067
1068         locale = info->locale;
1069         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1070
1071         if (info->pkg_info == NULL || info->pkg_info->description == NULL)
1072                 return PMINFO_R_ERROR;
1073
1074         for (tmp = info->pkg_info->description; tmp; tmp = tmp->next) {
1075                 ptr = (description_x *)tmp->data;
1076                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1077                                 strcmp(ptr->lang, locale))
1078                         continue;
1079                 *description = (char *)ptr->text;
1080                 return PMINFO_R_OK;
1081         }
1082
1083         locale = DEFAULT_LOCALE;
1084         for (tmp = info->pkg_info->description; tmp; tmp = tmp->next) {
1085                 ptr = (description_x *)tmp->data;
1086                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1087                                 strcmp(ptr->lang, locale))
1088                         continue;
1089                 *description = (char *)ptr->text;
1090                 return PMINFO_R_OK;
1091         }
1092
1093         *description = "";
1094
1095         return PMINFO_R_OK;
1096 }
1097
1098 API int pkgmgrinfo_pkginfo_get_author_name(pkgmgrinfo_pkginfo_h handle, char **author_name)
1099 {
1100         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1101         author_x *author;
1102
1103         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1104         retvm_if(author_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1105
1106         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1107                 return PMINFO_R_ERROR;
1108
1109         author = (author_x *)info->pkg_info->author->data;
1110         if (author == NULL)
1111                 return PMINFO_R_ERROR;
1112         if (author->text == NULL)
1113                 author->text = strdup("");
1114
1115         *author_name = (char *)author->text;
1116
1117         return PMINFO_R_OK;
1118 }
1119
1120 API int pkgmgrinfo_pkginfo_get_author_email(pkgmgrinfo_pkginfo_h handle, char **author_email)
1121 {
1122         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1123         author_x *author;
1124
1125         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1126         retvm_if(author_email == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1127
1128         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1129                 return PMINFO_R_ERROR;
1130
1131         author = (author_x *)info->pkg_info->author->data;
1132         if (author == NULL)
1133                 return PMINFO_R_ERROR;
1134         if (author->email == NULL)
1135                 author->email = strdup("");
1136
1137         *author_email = (char *)author->email;
1138
1139         return PMINFO_R_OK;
1140 }
1141
1142 API int pkgmgrinfo_pkginfo_get_author_href(pkgmgrinfo_pkginfo_h handle, char **author_href)
1143 {
1144         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1145         author_x *author;
1146
1147         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1148         retvm_if(author_href == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1149
1150         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1151                 return PMINFO_R_ERROR;
1152
1153         author = (author_x *)info->pkg_info->author->data;
1154         if (author == NULL)
1155                 return PMINFO_R_ERROR;
1156         if (author->href == NULL)
1157                 author->href = strdup("");
1158
1159         *author_href = (char *)author->href;
1160
1161         return PMINFO_R_OK;
1162 }
1163
1164 API int pkgmgrinfo_pkginfo_get_installed_storage(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_installed_storage *storage)
1165 {
1166         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1167
1168         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1169         retvm_if(storage == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1170
1171         if (info->pkg_info == NULL || info->pkg_info->installed_storage == NULL)
1172                 return PMINFO_R_ERROR;
1173
1174         if (strcmp(info->pkg_info->installed_storage, "installed_internal") == 0)
1175                 *storage = PMINFO_INTERNAL_STORAGE;
1176         else if (strcmp(info->pkg_info->installed_storage, "installed_external") == 0)
1177                 *storage = PMINFO_EXTERNAL_STORAGE;
1178         else
1179                 return PMINFO_R_ERROR;
1180
1181         return PMINFO_R_OK;
1182 }
1183
1184 API int pkgmgrinfo_pkginfo_get_installed_time(pkgmgrinfo_pkginfo_h handle, int *installed_time)
1185 {
1186         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1187
1188         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1189         retvm_if(installed_time == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1190
1191         if (info->pkg_info == NULL || info->pkg_info->installed_time == NULL)
1192                 return PMINFO_R_ERROR;
1193
1194         *installed_time = atoi(info->pkg_info->installed_time);
1195
1196         return PMINFO_R_OK;
1197 }
1198
1199 API int pkgmgrinfo_pkginfo_get_storeclientid(pkgmgrinfo_pkginfo_h handle, char **storeclientid)
1200 {
1201         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1202
1203         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1204         retvm_if(storeclientid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1205
1206         if (info->pkg_info == NULL)
1207                 return PMINFO_R_ERROR;
1208         if (info->pkg_info->storeclient_id == NULL)
1209                 info->pkg_info->storeclient_id = strdup("");
1210
1211         *storeclientid = (char *)info->pkg_info->storeclient_id;
1212
1213         return PMINFO_R_OK;
1214 }
1215
1216 API int pkgmgrinfo_pkginfo_get_mainappid(pkgmgrinfo_pkginfo_h handle, char **mainappid)
1217 {
1218         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1219
1220         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1221         retvm_if(mainappid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1222
1223         if (info->pkg_info == NULL || info->pkg_info->mainapp_id == NULL)
1224                 return PMINFO_R_ERROR;
1225
1226         *mainappid = (char *)info->pkg_info->mainapp_id;
1227
1228         return PMINFO_R_OK;
1229 }
1230
1231 API int pkgmgrinfo_pkginfo_get_url(pkgmgrinfo_pkginfo_h handle, char **url)
1232 {
1233         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1234
1235         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1236         retvm_if(url == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1237
1238         if (info->pkg_info == NULL)
1239                 return PMINFO_R_ERROR;
1240         if (info->pkg_info->package_url == NULL)
1241                 info->pkg_info->package_url = strdup("");
1242
1243         *url = (char *)info->pkg_info->package_url;
1244
1245         return PMINFO_R_OK;
1246 }
1247
1248 API int pkgmgrinfo_pkginfo_get_root_path(pkgmgrinfo_pkginfo_h handle, char **path)
1249 {
1250         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1251
1252         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1253         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1254
1255         if (info->pkg_info == NULL || info->pkg_info->root_path == NULL)
1256                 return PMINFO_R_ERROR;
1257
1258         *path = (char *)info->pkg_info->root_path;
1259
1260         return PMINFO_R_OK;
1261 }
1262
1263 API int pkgmgrinfo_pkginfo_get_csc_path(pkgmgrinfo_pkginfo_h handle, char **path)
1264 {
1265         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1266
1267         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1268         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1269
1270         if (info->pkg_info == NULL)
1271                 return PMINFO_R_ERROR;
1272         if (info->pkg_info->csc_path == NULL)
1273                 info->pkg_info->csc_path = strdup("");
1274
1275         *path = (char *)info->pkg_info->csc_path;
1276
1277         return PMINFO_R_OK;
1278 }
1279
1280
1281 API int pkgmgrinfo_pkginfo_is_accessible(pkgmgrinfo_pkginfo_h handle, bool *accessible)
1282 {
1283         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1284         retvm_if(accessible == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1285
1286 #if 0 /* smack issue occured, check later */
1287         char *pkgid = NULL;
1288         pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
1289         if (pkgid == NULL) {
1290                  _LOGD("invalid func parameters\n");
1291                  return PMINFO_R_ERROR;
1292         }
1293          _LOGD("pkgmgr_get_pkg_external_validation() called\n");
1294
1295         FILE *fp = NULL;
1296         char app_mmc_path[FILENAME_MAX] = { 0, };
1297         char app_dir_path[FILENAME_MAX] = { 0, };
1298         char app_mmc_internal_path[FILENAME_MAX] = { 0, };
1299         snprintf(app_dir_path, FILENAME_MAX, "%s%s", PKG_INSTALLATION_PATH, pkgid);
1300         snprintf(app_mmc_path, FILENAME_MAX, "%s%s", PKG_SD_PATH, pkgid);
1301         snprintf(app_mmc_internal_path, FILENAME_MAX, "%s%s/.mmc", PKG_INSTALLATION_PATH, pkgid);
1302
1303         /*check whether application is in external memory or not */
1304         fp = fopen(app_mmc_path, "r");
1305         if (fp == NULL) {
1306                 _LOGD(" app path in external memory not accesible\n");
1307         } else {
1308                 fclose(fp);
1309                 fp = NULL;
1310                 *accessible = 1;
1311                 _LOGD("pkgmgr_get_pkg_external_validation() : SD_CARD \n");
1312                 return PMINFO_R_OK;
1313         }
1314
1315         /*check whether application is in internal or not */
1316         if (fp == NULL) {
1317                 _LOGD(" app path in internal memory not accesible\n");
1318                 *accessible = 0;
1319                 return PMINFO_R_ERROR;
1320         } else {
1321                 fclose(fp);
1322                 /*check whether the application is installed in SD card
1323                 but SD card is not present*/
1324                 fp = fopen(app_mmc_internal_path, "r");
1325                 if (fp == NULL) {
1326                         *accessible = 1;
1327                         _LOGD("pkgmgr_get_pkg_external_validation() : INTERNAL_MEM \n");
1328                         return PMINFO_R_OK;
1329                 } else {
1330                         *accessible = 0;
1331                         _LOGD("pkgmgr_get_pkg_external_validation() : ERROR_MMC_STATUS \n");
1332                 }
1333                 fclose(fp);
1334         }
1335
1336         _LOGD("pkgmgr_get_pkg_external_validation() end\n");
1337 #endif
1338
1339         *accessible = 1;
1340         return PMINFO_R_OK;
1341 }
1342
1343 API int pkgmgrinfo_pkginfo_is_removable(pkgmgrinfo_pkginfo_h handle, bool *removable)
1344 {
1345         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1346
1347         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1348         retvm_if(removable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1349
1350         if (info->pkg_info == NULL || info->pkg_info->removable == NULL)
1351                 return PMINFO_R_ERROR;
1352
1353         *removable = _get_bool_value(info->pkg_info->removable);
1354
1355         return PMINFO_R_OK;
1356 }
1357
1358 API int pkgmgrinfo_pkginfo_is_movable(pkgmgrinfo_pkginfo_h handle, bool *movable)
1359 {
1360         char *val;
1361         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1362
1363         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1364         retvm_if(movable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1365
1366         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
1367                 return PMINFO_R_ERROR;
1368
1369         val = (char *)info->pkg_info->installlocation;
1370         if (strcmp(val, "internal-only") == 0)
1371                 *movable = 0;
1372         else if (strcmp(val, "prefer-external") == 0)
1373                 *movable = 1;
1374         else
1375                 *movable = 1;
1376
1377         return PMINFO_R_OK;
1378 }
1379
1380 API int pkgmgrinfo_pkginfo_is_preload(pkgmgrinfo_pkginfo_h handle, bool *preload)
1381 {
1382         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1383
1384         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1385         retvm_if(preload == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1386
1387         if (info->pkg_info == NULL || info->pkg_info->preload == NULL)
1388                 return PMINFO_R_ERROR;
1389
1390         *preload = _get_bool_value(info->pkg_info->preload);
1391
1392         return PMINFO_R_OK;
1393 }
1394
1395 API int pkgmgrinfo_pkginfo_is_system(pkgmgrinfo_pkginfo_h handle, bool *system)
1396 {
1397         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1398
1399         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1400         retvm_if(system == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1401
1402         if (info->pkg_info == NULL || info->pkg_info->system == NULL)
1403                 return PMINFO_R_ERROR;
1404
1405         *system = _get_bool_value(info->pkg_info->system);
1406
1407         return PMINFO_R_OK;
1408 }
1409
1410 API int pkgmgrinfo_pkginfo_is_readonly(pkgmgrinfo_pkginfo_h handle, bool *readonly)
1411 {
1412         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1413
1414         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1415         retvm_if(readonly == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1416
1417         if (info->pkg_info == NULL || info->pkg_info->readonly == NULL)
1418                 return PMINFO_R_ERROR;
1419
1420         *readonly = _get_bool_value(info->pkg_info->readonly);
1421
1422         return PMINFO_R_OK;
1423 }
1424
1425 API int pkgmgrinfo_pkginfo_is_update(pkgmgrinfo_pkginfo_h handle, bool *update)
1426 {
1427         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1428
1429         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1430         retvm_if(update == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1431
1432         if (info->pkg_info == NULL || info->pkg_info->update == NULL)
1433                 return PMINFO_R_ERROR;
1434
1435         *update = _get_bool_value(info->pkg_info->update);
1436
1437         return PMINFO_R_OK;
1438 }
1439
1440 API int pkgmgrinfo_pkginfo_is_support_disable(pkgmgrinfo_pkginfo_h handle, bool *support_disable)
1441 {
1442         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1443
1444         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1445         retvm_if(support_disable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1446
1447         if (info->pkg_info == NULL || info->pkg_info->support_disable == NULL)
1448                 return PMINFO_R_ERROR;
1449
1450         *support_disable = _get_bool_value(info->pkg_info->support_disable);
1451
1452         return PMINFO_R_OK;
1453 }
1454
1455 API int pkgmgrinfo_pkginfo_is_global(pkgmgrinfo_pkginfo_h handle, bool *global)
1456 {
1457         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1458
1459         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1460         retvm_if(global == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1461
1462         if (info->pkg_info == NULL || info->pkg_info->for_all_users == NULL)
1463                 return PMINFO_R_ERROR;
1464
1465         *global = _get_bool_value(info->pkg_info->for_all_users);
1466
1467         return PMINFO_R_OK;
1468 }
1469
1470 API int pkgmgrinfo_pkginfo_is_for_all_users(pkgmgrinfo_pkginfo_h handle, bool *for_all_users)
1471 {
1472         return pkgmgrinfo_pkginfo_is_global(handle, for_all_users);
1473 }
1474
1475 API int pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo_h handle)
1476 {
1477         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1478
1479         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1480
1481         __cleanup_pkginfo(info);
1482
1483         return PMINFO_R_OK;
1484 }
1485
1486 API int pkgmgrinfo_pkginfo_filter_create(pkgmgrinfo_pkginfo_filter_h *handle)
1487 {
1488         pkgmgrinfo_filter_x *filter;
1489
1490         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle output parameter is NULL\n");
1491
1492         filter = (pkgmgrinfo_filter_x*)calloc(1, sizeof(pkgmgrinfo_filter_x));
1493         if (filter == NULL) {
1494                 _LOGE("Out of Memory!!!");
1495                 return PMINFO_R_ERROR;
1496         }
1497
1498         *handle = filter;
1499
1500         return PMINFO_R_OK;
1501 }
1502
1503 API int pkgmgrinfo_pkginfo_filter_destroy(pkgmgrinfo_pkginfo_filter_h handle)
1504 {
1505         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1506
1507         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1508
1509         if (filter->list) {
1510                 g_slist_foreach(filter->list, __destroy_each_node, NULL);
1511                 g_slist_free(filter->list);
1512         }
1513
1514         free(filter);
1515
1516         return PMINFO_R_OK;
1517 }
1518
1519 API int pkgmgrinfo_pkginfo_filter_add_int(pkgmgrinfo_pkginfo_filter_h handle,
1520                                 const char *property, const int value)
1521 {
1522         char buf[PKG_VALUE_STRING_LEN_MAX] = {'\0'};
1523         char *val;
1524         GSList *link;
1525         int prop;
1526         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1527         pkgmgrinfo_node_x *node;
1528
1529         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1530         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1531
1532         prop = _pminfo_pkginfo_convert_to_prop_int(property);
1533         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_INT ||
1534                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_INT) {
1535                 _LOGE("Invalid Integer Property\n");
1536                 return PMINFO_R_EINVAL;
1537         }
1538         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1539         if (node == NULL) {
1540                 _LOGE("Out of Memory!!!\n");
1541                 return PMINFO_R_ERROR;
1542         }
1543         snprintf(buf, PKG_VALUE_STRING_LEN_MAX - 1, "%d", value);
1544         val = strndup(buf, PKG_VALUE_STRING_LEN_MAX - 1);
1545         if (val == NULL) {
1546                 _LOGE("Out of Memory\n");
1547                 free(node);
1548                 return PMINFO_R_ERROR;
1549         }
1550         node->prop = prop;
1551         node->value = val;
1552         /*If API is called multiple times for same property, we should override the previous values.
1553         Last value set will be used for filtering.*/
1554         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1555         if (link)
1556                 filter->list = g_slist_delete_link(filter->list, link);
1557         filter->list = g_slist_append(filter->list, (gpointer)node);
1558         return PMINFO_R_OK;
1559
1560 }
1561
1562 API int pkgmgrinfo_pkginfo_filter_add_bool(pkgmgrinfo_pkginfo_filter_h handle,
1563                                 const char *property, const bool value)
1564 {
1565         char *val;
1566         GSList *link;
1567         int prop;
1568         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1569         pkgmgrinfo_node_x *node;
1570
1571         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1572         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1573
1574         prop = _pminfo_pkginfo_convert_to_prop_bool(property);
1575         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_BOOL ||
1576                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_BOOL) {
1577                 _LOGE("Invalid Boolean Property\n");
1578                 return PMINFO_R_EINVAL;
1579         }
1580         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1581         if (node == NULL) {
1582                 _LOGE("Out of Memory!!!\n");
1583                 return PMINFO_R_ERROR;
1584         }
1585         if (value)
1586                 val = strndup("true", 4);
1587         else
1588                 val = strndup("false", 5);
1589         if (val == NULL) {
1590                 _LOGE("Out of Memory\n");
1591                 free(node);
1592                 return PMINFO_R_ERROR;
1593         }
1594         node->prop = prop;
1595         node->value = val;
1596         /*If API is called multiple times for same property, we should override the previous values.
1597         Last value set will be used for filtering.*/
1598         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1599         if (link)
1600                 filter->list = g_slist_delete_link(filter->list, link);
1601         filter->list = g_slist_append(filter->list, (gpointer)node);
1602         return PMINFO_R_OK;
1603
1604 }
1605
1606 API int pkgmgrinfo_pkginfo_filter_add_string(pkgmgrinfo_pkginfo_filter_h handle,
1607                                 const char *property, const char *value)
1608 {
1609         char *val;
1610         GSList *link;
1611         int prop;
1612         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1613         pkgmgrinfo_node_x *node;
1614
1615         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1616         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1617         retvm_if(value == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1618
1619         prop = _pminfo_pkginfo_convert_to_prop_str(property);
1620         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_STR ||
1621                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_STR) {
1622                 _LOGE("Invalid String Property\n");
1623                 return PMINFO_R_EINVAL;
1624         }
1625         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1626         if (node == NULL) {
1627                 _LOGE("Out of Memory!!!\n");
1628                 return PMINFO_R_ERROR;
1629         }
1630         if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_AUTO) == 0)
1631                 val = strndup("auto", PKG_STRING_LEN_MAX - 1);
1632         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_INTERNAL) == 0)
1633                 val = strndup("internal-only", PKG_STRING_LEN_MAX - 1);
1634         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_EXTERNAL) == 0)
1635                 val = strndup("prefer-external", PKG_STRING_LEN_MAX - 1);
1636         else if (strcmp(value, "installed_internal") == 0)
1637                 val = strndup("installed_internal", PKG_STRING_LEN_MAX - 1);
1638         else if (strcmp(value, "installed_external") == 0)
1639                 val = strndup("installed_external", PKG_STRING_LEN_MAX - 1);
1640         else
1641                 val = strndup(value, PKG_STRING_LEN_MAX - 1);
1642         if (val == NULL) {
1643                 _LOGE("Out of Memory\n");
1644                 free(node);
1645                 return PMINFO_R_ERROR;
1646         }
1647         node->prop = prop;
1648         node->value = val;
1649         /*If API is called multiple times for same property, we should override the previous values.
1650         Last value set will be used for filtering.*/
1651         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1652         if (link)
1653                 filter->list = g_slist_delete_link(filter->list, link);
1654         filter->list = g_slist_append(filter->list, (gpointer)node);
1655         return PMINFO_R_OK;
1656
1657 }
1658
1659 API int pkgmgrinfo_pkginfo_usr_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count, uid_t uid)
1660 {
1661         int ret;
1662         char *locale;
1663         GHashTable *list = NULL;
1664
1665         if (handle == NULL || count == NULL) {
1666                 _LOGE("invalid parameter");
1667                 return PMINFO_R_EINVAL;
1668         }
1669
1670         locale = _get_system_locale();
1671         if (locale == NULL)
1672                 return PMINFO_R_ERROR;
1673
1674         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
1675                         __free_packages);
1676         if (list == NULL) {
1677                 free(locale);
1678                 return PMINFO_R_ERROR;
1679         }
1680
1681         ret = _pkginfo_get_packages(uid, locale,
1682                         (pkgmgrinfo_filter_x *)handle, 0, list);
1683         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
1684                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, handle, 0,
1685                                 list);
1686
1687         if (ret != PMINFO_R_OK) {
1688                 g_hash_table_destroy(list);
1689                 free(locale);
1690                 return PMINFO_R_ERROR;
1691         }
1692
1693         *count = g_hash_table_size(list);
1694
1695         g_hash_table_destroy(list);
1696         free(locale);
1697
1698         return PMINFO_R_OK;
1699 }
1700
1701 API int pkgmgrinfo_pkginfo_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count)
1702 {
1703         return pkgmgrinfo_pkginfo_usr_filter_count(handle, count, _getuid());
1704 }
1705
1706 API int pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(
1707                 pkgmgrinfo_pkginfo_filter_h handle,
1708                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data, uid_t uid)
1709 {
1710         if (handle == NULL || pkg_cb == NULL) {
1711                 LOGE("invalid parameter");
1712                 return PMINFO_R_EINVAL;
1713         }
1714
1715         return _pkginfo_get_filtered_foreach_pkginfo(uid, handle,
1716                         PMINFO_PKGINFO_GET_ALL, pkg_cb, user_data);
1717 }
1718
1719 API int pkgmgrinfo_pkginfo_filter_foreach_pkginfo(pkgmgrinfo_pkginfo_filter_h handle,
1720                                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data)
1721 {
1722         return pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, pkg_cb, user_data, _getuid());
1723 }
1724
1725 API int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle,
1726                         pkgmgrinfo_pkg_privilege_list_cb privilege_func, void *user_data)
1727 {
1728         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1729         retvm_if(privilege_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
1730         int ret;
1731         const char *privilege;
1732         GList *tmp;
1733         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1734
1735         if (info->pkg_info == NULL)
1736                 return PMINFO_R_ERROR;
1737
1738         for (tmp = info->pkg_info->privileges; tmp; tmp = tmp->next) {
1739                 privilege = (const char *)tmp->data;
1740                 if (privilege == NULL)
1741                         continue;
1742                 ret = privilege_func(privilege, user_data);
1743                 if (ret < 0)
1744                         break;
1745         }
1746         return PMINFO_R_OK;
1747 }