051979f6ee8e6be49202d6d0e121c6a9eadd693a
[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 (info->pkg_info->zip_mount_file &&
958                         strlen(info->pkg_info->zip_mount_file) > 0)
959                 *zip_mount_file = (char *)info->pkg_info->zip_mount_file;
960
961         return PMINFO_R_OK;
962 }
963
964 API int pkgmgrinfo_pkginfo_get_install_location(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_install_location *location)
965 {
966         char *val;
967         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
968
969         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
970         retvm_if(location == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
971
972         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
973                 return PMINFO_R_ERROR;
974
975         val = (char *)info->pkg_info->installlocation;
976         if (strcmp(val, "internal-only") == 0)
977                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
978         else if (strcmp(val, "prefer-external") == 0)
979                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
980         else
981                 *location = PMINFO_INSTALL_LOCATION_AUTO;
982
983         return PMINFO_R_OK;
984 }
985
986 API int pkgmgrinfo_pkginfo_get_package_size(pkgmgrinfo_pkginfo_h handle, int *size)
987 {
988         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
989
990         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
991         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
992
993         if (info->pkg_info == NULL || info->pkg_info->package_size == NULL)
994                 return PMINFO_R_ERROR;
995
996         *size = atoi((char *)info->pkg_info->package_size);
997
998         return PMINFO_R_OK;
999 }
1000
1001 API int pkgmgrinfo_pkginfo_get_total_size(pkgmgrinfo_pkginfo_h handle, int *size)
1002 {
1003         char *pkgid;
1004         char device_path[PKG_STRING_LEN_MAX] = { '\0', };
1005         long long rw_size = 0;
1006         long long ro_size = 0;
1007         long long tmp_size = 0;
1008         long long total_size = 0;
1009         struct stat fileinfo;
1010         int ret;
1011
1012         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1013         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1014
1015         ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
1016         if (ret < 0)
1017                 return PMINFO_R_ERROR;
1018
1019         /* RW area */
1020         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/bin", PKG_RW_PATH, pkgid);
1021         if (lstat(device_path, &fileinfo) == 0) {
1022                 if (!S_ISLNK(fileinfo.st_mode)) {
1023                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1024                         if (tmp_size > 0)
1025                                 rw_size += tmp_size;
1026                 }
1027         }
1028
1029         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/info", PKG_RW_PATH, pkgid);
1030         if (lstat(device_path, &fileinfo) == 0) {
1031                 if (!S_ISLNK(fileinfo.st_mode)) {
1032                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1033                         if (tmp_size > 0)
1034                         rw_size += tmp_size;
1035                 }
1036         }
1037
1038         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/res", PKG_RW_PATH, pkgid);
1039         if (lstat(device_path, &fileinfo) == 0) {
1040                 if (!S_ISLNK(fileinfo.st_mode)) {
1041                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1042                         if (tmp_size > 0)
1043                         rw_size += tmp_size;
1044                 }
1045         }
1046
1047         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/data", PKG_RW_PATH, pkgid);
1048         if (lstat(device_path, &fileinfo) == 0) {
1049                 if (!S_ISLNK(fileinfo.st_mode)) {
1050                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1051                         if (tmp_size > 0)
1052                                 rw_size += tmp_size;
1053                 }
1054         }
1055
1056         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/shared", PKG_RW_PATH, pkgid);
1057         if (lstat(device_path, &fileinfo) == 0) {
1058                 if (!S_ISLNK(fileinfo.st_mode)) {
1059                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1060                         if (tmp_size > 0)
1061                                 rw_size += tmp_size;
1062         }
1063         }
1064
1065         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/setting", PKG_RW_PATH, pkgid);
1066         if (lstat(device_path, &fileinfo) == 0) {
1067                 if (!S_ISLNK(fileinfo.st_mode)) {
1068                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1069                         if (tmp_size > 0)
1070                                 rw_size += tmp_size;
1071                 }
1072         }
1073
1074         /* RO area */
1075         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/bin", PKG_RO_PATH, pkgid);
1076         if (lstat(device_path, &fileinfo) == 0) {
1077                 if (!S_ISLNK(fileinfo.st_mode)) {
1078                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1079                         if (tmp_size > 0)
1080                                 ro_size += tmp_size;
1081                 }
1082         }
1083
1084         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/info", PKG_RO_PATH, pkgid);
1085         if (lstat(device_path, &fileinfo) == 0) {
1086                 if (!S_ISLNK(fileinfo.st_mode)) {
1087                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1088                         if (tmp_size > 0)
1089                                 ro_size += tmp_size;
1090                 }
1091         }
1092
1093         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/res", PKG_RO_PATH, pkgid);
1094         if (lstat(device_path, &fileinfo) == 0) {
1095                 if (!S_ISLNK(fileinfo.st_mode)) {
1096                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1097                         if (tmp_size > 0)
1098                                 ro_size += tmp_size;
1099                 }
1100         }
1101
1102         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/data", PKG_RO_PATH, pkgid);
1103         if (lstat(device_path, &fileinfo) == 0) {
1104                 if (!S_ISLNK(fileinfo.st_mode)) {
1105                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1106                         if (tmp_size > 0)
1107                                 ro_size += tmp_size;
1108                 }
1109         }
1110
1111         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/shared", PKG_RO_PATH, pkgid);
1112         if (lstat(device_path, &fileinfo) == 0) {
1113                 if (!S_ISLNK(fileinfo.st_mode)) {
1114                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1115                         if (tmp_size > 0)
1116                                 ro_size += tmp_size;
1117                 }
1118         }
1119
1120         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/setting", PKG_RO_PATH, pkgid);
1121         if (lstat(device_path, &fileinfo) == 0) {
1122                 if (!S_ISLNK(fileinfo.st_mode)) {
1123                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1124                         if (tmp_size > 0)
1125                                 ro_size += tmp_size;
1126                 }
1127         }
1128
1129         /* Total size */
1130         total_size = rw_size + ro_size;
1131         *size = (int)total_size;
1132
1133         return PMINFO_R_OK;
1134 }
1135
1136 API int pkgmgrinfo_pkginfo_get_data_size(pkgmgrinfo_pkginfo_h handle, int *size)
1137 {
1138         char *pkgid;
1139         char device_path[PKG_STRING_LEN_MAX] = { '\0', };
1140         long long total_size = 0;
1141
1142         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1143         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1144
1145         if (pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid) < 0)
1146                 return PMINFO_R_ERROR;
1147
1148         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/data", PKG_RW_PATH, pkgid);
1149         if (access(device_path, R_OK) == 0)
1150                 total_size = _pkgmgr_calculate_dir_size(device_path);
1151         if (total_size < 0)
1152                 return PMINFO_R_ERROR;
1153
1154         *size = (int)total_size;
1155
1156         return PMINFO_R_OK;
1157 }
1158
1159 API int pkgmgrinfo_pkginfo_get_icon(pkgmgrinfo_pkginfo_h handle, char **icon)
1160 {
1161         const char *locale;
1162         icon_x *ptr;
1163         GList *tmp;
1164         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1165
1166         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1167         retvm_if(icon == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1168
1169         locale = info->locale;
1170         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1171
1172         if (info->pkg_info == NULL)
1173                 return PMINFO_R_ERROR;
1174
1175         for (tmp = info->pkg_info->icon; tmp; tmp = tmp->next) {
1176                 ptr = (icon_x *)tmp->data;
1177                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1178                                 !strcasecmp(ptr->text, "(null)") ||
1179                                 strcmp(ptr->lang, locale))
1180                         continue;
1181                 *icon = (char *)ptr->text;
1182                 return PMINFO_R_OK;
1183         }
1184
1185         locale = DEFAULT_LOCALE;
1186         for (tmp = info->pkg_info->icon; tmp; tmp = tmp->next) {
1187                 ptr = (icon_x *)tmp->data;
1188                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1189                                 strcmp(ptr->lang, locale))
1190                         continue;
1191                 *icon = (char *)ptr->text;
1192                 return PMINFO_R_OK;
1193         }
1194
1195         return PMINFO_R_ERROR;
1196 }
1197
1198 API int pkgmgrinfo_pkginfo_get_label(pkgmgrinfo_pkginfo_h handle, char **label)
1199 {
1200         const char *locale;
1201         label_x *ptr;
1202         GList *tmp;
1203         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1204
1205         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1206         retvm_if(label == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1207
1208         locale = info->locale;
1209         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1210
1211         for (tmp = info->pkg_info->label; tmp != NULL; tmp = tmp->next) {
1212                 ptr = (label_x *)tmp->data;
1213                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1214                                 strcmp(ptr->lang, locale))
1215                         continue;
1216                 *label = (char *)ptr->text;
1217                 return PMINFO_R_OK;
1218         }
1219
1220         locale = DEFAULT_LOCALE;
1221         for (tmp = info->pkg_info->label; tmp != NULL; tmp = tmp->next) {
1222                 ptr = (label_x *)tmp->data;
1223                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1224                                 strcmp(ptr->lang, locale))
1225                         continue;
1226                 *label = (char *)ptr->text;
1227                 return PMINFO_R_OK;
1228         }
1229
1230         return PMINFO_R_ERROR;
1231 }
1232
1233 API int pkgmgrinfo_pkginfo_get_description(pkgmgrinfo_pkginfo_h handle, char **description)
1234 {
1235         const char *locale;
1236         description_x *ptr;
1237         GList *tmp;
1238         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1239
1240         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1241         retvm_if(description == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1242
1243         locale = info->locale;
1244         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1245
1246         for (tmp = info->pkg_info->description; tmp; tmp = tmp->next) {
1247                 ptr = (description_x *)tmp->data;
1248                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1249                                 strcmp(ptr->lang, locale))
1250                         continue;
1251                 *description = (char *)ptr->text;
1252                 return PMINFO_R_OK;
1253         }
1254
1255         locale = DEFAULT_LOCALE;
1256         for (tmp = info->pkg_info->description; tmp; tmp = tmp->next) {
1257                 ptr = (description_x *)tmp->data;
1258                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1259                                 strcmp(ptr->lang, locale))
1260                         continue;
1261                 *description = (char *)ptr->text;
1262                 return PMINFO_R_OK;
1263         }
1264
1265         return PMINFO_R_ERROR;
1266 }
1267
1268 API int pkgmgrinfo_pkginfo_get_author_name(pkgmgrinfo_pkginfo_h handle, char **author_name)
1269 {
1270         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1271         author_x *author;
1272
1273         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1274         retvm_if(author_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1275
1276         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1277                 return PMINFO_R_ERROR;
1278
1279         author = (author_x *)info->pkg_info->author->data;
1280         if (author == NULL || author->text == NULL)
1281                 return PMINFO_R_ERROR;
1282
1283         *author_name = (char *)author->text;
1284
1285         return PMINFO_R_OK;
1286 }
1287
1288 API int pkgmgrinfo_pkginfo_get_author_email(pkgmgrinfo_pkginfo_h handle, char **author_email)
1289 {
1290         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1291         author_x *author;
1292
1293         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1294         retvm_if(author_email == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1295
1296         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1297                 return PMINFO_R_ERROR;
1298
1299         author = (author_x *)info->pkg_info->author->data;
1300         if (author == NULL || author->email == NULL)
1301                 return PMINFO_R_ERROR;
1302
1303         *author_email = (char *)author->email;
1304
1305         return PMINFO_R_OK;
1306 }
1307
1308 API int pkgmgrinfo_pkginfo_get_author_href(pkgmgrinfo_pkginfo_h handle, char **author_href)
1309 {
1310         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1311         author_x *author;
1312
1313         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1314         retvm_if(author_href == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1315
1316         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1317                 return PMINFO_R_ERROR;
1318
1319         author = (author_x *)info->pkg_info->author->data;
1320         if (author == NULL || author->href == NULL)
1321                 return PMINFO_R_ERROR;
1322
1323         *author_href = (char *)author->href;
1324
1325         return PMINFO_R_OK;
1326 }
1327
1328 API int pkgmgrinfo_pkginfo_get_installed_storage(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_installed_storage *storage)
1329 {
1330         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1331
1332         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1333         retvm_if(storage == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1334
1335         if (info->pkg_info == NULL || info->pkg_info->installed_storage == NULL)
1336                 return PMINFO_R_ERROR;
1337
1338         if (strcmp(info->pkg_info->installed_storage,"installed_internal") == 0)
1339                 *storage = PMINFO_INTERNAL_STORAGE;
1340         else if (strcmp(info->pkg_info->installed_storage,"installed_external") == 0)
1341                 *storage = PMINFO_EXTERNAL_STORAGE;
1342         else
1343                 return PMINFO_R_ERROR;
1344
1345         return PMINFO_R_OK;
1346 }
1347
1348 API int pkgmgrinfo_pkginfo_get_installed_time(pkgmgrinfo_pkginfo_h handle, int *installed_time)
1349 {
1350         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1351
1352         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1353         retvm_if(installed_time == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1354
1355         if (info->pkg_info == NULL || info->pkg_info->installed_time == NULL)
1356                 return PMINFO_R_ERROR;
1357
1358         *installed_time = atoi(info->pkg_info->installed_time);
1359
1360         return PMINFO_R_OK;
1361 }
1362
1363 API int pkgmgrinfo_pkginfo_get_storeclientid(pkgmgrinfo_pkginfo_h handle, char **storeclientid)
1364 {
1365         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1366
1367         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1368         retvm_if(storeclientid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1369
1370         if (info->pkg_info == NULL || info->pkg_info->storeclient_id == NULL)
1371                 return PMINFO_R_ERROR;
1372
1373         *storeclientid = (char *)info->pkg_info->storeclient_id;
1374
1375         return PMINFO_R_OK;
1376 }
1377
1378 API int pkgmgrinfo_pkginfo_get_mainappid(pkgmgrinfo_pkginfo_h handle, char **mainappid)
1379 {
1380         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1381
1382         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1383         retvm_if(mainappid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1384
1385         if (info->pkg_info == NULL || info->pkg_info->mainapp_id == NULL)
1386                 return PMINFO_R_ERROR;
1387
1388         *mainappid = (char *)info->pkg_info->mainapp_id;
1389
1390         return PMINFO_R_OK;
1391 }
1392
1393 API int pkgmgrinfo_pkginfo_get_url(pkgmgrinfo_pkginfo_h handle, char **url)
1394 {
1395         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1396
1397         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1398         retvm_if(url == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1399
1400         if (info->pkg_info == NULL || info->pkg_info->package_url == NULL)
1401                 return PMINFO_R_ERROR;
1402
1403         *url = (char *)info->pkg_info->package_url;
1404
1405         return PMINFO_R_OK;
1406 }
1407
1408 API int pkgmgrinfo_pkginfo_get_size_from_xml(const char *manifest, int *size)
1409 {
1410         const char *val = NULL;
1411         const xmlChar *node;
1412         xmlTextReaderPtr reader;
1413         retvm_if(manifest == NULL, PMINFO_R_EINVAL, "Input argument is NULL\n");
1414         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1415
1416         xmlInitParser();
1417         reader = xmlReaderForFile(manifest, NULL, 0);
1418
1419         if (reader){
1420                 if (__child_element(reader, -1)) {
1421                         node = xmlTextReaderConstName(reader);
1422                         if (!node) {
1423                                 _LOGE("xmlTextReaderConstName value is NULL\n");
1424                                 xmlFreeTextReader(reader);
1425                                 xmlCleanupParser();
1426                                 return PMINFO_R_ERROR;
1427                         }
1428
1429                         if (!strcmp(ASC_CHAR(node), "manifest")) {
1430                                 if (xmlTextReaderGetAttribute(reader, XML_CHAR("size")))
1431                                         val = ASC_CHAR(xmlTextReaderGetAttribute(reader, XML_CHAR("size")));
1432
1433                                 if (val) {
1434                                         *size = atoi(val);
1435                                 } else {
1436                                         *size = 0;
1437                                         _LOGE("package size is not specified\n");
1438                                         xmlFreeTextReader(reader);
1439                                         xmlCleanupParser();
1440                                         return PMINFO_R_ERROR;
1441                                 }
1442                         } else {
1443                                 _LOGE("Unable to create xml reader\n");
1444                                 xmlFreeTextReader(reader);
1445                                 xmlCleanupParser();
1446                                 return PMINFO_R_ERROR;
1447                         }
1448                 }
1449         } else {
1450                 _LOGE("xmlReaderForFile value is NULL\n");
1451                 xmlCleanupParser();
1452                 return PMINFO_R_ERROR;
1453         }
1454
1455         xmlFreeTextReader(reader);
1456         xmlCleanupParser();
1457
1458         return PMINFO_R_OK;
1459 }
1460
1461 API int pkgmgrinfo_pkginfo_get_location_from_xml(const char *manifest, pkgmgrinfo_install_location *location)
1462 {
1463         const char *val = NULL;
1464         const xmlChar *node;
1465         xmlTextReaderPtr reader;
1466         retvm_if(manifest == NULL, PMINFO_R_EINVAL, "Input argument is NULL\n");
1467         retvm_if(location == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1468
1469         xmlInitParser();
1470         reader = xmlReaderForFile(manifest, NULL, 0);
1471
1472         if (reader) {
1473                 if ( __child_element(reader, -1)) {
1474                         node = xmlTextReaderConstName(reader);
1475                         if (!node) {
1476                                 _LOGE("xmlTextReaderConstName value is NULL\n");
1477                                 xmlFreeTextReader(reader);
1478                                 xmlCleanupParser();
1479                                 return PMINFO_R_ERROR;
1480                         }
1481
1482                         if (!strcmp(ASC_CHAR(node), "manifest")) {
1483                                 if (xmlTextReaderGetAttribute(reader, XML_CHAR("install-location")))
1484                                         val = ASC_CHAR(xmlTextReaderGetAttribute(reader, XML_CHAR("install-location")));
1485
1486                                 if (val) {
1487                                         if (strcmp(val, "internal-only") == 0)
1488                                                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
1489                                         else if (strcmp(val, "prefer-external") == 0)
1490                                                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
1491                                         else
1492                                                 *location = PMINFO_INSTALL_LOCATION_AUTO;
1493                                 }
1494                         } else {
1495                                 _LOGE("Unable to create xml reader\n");
1496                                 xmlFreeTextReader(reader);
1497                                 xmlCleanupParser();
1498                                 return PMINFO_R_ERROR;
1499                         }
1500                 }
1501         } else {
1502                 _LOGE("xmlReaderForFile value is NULL\n");
1503                 xmlCleanupParser();
1504                 return PMINFO_R_ERROR;
1505         }
1506
1507         xmlFreeTextReader(reader);
1508         xmlCleanupParser();
1509
1510         return PMINFO_R_OK;
1511 }
1512
1513
1514 API int pkgmgrinfo_pkginfo_get_root_path(pkgmgrinfo_pkginfo_h handle, char **path)
1515 {
1516         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1517
1518         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1519         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1520
1521         if (info->pkg_info == NULL || info->pkg_info->root_path == NULL)
1522                 return PMINFO_R_ERROR;
1523
1524         *path = (char *)info->pkg_info->root_path;
1525
1526         return PMINFO_R_OK;
1527 }
1528
1529 API int pkgmgrinfo_pkginfo_get_csc_path(pkgmgrinfo_pkginfo_h handle, char **path)
1530 {
1531         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1532
1533         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1534         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1535
1536         if (info->pkg_info == NULL || info->pkg_info->csc_path == NULL)
1537                 return PMINFO_R_ERROR;
1538
1539         *path = (char *)info->pkg_info->csc_path;
1540
1541         return PMINFO_R_OK;
1542 }
1543
1544
1545 API int pkgmgrinfo_pkginfo_is_accessible(pkgmgrinfo_pkginfo_h handle, bool *accessible)
1546 {
1547         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1548         retvm_if(accessible == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1549
1550 #if 0 //smack issue occured, check later
1551         char *pkgid = NULL;
1552         pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
1553         if (pkgid == NULL){
1554                  _LOGD("invalid func parameters\n");
1555                  return PMINFO_R_ERROR;
1556         }
1557          _LOGD("pkgmgr_get_pkg_external_validation() called\n");
1558
1559         FILE *fp = NULL;
1560         char app_mmc_path[FILENAME_MAX] = { 0, };
1561         char app_dir_path[FILENAME_MAX] = { 0, };
1562         char app_mmc_internal_path[FILENAME_MAX] = { 0, };
1563         snprintf(app_dir_path, FILENAME_MAX,"%s%s", PKG_INSTALLATION_PATH, pkgid);
1564         snprintf(app_mmc_path, FILENAME_MAX,"%s%s", PKG_SD_PATH, pkgid);
1565         snprintf(app_mmc_internal_path, FILENAME_MAX,"%s%s/.mmc", PKG_INSTALLATION_PATH, pkgid);
1566
1567         /*check whether application is in external memory or not */
1568         fp = fopen(app_mmc_path, "r");
1569         if (fp == NULL){
1570                 _LOGD(" app path in external memory not accesible\n");
1571         } else {
1572                 fclose(fp);
1573                 fp = NULL;
1574                 *accessible = 1;
1575                 _LOGD("pkgmgr_get_pkg_external_validation() : SD_CARD \n");
1576                 return PMINFO_R_OK;
1577         }
1578
1579         /*check whether application is in internal or not */
1580         fp = fopen(app_dir_path, "r");
1581         if (fp == NULL) {
1582                 _LOGD(" app path in internal memory not accesible\n");
1583                 *accessible = 0;
1584                 return PMINFO_R_ERROR;
1585         } else {
1586                 fclose(fp);
1587                 /*check whether the application is installed in SD card
1588                 but SD card is not present*/
1589                 fp = fopen(app_mmc_internal_path, "r");
1590                 if (fp == NULL){
1591                         *accessible = 1;
1592                         _LOGD("pkgmgr_get_pkg_external_validation() : INTERNAL_MEM \n");
1593                         return PMINFO_R_OK;
1594                 }
1595                 else{
1596                         *accessible = 0;
1597                         _LOGD("pkgmgr_get_pkg_external_validation() : ERROR_MMC_STATUS \n");
1598                 }
1599                 fclose(fp);
1600         }
1601
1602         _LOGD("pkgmgr_get_pkg_external_validation() end\n");
1603 #endif
1604
1605         *accessible = 1;
1606         return PMINFO_R_OK;
1607 }
1608
1609 API int pkgmgrinfo_pkginfo_is_removable(pkgmgrinfo_pkginfo_h handle, bool *removable)
1610 {
1611         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1612
1613         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1614         retvm_if(removable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1615
1616         if (info->pkg_info == NULL || info->pkg_info->removable == NULL)
1617                 return PMINFO_R_ERROR;
1618
1619         *removable = _get_bool_value(info->pkg_info->removable);
1620
1621         return PMINFO_R_OK;
1622 }
1623
1624 API int pkgmgrinfo_pkginfo_is_movable(pkgmgrinfo_pkginfo_h handle, bool *movable)
1625 {
1626         char *val;
1627         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1628
1629         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1630         retvm_if(movable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1631
1632         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
1633                 return PMINFO_R_ERROR;
1634
1635         val = (char *)info->pkg_info->installlocation;
1636         if (strcmp(val, "internal-only") == 0)
1637                 *movable = 0;
1638         else if (strcmp(val, "prefer-external") == 0)
1639                 *movable = 1;
1640         else
1641                 *movable = 1;
1642
1643         return PMINFO_R_OK;
1644 }
1645
1646 API int pkgmgrinfo_pkginfo_is_preload(pkgmgrinfo_pkginfo_h handle, bool *preload)
1647 {
1648         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1649
1650         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1651         retvm_if(preload == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1652
1653         if (info->pkg_info == NULL || info->pkg_info->preload == NULL)
1654                 return PMINFO_R_ERROR;
1655
1656         *preload = _get_bool_value(info->pkg_info->preload);
1657
1658         return PMINFO_R_OK;
1659 }
1660
1661 API int pkgmgrinfo_pkginfo_is_system(pkgmgrinfo_pkginfo_h handle, bool *system)
1662 {
1663         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1664
1665         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1666         retvm_if(system == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1667
1668         if (info->pkg_info == NULL || info->pkg_info->system == NULL)
1669                 return PMINFO_R_ERROR;
1670
1671         *system = _get_bool_value(info->pkg_info->system);
1672
1673         return PMINFO_R_OK;
1674 }
1675
1676 API int pkgmgrinfo_pkginfo_is_readonly(pkgmgrinfo_pkginfo_h handle, bool *readonly)
1677 {
1678         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1679
1680         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1681         retvm_if(readonly == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1682
1683         if (info->pkg_info == NULL || info->pkg_info->readonly == NULL)
1684                 return PMINFO_R_ERROR;
1685
1686         *readonly = _get_bool_value(info->pkg_info->readonly);
1687
1688         return PMINFO_R_OK;
1689 }
1690
1691 API int pkgmgrinfo_pkginfo_is_update(pkgmgrinfo_pkginfo_h handle, bool *update)
1692 {
1693         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1694
1695         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1696         retvm_if(update == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1697
1698         if (info->pkg_info == NULL || info->pkg_info->update == NULL)
1699                 return PMINFO_R_ERROR;
1700
1701         *update = _get_bool_value(info->pkg_info->update);
1702
1703         return PMINFO_R_OK;
1704 }
1705
1706 API int pkgmgrinfo_pkginfo_is_support_disable(pkgmgrinfo_pkginfo_h handle, bool *support_disable)
1707 {
1708         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1709
1710         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1711         retvm_if(support_disable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1712
1713         if (info->pkg_info == NULL || info->pkg_info->support_disable == NULL)
1714                 return PMINFO_R_ERROR;
1715
1716         *support_disable = _get_bool_value(info->pkg_info->support_disable);
1717
1718         return PMINFO_R_OK;
1719 }
1720
1721 API int pkgmgrinfo_pkginfo_is_global(pkgmgrinfo_pkginfo_h handle, bool *global)
1722 {
1723         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1724
1725         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1726         retvm_if(global == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1727
1728         if (info->pkg_info == NULL || info->pkg_info->for_all_users == NULL)
1729                 return PMINFO_R_ERROR;
1730
1731         *global = _get_bool_value(info->pkg_info->for_all_users);
1732
1733         return PMINFO_R_OK;
1734 }
1735
1736 API int pkgmgrinfo_pkginfo_is_for_all_users(pkgmgrinfo_pkginfo_h handle, bool *for_all_users)
1737 {
1738         return pkgmgrinfo_pkginfo_is_global(handle, for_all_users);
1739 }
1740
1741 API int pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo_h handle)
1742 {
1743         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1744
1745         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1746
1747         __cleanup_pkginfo(info);
1748
1749         return PMINFO_R_OK;
1750 }
1751
1752 API int pkgmgrinfo_pkginfo_filter_create(pkgmgrinfo_pkginfo_filter_h *handle)
1753 {
1754         pkgmgrinfo_filter_x *filter;
1755
1756         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle output parameter is NULL\n");
1757
1758         filter = (pkgmgrinfo_filter_x*)calloc(1, sizeof(pkgmgrinfo_filter_x));
1759         if (filter == NULL) {
1760                 _LOGE("Out of Memory!!!");
1761                 return PMINFO_R_ERROR;
1762         }
1763
1764         *handle = filter;
1765
1766         return PMINFO_R_OK;
1767 }
1768
1769 API int pkgmgrinfo_pkginfo_filter_destroy(pkgmgrinfo_pkginfo_filter_h handle)
1770 {
1771         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1772
1773         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1774
1775         if (filter->list) {
1776                 g_slist_foreach(filter->list, __destroy_each_node, NULL);
1777                 g_slist_free(filter->list);
1778         }
1779
1780         free(filter);
1781
1782         return PMINFO_R_OK;
1783 }
1784
1785 API int pkgmgrinfo_pkginfo_filter_add_int(pkgmgrinfo_pkginfo_filter_h handle,
1786                                 const char *property, const int value)
1787 {
1788         char buf[PKG_VALUE_STRING_LEN_MAX] = {'\0'};
1789         char *val;
1790         GSList *link;
1791         int prop;
1792         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1793         pkgmgrinfo_node_x *node;
1794
1795         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1796         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1797
1798         prop = _pminfo_pkginfo_convert_to_prop_int(property);
1799         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_INT ||
1800                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_INT) {
1801                 _LOGE("Invalid Integer Property\n");
1802                 return PMINFO_R_EINVAL;
1803         }
1804         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1805         if (node == NULL) {
1806                 _LOGE("Out of Memory!!!\n");
1807                 return PMINFO_R_ERROR;
1808         }
1809         snprintf(buf, PKG_VALUE_STRING_LEN_MAX - 1, "%d", value);
1810         val = strndup(buf, PKG_VALUE_STRING_LEN_MAX - 1);
1811         if (val == NULL) {
1812                 _LOGE("Out of Memory\n");
1813                 free(node);
1814                 return PMINFO_R_ERROR;
1815         }
1816         node->prop = prop;
1817         node->value = val;
1818         /*If API is called multiple times for same property, we should override the previous values.
1819         Last value set will be used for filtering.*/
1820         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1821         if (link)
1822                 filter->list = g_slist_delete_link(filter->list, link);
1823         filter->list = g_slist_append(filter->list, (gpointer)node);
1824         return PMINFO_R_OK;
1825
1826 }
1827
1828 API int pkgmgrinfo_pkginfo_filter_add_bool(pkgmgrinfo_pkginfo_filter_h handle,
1829                                 const char *property, const bool value)
1830 {
1831         char *val;
1832         GSList *link;
1833         int prop;
1834         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1835         pkgmgrinfo_node_x *node;
1836
1837         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1838         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1839
1840         prop = _pminfo_pkginfo_convert_to_prop_bool(property);
1841         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_BOOL ||
1842                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_BOOL) {
1843                 _LOGE("Invalid Boolean Property\n");
1844                 return PMINFO_R_EINVAL;
1845         }
1846         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1847         if (node == NULL) {
1848                 _LOGE("Out of Memory!!!\n");
1849                 return PMINFO_R_ERROR;
1850         }
1851         if (value)
1852                 val = strndup("true", 4);
1853         else
1854                 val = strndup("false", 5);
1855         if (val == NULL) {
1856                 _LOGE("Out of Memory\n");
1857                 free(node);
1858                 return PMINFO_R_ERROR;
1859         }
1860         node->prop = prop;
1861         node->value = val;
1862         /*If API is called multiple times for same property, we should override the previous values.
1863         Last value set will be used for filtering.*/
1864         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1865         if (link)
1866                 filter->list = g_slist_delete_link(filter->list, link);
1867         filter->list = g_slist_append(filter->list, (gpointer)node);
1868         return PMINFO_R_OK;
1869
1870 }
1871
1872 API int pkgmgrinfo_pkginfo_filter_add_string(pkgmgrinfo_pkginfo_filter_h handle,
1873                                 const char *property, const char *value)
1874 {
1875         char *val;
1876         GSList *link;
1877         int prop;
1878         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1879         pkgmgrinfo_node_x *node;
1880
1881         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1882         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1883         retvm_if(value == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1884
1885         prop = _pminfo_pkginfo_convert_to_prop_str(property);
1886         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_STR ||
1887                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_STR) {
1888                 _LOGE("Invalid String Property\n");
1889                 return PMINFO_R_EINVAL;
1890         }
1891         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1892         if (node == NULL) {
1893                 _LOGE("Out of Memory!!!\n");
1894                 return PMINFO_R_ERROR;
1895         }
1896         if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_AUTO) == 0)
1897                 val = strndup("auto", PKG_STRING_LEN_MAX - 1);
1898         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_INTERNAL) == 0)
1899                 val = strndup("internal-only", PKG_STRING_LEN_MAX - 1);
1900         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_EXTERNAL) == 0)
1901                 val = strndup("prefer-external", PKG_STRING_LEN_MAX - 1);
1902         else if (strcmp(value, "installed_internal") == 0)
1903                 val = strndup("installed_internal", PKG_STRING_LEN_MAX - 1);
1904         else if (strcmp(value, "installed_external") == 0)
1905                 val = strndup("installed_external", PKG_STRING_LEN_MAX - 1);
1906         else
1907                 val = strndup(value, PKG_STRING_LEN_MAX - 1);
1908         if (val == NULL) {
1909                 _LOGE("Out of Memory\n");
1910                 free(node);
1911                 return PMINFO_R_ERROR;
1912         }
1913         node->prop = prop;
1914         node->value = val;
1915         /*If API is called multiple times for same property, we should override the previous values.
1916         Last value set will be used for filtering.*/
1917         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1918         if (link)
1919                 filter->list = g_slist_delete_link(filter->list, link);
1920         filter->list = g_slist_append(filter->list, (gpointer)node);
1921         return PMINFO_R_OK;
1922
1923 }
1924
1925 API int pkgmgrinfo_pkginfo_usr_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count, uid_t uid)
1926 {
1927         int ret;
1928         char *locale;
1929         GHashTable *list = NULL;
1930
1931         if (handle == NULL || count == NULL) {
1932                 _LOGE("invalid parameter");
1933                 return PMINFO_R_EINVAL;
1934         }
1935
1936         locale = _get_system_locale();
1937         if (locale == NULL)
1938                 return PMINFO_R_ERROR;
1939
1940         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
1941                         __free_packages);
1942         if (list == NULL) {
1943                 free(locale);
1944                 return PMINFO_R_ERROR;
1945         }
1946
1947         ret = _pkginfo_get_packages(uid, locale,
1948                         (pkgmgrinfo_filter_x *)handle, 0, list);
1949         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
1950                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, handle, 0,
1951                                 list);
1952
1953         if (ret != PMINFO_R_OK) {
1954                 g_hash_table_destroy(list);
1955                 free(locale);
1956                 return PMINFO_R_ERROR;
1957         }
1958
1959         *count = g_hash_table_size(list);
1960
1961         g_hash_table_destroy(list);
1962         free(locale);
1963
1964         return PMINFO_R_OK;
1965 }
1966
1967 API int pkgmgrinfo_pkginfo_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count)
1968 {
1969         return pkgmgrinfo_pkginfo_usr_filter_count(handle, count, _getuid());
1970 }
1971
1972 API int pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(
1973                 pkgmgrinfo_pkginfo_filter_h handle,
1974                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data, uid_t uid)
1975 {
1976         if (handle == NULL || pkg_cb == NULL) {
1977                 LOGE("invalid parameter");
1978                 return PMINFO_R_EINVAL;
1979         }
1980
1981         return _pkginfo_get_filtered_foreach_pkginfo(uid, handle,
1982                         PMINFO_PKGINFO_GET_ALL, pkg_cb, user_data);
1983 }
1984
1985 API int pkgmgrinfo_pkginfo_filter_foreach_pkginfo(pkgmgrinfo_pkginfo_filter_h handle,
1986                                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data)
1987 {
1988         return pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, pkg_cb, user_data, _getuid());
1989 }
1990
1991 API int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle,
1992                         pkgmgrinfo_pkg_privilege_list_cb privilege_func, void *user_data)
1993 {
1994         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1995         retvm_if(privilege_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
1996         int ret;
1997         const char *privilege;
1998         GList *tmp;
1999         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
2000
2001         if (info->pkg_info == NULL)
2002                 return PMINFO_R_ERROR;
2003
2004         for (tmp = info->pkg_info->privileges; tmp; tmp = tmp->next) {
2005                 privilege = (const char *)tmp->data;
2006                 if (privilege == NULL)
2007                         continue;
2008                 ret = privilege_func(privilege, user_data);
2009                 if (ret < 0)
2010                         break;
2011         }
2012         return PMINFO_R_OK;
2013 }