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