cd0d0e7e7a235bd96bf64cec236c0f731e474a71
[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                 "package_support_disable "
692                 "FROM package_info WHERE package=%Q";
693         int ret;
694         char *query;
695         sqlite3_stmt *stmt;
696         int idx;
697         package_x *info;
698
699         query = sqlite3_mprintf(query_raw, pkgid);
700         if (query == NULL) {
701                 LOGE("out of memory");
702                 return PMINFO_R_ERROR;
703         }
704
705         ret = sqlite3_prepare_v2(db, query, strlen(query),
706                         &stmt, NULL);
707         sqlite3_free(query);
708         if (ret != SQLITE_OK) {
709                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
710                 return PMINFO_R_ERROR;
711         }
712
713         ret = sqlite3_step(stmt);
714         if (ret == SQLITE_DONE) {
715                 sqlite3_finalize(stmt);
716                 return PMINFO_R_ENOENT;
717         } else if (ret != SQLITE_ROW) {
718                 LOGE("step failed: %s", sqlite3_errmsg(db));
719                 sqlite3_finalize(stmt);
720                 return PMINFO_R_ERROR;
721         }
722
723         info = calloc(1, sizeof(package_x));
724         if (info == NULL) {
725                 LOGE("out of memory");
726                 sqlite3_finalize(stmt);
727                 return PMINFO_R_ERROR;
728         }
729         idx = 0;
730         _save_column_str(stmt, idx++, &info->package);
731         _save_column_str(stmt, idx++, &info->version);
732         _save_column_str(stmt, idx++, &info->installlocation);
733         _save_column_str(stmt, idx++, &info->removable);
734         _save_column_str(stmt, idx++, &info->preload);
735         _save_column_str(stmt, idx++, &info->readonly);
736         _save_column_str(stmt, idx++, &info->update);
737         _save_column_str(stmt, idx++, &info->appsetting);
738         _save_column_str(stmt, idx++, &info->system);
739         _save_column_str(stmt, idx++, &info->type);
740         _save_column_str(stmt, idx++, &info->package_size);
741         _save_column_str(stmt, idx++, &info->installed_time);
742         _save_column_str(stmt, idx++, &info->installed_storage);
743         _save_column_str(stmt, idx++, &info->storeclient_id);
744         _save_column_str(stmt, idx++, &info->mainapp_id);
745         _save_column_str(stmt, idx++, &info->package_url);
746         _save_column_str(stmt, idx++, &info->root_path);
747         _save_column_str(stmt, idx++, &info->csc_path);
748         _save_column_str(stmt, idx++, &info->nodisplay_setting);
749         _save_column_str(stmt, idx++, &info->api_version);
750         _save_column_str(stmt, idx++, &info->support_disable);
751
752         if (_pkginfo_get_author(db, info->package, &info->author)) {
753                 pkgmgrinfo_basic_free_package(info);
754                 sqlite3_finalize(stmt);
755                 return PMINFO_R_ERROR;
756         }
757
758         if (_pkginfo_get_label(db, info->package, locale, &info->label)) {
759                 pkgmgrinfo_basic_free_package(info);
760                 sqlite3_finalize(stmt);
761                 return PMINFO_R_ERROR;
762         }
763
764         if (_pkginfo_get_icon(db, info->package, locale, &info->icon)) {
765                 pkgmgrinfo_basic_free_package(info);
766                 sqlite3_finalize(stmt);
767                 return PMINFO_R_ERROR;
768         }
769
770         if (_pkginfo_get_description(db, info->package, locale,
771                                 &info->description)) {
772                 pkgmgrinfo_basic_free_package(info);
773                 sqlite3_finalize(stmt);
774                 return PMINFO_R_ERROR;
775         }
776
777         if (_pkginfo_get_privilege(db, info->package, &info->privileges)) {
778                 pkgmgrinfo_basic_free_package(info);
779                 sqlite3_finalize(stmt);
780                 return PMINFO_R_ERROR;
781         }
782
783         *package = info;
784         sqlite3_finalize(stmt);
785
786         return PMINFO_R_OK;
787 }
788
789 static int _pkginfo_get_pkginfo(const char *pkgid, uid_t uid,
790                 pkgmgr_pkginfo_x **pkginfo)
791 {
792         int ret;
793         sqlite3 *db;
794         const char *dbpath;
795         char *locale;
796         pkgmgr_pkginfo_x *info;
797
798         dbpath = getUserPkgParserDBPathUID(uid);
799         if (dbpath == NULL)
800                 return PMINFO_R_ERROR;
801
802         locale = _get_system_locale();
803         if (locale == NULL)
804                 return PMINFO_R_ERROR;
805
806         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
807         if (ret != SQLITE_OK) {
808                 _LOGE("failed to open db: %d", ret);
809                 free(locale);
810                 return PMINFO_R_ERROR;
811         }
812
813         info = calloc(1, sizeof(pkgmgr_pkginfo_x));
814         if (info == NULL) {
815                 _LOGE("out of memory");
816                 free(locale);
817                 sqlite3_close_v2(db);
818                 return PMINFO_R_ERROR;
819         }
820
821         ret = _pkginfo_get_package(db, pkgid, locale, &info->pkg_info);
822         if (ret == PMINFO_R_OK) {
823                 info->locale = strdup(locale);
824                 info->uid = uid;
825                 info->pkg_info->for_all_users = strdup(
826                                 uid != GLOBAL_USER ? "false" : "true");
827         }
828
829         *pkginfo = info;
830
831         free(locale);
832         sqlite3_close_v2(db);
833
834         return ret;
835 }
836
837 API int pkgmgrinfo_pkginfo_get_usr_pkginfo(const char *pkgid, uid_t uid,
838                 pkgmgrinfo_pkginfo_h *handle)
839 {
840         int ret;
841
842         if (pkgid == NULL || handle == NULL) {
843                 LOGE("invalid parameter");
844                 return PMINFO_R_EINVAL;
845         }
846
847         ret = _pkginfo_get_pkginfo(pkgid, uid, (pkgmgr_pkginfo_x **)handle);
848         if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
849                 ret = _pkginfo_get_pkginfo(pkgid, GLOBAL_USER,
850                                 (pkgmgr_pkginfo_x **)handle);
851
852         if (ret != PMINFO_R_OK)
853                 _LOGE("failed to get pkginfo of %s for user %d", pkgid, uid);
854
855         return ret;
856 }
857
858 API int pkgmgrinfo_pkginfo_get_pkginfo(const char *pkgid, pkgmgrinfo_pkginfo_h *handle)
859 {
860         return pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, GLOBAL_USER, handle);
861 }
862
863 API int pkgmgrinfo_pkginfo_get_pkgname(pkgmgrinfo_pkginfo_h handle, char **pkg_name)
864 {
865         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
866
867         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
868         retvm_if(pkg_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
869
870         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
871                 return PMINFO_R_ERROR;
872
873         *pkg_name = (char *)info->pkg_info->package;
874
875         return PMINFO_R_OK;
876 }
877
878 API int pkgmgrinfo_pkginfo_get_pkgid(pkgmgrinfo_pkginfo_h handle, char **pkgid)
879 {
880         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
881
882         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
883         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
884
885         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
886                 return PMINFO_R_ERROR;
887
888         *pkgid = (char *)info->pkg_info->package;
889
890         return PMINFO_R_OK;
891 }
892
893 API int pkgmgrinfo_pkginfo_get_type(pkgmgrinfo_pkginfo_h handle, char **type)
894 {
895         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
896
897         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
898         retvm_if(type == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
899
900         if (info->pkg_info == NULL || info->pkg_info->type == NULL)
901                 return PMINFO_R_ERROR;
902
903         *type = (char *)info->pkg_info->type;
904
905         return PMINFO_R_OK;
906 }
907
908 API int pkgmgrinfo_pkginfo_get_version(pkgmgrinfo_pkginfo_h handle, char **version)
909 {
910         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
911
912         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
913         retvm_if(version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
914
915         if (info->pkg_info == NULL || info->pkg_info->version == NULL)
916                 return PMINFO_R_ERROR;
917
918         *version = (char *)info->pkg_info->version;
919
920         return PMINFO_R_OK;
921 }
922
923 API int pkgmgrinfo_pkginfo_get_install_location(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_install_location *location)
924 {
925         char *val;
926         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
927
928         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
929         retvm_if(location == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
930
931         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
932                 return PMINFO_R_ERROR;
933
934         val = (char *)info->pkg_info->installlocation;
935         if (strcmp(val, "internal-only") == 0)
936                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
937         else if (strcmp(val, "prefer-external") == 0)
938                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
939         else
940                 *location = PMINFO_INSTALL_LOCATION_AUTO;
941
942         return PMINFO_R_OK;
943 }
944
945 API int pkgmgrinfo_pkginfo_get_package_size(pkgmgrinfo_pkginfo_h handle, int *size)
946 {
947         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
948
949         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
950         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
951
952         if (info->pkg_info == NULL || info->pkg_info->package_size == NULL)
953                 return PMINFO_R_ERROR;
954
955         *size = atoi((char *)info->pkg_info->package_size);
956
957         return PMINFO_R_OK;
958 }
959
960 API int pkgmgrinfo_pkginfo_get_total_size(pkgmgrinfo_pkginfo_h handle, int *size)
961 {
962         char *pkgid;
963         char device_path[PKG_STRING_LEN_MAX] = { '\0', };
964         long long rw_size = 0;
965         long long ro_size = 0;
966         long long tmp_size = 0;
967         long long total_size = 0;
968         struct stat fileinfo;
969         int ret;
970
971         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
972         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
973
974         ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
975         if (ret < 0)
976                 return PMINFO_R_ERROR;
977
978         /* RW area */
979         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/bin", PKG_RW_PATH, pkgid);
980         if (lstat(device_path, &fileinfo) == 0) {
981                 if (!S_ISLNK(fileinfo.st_mode)) {
982                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
983                         if (tmp_size > 0)
984                                 rw_size += tmp_size;
985                 }
986         }
987
988         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/info", PKG_RW_PATH, pkgid);
989         if (lstat(device_path, &fileinfo) == 0) {
990                 if (!S_ISLNK(fileinfo.st_mode)) {
991                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
992                         if (tmp_size > 0)
993                         rw_size += tmp_size;
994                 }
995         }
996
997         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/res", PKG_RW_PATH, pkgid);
998         if (lstat(device_path, &fileinfo) == 0) {
999                 if (!S_ISLNK(fileinfo.st_mode)) {
1000                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1001                         if (tmp_size > 0)
1002                         rw_size += tmp_size;
1003                 }
1004         }
1005
1006         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/data", PKG_RW_PATH, pkgid);
1007         if (lstat(device_path, &fileinfo) == 0) {
1008                 if (!S_ISLNK(fileinfo.st_mode)) {
1009                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1010                         if (tmp_size > 0)
1011                                 rw_size += tmp_size;
1012                 }
1013         }
1014
1015         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/shared", PKG_RW_PATH, pkgid);
1016         if (lstat(device_path, &fileinfo) == 0) {
1017                 if (!S_ISLNK(fileinfo.st_mode)) {
1018                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1019                         if (tmp_size > 0)
1020                                 rw_size += tmp_size;
1021         }
1022         }
1023
1024         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/setting", PKG_RW_PATH, pkgid);
1025         if (lstat(device_path, &fileinfo) == 0) {
1026                 if (!S_ISLNK(fileinfo.st_mode)) {
1027                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1028                         if (tmp_size > 0)
1029                                 rw_size += tmp_size;
1030                 }
1031         }
1032
1033         /* RO area */
1034         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/bin", PKG_RO_PATH, pkgid);
1035         if (lstat(device_path, &fileinfo) == 0) {
1036                 if (!S_ISLNK(fileinfo.st_mode)) {
1037                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1038                         if (tmp_size > 0)
1039                                 ro_size += tmp_size;
1040                 }
1041         }
1042
1043         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/info", PKG_RO_PATH, pkgid);
1044         if (lstat(device_path, &fileinfo) == 0) {
1045                 if (!S_ISLNK(fileinfo.st_mode)) {
1046                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1047                         if (tmp_size > 0)
1048                                 ro_size += tmp_size;
1049                 }
1050         }
1051
1052         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/res", PKG_RO_PATH, pkgid);
1053         if (lstat(device_path, &fileinfo) == 0) {
1054                 if (!S_ISLNK(fileinfo.st_mode)) {
1055                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1056                         if (tmp_size > 0)
1057                                 ro_size += tmp_size;
1058                 }
1059         }
1060
1061         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/data", PKG_RO_PATH, pkgid);
1062         if (lstat(device_path, &fileinfo) == 0) {
1063                 if (!S_ISLNK(fileinfo.st_mode)) {
1064                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1065                         if (tmp_size > 0)
1066                                 ro_size += tmp_size;
1067                 }
1068         }
1069
1070         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/shared", PKG_RO_PATH, pkgid);
1071         if (lstat(device_path, &fileinfo) == 0) {
1072                 if (!S_ISLNK(fileinfo.st_mode)) {
1073                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1074                         if (tmp_size > 0)
1075                                 ro_size += tmp_size;
1076                 }
1077         }
1078
1079         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/setting", PKG_RO_PATH, pkgid);
1080         if (lstat(device_path, &fileinfo) == 0) {
1081                 if (!S_ISLNK(fileinfo.st_mode)) {
1082                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1083                         if (tmp_size > 0)
1084                                 ro_size += tmp_size;
1085                 }
1086         }
1087
1088         /* Total size */
1089         total_size = rw_size + ro_size;
1090         *size = (int)total_size;
1091
1092         return PMINFO_R_OK;
1093 }
1094
1095 API int pkgmgrinfo_pkginfo_get_data_size(pkgmgrinfo_pkginfo_h handle, int *size)
1096 {
1097         char *pkgid;
1098         char device_path[PKG_STRING_LEN_MAX] = { '\0', };
1099         long long total_size = 0;
1100
1101         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1102         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1103
1104         if (pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid) < 0)
1105                 return PMINFO_R_ERROR;
1106
1107         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/data", PKG_RW_PATH, pkgid);
1108         if (access(device_path, R_OK) == 0)
1109                 total_size = _pkgmgr_calculate_dir_size(device_path);
1110         if (total_size < 0)
1111                 return PMINFO_R_ERROR;
1112
1113         *size = (int)total_size;
1114
1115         return PMINFO_R_OK;
1116 }
1117
1118 API int pkgmgrinfo_pkginfo_get_icon(pkgmgrinfo_pkginfo_h handle, char **icon)
1119 {
1120         char *locale;
1121         icon_x *ptr;
1122         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1123
1124         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1125         retvm_if(icon == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1126
1127         locale = info->locale;
1128         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1129
1130         for (ptr = info->pkg_info->icon; ptr != NULL; ptr = ptr->next) {
1131                 if (ptr->lang == NULL)
1132                         continue;
1133
1134                 if (strcmp(ptr->lang, locale) == 0) {
1135                         *icon = (char *)ptr->text;
1136                         if (strcasecmp(*icon, "(null)") == 0) {
1137                                 locale = DEFAULT_LOCALE;
1138                                 continue;
1139                         } else {
1140                                 return PMINFO_R_OK;
1141                         }
1142                 } else if (strcmp(ptr->lang, DEFAULT_LOCALE) == 0) {
1143                         *icon = (char *)ptr->text;
1144                         return PMINFO_R_OK;
1145                 }
1146         }
1147
1148         return PMINFO_R_ERROR;
1149 }
1150
1151 API int pkgmgrinfo_pkginfo_get_label(pkgmgrinfo_pkginfo_h handle, char **label)
1152 {
1153         char *locale;
1154         label_x *ptr;
1155         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1156
1157         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1158         retvm_if(label == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1159
1160         locale = info->locale;
1161         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1162
1163         for (ptr = info->pkg_info->label; ptr != NULL; ptr = ptr->next) {
1164                 if (ptr->lang == NULL)
1165                         continue;
1166
1167                 if (strcmp(ptr->lang, locale) == 0) {
1168                         *label = (char *)ptr->text;
1169                         if (strcasecmp(*label, "(null)") == 0) {
1170                                 locale = DEFAULT_LOCALE;
1171                                 continue;
1172                         } else {
1173                                 return PMINFO_R_OK;
1174                         }
1175                 } else if (strcmp(ptr->lang, DEFAULT_LOCALE) == 0) {
1176                         *label = (char *)ptr->text;
1177                         return PMINFO_R_OK;
1178                 }
1179         }
1180
1181         return PMINFO_R_ERROR;
1182 }
1183
1184 API int pkgmgrinfo_pkginfo_get_description(pkgmgrinfo_pkginfo_h handle, char **description)
1185 {
1186         char *locale;
1187         description_x *ptr;
1188         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1189
1190         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1191         retvm_if(description == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1192
1193         locale = info->locale;
1194         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1195
1196         for (ptr = info->pkg_info->description; ptr != NULL; ptr = ptr->next) {
1197                 if (ptr->lang == NULL)
1198                         continue;
1199
1200                 if (strcmp(ptr->lang, locale) == 0) {
1201                         *description = (char *)ptr->text;
1202                         if (strcasecmp(*description, PKGMGR_PARSER_EMPTY_STR) == 0) {
1203                                 locale = DEFAULT_LOCALE;
1204                                 continue;
1205                         } else {
1206                                 return PMINFO_R_OK;
1207                         }
1208                 } else if (strcmp(ptr->lang, DEFAULT_LOCALE) == 0) {
1209                         *description = (char *)ptr->text;
1210                         return PMINFO_R_OK;
1211                 }
1212         }
1213
1214         return PMINFO_R_ERROR;
1215 }
1216
1217 API int pkgmgrinfo_pkginfo_get_author_name(pkgmgrinfo_pkginfo_h handle, char **author_name)
1218 {
1219         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1220
1221         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1222         retvm_if(author_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1223
1224         if (info->pkg_info == NULL || info->pkg_info->author == NULL ||
1225                         info->pkg_info->author->text == NULL)
1226                 return PMINFO_R_ERROR;
1227
1228         *author_name = (char *)info->pkg_info->author->text;
1229
1230         return PMINFO_R_OK;
1231 }
1232
1233 API int pkgmgrinfo_pkginfo_get_author_email(pkgmgrinfo_pkginfo_h handle, char **author_email)
1234 {
1235         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1236
1237         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1238         retvm_if(author_email == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1239
1240         if (info->pkg_info == NULL || info->pkg_info->author == NULL ||
1241                         info->pkg_info->author->email == NULL)
1242                 return PMINFO_R_ERROR;
1243
1244         *author_email = (char *)info->pkg_info->author->email;
1245
1246         return PMINFO_R_OK;
1247 }
1248
1249 API int pkgmgrinfo_pkginfo_get_author_href(pkgmgrinfo_pkginfo_h handle, char **author_href)
1250 {
1251         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1252
1253         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1254         retvm_if(author_href == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1255
1256         if (info->pkg_info == NULL || info->pkg_info->author == NULL ||
1257                         info->pkg_info->author->href == NULL)
1258                 return PMINFO_R_ERROR;
1259
1260         *author_href = (char *)info->pkg_info->author->href;
1261
1262         return PMINFO_R_OK;
1263 }
1264
1265 API int pkgmgrinfo_pkginfo_get_installed_storage(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_installed_storage *storage)
1266 {
1267         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1268
1269         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1270         retvm_if(storage == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1271
1272         if (info->pkg_info == NULL || info->pkg_info->installed_storage == NULL)
1273                 return PMINFO_R_ERROR;
1274
1275         if (strcmp(info->pkg_info->installed_storage,"installed_internal") == 0)
1276                 *storage = PMINFO_INTERNAL_STORAGE;
1277         else if (strcmp(info->pkg_info->installed_storage,"installed_external") == 0)
1278                 *storage = PMINFO_EXTERNAL_STORAGE;
1279         else
1280                 return PMINFO_R_ERROR;
1281
1282         return PMINFO_R_OK;
1283 }
1284
1285 API int pkgmgrinfo_pkginfo_get_installed_time(pkgmgrinfo_pkginfo_h handle, int *installed_time)
1286 {
1287         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1288
1289         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1290         retvm_if(installed_time == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1291
1292         if (info->pkg_info == NULL || info->pkg_info->installed_time == NULL)
1293                 return PMINFO_R_ERROR;
1294
1295         *installed_time = atoi(info->pkg_info->installed_time);
1296
1297         return PMINFO_R_OK;
1298 }
1299
1300 API int pkgmgrinfo_pkginfo_get_storeclientid(pkgmgrinfo_pkginfo_h handle, char **storeclientid)
1301 {
1302         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1303
1304         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1305         retvm_if(storeclientid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1306
1307         if (info->pkg_info == NULL || info->pkg_info->storeclient_id == NULL)
1308                 return PMINFO_R_ERROR;
1309
1310         *storeclientid = (char *)info->pkg_info->storeclient_id;
1311
1312         return PMINFO_R_OK;
1313 }
1314
1315 API int pkgmgrinfo_pkginfo_get_mainappid(pkgmgrinfo_pkginfo_h handle, char **mainappid)
1316 {
1317         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1318
1319         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1320         retvm_if(mainappid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1321
1322         if (info->pkg_info == NULL || info->pkg_info->mainapp_id == NULL)
1323                 return PMINFO_R_ERROR;
1324
1325         *mainappid = (char *)info->pkg_info->mainapp_id;
1326
1327         return PMINFO_R_OK;
1328 }
1329
1330 API int pkgmgrinfo_pkginfo_get_url(pkgmgrinfo_pkginfo_h handle, char **url)
1331 {
1332         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1333
1334         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1335         retvm_if(url == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1336
1337         if (info->pkg_info == NULL || info->pkg_info->package_url == NULL)
1338                 return PMINFO_R_ERROR;
1339
1340         *url = (char *)info->pkg_info->package_url;
1341
1342         return PMINFO_R_OK;
1343 }
1344
1345 API int pkgmgrinfo_pkginfo_get_size_from_xml(const char *manifest, int *size)
1346 {
1347         const char *val = NULL;
1348         const xmlChar *node;
1349         xmlTextReaderPtr reader;
1350         retvm_if(manifest == NULL, PMINFO_R_EINVAL, "Input argument is NULL\n");
1351         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1352
1353         xmlInitParser();
1354         reader = xmlReaderForFile(manifest, NULL, 0);
1355
1356         if (reader){
1357                 if (__child_element(reader, -1)) {
1358                         node = xmlTextReaderConstName(reader);
1359                         if (!node) {
1360                                 _LOGE("xmlTextReaderConstName value is NULL\n");
1361                                 xmlFreeTextReader(reader);
1362                                 xmlCleanupParser();
1363                                 return PMINFO_R_ERROR;
1364                         }
1365
1366                         if (!strcmp(ASC_CHAR(node), "manifest")) {
1367                                 if (xmlTextReaderGetAttribute(reader, XML_CHAR("size")))
1368                                         val = ASC_CHAR(xmlTextReaderGetAttribute(reader, XML_CHAR("size")));
1369
1370                                 if (val) {
1371                                         *size = atoi(val);
1372                                 } else {
1373                                         *size = 0;
1374                                         _LOGE("package size is not specified\n");
1375                                         xmlFreeTextReader(reader);
1376                                         xmlCleanupParser();
1377                                         return PMINFO_R_ERROR;
1378                                 }
1379                         } else {
1380                                 _LOGE("Unable to create xml reader\n");
1381                                 xmlFreeTextReader(reader);
1382                                 xmlCleanupParser();
1383                                 return PMINFO_R_ERROR;
1384                         }
1385                 }
1386         } else {
1387                 _LOGE("xmlReaderForFile value is NULL\n");
1388                 xmlCleanupParser();
1389                 return PMINFO_R_ERROR;
1390         }
1391
1392         xmlFreeTextReader(reader);
1393         xmlCleanupParser();
1394
1395         return PMINFO_R_OK;
1396 }
1397
1398 API int pkgmgrinfo_pkginfo_get_location_from_xml(const char *manifest, pkgmgrinfo_install_location *location)
1399 {
1400         const char *val = NULL;
1401         const xmlChar *node;
1402         xmlTextReaderPtr reader;
1403         retvm_if(manifest == NULL, PMINFO_R_EINVAL, "Input argument is NULL\n");
1404         retvm_if(location == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1405
1406         xmlInitParser();
1407         reader = xmlReaderForFile(manifest, NULL, 0);
1408
1409         if (reader) {
1410                 if ( __child_element(reader, -1)) {
1411                         node = xmlTextReaderConstName(reader);
1412                         if (!node) {
1413                                 _LOGE("xmlTextReaderConstName value is NULL\n");
1414                                 xmlFreeTextReader(reader);
1415                                 xmlCleanupParser();
1416                                 return PMINFO_R_ERROR;
1417                         }
1418
1419                         if (!strcmp(ASC_CHAR(node), "manifest")) {
1420                                 if (xmlTextReaderGetAttribute(reader, XML_CHAR("install-location")))
1421                                         val = ASC_CHAR(xmlTextReaderGetAttribute(reader, XML_CHAR("install-location")));
1422
1423                                 if (val) {
1424                                         if (strcmp(val, "internal-only") == 0)
1425                                                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
1426                                         else if (strcmp(val, "prefer-external") == 0)
1427                                                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
1428                                         else
1429                                                 *location = PMINFO_INSTALL_LOCATION_AUTO;
1430                                 }
1431                         } else {
1432                                 _LOGE("Unable to create xml reader\n");
1433                                 xmlFreeTextReader(reader);
1434                                 xmlCleanupParser();
1435                                 return PMINFO_R_ERROR;
1436                         }
1437                 }
1438         } else {
1439                 _LOGE("xmlReaderForFile value is NULL\n");
1440                 xmlCleanupParser();
1441                 return PMINFO_R_ERROR;
1442         }
1443
1444         xmlFreeTextReader(reader);
1445         xmlCleanupParser();
1446
1447         return PMINFO_R_OK;
1448 }
1449
1450
1451 API int pkgmgrinfo_pkginfo_get_root_path(pkgmgrinfo_pkginfo_h handle, char **path)
1452 {
1453         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1454
1455         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1456         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1457
1458         if (info->pkg_info == NULL || info->pkg_info->root_path == NULL)
1459                 return PMINFO_R_ERROR;
1460
1461         *path = (char *)info->pkg_info->root_path;
1462
1463         return PMINFO_R_OK;
1464 }
1465
1466 API int pkgmgrinfo_pkginfo_get_csc_path(pkgmgrinfo_pkginfo_h handle, char **path)
1467 {
1468         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1469
1470         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1471         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1472
1473         if (info->pkg_info == NULL || info->pkg_info->csc_path == NULL)
1474                 return PMINFO_R_ERROR;
1475
1476         *path = (char *)info->pkg_info->csc_path;
1477
1478         return PMINFO_R_OK;
1479 }
1480
1481
1482 API int pkgmgrinfo_pkginfo_is_accessible(pkgmgrinfo_pkginfo_h handle, bool *accessible)
1483 {
1484         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1485         retvm_if(accessible == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1486
1487 #if 0 //smack issue occured, check later
1488         char *pkgid = NULL;
1489         pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
1490         if (pkgid == NULL){
1491                  _LOGD("invalid func parameters\n");
1492                  return PMINFO_R_ERROR;
1493         }
1494          _LOGD("pkgmgr_get_pkg_external_validation() called\n");
1495
1496         FILE *fp = NULL;
1497         char app_mmc_path[FILENAME_MAX] = { 0, };
1498         char app_dir_path[FILENAME_MAX] = { 0, };
1499         char app_mmc_internal_path[FILENAME_MAX] = { 0, };
1500         snprintf(app_dir_path, FILENAME_MAX,"%s%s", PKG_INSTALLATION_PATH, pkgid);
1501         snprintf(app_mmc_path, FILENAME_MAX,"%s%s", PKG_SD_PATH, pkgid);
1502         snprintf(app_mmc_internal_path, FILENAME_MAX,"%s%s/.mmc", PKG_INSTALLATION_PATH, pkgid);
1503
1504         /*check whether application is in external memory or not */
1505         fp = fopen(app_mmc_path, "r");
1506         if (fp == NULL){
1507                 _LOGD(" app path in external memory not accesible\n");
1508         } else {
1509                 fclose(fp);
1510                 fp = NULL;
1511                 *accessible = 1;
1512                 _LOGD("pkgmgr_get_pkg_external_validation() : SD_CARD \n");
1513                 return PMINFO_R_OK;
1514         }
1515
1516         /*check whether application is in internal or not */
1517         fp = fopen(app_dir_path, "r");
1518         if (fp == NULL) {
1519                 _LOGD(" app path in internal memory not accesible\n");
1520                 *accessible = 0;
1521                 return PMINFO_R_ERROR;
1522         } else {
1523                 fclose(fp);
1524                 /*check whether the application is installed in SD card
1525                 but SD card is not present*/
1526                 fp = fopen(app_mmc_internal_path, "r");
1527                 if (fp == NULL){
1528                         *accessible = 1;
1529                         _LOGD("pkgmgr_get_pkg_external_validation() : INTERNAL_MEM \n");
1530                         return PMINFO_R_OK;
1531                 }
1532                 else{
1533                         *accessible = 0;
1534                         _LOGD("pkgmgr_get_pkg_external_validation() : ERROR_MMC_STATUS \n");
1535                 }
1536                 fclose(fp);
1537         }
1538
1539         _LOGD("pkgmgr_get_pkg_external_validation() end\n");
1540 #endif
1541
1542         *accessible = 1;
1543         return PMINFO_R_OK;
1544 }
1545
1546 API int pkgmgrinfo_pkginfo_is_removable(pkgmgrinfo_pkginfo_h handle, bool *removable)
1547 {
1548         char *val;
1549         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1550
1551         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1552         retvm_if(removable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1553
1554         if (info->pkg_info == NULL || info->pkg_info->removable == NULL)
1555                 return PMINFO_R_ERROR;
1556
1557         val = (char *)info->pkg_info->removable;
1558         if (strcasecmp(val, "true") == 0)
1559                 *removable = 1;
1560         else if (strcasecmp(val, "false") == 0)
1561                 *removable = 0;
1562         else
1563                 *removable = 1;
1564
1565         return PMINFO_R_OK;
1566 }
1567
1568 API int pkgmgrinfo_pkginfo_is_movable(pkgmgrinfo_pkginfo_h handle, bool *movable)
1569 {
1570         char *val;
1571         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1572
1573         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1574         retvm_if(movable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1575
1576         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
1577                 return PMINFO_R_ERROR;
1578
1579         val = (char *)info->pkg_info->installlocation;
1580         if (strcmp(val, "internal-only") == 0)
1581                 *movable = 0;
1582         else if (strcmp(val, "prefer-external") == 0)
1583                 *movable = 1;
1584         else
1585                 *movable = 1;
1586
1587         return PMINFO_R_OK;
1588 }
1589
1590 API int pkgmgrinfo_pkginfo_is_preload(pkgmgrinfo_pkginfo_h handle, bool *preload)
1591 {
1592         char *val;
1593         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1594
1595         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1596         retvm_if(preload == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1597
1598         if (info->pkg_info == NULL || info->pkg_info->preload == NULL)
1599                 return PMINFO_R_ERROR;
1600
1601         val = (char *)info->pkg_info->preload;
1602         if (strcasecmp(val, "true") == 0)
1603                 *preload = 1;
1604         else if (strcasecmp(val, "false") == 0)
1605                 *preload = 0;
1606         else
1607                 *preload = 0;
1608
1609         return PMINFO_R_OK;
1610 }
1611
1612 API int pkgmgrinfo_pkginfo_is_system(pkgmgrinfo_pkginfo_h handle, bool *system)
1613 {
1614         char *val;
1615         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1616
1617         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1618         retvm_if(system == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1619
1620         if (info->pkg_info == NULL || info->pkg_info->system == NULL)
1621                 return PMINFO_R_ERROR;
1622
1623         val = (char *)info->pkg_info->system;
1624         if (strcasecmp(val, "true") == 0)
1625                 *system = 1;
1626         else if (strcasecmp(val, "false") == 0)
1627                 *system = 0;
1628         else
1629                 *system = 0;
1630
1631         return PMINFO_R_OK;
1632 }
1633
1634 API int pkgmgrinfo_pkginfo_is_readonly(pkgmgrinfo_pkginfo_h handle, bool *readonly)
1635 {
1636         char *val;
1637         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1638
1639         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1640         retvm_if(readonly == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1641
1642         if (info->pkg_info == NULL || info->pkg_info->readonly == NULL)
1643                 return PMINFO_R_ERROR;
1644
1645         val = (char *)info->pkg_info->readonly;
1646         if (strcasecmp(val, "true") == 0)
1647                 *readonly = 1;
1648         else if (strcasecmp(val, "false") == 0)
1649                 *readonly = 0;
1650         else
1651                 *readonly = 0;
1652
1653         return PMINFO_R_OK;
1654 }
1655
1656 API int pkgmgrinfo_pkginfo_is_update(pkgmgrinfo_pkginfo_h handle, bool *update)
1657 {
1658         char *val;
1659         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1660
1661         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1662         retvm_if(update == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1663
1664         if (info->pkg_info == NULL || info->pkg_info->update == NULL)
1665                 return PMINFO_R_ERROR;
1666
1667         val = (char *)info->pkg_info->update;
1668         if (strcasecmp(val, "true") == 0)
1669                 *update = 1;
1670         else if (strcasecmp(val, "false") == 0)
1671                 *update = 0;
1672         else
1673                 *update = 1;
1674
1675         return PMINFO_R_OK;
1676 }
1677
1678 API int pkgmgrinfo_pkginfo_is_support_disable(pkgmgrinfo_pkginfo_h handle, bool *support_disable)
1679 {
1680         char *val;
1681         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1682
1683         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1684         retvm_if(support_disable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1685
1686         if (info->pkg_info == NULL || info->pkg_info->support_disable == NULL)
1687                 return PMINFO_R_ERROR;
1688
1689         val = (char *)info->pkg_info->support_disable;
1690         if (strcasecmp(val, "true") == 0)
1691                 *support_disable = 1;
1692         else if (strcasecmp(val, "false") == 0)
1693                 *support_disable = 0;
1694         else
1695                 *support_disable = 1;
1696
1697         return PMINFO_R_OK;
1698 }
1699
1700 API int pkgmgrinfo_pkginfo_is_for_all_users(pkgmgrinfo_pkginfo_h handle, bool *for_all_users)
1701 {
1702         char *val;
1703         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1704
1705         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1706         retvm_if(for_all_users == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1707
1708         if (info->pkg_info == NULL || info->pkg_info->for_all_users == NULL)
1709                 return PMINFO_R_ERROR;
1710
1711         val = (char *)info->pkg_info->for_all_users;
1712         if (strcasecmp(val, "true") == 0)
1713                 *for_all_users = 1;
1714         else if (strcasecmp(val, "false") == 0)
1715                 *for_all_users = 0;
1716         else
1717                 *for_all_users = 1;
1718
1719         return PMINFO_R_OK;
1720 }
1721
1722 API int pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo_h handle)
1723 {
1724         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1725
1726         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1727
1728         __cleanup_pkginfo(info);
1729
1730         return PMINFO_R_OK;
1731 }
1732
1733 API int pkgmgrinfo_pkginfo_filter_create(pkgmgrinfo_pkginfo_filter_h *handle)
1734 {
1735         pkgmgrinfo_filter_x *filter;
1736
1737         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle output parameter is NULL\n");
1738
1739         filter = (pkgmgrinfo_filter_x*)calloc(1, sizeof(pkgmgrinfo_filter_x));
1740         if (filter == NULL) {
1741                 _LOGE("Out of Memory!!!");
1742                 return PMINFO_R_ERROR;
1743         }
1744
1745         *handle = filter;
1746
1747         return PMINFO_R_OK;
1748 }
1749
1750 API int pkgmgrinfo_pkginfo_filter_destroy(pkgmgrinfo_pkginfo_filter_h handle)
1751 {
1752         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1753
1754         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1755
1756         if (filter->list) {
1757                 g_slist_foreach(filter->list, __destroy_each_node, NULL);
1758                 g_slist_free(filter->list);
1759         }
1760
1761         free(filter);
1762
1763         return PMINFO_R_OK;
1764 }
1765
1766 API int pkgmgrinfo_pkginfo_filter_add_int(pkgmgrinfo_pkginfo_filter_h handle,
1767                                 const char *property, const int value)
1768 {
1769         char buf[PKG_VALUE_STRING_LEN_MAX] = {'\0'};
1770         char *val;
1771         GSList *link;
1772         int prop;
1773         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1774         pkgmgrinfo_node_x *node;
1775
1776         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1777         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1778
1779         prop = _pminfo_pkginfo_convert_to_prop_int(property);
1780         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_INT ||
1781                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_INT) {
1782                 _LOGE("Invalid Integer Property\n");
1783                 return PMINFO_R_EINVAL;
1784         }
1785         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1786         if (node == NULL) {
1787                 _LOGE("Out of Memory!!!\n");
1788                 return PMINFO_R_ERROR;
1789         }
1790         snprintf(buf, PKG_VALUE_STRING_LEN_MAX - 1, "%d", value);
1791         val = strndup(buf, PKG_VALUE_STRING_LEN_MAX - 1);
1792         if (val == NULL) {
1793                 _LOGE("Out of Memory\n");
1794                 free(node);
1795                 return PMINFO_R_ERROR;
1796         }
1797         node->prop = prop;
1798         node->value = val;
1799         /*If API is called multiple times for same property, we should override the previous values.
1800         Last value set will be used for filtering.*/
1801         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1802         if (link)
1803                 filter->list = g_slist_delete_link(filter->list, link);
1804         filter->list = g_slist_append(filter->list, (gpointer)node);
1805         return PMINFO_R_OK;
1806
1807 }
1808
1809 API int pkgmgrinfo_pkginfo_filter_add_bool(pkgmgrinfo_pkginfo_filter_h handle,
1810                                 const char *property, const bool value)
1811 {
1812         char *val;
1813         GSList *link;
1814         int prop;
1815         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1816         pkgmgrinfo_node_x *node;
1817
1818         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1819         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1820
1821         prop = _pminfo_pkginfo_convert_to_prop_bool(property);
1822         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_BOOL ||
1823                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_BOOL) {
1824                 _LOGE("Invalid Boolean Property\n");
1825                 return PMINFO_R_EINVAL;
1826         }
1827         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1828         if (node == NULL) {
1829                 _LOGE("Out of Memory!!!\n");
1830                 return PMINFO_R_ERROR;
1831         }
1832         if (value)
1833                 val = strndup("('true','True')", 15);
1834         else
1835                 val = strndup("('false','False')", 17);
1836         if (val == NULL) {
1837                 _LOGE("Out of Memory\n");
1838                 free(node);
1839                 return PMINFO_R_ERROR;
1840         }
1841         node->prop = prop;
1842         node->value = val;
1843         /*If API is called multiple times for same property, we should override the previous values.
1844         Last value set will be used for filtering.*/
1845         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1846         if (link)
1847                 filter->list = g_slist_delete_link(filter->list, link);
1848         filter->list = g_slist_append(filter->list, (gpointer)node);
1849         return PMINFO_R_OK;
1850
1851 }
1852
1853 API int pkgmgrinfo_pkginfo_filter_add_string(pkgmgrinfo_pkginfo_filter_h handle,
1854                                 const char *property, const char *value)
1855 {
1856         char *val;
1857         GSList *link;
1858         int prop;
1859         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1860         pkgmgrinfo_node_x *node;
1861
1862         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1863         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1864         retvm_if(value == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1865
1866         prop = _pminfo_pkginfo_convert_to_prop_str(property);
1867         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_STR ||
1868                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_STR) {
1869                 _LOGE("Invalid String Property\n");
1870                 return PMINFO_R_EINVAL;
1871         }
1872         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1873         if (node == NULL) {
1874                 _LOGE("Out of Memory!!!\n");
1875                 return PMINFO_R_ERROR;
1876         }
1877         if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_AUTO) == 0)
1878                 val = strndup("auto", PKG_STRING_LEN_MAX - 1);
1879         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_INTERNAL) == 0)
1880                 val = strndup("internal-only", PKG_STRING_LEN_MAX - 1);
1881         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_EXTERNAL) == 0)
1882                 val = strndup("prefer-external", PKG_STRING_LEN_MAX - 1);
1883         else if (strcmp(value, "installed_internal") == 0)
1884                 val = strndup("installed_internal", PKG_STRING_LEN_MAX - 1);
1885         else if (strcmp(value, "installed_external") == 0)
1886                 val = strndup("installed_external", PKG_STRING_LEN_MAX - 1);
1887         else
1888                 val = strndup(value, PKG_STRING_LEN_MAX - 1);
1889         if (val == NULL) {
1890                 _LOGE("Out of Memory\n");
1891                 free(node);
1892                 return PMINFO_R_ERROR;
1893         }
1894         node->prop = prop;
1895         node->value = val;
1896         /*If API is called multiple times for same property, we should override the previous values.
1897         Last value set will be used for filtering.*/
1898         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1899         if (link)
1900                 filter->list = g_slist_delete_link(filter->list, link);
1901         filter->list = g_slist_append(filter->list, (gpointer)node);
1902         return PMINFO_R_OK;
1903
1904 }
1905
1906 API int pkgmgrinfo_pkginfo_usr_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count, uid_t uid)
1907 {
1908         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1909         retvm_if(count == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1910         char *locale = NULL;
1911         char *condition = NULL;
1912         char *error_message = NULL;
1913         char query[MAX_QUERY_LEN] = {'\0'};
1914         char where[MAX_QUERY_LEN] = {'\0'};
1915         GSList *list;
1916         int ret = 0;
1917
1918         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x*)handle;
1919         filter->uid = uid;
1920         /*Get current locale*/
1921         locale = _get_system_locale();
1922         if (locale == NULL) {
1923                 _LOGE("manifest locale is NULL\n");
1924                 return PMINFO_R_ERROR;
1925         }
1926
1927         ret = __open_manifest_db(uid, true);
1928         if (ret == -1) {
1929                 _LOGE("Fail to open manifest DB\n");
1930                 free(locale);
1931                 return PMINFO_R_ERROR;
1932         }
1933
1934         /*Start constructing query*/
1935         snprintf(query, MAX_QUERY_LEN - 1, FILTER_QUERY_COUNT_PACKAGE, locale);
1936
1937         /*Get where clause*/
1938         for (list = filter->list; list; list = g_slist_next(list)) {
1939                 __get_filter_condition(list->data, &condition);
1940                 if (condition) {
1941                         strncat(where, condition, sizeof(where) - strlen(where) -1);
1942                         where[sizeof(where) - 1] = '\0';
1943                         free(condition);
1944                         condition = NULL;
1945                 }
1946                 if (g_slist_next(list)) {
1947                         strncat(where, " and ", sizeof(where) - strlen(where) - 1);
1948                         where[sizeof(where) - 1] = '\0';
1949                 }
1950         }
1951         if (strlen(where) > 0) {
1952                 strncat(query, where, sizeof(query) - strlen(query) - 1);
1953                 query[sizeof(query) - 1] = '\0';
1954         }
1955
1956         /*Execute Query*/
1957         if (SQLITE_OK !=
1958             sqlite3_exec(GET_DB(manifest_db), query, __count_cb, (void *)count, &error_message)) {
1959                 _LOGE("Don't execute query = %s error message = %s\n", query,
1960                        error_message);
1961                 sqlite3_free(error_message);
1962                 ret = PMINFO_R_ERROR;
1963                 *count = 0;
1964                 goto err;
1965         }
1966         ret = PMINFO_R_OK;
1967 err:
1968         if (locale) {
1969                 free(locale);
1970                 locale = NULL;
1971         }
1972         __close_manifest_db();
1973         return ret;
1974 }
1975
1976 API int pkgmgrinfo_pkginfo_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count)
1977 {
1978         return pkgmgrinfo_pkginfo_usr_filter_count(handle, count, GLOBAL_USER);
1979 }
1980
1981 API int pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(
1982                 pkgmgrinfo_pkginfo_filter_h handle,
1983                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data, uid_t uid)
1984 {
1985         if (handle == NULL || pkg_cb == NULL) {
1986                 LOGE("invalid parameter");
1987                 return PMINFO_R_EINVAL;
1988         }
1989
1990         return _pkginfo_get_filtered_foreach_pkginfo(handle, pkg_cb, user_data,
1991                         uid);
1992 }
1993
1994 API int pkgmgrinfo_pkginfo_filter_foreach_pkginfo(pkgmgrinfo_pkginfo_filter_h handle,
1995                                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data)
1996 {
1997         return pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, pkg_cb, user_data, GLOBAL_USER);
1998 }
1999
2000 API int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle,
2001                         pkgmgrinfo_pkg_privilege_list_cb privilege_func, void *user_data)
2002 {
2003         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
2004         retvm_if(privilege_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
2005         int ret = -1;
2006         privilege_x *ptr = NULL;
2007         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
2008         ptr = info->pkg_info->privileges->privilege;
2009         for (; ptr; ptr = ptr->next) {
2010                 if (ptr->text){
2011                         ret = privilege_func(ptr->text, user_data);
2012                         if (ret < 0)
2013                                 break;
2014                 }
2015         }
2016         return PMINFO_R_OK;
2017 }
2018
2019 API int pkgmgrinfo_create_pkgusrdbinfo(const char *pkgid, uid_t uid, 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_usr_manifest_file(pkgid, uid);
2028         retvm_if(manifest == NULL, PMINFO_R_EINVAL, "pkg[%s] dont have manifest file", pkgid);
2029
2030         mfx = pkgmgr_parser_usr_process_manifest_xml(manifest, uid);
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_create_pkgdbinfo(const char *pkgid, pkgmgrinfo_pkgdbinfo_h *handle)
2043 {
2044         retvm_if(!pkgid, PMINFO_R_EINVAL, "pkgid is NULL");
2045         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2046
2047         char *manifest = NULL;
2048         manifest_x *mfx = NULL;
2049         *handle = NULL;
2050         manifest = pkgmgr_parser_get_manifest_file(pkgid);
2051         retvm_if(manifest == NULL, PMINFO_R_EINVAL, "pkg[%s] dont have manifest file", pkgid);
2052
2053         mfx = pkgmgr_parser_process_manifest_xml(manifest);
2054         if (manifest) {
2055                 free(manifest);
2056                 manifest = NULL;
2057         }
2058         retvm_if(mfx == NULL, PMINFO_R_EINVAL, "pkg[%s] parsing fail", pkgid);
2059
2060         *handle = (void *)mfx;
2061
2062         return PMINFO_R_OK;
2063 }
2064
2065 API int pkgmgrinfo_set_type_to_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle, const char *type)
2066 {
2067         int len;
2068         manifest_x *mfx = (manifest_x *)handle;
2069
2070         retvm_if(!type, PMINFO_R_EINVAL, "Argument supplied is NULL");
2071         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2072
2073         len = strlen(type);
2074         retvm_if(len > PKG_TYPE_STRING_LEN_MAX, PMINFO_R_EINVAL, "pkg type length exceeds the max limit");
2075
2076         if (mfx->type)
2077                 free((void *)mfx->type);
2078
2079         mfx->type = strndup(type, PKG_TYPE_STRING_LEN_MAX);
2080
2081         return PMINFO_R_OK;
2082 }
2083
2084 API int pkgmgrinfo_set_version_to_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle, const char *version)
2085 {
2086         int len;
2087         manifest_x *mfx = (manifest_x *)handle;
2088
2089         retvm_if(!version, PMINFO_R_EINVAL, "Argument supplied is NULL");
2090         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2091
2092         len = strlen(version);
2093         retvm_if(len > PKG_TYPE_STRING_LEN_MAX, PMINFO_R_EINVAL, "pkg type length exceeds the max limit");
2094
2095         if (mfx->version)
2096                 free((void *)mfx->version);
2097
2098         mfx->version = strndup(version, PKG_VERSION_STRING_LEN_MAX);
2099         return PMINFO_R_OK;
2100 }
2101
2102 API int pkgmgrinfo_set_install_location_to_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle, INSTALL_LOCATION location)
2103 {
2104         manifest_x *mfx = (manifest_x *)handle;
2105
2106         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2107         retvm_if((location < 0) || (location > 1), PMINFO_R_EINVAL, "Argument supplied is NULL");
2108
2109         if (mfx->installlocation)
2110                 free((void *)mfx->installlocation);
2111
2112         if (location == INSTALL_INTERNAL)
2113                 mfx->installlocation = strdup("internal-only");
2114         else if (location == INSTALL_EXTERNAL)
2115                 mfx->installlocation = strdup("prefer-external");
2116
2117         return PMINFO_R_OK;
2118 }
2119
2120 API int pkgmgrinfo_set_size_to_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle, const char *size)
2121 {
2122         manifest_x *mfx = (manifest_x *)handle;
2123
2124         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2125         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL");
2126
2127         if (mfx->package_size)
2128                 free((void *)mfx->package_size);
2129
2130         mfx->package_size = strdup(size);
2131
2132         return PMINFO_R_OK;
2133 }
2134
2135 API int pkgmgrinfo_set_label_to_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle, const char *label_txt, const char *locale)
2136 {
2137         int len;
2138         manifest_x *mfx = (manifest_x *)handle;
2139         label_x *label;
2140
2141         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2142         retvm_if(!label_txt, PMINFO_R_EINVAL, "Argument supplied is NULL");
2143
2144         len = strlen(label_txt);
2145         retvm_if(len > PKG_TYPE_STRING_LEN_MAX, PMINFO_R_EINVAL, "pkg type length exceeds the max limit");
2146
2147         label = calloc(1, sizeof(label_x));
2148         retvm_if(label == NULL, PMINFO_R_EINVAL, "Malloc Failed");
2149
2150         LISTADD(mfx->label, label);
2151         if (locale)
2152                 mfx->label->lang = strdup(locale);
2153         else
2154                 mfx->label->lang = strdup(DEFAULT_LOCALE);
2155         mfx->label->text = strdup(label_txt);
2156
2157         return PMINFO_R_OK;
2158 }
2159
2160 API int pkgmgrinfo_set_icon_to_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle, const char *icon_txt, const char *locale)
2161 {
2162         int len;
2163         manifest_x *mfx = (manifest_x *)handle;
2164         icon_x *icon;
2165
2166         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2167         retvm_if(!icon_txt, PMINFO_R_EINVAL, "Argument supplied is NULL");
2168
2169         len = strlen(icon_txt);
2170         retvm_if(len > PKG_TYPE_STRING_LEN_MAX, PMINFO_R_EINVAL, "pkg type length exceeds the max limit");
2171
2172         icon = calloc(1, sizeof(icon_x));
2173         retvm_if(icon == NULL, PMINFO_R_EINVAL, "Malloc Failed");
2174
2175         LISTADD(mfx->icon, icon);
2176         if (locale)
2177                 mfx->icon->lang = strdup(locale);
2178         else
2179                 mfx->icon->lang = strdup(DEFAULT_LOCALE);
2180         mfx->icon->text = strdup(icon_txt);
2181
2182         return PMINFO_R_OK;
2183 }
2184
2185 API int pkgmgrinfo_set_description_to_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle, const char *desc_txt, const char *locale)
2186 {
2187         int len = strlen(desc_txt);
2188         manifest_x *mfx = (manifest_x *)handle;
2189         description_x *description;
2190
2191         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2192         retvm_if(!desc_txt, PMINFO_R_EINVAL, "Argument supplied is NULL");
2193
2194         len = strlen(desc_txt);
2195         retvm_if(len > PKG_TYPE_STRING_LEN_MAX, PMINFO_R_EINVAL, "pkg type length exceeds the max limit");
2196
2197         description = calloc(1, sizeof(description_x));
2198         retvm_if(description == NULL, PMINFO_R_EINVAL, "Malloc Failed");
2199
2200         LISTADD(mfx->description, description);
2201         if (locale)
2202                 mfx->description->lang = strdup(locale);
2203         else
2204                 mfx->description->lang = strdup(DEFAULT_LOCALE);
2205         mfx->description->text = strdup(desc_txt);
2206
2207         return PMINFO_R_OK;
2208 }
2209
2210 API int pkgmgrinfo_set_author_to_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle, const char *author_name,
2211                 const char *author_email, const char *author_href, const char *locale)
2212 {
2213         manifest_x *mfx = (manifest_x *)handle;
2214         author_x *author;
2215
2216         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2217
2218         author = calloc(1, sizeof(author_x));
2219         retvm_if(author == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL");
2220
2221         LISTADD(mfx->author, author);
2222         if (author_name)
2223                 mfx->author->text = strdup(author_name);
2224         if (author_email)
2225                 mfx->author->email = strdup(author_email);
2226         if (author_href)
2227                 mfx->author->href = strdup(author_href);
2228         if (locale)
2229                 mfx->author->lang = strdup(locale);
2230         else
2231                 mfx->author->lang = strdup(DEFAULT_LOCALE);
2232         return PMINFO_R_OK;
2233 }
2234
2235 API int pkgmgrinfo_set_removable_to_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle, int removable)
2236 {
2237         manifest_x *mfx = (manifest_x *)handle;
2238
2239         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2240         retvm_if((removable < 0) || (removable > 1), PMINFO_R_EINVAL, "Argument supplied is NULL");
2241
2242         if (mfx->removable)
2243                 free((void *)mfx->removable);
2244
2245         if (removable == 0)
2246                 mfx->removable = strdup("false");
2247         else if (removable == 1)
2248                 mfx->removable = strdup("true");
2249
2250         return PMINFO_R_OK;
2251 }
2252
2253 API int pkgmgrinfo_set_preload_to_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle, int preload)
2254 {
2255         manifest_x *mfx = (manifest_x *)handle;
2256
2257         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2258         retvm_if((preload < 0) || (preload > 1), PMINFO_R_EINVAL, "Argument supplied is NULL");
2259
2260         if (mfx->preload)
2261                 free((void *)mfx->preload);
2262
2263         if (preload == 0)
2264                 mfx->preload = strdup("false");
2265         else if (preload == 1)
2266                 mfx->preload = strdup("true");
2267
2268         return PMINFO_R_OK;
2269 }
2270
2271 API int pkgmgrinfo_set_installed_storage_to_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle, INSTALL_LOCATION location)
2272 {
2273         manifest_x *mfx = (manifest_x *)handle;
2274
2275         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2276         retvm_if((location < 0) || (location > 1), PMINFO_R_EINVAL, "Argument supplied is NULL");
2277
2278         if (mfx->installed_storage)
2279                 free((void *)mfx->installed_storage);
2280
2281         if (location == INSTALL_INTERNAL)
2282                 mfx->installed_storage = strdup("installed_internal");
2283         else if (location == INSTALL_EXTERNAL)
2284                 mfx->installed_storage = strdup("installed_external");
2285
2286         return PMINFO_R_OK;
2287 }
2288
2289 API int pkgmgrinfo_save_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle)
2290 {
2291         int ret;
2292         manifest_x *mfx = (manifest_x *)handle;
2293         mfx = (manifest_x *)handle;
2294
2295         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2296
2297         ret = pkgmgr_parser_update_manifest_info_in_db(mfx);
2298         if (ret == 0) {
2299                 _LOGE("Successfully stored info in DB\n");
2300                 return PMINFO_R_OK;
2301         } else {
2302                 _LOGE("Failed to store info in DB\n");
2303                 return PMINFO_R_ERROR;
2304         }
2305 }
2306
2307 API int pkgmgrinfo_save_pkgusrdbinfo(pkgmgrinfo_pkgdbinfo_h handle, uid_t uid)
2308 {
2309         int ret;
2310         manifest_x *mfx = (manifest_x *)handle;
2311
2312         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2313
2314         ret = pkgmgr_parser_update_manifest_info_in_usr_db(mfx, uid);
2315         if (ret == 0) {
2316                 _LOGE("Successfully stored info in DB\n");
2317                 return PMINFO_R_OK;
2318         } else {
2319                 _LOGE("Failed to store info in DB\n");
2320                 return PMINFO_R_ERROR;
2321         }
2322 }
2323
2324 API int pkgmgrinfo_destroy_pkgdbinfo(pkgmgrinfo_pkgdbinfo_h handle)
2325 {
2326         manifest_x *mfx = (manifest_x *)handle;
2327
2328         retvm_if(!handle, PMINFO_R_EINVAL, "Argument supplied is NULL");
2329
2330         pkgmgrinfo_basic_free_package(mfx);
2331
2332         return PMINFO_R_OK;
2333 }