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