8423b8a9bea0ffa06ebd5c209fbfc295fb8598d2
[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                         }
144                         total += q * BLOCK_SIZE;
145                         }
146                 }
147         }
148         (void)closedir(dp);
149         return total;
150
151 }
152
153 static int _pkginfo_get_author(sqlite3 *db, const char *pkgid,
154                 GList **author)
155 {
156         static const char query_raw[] =
157                 "SELECT author_name, author_email, author_href "
158                 "FROM package_info WHERE package=%Q";
159         int ret;
160         char *query;
161         sqlite3_stmt *stmt;
162         int idx = 0;
163         author_x *info;
164
165         query = sqlite3_mprintf(query_raw, pkgid);
166         if (query == NULL) {
167                 LOGE("out of memory");
168                 return PMINFO_R_ERROR;
169         }
170
171         ret = sqlite3_prepare_v2(db, query, strlen(query),
172                         &stmt, NULL);
173         sqlite3_free(query);
174         if (ret != SQLITE_OK) {
175                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
176                 return PMINFO_R_ERROR;
177         }
178
179         if (sqlite3_step(stmt) == SQLITE_ERROR) {
180                 LOGE("step error: %s", sqlite3_errmsg(db));
181                 sqlite3_finalize(stmt);
182                 return PMINFO_R_ERROR;
183         }
184
185         /* one author per one package */
186         info = calloc(1, sizeof(author_x));
187         if (info == NULL) {
188                 LOGE("out of memory");
189                 sqlite3_finalize(stmt);
190                 return PMINFO_R_ERROR;
191         }
192
193         _save_column_str(stmt, idx++, &info->text);
194         _save_column_str(stmt, idx++, &info->email);
195         _save_column_str(stmt, idx++, &info->href);
196
197         /* TODO: revised */
198         *author = g_list_append(*author, info);
199
200         sqlite3_finalize(stmt);
201
202         return PMINFO_R_OK;
203 }
204
205 static int _pkginfo_get_label(sqlite3 *db, const char *pkgid,
206                 const char *locale, GList **label)
207 {
208         static const char query_raw[] =
209                 "SELECT package_label, package_locale "
210                 "FROM package_localized_info "
211                 "WHERE package=%Q AND package_locale IN (%Q, %Q)";
212         int ret;
213         char *query;
214         sqlite3_stmt *stmt;
215         int idx;
216         label_x *info;
217
218         query = sqlite3_mprintf(query_raw, pkgid, locale, DEFAULT_LOCALE);
219         if (query == NULL) {
220                 LOGE("out of memory");
221                 return PMINFO_R_ERROR;
222         }
223
224         ret = sqlite3_prepare_v2(db, query, strlen(query),
225                         &stmt, NULL);
226         sqlite3_free(query);
227         if (ret != SQLITE_OK) {
228                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
229                 return PMINFO_R_ERROR;
230         }
231
232         while (sqlite3_step(stmt) == SQLITE_ROW) {
233                 info = calloc(1, sizeof(label_x));
234                 if (info == NULL) {
235                         LOGE("out of memory");
236                         sqlite3_finalize(stmt);
237                         return PMINFO_R_ERROR;
238                 }
239                 idx = 0;
240                 _save_column_str(stmt, idx++, &info->text);
241                 _save_column_str(stmt, idx++, &info->lang);
242                 *label = g_list_append(*label, info);
243         }
244
245         sqlite3_finalize(stmt);
246
247         return PMINFO_R_OK;
248 }
249
250 static int _pkginfo_get_icon(sqlite3 *db, const char *pkgid, const char *locale,
251                 GList **icon)
252 {
253         static const char query_raw[] =
254                 "SELECT package_icon, package_locale "
255                 "FROM package_localized_info "
256                 "WHERE package=%Q AND package_locale IN (%Q, %Q)";
257         int ret;
258         char *query;
259         sqlite3_stmt *stmt;
260         int idx;
261         icon_x *info;
262
263         query = sqlite3_mprintf(query_raw, pkgid, locale, DEFAULT_LOCALE);
264         if (query == NULL) {
265                 LOGE("out of memory");
266                 return PMINFO_R_ERROR;
267         }
268
269         ret = sqlite3_prepare_v2(db, query, strlen(query),
270                         &stmt, NULL);
271         sqlite3_free(query);
272         if (ret != SQLITE_OK) {
273                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
274                 return PMINFO_R_ERROR;
275         }
276
277         while (sqlite3_step(stmt) == SQLITE_ROW) {
278                 info = calloc(1, sizeof(icon_x));
279                 if (info == NULL) {
280                         LOGE("out of memory");
281                         sqlite3_finalize(stmt);
282                         return PMINFO_R_ERROR;
283                 }
284                 idx = 0;
285                 _save_column_str(stmt, idx++, &info->text);
286                 _save_column_str(stmt, idx++, &info->lang);
287                 *icon = g_list_append(*icon, info);
288         }
289
290         sqlite3_finalize(stmt);
291
292         return PMINFO_R_OK;
293 }
294
295 static int _pkginfo_get_description(sqlite3 *db, const char *pkgid,
296                 const char *locale, GList **description)
297 {
298         static const char query_raw[] =
299                 "SELECT package_description, package_locale "
300                 "FROM package_localized_info "
301                 "WHERE package=%Q AND package_locale IN (%Q, %Q)";
302         int ret;
303         char *query;
304         sqlite3_stmt *stmt;
305         int idx;
306         description_x *info;
307
308         query = sqlite3_mprintf(query_raw, pkgid, locale, DEFAULT_LOCALE);
309         if (query == NULL) {
310                 LOGE("out of memory");
311                 return PMINFO_R_ERROR;
312         }
313
314         ret = sqlite3_prepare_v2(db, query, strlen(query),
315                         &stmt, NULL);
316         sqlite3_free(query);
317         if (ret != SQLITE_OK) {
318                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
319                 return PMINFO_R_ERROR;
320         }
321
322         while (sqlite3_step(stmt) == SQLITE_ROW) {
323                 info = calloc(1, sizeof(description_x));
324                 if (info == NULL) {
325                         LOGE("out of memory");
326                         sqlite3_finalize(stmt);
327                         return PMINFO_R_ERROR;
328                 }
329                 idx = 0;
330                 _save_column_str(stmt, idx++, &info->text);
331                 _save_column_str(stmt, idx++, &info->lang);
332                 *description = g_list_append(*description, info);
333         }
334
335         sqlite3_finalize(stmt);
336
337         return PMINFO_R_OK;
338 }
339
340 static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid,
341                 GList **privileges)
342 {
343         static const char query_raw[] =
344                 "SELECT privilege FROM package_privilege_info WHERE package=%Q";
345         int ret;
346         char *query;
347         sqlite3_stmt *stmt;
348         char *privilege;
349
350         query = sqlite3_mprintf(query_raw, pkgid);
351         if (query == NULL) {
352                 LOGE("out of memory");
353                 return PMINFO_R_ERROR;
354         }
355
356         ret = sqlite3_prepare_v2(db, query, strlen(query),
357                         &stmt, NULL);
358         sqlite3_free(query);
359         if (ret != SQLITE_OK) {
360                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
361                 return PMINFO_R_ERROR;
362         }
363
364         while (sqlite3_step(stmt) == SQLITE_ROW) {
365                 privilege = NULL;
366                 _save_column_str(stmt, 0, &privilege);
367                 if (privilege)
368                         *privileges = g_list_append(*privileges,
369                                         (gpointer)privilege);
370         }
371
372         sqlite3_finalize(stmt);
373
374         return PMINFO_R_OK;
375 }
376
377 static const char join_localized_info[] =
378         " LEFT OUTER JOIN package_localized_info"
379         "  ON pi.package=package_localized_info.package"
380         "  AND package_localized_info.package_locale=?";
381 static const char join_privilege_info[] =
382         " LEFT OUTER JOIN package_privilege_info"
383         "  ON pi.package=package_privilege_info.package";
384
385 static int _get_filtered_query(pkgmgrinfo_filter_x *filter,
386                 const char *locale, char **query, GList **bind_params)
387 {
388         int joined = 0;
389         char buf[MAX_QUERY_LEN] = { '\0' };
390         char buf2[MAX_QUERY_LEN] = { '\0' };
391         char *condition = NULL;
392         size_t len = 0;
393         GSList *list = NULL;
394
395         if (filter == NULL)
396                 return PMINFO_R_OK;
397
398         len += strlen(" WHERE 1=1 ");
399         strncat(buf, " WHERE 1=1 ", MAX_QUERY_LEN - len - 1);
400         for (list = filter->list; list; list = list->next) {
401                 joined |= __get_filter_condition(list->data, &condition,
402                                 bind_params);
403                 if (condition == NULL)
404                         continue;
405
406                 len += strlen(" AND ");
407                 strncat(buf, " AND ", MAX_QUERY_LEN - len - 1);
408
409                 len += strlen(condition);
410                 strncat(buf, condition, sizeof(buf) - len - 1);
411                 free(condition);
412                 condition = NULL;
413         }
414
415         if (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) {
416                 strncat(buf2, join_localized_info, MAX_QUERY_LEN - len - 1);
417                 len += strlen(join_localized_info);
418                 *bind_params = g_list_append(*bind_params, strdup(locale));
419         }
420         if (joined & E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO) {
421                 strncat(buf2, join_privilege_info, MAX_QUERY_LEN - len - 1);
422                 len += strlen(join_privilege_info);
423         }
424         strncat(buf2, buf, MAX_QUERY_LEN - len - 1);
425
426         *query = strdup(buf2);
427         if (*query == NULL)
428                 return PMINFO_R_ERROR;
429
430         return PMINFO_R_OK;
431 }
432
433 static void __free_packages(gpointer data)
434 {
435         pkgmgrinfo_basic_free_package((package_x *)data);
436 }
437
438 static int __bind_params(sqlite3_stmt *stmt, GList *params)
439 {
440         GList *tmp_list = NULL;
441         int idx = 0;
442         int ret;
443
444         if (stmt == NULL || params == NULL)
445                 return PMINFO_R_EINVAL;
446
447         tmp_list = params;
448         while (tmp_list) {
449                 ret = sqlite3_bind_text(stmt, ++idx, (char *)tmp_list->data, -1, SQLITE_STATIC);
450                 if (ret != SQLITE_OK)
451                         return PMINFO_R_ERROR;
452                 tmp_list = tmp_list->next;
453         }
454
455         return PMINFO_R_OK;
456 }
457
458 static int _pkginfo_get_packages(uid_t uid, const char *locale,
459                 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages)
460 {
461         static const char query_raw[] =
462                 "SELECT DISTINCT pi.package, pi.package_version, "
463                 "pi.install_location, pi.package_removable, "
464                 "pi.package_preload, pi.package_readonly, pi.package_update, "
465                 "pi.package_appsetting, pi.package_system, pi.package_type, "
466                 "pi.package_size, pi.installed_time, pi.installed_storage, "
467                 "pi.storeclient_id, pi.mainapp_id, pi.package_url, "
468                 "pi.root_path, pi.csc_path, pi.package_nodisplay, "
469                 "pi.package_api_version, pi.package_support_disable, "
470                 "pi.package_tep_name, pi.package_zip_mount_file "
471                 "FROM package_info as pi ";
472         int ret = PMINFO_R_ERROR;
473         int idx = 0;
474         const char *dbpath;
475         char *constraints = NULL;
476         char query[MAX_QUERY_LEN] = { '\0' };
477         package_x *info = NULL;
478         GList *bind_params = NULL;
479         sqlite3 *db;
480         sqlite3_stmt *stmt;
481         pkgmgrinfo_filter_x *tmp_filter = NULL;
482
483         dbpath = getUserPkgParserDBPathUID(uid);
484         if (dbpath == NULL)
485                 return PMINFO_R_ERROR;
486
487         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
488         if (ret != SQLITE_OK) {
489                 _LOGD("failed to open db: %d", ret);
490                 return PMINFO_R_ERROR;
491         }
492
493         if (filter != NULL) {
494                 tmp_filter = filter;
495         } else {
496                 ret = pkgmgrinfo_pkginfo_filter_create((void *)&tmp_filter);
497                 if (ret != PMINFO_R_OK) {
498                         _LOGE("Failed to create filter");
499                         return PMINFO_R_ERROR;
500                 }
501         }
502
503         /* add package_disable='false' clause by default */
504         pkgmgrinfo_pkginfo_filter_add_bool(tmp_filter, PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
505
506         ret = _get_filtered_query(tmp_filter, locale, &constraints, &bind_params);
507         if (ret != PMINFO_R_OK) {
508                 LOGE("Failed to get WHERE clause");
509                 goto catch;
510         }
511
512         if (constraints)
513                 snprintf(query, MAX_QUERY_LEN - 1, "%s%s", query_raw, constraints);
514         else
515                 snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
516
517         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
518         if (ret != SQLITE_OK) {
519                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
520                 ret = PMINFO_R_ERROR;
521                 goto catch;
522         }
523
524         ret = __bind_params(stmt, bind_params);
525         if (ret != SQLITE_OK) {
526                 LOGE("Failed to bind parameters");
527                 goto catch;
528         }
529
530         while (sqlite3_step(stmt) == SQLITE_ROW) {
531                 info = calloc(1, sizeof(package_x));
532                 if (info == NULL) {
533                         LOGE("out of memory");
534                         sqlite3_finalize(stmt);
535                         sqlite3_close_v2(db);
536                         return PMINFO_R_ERROR;
537                 }
538                 idx = 0;
539                 _save_column_str(stmt, idx++, &info->package);
540                 if (g_hash_table_contains(packages,
541                                         (gconstpointer)info->package)) {
542                         free(info->package);
543                         free(info);
544                         continue;
545                 }
546                 _save_column_str(stmt, idx++, &info->version);
547                 _save_column_str(stmt, idx++, &info->installlocation);
548                 _save_column_str(stmt, idx++, &info->removable);
549                 _save_column_str(stmt, idx++, &info->preload);
550                 _save_column_str(stmt, idx++, &info->readonly);
551                 _save_column_str(stmt, idx++, &info->update);
552                 _save_column_str(stmt, idx++, &info->appsetting);
553                 _save_column_str(stmt, idx++, &info->system);
554                 _save_column_str(stmt, idx++, &info->type);
555                 _save_column_str(stmt, idx++, &info->package_size);
556                 _save_column_str(stmt, idx++, &info->installed_time);
557                 _save_column_str(stmt, idx++, &info->installed_storage);
558                 _save_column_str(stmt, idx++, &info->storeclient_id);
559                 _save_column_str(stmt, idx++, &info->mainapp_id);
560                 _save_column_str(stmt, idx++, &info->package_url);
561                 _save_column_str(stmt, idx++, &info->root_path);
562                 _save_column_str(stmt, idx++, &info->csc_path);
563                 _save_column_str(stmt, idx++, &info->nodisplay_setting);
564                 _save_column_str(stmt, idx++, &info->api_version);
565                 _save_column_str(stmt, idx++, &info->support_disable);
566                 _save_column_str(stmt, idx++, &info->tep_name);
567                 _save_column_str(stmt, idx++, &info->zip_mount_file);
568                 info->for_all_users =
569                         strdup((uid != GLOBAL_USER) ? "false" : "true");
570
571                 if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
572                         if (_pkginfo_get_author(db, info->package,
573                                                 &info->author)) {
574                                 pkgmgrinfo_basic_free_package(info);
575                                 sqlite3_finalize(stmt);
576                                 sqlite3_close_v2(db);
577                                 return PMINFO_R_ERROR;
578                         }
579                 }
580
581                 if (flag & PMINFO_PKGINFO_GET_LABEL) {
582                         if (_pkginfo_get_label(db, info->package, locale,
583                                                 &info->label)) {
584                                 pkgmgrinfo_basic_free_package(info);
585                                 sqlite3_finalize(stmt);
586                                 sqlite3_close_v2(db);
587                                 return PMINFO_R_ERROR;
588                         }
589                 }
590
591                 if (flag & PMINFO_PKGINFO_GET_ICON) {
592                         if (_pkginfo_get_icon(db, info->package, locale,
593                                                 &info->icon)) {
594                                 pkgmgrinfo_basic_free_package(info);
595                                 sqlite3_finalize(stmt);
596                                 sqlite3_close_v2(db);
597                                 return PMINFO_R_ERROR;
598                         }
599                 }
600
601                 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
602                         if (_pkginfo_get_description(db, info->package, locale,
603                                                 &info->description)) {
604                                 pkgmgrinfo_basic_free_package(info);
605                                 sqlite3_finalize(stmt);
606                                 sqlite3_close_v2(db);
607                                 return PMINFO_R_ERROR;
608                         }
609                 }
610
611                 if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) {
612                         if (_pkginfo_get_privilege(db, info->package,
613                                                 &info->privileges)) {
614                                 pkgmgrinfo_basic_free_package(info);
615                                 sqlite3_finalize(stmt);
616                                 sqlite3_close_v2(db);
617                                 return PMINFO_R_ERROR;
618                         }
619                 }
620
621                 g_hash_table_insert(packages, (gpointer)info->package,
622                                 (gpointer)info);
623         }
624
625         ret = PMINFO_R_OK;
626
627 catch:
628         if (constraints)
629                 free(constraints);
630
631         if (ret != PMINFO_R_OK && info != NULL)
632                 pkgmgrinfo_basic_free_package(info);
633
634         if (filter == NULL)
635                 pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
636
637         g_list_free_full(bind_params, free);
638         sqlite3_close_v2(db);
639         sqlite3_finalize(stmt);
640
641         return ret;
642 }
643
644 static int _pkginfo_get_filtered_foreach_pkginfo(uid_t uid,
645                 pkgmgrinfo_filter_x *filter, int flag,
646                 pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data)
647 {
648         int ret;
649         char *locale;
650         package_x *pkg;
651         pkgmgr_pkginfo_x info;
652         GHashTable *list;
653         GHashTableIter iter;
654         gpointer value;
655
656         locale = _get_system_locale();
657         if (locale == NULL)
658                 return PMINFO_R_ERROR;
659
660         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
661                         __free_packages);
662         if (list == NULL) {
663                 free(locale);
664                 return PMINFO_R_ERROR;
665         }
666
667         ret = _pkginfo_get_packages(uid, locale, filter, flag, list);
668         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
669                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
670                                 flag, list);
671
672         if (ret != PMINFO_R_OK) {
673                 g_hash_table_destroy(list);
674                 free(locale);
675                 return PMINFO_R_ERROR;
676         }
677
678         g_hash_table_iter_init(&iter, list);
679         while (g_hash_table_iter_next(&iter, NULL, &value)) {
680                 pkg = (package_x *)value;
681                 info.uid = uid;
682                 info.pkg_info = pkg;
683                 info.locale = locale;
684                 if (pkg_list_cb(&info, user_data) < 0)
685                         break;
686         }
687
688         g_hash_table_destroy(list);
689         free(locale);
690
691         return PMINFO_R_OK;
692 }
693
694 API int pkgmgrinfo_pkginfo_get_usr_pkginfo(const char *pkgid, uid_t uid,
695                 pkgmgrinfo_pkginfo_h *handle)
696 {
697         int ret;
698         char *locale;
699         GHashTable *list;
700         pkgmgrinfo_pkginfo_filter_h filter;
701         pkgmgr_pkginfo_x *info;
702
703         if (pkgid == NULL || handle == NULL) {
704                 LOGE("invalid parameter");
705                 return PMINFO_R_EINVAL;
706         }
707
708         locale = _get_system_locale();
709         if (locale == NULL)
710                 return PMINFO_R_ERROR;
711
712         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
713         if (ret != PMINFO_R_OK) {
714                 free(locale);
715                 return ret;
716         }
717
718         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
719                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
720         if (ret != PMINFO_R_OK) {
721                 pkgmgrinfo_pkginfo_filter_destroy(filter);
722                 free(locale);
723                 return PMINFO_R_ERROR;
724         }
725
726         list = g_hash_table_new(g_str_hash, g_str_equal);
727         if (list == NULL) {
728                 pkgmgrinfo_pkginfo_filter_destroy(filter);
729                 free(locale);
730                 return PMINFO_R_ERROR;
731         }
732
733         ret = _pkginfo_get_packages(uid, locale, filter,
734                         PMINFO_PKGINFO_GET_ALL, list);
735         if (!g_hash_table_size(list) && uid != GLOBAL_USER)
736                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
737                                 PMINFO_PKGINFO_GET_ALL, list);
738
739         pkgmgrinfo_pkginfo_filter_destroy(filter);
740         if (ret != PMINFO_R_OK) {
741                 g_hash_table_destroy(list);
742                 free(locale);
743                 return ret;
744         }
745
746         if (!g_hash_table_size(list)) {
747                 _LOGI("pkginfo for [%s] is not existed for user [%d]",
748                                 pkgid, uid);
749                 g_hash_table_destroy(list);
750                 free(locale);
751                 return PMINFO_R_ENOENT;
752         }
753
754         info = calloc(1, sizeof(pkgmgr_pkginfo_x));
755         if (info == NULL) {
756                 _LOGE("out of memory");
757                 g_hash_table_destroy(list);
758                 free(locale);
759                 return PMINFO_R_ERROR;
760         }
761
762         info->uid = uid;
763         info->pkg_info = (package_x *)g_hash_table_lookup(list, pkgid);
764         info->locale = locale;
765
766         /* just free list only */
767         g_hash_table_destroy(list);
768
769         *handle = info;
770
771         return ret;
772 }
773
774 API int pkgmgrinfo_pkginfo_get_pkginfo(const char *pkgid,
775                 pkgmgrinfo_pkginfo_h *handle)
776 {
777         return pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, _getuid(), handle);
778 }
779
780 API int pkgmgrinfo_pkginfo_get_usr_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
781                 int flag, void *user_data, uid_t uid)
782 {
783         if (pkg_list_cb == NULL) {
784                 LOGE("invalid parameter");
785                 return PMINFO_R_EINVAL;
786         }
787
788         return _pkginfo_get_filtered_foreach_pkginfo(uid, NULL, flag,
789                         pkg_list_cb, user_data);
790 }
791
792 API int pkgmgrinfo_pkginfo_get_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
793                 int flag, void *user_data)
794 {
795         return pkgmgrinfo_pkginfo_get_usr_list_full(pkg_list_cb, flag,
796                         user_data, _getuid());
797 }
798
799 API int pkgmgrinfo_pkginfo_get_usr_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
800                 void *user_data, uid_t uid)
801 {
802         if (pkg_list_cb == NULL) {
803                 LOGE("invalid parameter");
804                 return PMINFO_R_EINVAL;
805         }
806
807         return _pkginfo_get_filtered_foreach_pkginfo(uid, NULL,
808                         PMINFO_PKGINFO_GET_ALL, pkg_list_cb, user_data);
809 }
810
811 API int pkgmgrinfo_pkginfo_get_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
812                 void *user_data)
813 {
814         return pkgmgrinfo_pkginfo_get_usr_list(pkg_list_cb, user_data,
815                         _getuid());
816 }
817
818 API int pkgmgrinfo_pkginfo_get_pkgname(pkgmgrinfo_pkginfo_h handle, char **pkg_name)
819 {
820         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
821
822         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
823         retvm_if(pkg_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
824
825         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
826                 return PMINFO_R_ERROR;
827
828         *pkg_name = (char *)info->pkg_info->package;
829
830         return PMINFO_R_OK;
831 }
832
833 API int pkgmgrinfo_pkginfo_get_pkgid(pkgmgrinfo_pkginfo_h handle, char **pkgid)
834 {
835         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
836
837         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
838         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
839
840         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
841                 return PMINFO_R_ERROR;
842
843         *pkgid = (char *)info->pkg_info->package;
844
845         return PMINFO_R_OK;
846 }
847
848 API int pkgmgrinfo_pkginfo_get_type(pkgmgrinfo_pkginfo_h handle, char **type)
849 {
850         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
851
852         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
853         retvm_if(type == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
854
855         if (info->pkg_info == NULL)
856                 return PMINFO_R_ERROR;
857         if (info->pkg_info->type == NULL)
858                 info->pkg_info->type = strdup("");
859
860         *type = (char *)info->pkg_info->type;
861
862         return PMINFO_R_OK;
863 }
864
865 API int pkgmgrinfo_pkginfo_get_version(pkgmgrinfo_pkginfo_h handle, char **version)
866 {
867         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
868
869         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
870         retvm_if(version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
871
872         if (info->pkg_info == NULL)
873                 return PMINFO_R_ERROR;
874         if (info->pkg_info->version == NULL)
875                 info->pkg_info->version = strdup("");
876
877         *version = (char *)info->pkg_info->version;
878
879         return PMINFO_R_OK;
880 }
881
882 API int pkgmgrinfo_pkginfo_get_api_version(pkgmgrinfo_pkginfo_h handle, char **api_version)
883 {
884         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
885
886         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
887         retvm_if(api_version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
888
889         if (info->pkg_info == NULL)
890                 return PMINFO_R_ERROR;
891         if (info->pkg_info->api_version == NULL)
892                 info->pkg_info->api_version = strdup("");
893
894         *api_version = (char *)info->pkg_info->api_version;
895
896         return PMINFO_R_OK;
897 }
898
899 API int pkgmgrinfo_pkginfo_get_tep_name(pkgmgrinfo_pkginfo_h handle, char **tep_name)
900 {
901         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
902
903         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
904         retvm_if(tep_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
905
906         if (info->pkg_info == NULL || info->pkg_info->tep_name == NULL)
907                 return PMINFO_R_ERROR;
908
909         *tep_name = (char *)info->pkg_info->tep_name;
910
911         return PMINFO_R_OK;
912 }
913
914 API int pkgmgrinfo_pkginfo_get_zip_mount_file(pkgmgrinfo_pkginfo_h handle, char **zip_mount_file)
915 {
916         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
917
918         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
919         retvm_if(zip_mount_file == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
920
921         if (info->pkg_info == NULL)
922                 return PMINFO_R_ERROR;
923         if (info->pkg_info->zip_mount_file == NULL)
924                 info->pkg_info->zip_mount_file = strdup("");
925
926         *zip_mount_file = (char *)info->pkg_info->zip_mount_file;
927
928         return PMINFO_R_OK;
929 }
930
931 API int pkgmgrinfo_pkginfo_get_install_location(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_install_location *location)
932 {
933         char *val;
934         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
935
936         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
937         retvm_if(location == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
938
939         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
940                 return PMINFO_R_ERROR;
941
942         val = (char *)info->pkg_info->installlocation;
943         if (strcmp(val, "internal-only") == 0)
944                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
945         else if (strcmp(val, "prefer-external") == 0)
946                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
947         else
948                 *location = PMINFO_INSTALL_LOCATION_AUTO;
949
950         return PMINFO_R_OK;
951 }
952
953 API int pkgmgrinfo_pkginfo_get_package_size(pkgmgrinfo_pkginfo_h handle, int *size)
954 {
955         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
956         char *temp = NULL;
957
958         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
959         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
960
961         if (info->pkg_info == NULL)
962                 return PMINFO_R_ERROR;
963
964         if (info->pkg_info->package_size == NULL) {
965                 temp = strdup("");
966                 if (temp == NULL) {
967                         _LOGE("out of memory");
968                         return PMINFO_R_ERROR;
969                 } else {
970                         info->pkg_info->package_size = temp;
971                 }
972         }
973
974         *size = atoi((char *)info->pkg_info->package_size);
975
976         return PMINFO_R_OK;
977 }
978
979 API int pkgmgrinfo_pkginfo_get_icon(pkgmgrinfo_pkginfo_h handle, char **icon)
980 {
981         const char *locale;
982         icon_x *ptr;
983         GList *tmp;
984         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
985
986         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
987         retvm_if(icon == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
988
989         locale = info->locale;
990         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
991
992         if (info->pkg_info == NULL || info->pkg_info->icon == NULL)
993                 return PMINFO_R_ERROR;
994
995         for (tmp = info->pkg_info->icon; tmp; tmp = tmp->next) {
996                 ptr = (icon_x *)tmp->data;
997                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
998                                 strcmp(ptr->lang, locale))
999                         continue;
1000                 *icon = (char *)ptr->text;
1001                 return PMINFO_R_OK;
1002         }
1003
1004         locale = DEFAULT_LOCALE;
1005         for (tmp = info->pkg_info->icon; tmp; tmp = tmp->next) {
1006                 ptr = (icon_x *)tmp->data;
1007                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1008                                 strcmp(ptr->lang, locale))
1009                         continue;
1010                 *icon = (char *)ptr->text;
1011                 return PMINFO_R_OK;
1012         }
1013
1014         *icon = "";
1015
1016         return PMINFO_R_OK;
1017 }
1018
1019 API int pkgmgrinfo_pkginfo_get_label(pkgmgrinfo_pkginfo_h handle, char **label)
1020 {
1021         const char *locale;
1022         label_x *ptr;
1023         GList *tmp;
1024         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1025
1026         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1027         retvm_if(label == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1028
1029         locale = info->locale;
1030         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1031
1032         if (info->pkg_info == NULL || info->pkg_info->label == NULL)
1033                 return PMINFO_R_ERROR;
1034
1035         for (tmp = info->pkg_info->label; tmp != NULL; tmp = tmp->next) {
1036                 ptr = (label_x *)tmp->data;
1037                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1038                                 strcmp(ptr->lang, locale))
1039                         continue;
1040                 *label = (char *)ptr->text;
1041                 return PMINFO_R_OK;
1042         }
1043
1044         locale = DEFAULT_LOCALE;
1045         for (tmp = info->pkg_info->label; tmp != NULL; tmp = tmp->next) {
1046                 ptr = (label_x *)tmp->data;
1047                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1048                                 strcmp(ptr->lang, locale))
1049                         continue;
1050                 *label = (char *)ptr->text;
1051                 return PMINFO_R_OK;
1052         }
1053
1054         *label = "";
1055
1056         return PMINFO_R_OK;
1057 }
1058
1059 API int pkgmgrinfo_pkginfo_get_description(pkgmgrinfo_pkginfo_h handle, char **description)
1060 {
1061         const char *locale;
1062         description_x *ptr;
1063         GList *tmp;
1064         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1065
1066         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1067         retvm_if(description == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1068
1069         locale = info->locale;
1070         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1071
1072         if (info->pkg_info == NULL || info->pkg_info->description == NULL)
1073                 return PMINFO_R_ERROR;
1074
1075         for (tmp = info->pkg_info->description; tmp; tmp = tmp->next) {
1076                 ptr = (description_x *)tmp->data;
1077                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1078                                 strcmp(ptr->lang, locale))
1079                         continue;
1080                 *description = (char *)ptr->text;
1081                 return PMINFO_R_OK;
1082         }
1083
1084         locale = DEFAULT_LOCALE;
1085         for (tmp = info->pkg_info->description; tmp; tmp = tmp->next) {
1086                 ptr = (description_x *)tmp->data;
1087                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1088                                 strcmp(ptr->lang, locale))
1089                         continue;
1090                 *description = (char *)ptr->text;
1091                 return PMINFO_R_OK;
1092         }
1093
1094         *description = "";
1095
1096         return PMINFO_R_OK;
1097 }
1098
1099 API int pkgmgrinfo_pkginfo_get_author_name(pkgmgrinfo_pkginfo_h handle, char **author_name)
1100 {
1101         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1102         author_x *author;
1103
1104         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1105         retvm_if(author_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1106
1107         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1108                 return PMINFO_R_ERROR;
1109
1110         author = (author_x *)info->pkg_info->author->data;
1111         if (author == NULL)
1112                 return PMINFO_R_ERROR;
1113         if (author->text == NULL)
1114                 author->text = strdup("");
1115
1116         *author_name = (char *)author->text;
1117
1118         return PMINFO_R_OK;
1119 }
1120
1121 API int pkgmgrinfo_pkginfo_get_author_email(pkgmgrinfo_pkginfo_h handle, char **author_email)
1122 {
1123         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1124         author_x *author;
1125
1126         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1127         retvm_if(author_email == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1128
1129         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1130                 return PMINFO_R_ERROR;
1131
1132         author = (author_x *)info->pkg_info->author->data;
1133         if (author == NULL)
1134                 return PMINFO_R_ERROR;
1135         if (author->email == NULL)
1136                 author->email = strdup("");
1137
1138         *author_email = (char *)author->email;
1139
1140         return PMINFO_R_OK;
1141 }
1142
1143 API int pkgmgrinfo_pkginfo_get_author_href(pkgmgrinfo_pkginfo_h handle, char **author_href)
1144 {
1145         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1146         author_x *author;
1147
1148         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1149         retvm_if(author_href == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1150
1151         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1152                 return PMINFO_R_ERROR;
1153
1154         author = (author_x *)info->pkg_info->author->data;
1155         if (author == NULL)
1156                 return PMINFO_R_ERROR;
1157         if (author->href == NULL)
1158                 author->href = strdup("");
1159
1160         *author_href = (char *)author->href;
1161
1162         return PMINFO_R_OK;
1163 }
1164
1165 API int pkgmgrinfo_pkginfo_get_installed_storage(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_installed_storage *storage)
1166 {
1167         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1168
1169         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1170         retvm_if(storage == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1171
1172         if (info->pkg_info == NULL || info->pkg_info->installed_storage == NULL)
1173                 return PMINFO_R_ERROR;
1174
1175         if (strcmp(info->pkg_info->installed_storage,"installed_internal") == 0)
1176                 *storage = PMINFO_INTERNAL_STORAGE;
1177         else if (strcmp(info->pkg_info->installed_storage,"installed_external") == 0)
1178                 *storage = PMINFO_EXTERNAL_STORAGE;
1179         else
1180                 return PMINFO_R_ERROR;
1181
1182         return PMINFO_R_OK;
1183 }
1184
1185 API int pkgmgrinfo_pkginfo_get_installed_time(pkgmgrinfo_pkginfo_h handle, int *installed_time)
1186 {
1187         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1188
1189         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1190         retvm_if(installed_time == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1191
1192         if (info->pkg_info == NULL || info->pkg_info->installed_time == NULL)
1193                 return PMINFO_R_ERROR;
1194
1195         *installed_time = atoi(info->pkg_info->installed_time);
1196
1197         return PMINFO_R_OK;
1198 }
1199
1200 API int pkgmgrinfo_pkginfo_get_storeclientid(pkgmgrinfo_pkginfo_h handle, char **storeclientid)
1201 {
1202         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1203
1204         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1205         retvm_if(storeclientid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1206
1207         if (info->pkg_info == NULL)
1208                 return PMINFO_R_ERROR;
1209         if (info->pkg_info->storeclient_id == NULL)
1210                 info->pkg_info->storeclient_id = strdup("");
1211
1212         *storeclientid = (char *)info->pkg_info->storeclient_id;
1213
1214         return PMINFO_R_OK;
1215 }
1216
1217 API int pkgmgrinfo_pkginfo_get_mainappid(pkgmgrinfo_pkginfo_h handle, char **mainappid)
1218 {
1219         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1220
1221         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1222         retvm_if(mainappid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1223
1224         if (info->pkg_info == NULL || info->pkg_info->mainapp_id == NULL)
1225                 return PMINFO_R_ERROR;
1226
1227         *mainappid = (char *)info->pkg_info->mainapp_id;
1228
1229         return PMINFO_R_OK;
1230 }
1231
1232 API int pkgmgrinfo_pkginfo_get_url(pkgmgrinfo_pkginfo_h handle, char **url)
1233 {
1234         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1235
1236         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1237         retvm_if(url == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1238
1239         if (info->pkg_info == NULL)
1240                 return PMINFO_R_ERROR;
1241         if (info->pkg_info->package_url == NULL)
1242                 info->pkg_info->package_url = strdup("");
1243
1244         *url = (char *)info->pkg_info->package_url;
1245
1246         return PMINFO_R_OK;
1247 }
1248
1249 API int pkgmgrinfo_pkginfo_get_root_path(pkgmgrinfo_pkginfo_h handle, char **path)
1250 {
1251         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1252
1253         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1254         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1255
1256         if (info->pkg_info == NULL || info->pkg_info->root_path == NULL)
1257                 return PMINFO_R_ERROR;
1258
1259         *path = (char *)info->pkg_info->root_path;
1260
1261         return PMINFO_R_OK;
1262 }
1263
1264 API int pkgmgrinfo_pkginfo_get_csc_path(pkgmgrinfo_pkginfo_h handle, char **path)
1265 {
1266         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1267
1268         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1269         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1270
1271         if (info->pkg_info == NULL)
1272                 return PMINFO_R_ERROR;
1273         if (info->pkg_info->csc_path == NULL)
1274                 info->pkg_info->csc_path = strdup("");
1275
1276         *path = (char *)info->pkg_info->csc_path;
1277
1278         return PMINFO_R_OK;
1279 }
1280
1281
1282 API int pkgmgrinfo_pkginfo_is_accessible(pkgmgrinfo_pkginfo_h handle, bool *accessible)
1283 {
1284         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1285         retvm_if(accessible == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1286
1287 #if 0 //smack issue occured, check later
1288         char *pkgid = NULL;
1289         pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
1290         if (pkgid == NULL){
1291                  _LOGD("invalid func parameters\n");
1292                  return PMINFO_R_ERROR;
1293         }
1294          _LOGD("pkgmgr_get_pkg_external_validation() called\n");
1295
1296         FILE *fp = NULL;
1297         char app_mmc_path[FILENAME_MAX] = { 0, };
1298         char app_dir_path[FILENAME_MAX] = { 0, };
1299         char app_mmc_internal_path[FILENAME_MAX] = { 0, };
1300         snprintf(app_dir_path, FILENAME_MAX,"%s%s", PKG_INSTALLATION_PATH, pkgid);
1301         snprintf(app_mmc_path, FILENAME_MAX,"%s%s", PKG_SD_PATH, pkgid);
1302         snprintf(app_mmc_internal_path, FILENAME_MAX,"%s%s/.mmc", PKG_INSTALLATION_PATH, pkgid);
1303
1304         /*check whether application is in external memory or not */
1305         fp = fopen(app_mmc_path, "r");
1306         if (fp == NULL){
1307                 _LOGD(" app path in external memory not accesible\n");
1308         } else {
1309                 fclose(fp);
1310                 fp = NULL;
1311                 *accessible = 1;
1312                 _LOGD("pkgmgr_get_pkg_external_validation() : SD_CARD \n");
1313                 return PMINFO_R_OK;
1314         }
1315
1316         /*check whether application is in internal or not */
1317         if (fp == NULL) {
1318                 _LOGD(" app path in internal memory not accesible\n");
1319                 *accessible = 0;
1320                 return PMINFO_R_ERROR;
1321         } else {
1322                 fclose(fp);
1323                 /*check whether the application is installed in SD card
1324                 but SD card is not present*/
1325                 fp = fopen(app_mmc_internal_path, "r");
1326                 if (fp == NULL){
1327                         *accessible = 1;
1328                         _LOGD("pkgmgr_get_pkg_external_validation() : INTERNAL_MEM \n");
1329                         return PMINFO_R_OK;
1330                 }
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 }