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