Fix getting privilege query
[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 <sqlite3.h>
36 #include <glib.h>
37
38 #include "pkgmgr_parser.h"
39 #include "pkgmgrinfo_basic.h"
40 #include "pkgmgrinfo_private.h"
41 #include "pkgmgrinfo_debug.h"
42 #include "pkgmgr-info.h"
43 #include "pkgmgr_parser_db.h"
44 #include "pkgmgr_parser_internal.h"
45
46 static bool _get_bool_value(const char *str)
47 {
48         if (str && !strcmp(str, "true"))
49                 return true;
50         else
51                 return false;
52 }
53
54 static gint __compare_func(gconstpointer data1, gconstpointer data2)
55 {
56         pkgmgrinfo_node_x *node1 = (pkgmgrinfo_node_x*)data1;
57         pkgmgrinfo_node_x *node2 = (pkgmgrinfo_node_x*)data2;
58         if (node1->prop == node2->prop)
59                 return 0;
60         else if (node1->prop > node2->prop)
61                 return 1;
62         else
63                 return -1;
64 }
65
66 static void __destroy_each_node(gpointer data, gpointer user_data)
67 {
68         ret_if(data == NULL);
69         pkgmgrinfo_node_x *node = (pkgmgrinfo_node_x*)data;
70         if (node->value) {
71                 free(node->value);
72                 node->value = NULL;
73         }
74         if (node->key) {
75                 free(node->key);
76                 node->key = NULL;
77         }
78         free(node);
79         node = NULL;
80 }
81
82 static void __cleanup_pkginfo(pkgmgr_pkginfo_x *data)
83 {
84         ret_if(data == NULL);
85         if (data->locale) {
86                 free((void *)data->locale);
87                 data->locale = NULL;
88         }
89
90         pkgmgrinfo_basic_free_package(data->pkg_info);
91         free((void *)data);
92         data = NULL;
93         return;
94 }
95
96 long long _pkgmgr_calculate_dir_size(char *dirname)
97 {
98         long long total = 0;
99         long long ret = 0;
100         int q = 0; /*quotient*/
101         int r = 0; /*remainder*/
102         DIR *dp = NULL;
103         struct dirent ep, *result;
104         struct stat fileinfo;
105         char abs_filename[FILENAME_MAX] = { 0, };
106         retvm_if(dirname == NULL, PMINFO_R_ERROR, "dirname is NULL");
107
108         dp = opendir(dirname);
109         if (dp == NULL) {
110                 _LOGE("Couldn't open the directory\n");
111                 return -1;
112         }
113
114         for (ret = readdir_r(dp, &ep, &result);
115                         ret == 0 && result != NULL;
116                         ret = readdir_r(dp, &ep, &result)) {
117                 if (!strcmp(ep.d_name, ".") ||
118                         !strcmp(ep.d_name, "..")) {
119                         continue;
120                 }
121                 snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
122                          ep.d_name);
123                 if (lstat(abs_filename, &fileinfo) < 0)
124                         perror(abs_filename);
125                 else {
126                         if (S_ISDIR(fileinfo.st_mode)) {
127                                 total += fileinfo.st_size;
128                                 if (strcmp(ep.d_name, ".")
129                                     && strcmp(ep.d_name, "..")) {
130                                         ret = _pkgmgr_calculate_dir_size
131                                             (abs_filename);
132                                         total = total + ret;
133                                 }
134                         } else if (S_ISLNK(fileinfo.st_mode)) {
135                                 continue;
136                         } else {
137                                 /*It is a file. Calculate the actual
138                                 size occupied (in terms of 4096 blocks)*/
139                         q = (fileinfo.st_size / BLOCK_SIZE);
140                         r = (fileinfo.st_size % BLOCK_SIZE);
141                         if (r)
142                                 q = q + 1;
143                         total += q * BLOCK_SIZE;
144                         }
145                 }
146         }
147         (void)closedir(dp);
148         return total;
149
150 }
151
152 static int _pkginfo_add_description_info_into_list(const char *locale,
153                 char *record, GList **description)
154 {
155         description_x *info;
156
157         info = calloc(1, sizeof(description_x));
158         if (info == NULL) {
159                 LOGE("out of memory");
160                 return PMINFO_R_ERROR;
161         }
162         info->lang = strdup(locale);
163         info->text = record;
164         *description = g_list_append(*description, info);
165
166         return PMINFO_R_OK;
167 }
168
169 static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid,
170                 GList **privileges)
171 {
172         static const char query_raw[] =
173                 "SELECT DISTINCT privilege FROM package_privilege_info "
174                 "WHERE package=%Q";
175         int ret;
176         char *query;
177         sqlite3_stmt *stmt;
178         char *privilege;
179
180         query = sqlite3_mprintf(query_raw, pkgid);
181         if (query == NULL) {
182                 LOGE("out of memory");
183                 return PMINFO_R_ERROR;
184         }
185
186         ret = sqlite3_prepare_v2(db, query, strlen(query),
187                         &stmt, NULL);
188         sqlite3_free(query);
189         if (ret != SQLITE_OK) {
190                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
191                 return PMINFO_R_ERROR;
192         }
193
194         while (sqlite3_step(stmt) == SQLITE_ROW) {
195                 privilege = NULL;
196                 _save_column_str(stmt, 0, &privilege);
197                 if (privilege)
198                         *privileges = g_list_append(*privileges,
199                                         (gpointer)privilege);
200         }
201
202         sqlite3_finalize(stmt);
203
204         return PMINFO_R_OK;
205 }
206
207 static const char join_localized_info[] =
208         " LEFT OUTER JOIN package_localized_info"
209         "  ON pi.package=package_localized_info.package"
210         "  AND package_localized_info.package_locale=?";
211 static const char join_privilege_info[] =
212         " LEFT OUTER JOIN package_privilege_info"
213         "  ON pi.package=package_privilege_info.package";
214
215 static int _get_filtered_query(pkgmgrinfo_filter_x *filter,
216                 const char *locale, char **query, GList **bind_params)
217 {
218         int joined = 0;
219         char buf[MAX_QUERY_LEN] = { '\0' };
220         char buf2[MAX_QUERY_LEN] = { '\0' };
221         char *condition = NULL;
222         size_t len = 0;
223         GSList *list = NULL;
224
225         if (filter == NULL)
226                 return PMINFO_R_OK;
227
228         len += strlen(" WHERE 1=1 ");
229         strncat(buf, " WHERE 1=1 ", MAX_QUERY_LEN - len - 1);
230         for (list = filter->list; list; list = list->next) {
231                 joined |= __get_filter_condition(list->data, &condition,
232                                 bind_params);
233                 if (condition == NULL)
234                         continue;
235
236                 len += strlen(" AND ");
237                 strncat(buf, " AND ", MAX_QUERY_LEN - len - 1);
238
239                 len += strlen(condition);
240                 strncat(buf, condition, sizeof(buf) - len - 1);
241                 free(condition);
242                 condition = NULL;
243         }
244
245         if (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) {
246                 strncat(buf2, join_localized_info, MAX_QUERY_LEN - len - 1);
247                 len += strlen(join_localized_info);
248                 *bind_params = g_list_append(*bind_params, strdup(locale));
249         }
250         if (joined & E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO) {
251                 strncat(buf2, join_privilege_info, MAX_QUERY_LEN - len - 1);
252                 len += strlen(join_privilege_info);
253         }
254         strncat(buf2, buf, MAX_QUERY_LEN - len - 1);
255
256         *query = strdup(buf2);
257         if (*query == NULL)
258                 return PMINFO_R_ERROR;
259
260         return PMINFO_R_OK;
261 }
262
263 static void __free_packages(gpointer data)
264 {
265         pkgmgrinfo_basic_free_package((package_x *)data);
266 }
267
268 static int __bind_params(sqlite3_stmt *stmt, GList *params)
269 {
270         GList *tmp_list = NULL;
271         int idx = 0;
272         int ret;
273
274         if (stmt == NULL || params == NULL)
275                 return PMINFO_R_EINVAL;
276
277         tmp_list = params;
278         while (tmp_list) {
279                 ret = sqlite3_bind_text(stmt, ++idx, (char *)tmp_list->data, -1, SQLITE_STATIC);
280                 if (ret != SQLITE_OK)
281                         return PMINFO_R_ERROR;
282                 tmp_list = tmp_list->next;
283         }
284
285         return PMINFO_R_OK;
286 }
287
288 static int _pkginfo_get_packages(uid_t uid, const char *locale,
289                 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages)
290 {
291         static const char query_raw[] =
292                 "SELECT DISTINCT pi.package, pi.package_version, "
293                 "pi.install_location, pi.package_removable, "
294                 "pi.package_preload, pi.package_readonly, pi.package_update, "
295                 "pi.package_appsetting, pi.package_system, pi.package_type, "
296                 "pi.package_size, pi.installed_time, pi.installed_storage, "
297                 "pi.storeclient_id, pi.mainapp_id, pi.package_url, "
298                 "pi.root_path, pi.csc_path, pi.package_nodisplay, "
299                 "pi.package_api_version, pi.package_support_disable, "
300                 "pi.package_tep_name, pi.package_zip_mount_file";
301         static const char query_author[] =
302                 ", pi.author_name, pi.author_email, pi.author_href";
303         static const char query_label[] =
304                 ", COALESCE("
305                 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
306                 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
307         static const char query_icon[] =
308                 ", COALESCE("
309                 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
310                 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
311         static const char query_description[] =
312                 ", COALESCE("
313                 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
314                 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
315         static const char query_from_clause[] = " FROM package_info as pi";
316         int ret = PMINFO_R_ERROR;
317         int idx = 0;
318         int query_len = 0;
319         char *dbpath;
320         char *tmp_record = NULL;
321         char *constraints = NULL;
322         char query[MAX_QUERY_LEN] = { '\0' };
323         package_x *info = NULL;
324         author_x *author = NULL;
325         GList *bind_params = NULL;
326         sqlite3 *db;
327         sqlite3_stmt *stmt;
328         pkgmgrinfo_filter_x *tmp_filter = NULL;
329
330         dbpath = getUserPkgParserDBPathUID(uid);
331         if (dbpath == NULL)
332                 return PMINFO_R_ERROR;
333
334         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
335         if (ret != SQLITE_OK) {
336                 _LOGD("failed to open db: %d", ret);
337                 free(dbpath);
338                 return PMINFO_R_ERROR;
339         }
340         free(dbpath);
341
342         if (filter != NULL) {
343                 tmp_filter = filter;
344         } else {
345                 ret = pkgmgrinfo_pkginfo_filter_create((void *)&tmp_filter);
346                 if (ret != PMINFO_R_OK) {
347                         _LOGE("Failed to create filter");
348                         return PMINFO_R_ERROR;
349                 }
350         }
351
352         /* add package_disable='false' clause by default */
353         pkgmgrinfo_pkginfo_filter_add_bool(tmp_filter, PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
354
355         query_len = strlen(query_raw);
356         snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
357         if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
358                 strncat(query, query_author, MAX_QUERY_LEN - query_len - 1);
359                 query_len += strlen(query_author);
360         }
361         if (flag & PMINFO_PKGINFO_GET_LABEL) {
362                 strncat(query, query_label, MAX_QUERY_LEN - query_len - 1);
363                 query_len += strlen(query_label);
364                 bind_params = g_list_append(bind_params, strdup(locale));
365         }
366         if (flag & PMINFO_PKGINFO_GET_ICON) {
367                 strncat(query, query_icon, MAX_QUERY_LEN - query_len - 1);
368                 query_len += strlen(query_icon);
369                 bind_params = g_list_append(bind_params, strdup(locale));
370         }
371         if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
372                 strncat(query, query_description, MAX_QUERY_LEN - query_len - 1);
373                 query_len += strlen(query_description);
374                 bind_params = g_list_append(bind_params, strdup(locale));
375         }
376
377         strncat(query, query_from_clause, MAX_QUERY_LEN - query_len - 1);
378         query_len += strlen(query_from_clause);
379
380         ret = _get_filtered_query(tmp_filter, locale, &constraints, &bind_params);
381         if (ret != PMINFO_R_OK) {
382                 LOGE("Failed to get WHERE clause");
383                 goto catch;
384         }
385
386         if (constraints)
387                 strncat(query, constraints, MAX_QUERY_LEN - query_len - 1);
388
389         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
390         if (ret != SQLITE_OK) {
391                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
392                 ret = PMINFO_R_ERROR;
393                 goto catch;
394         }
395
396         ret = __bind_params(stmt, bind_params);
397         if (ret != SQLITE_OK) {
398                 LOGE("Failed to bind parameters");
399                 goto catch;
400         }
401
402         while (sqlite3_step(stmt) == SQLITE_ROW) {
403                 info = calloc(1, sizeof(package_x));
404                 if (info == NULL) {
405                         LOGE("out of memory");
406                         sqlite3_finalize(stmt);
407                         sqlite3_close_v2(db);
408                         return PMINFO_R_ERROR;
409                 }
410                 idx = 0;
411                 _save_column_str(stmt, idx++, &info->package);
412                 if (g_hash_table_contains(packages,
413                                         (gconstpointer)info->package)) {
414                         free(info->package);
415                         free(info);
416                         continue;
417                 }
418                 _save_column_str(stmt, idx++, &info->version);
419                 _save_column_str(stmt, idx++, &info->installlocation);
420                 _save_column_str(stmt, idx++, &info->removable);
421                 _save_column_str(stmt, idx++, &info->preload);
422                 _save_column_str(stmt, idx++, &info->readonly);
423                 _save_column_str(stmt, idx++, &info->update);
424                 _save_column_str(stmt, idx++, &info->appsetting);
425                 _save_column_str(stmt, idx++, &info->system);
426                 _save_column_str(stmt, idx++, &info->type);
427                 _save_column_str(stmt, idx++, &info->package_size);
428                 _save_column_str(stmt, idx++, &info->installed_time);
429                 _save_column_str(stmt, idx++, &info->installed_storage);
430                 _save_column_str(stmt, idx++, &info->storeclient_id);
431                 _save_column_str(stmt, idx++, &info->mainapp_id);
432                 _save_column_str(stmt, idx++, &info->package_url);
433                 _save_column_str(stmt, idx++, &info->root_path);
434                 _save_column_str(stmt, idx++, &info->csc_path);
435                 _save_column_str(stmt, idx++, &info->nodisplay_setting);
436                 _save_column_str(stmt, idx++, &info->api_version);
437                 _save_column_str(stmt, idx++, &info->support_disable);
438                 _save_column_str(stmt, idx++, &info->tep_name);
439                 _save_column_str(stmt, idx++, &info->zip_mount_file);
440                 info->for_all_users =
441                         strdup((uid != GLOBAL_USER) ? "false" : "true");
442
443                 if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
444                         /* TODO : author should be retrieved at package_localized_info */
445                         author = calloc(1, sizeof(author_x));
446                         if (author == NULL) {
447                                 pkgmgrinfo_basic_free_package(info);
448                                 sqlite3_finalize(stmt);
449                                 sqlite3_close_v2(db);
450                                 return PMINFO_R_ERROR;
451                         }
452                         _save_column_str(stmt, idx++, &author->text);
453                         _save_column_str(stmt, idx++, &author->email);
454                         _save_column_str(stmt, idx++, &author->href);
455                         info->author = g_list_append(info->author, author);
456                 }
457
458                 if (flag & PMINFO_PKGINFO_GET_LABEL) {
459                         tmp_record = NULL;
460                         _save_column_str(stmt, idx++, &tmp_record);
461
462                         if (_add_label_info_into_list(locale, tmp_record, &info->label)) {
463                                 pkgmgrinfo_basic_free_package(info);
464                                 sqlite3_finalize(stmt);
465                                 sqlite3_close_v2(db);
466                                 return PMINFO_R_ERROR;
467                         }
468                 }
469
470                 if (flag & PMINFO_PKGINFO_GET_ICON) {
471                         tmp_record = NULL;
472                         _save_column_str(stmt, idx++, &tmp_record);
473                         if (_add_icon_info_into_list(locale, tmp_record, &info->icon)) {
474                                 pkgmgrinfo_basic_free_package(info);
475                                 sqlite3_finalize(stmt);
476                                 sqlite3_close_v2(db);
477                                 return PMINFO_R_ERROR;
478                         }
479                 }
480
481                 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
482                         tmp_record = NULL;
483                         _save_column_str(stmt, idx++, &tmp_record);
484                         if (_pkginfo_add_description_info_into_list(locale, tmp_record,
485                                         &info->description)) {
486                                 pkgmgrinfo_basic_free_package(info);
487                                 sqlite3_finalize(stmt);
488                                 sqlite3_close_v2(db);
489                                 return PMINFO_R_ERROR;
490                         }
491                 }
492
493                 if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) {
494                         if (_pkginfo_get_privilege(db, info->package,
495                                                 &info->privileges)) {
496                                 pkgmgrinfo_basic_free_package(info);
497                                 sqlite3_finalize(stmt);
498                                 sqlite3_close_v2(db);
499                                 return PMINFO_R_ERROR;
500                         }
501                 }
502
503                 g_hash_table_insert(packages, (gpointer)info->package,
504                                 (gpointer)info);
505         }
506
507         ret = PMINFO_R_OK;
508
509 catch:
510         if (constraints)
511                 free(constraints);
512
513         if (ret != PMINFO_R_OK && info != NULL)
514                 pkgmgrinfo_basic_free_package(info);
515
516         if (filter == NULL)
517                 pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
518
519         g_list_free_full(bind_params, free);
520         sqlite3_close_v2(db);
521         sqlite3_finalize(stmt);
522
523         return ret;
524 }
525
526 static int _pkginfo_get_filtered_foreach_pkginfo(uid_t uid,
527                 pkgmgrinfo_filter_x *filter, int flag,
528                 pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data)
529 {
530         int ret;
531         char *locale;
532         package_x *pkg;
533         pkgmgr_pkginfo_x info;
534         GHashTable *list;
535         GHashTableIter iter;
536         gpointer value;
537
538         locale = _get_system_locale();
539         if (locale == NULL)
540                 return PMINFO_R_ERROR;
541
542         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
543                         __free_packages);
544         if (list == NULL) {
545                 free(locale);
546                 return PMINFO_R_ERROR;
547         }
548
549         ret = _pkginfo_get_packages(uid, locale, filter, flag, list);
550         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
551                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
552                                 flag, list);
553
554         if (ret != PMINFO_R_OK) {
555                 g_hash_table_destroy(list);
556                 free(locale);
557                 return PMINFO_R_ERROR;
558         }
559
560         g_hash_table_iter_init(&iter, list);
561         while (g_hash_table_iter_next(&iter, NULL, &value)) {
562                 pkg = (package_x *)value;
563                 info.uid = uid;
564                 info.pkg_info = pkg;
565                 info.locale = locale;
566                 if (pkg_list_cb(&info, user_data) < 0)
567                         break;
568         }
569
570         g_hash_table_destroy(list);
571         free(locale);
572
573         return PMINFO_R_OK;
574 }
575
576 API int pkgmgrinfo_pkginfo_get_usr_pkginfo(const char *pkgid, uid_t uid,
577                 pkgmgrinfo_pkginfo_h *handle)
578 {
579         int ret;
580         char *locale;
581         GHashTable *list;
582         pkgmgrinfo_pkginfo_filter_h filter;
583         pkgmgr_pkginfo_x *info;
584
585         if (pkgid == NULL || handle == NULL) {
586                 LOGE("invalid parameter");
587                 return PMINFO_R_EINVAL;
588         }
589
590         locale = _get_system_locale();
591         if (locale == NULL)
592                 return PMINFO_R_ERROR;
593
594         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
595         if (ret != PMINFO_R_OK) {
596                 free(locale);
597                 return ret;
598         }
599
600         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
601                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
602         if (ret != PMINFO_R_OK) {
603                 pkgmgrinfo_pkginfo_filter_destroy(filter);
604                 free(locale);
605                 return PMINFO_R_ERROR;
606         }
607
608         list = g_hash_table_new(g_str_hash, g_str_equal);
609         if (list == NULL) {
610                 pkgmgrinfo_pkginfo_filter_destroy(filter);
611                 free(locale);
612                 return PMINFO_R_ERROR;
613         }
614
615         ret = _pkginfo_get_packages(uid, locale, filter,
616                         PMINFO_PKGINFO_GET_ALL, list);
617         if (!g_hash_table_size(list) && uid != GLOBAL_USER)
618                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
619                                 PMINFO_PKGINFO_GET_ALL, list);
620
621         pkgmgrinfo_pkginfo_filter_destroy(filter);
622         if (ret != PMINFO_R_OK) {
623                 g_hash_table_destroy(list);
624                 free(locale);
625                 return ret;
626         }
627
628         if (!g_hash_table_size(list)) {
629                 _LOGI("pkginfo for [%s] is not existed for user [%d]",
630                                 pkgid, uid);
631                 g_hash_table_destroy(list);
632                 free(locale);
633                 return PMINFO_R_ENOENT;
634         }
635
636         info = calloc(1, sizeof(pkgmgr_pkginfo_x));
637         if (info == NULL) {
638                 _LOGE("out of memory");
639                 g_hash_table_destroy(list);
640                 free(locale);
641                 return PMINFO_R_ERROR;
642         }
643
644         info->uid = uid;
645         info->pkg_info = (package_x *)g_hash_table_lookup(list, pkgid);
646         info->locale = locale;
647
648         /* just free list only */
649         g_hash_table_destroy(list);
650
651         *handle = info;
652
653         return ret;
654 }
655
656 API int pkgmgrinfo_pkginfo_get_pkginfo(const char *pkgid,
657                 pkgmgrinfo_pkginfo_h *handle)
658 {
659         return pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, _getuid(), handle);
660 }
661
662 API int pkgmgrinfo_pkginfo_get_usr_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
663                 int flag, void *user_data, uid_t uid)
664 {
665         if (pkg_list_cb == NULL) {
666                 LOGE("invalid parameter");
667                 return PMINFO_R_EINVAL;
668         }
669
670         return _pkginfo_get_filtered_foreach_pkginfo(uid, NULL, flag,
671                         pkg_list_cb, user_data);
672 }
673
674 API int pkgmgrinfo_pkginfo_get_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
675                 int flag, void *user_data)
676 {
677         return pkgmgrinfo_pkginfo_get_usr_list_full(pkg_list_cb, flag,
678                         user_data, _getuid());
679 }
680
681 API int pkgmgrinfo_pkginfo_get_usr_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
682                 void *user_data, uid_t uid)
683 {
684         if (pkg_list_cb == NULL) {
685                 LOGE("invalid parameter");
686                 return PMINFO_R_EINVAL;
687         }
688
689         return _pkginfo_get_filtered_foreach_pkginfo(uid, NULL,
690                         PMINFO_PKGINFO_GET_ALL, pkg_list_cb, user_data);
691 }
692
693 API int pkgmgrinfo_pkginfo_get_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
694                 void *user_data)
695 {
696         return pkgmgrinfo_pkginfo_get_usr_list(pkg_list_cb, user_data,
697                         _getuid());
698 }
699
700 API int pkgmgrinfo_pkginfo_get_pkgname(pkgmgrinfo_pkginfo_h handle, char **pkg_name)
701 {
702         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
703
704         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
705         retvm_if(pkg_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
706
707         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
708                 return PMINFO_R_ERROR;
709
710         *pkg_name = (char *)info->pkg_info->package;
711
712         return PMINFO_R_OK;
713 }
714
715 API int pkgmgrinfo_pkginfo_get_pkgid(pkgmgrinfo_pkginfo_h handle, char **pkgid)
716 {
717         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
718
719         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
720         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
721
722         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
723                 return PMINFO_R_ERROR;
724
725         *pkgid = (char *)info->pkg_info->package;
726
727         return PMINFO_R_OK;
728 }
729
730 API int pkgmgrinfo_pkginfo_get_type(pkgmgrinfo_pkginfo_h handle, char **type)
731 {
732         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
733
734         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
735         retvm_if(type == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
736
737         if (info->pkg_info == NULL)
738                 return PMINFO_R_ERROR;
739
740         if (info->pkg_info->type == NULL)
741                 *type = "";
742         else
743                 *type = (char *)info->pkg_info->type;
744
745         return PMINFO_R_OK;
746 }
747
748 API int pkgmgrinfo_pkginfo_get_version(pkgmgrinfo_pkginfo_h handle, char **version)
749 {
750         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
751
752         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
753         retvm_if(version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
754
755         if (info->pkg_info == NULL)
756                 return PMINFO_R_ERROR;
757
758         if (info->pkg_info->version == NULL)
759                 *version = "";
760         else
761                 *version = (char *)info->pkg_info->version;
762
763         return PMINFO_R_OK;
764 }
765
766 API int pkgmgrinfo_pkginfo_get_api_version(pkgmgrinfo_pkginfo_h handle, char **api_version)
767 {
768         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
769
770         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
771         retvm_if(api_version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
772
773         if (info->pkg_info == NULL)
774                 return PMINFO_R_ERROR;
775
776         if (info->pkg_info->api_version == NULL)
777                 *api_version = "";
778         else
779                 *api_version = (char *)info->pkg_info->api_version;
780
781         return PMINFO_R_OK;
782 }
783
784 API int pkgmgrinfo_pkginfo_get_tep_name(pkgmgrinfo_pkginfo_h handle, char **tep_name)
785 {
786         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
787
788         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
789         retvm_if(tep_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
790
791         if (info->pkg_info == NULL || info->pkg_info->tep_name == NULL)
792                 return PMINFO_R_ERROR;
793
794         *tep_name = (char *)info->pkg_info->tep_name;
795
796         return PMINFO_R_OK;
797 }
798
799 API int pkgmgrinfo_pkginfo_get_zip_mount_file(pkgmgrinfo_pkginfo_h handle, char **zip_mount_file)
800 {
801         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
802
803         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
804         retvm_if(zip_mount_file == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
805
806         if (info->pkg_info == NULL)
807                 return PMINFO_R_ERROR;
808
809         if (info->pkg_info->zip_mount_file == NULL)
810                 *zip_mount_file = "";
811         else
812                 *zip_mount_file = (char *)info->pkg_info->zip_mount_file;
813
814         return PMINFO_R_OK;
815 }
816
817 API int pkgmgrinfo_pkginfo_get_install_location(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_install_location *location)
818 {
819         char *val;
820         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
821
822         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
823         retvm_if(location == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
824
825         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
826                 return PMINFO_R_ERROR;
827
828         val = (char *)info->pkg_info->installlocation;
829         if (strcmp(val, "internal-only") == 0)
830                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
831         else if (strcmp(val, "prefer-external") == 0)
832                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
833         else
834                 *location = PMINFO_INSTALL_LOCATION_AUTO;
835
836         return PMINFO_R_OK;
837 }
838
839 API int pkgmgrinfo_pkginfo_get_package_size(pkgmgrinfo_pkginfo_h handle, int *size)
840 {
841         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
842         char *temp = NULL;
843
844         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
845         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
846
847         if (info->pkg_info == NULL)
848                 return PMINFO_R_ERROR;
849
850         if (info->pkg_info->package_size == NULL) {
851                 temp = strdup("");
852                 if (temp == NULL) {
853                         _LOGE("out of memory");
854                         return PMINFO_R_ERROR;
855                 } else {
856                         info->pkg_info->package_size = temp;
857                 }
858         }
859
860         *size = atoi((char *)info->pkg_info->package_size);
861
862         return PMINFO_R_OK;
863 }
864
865 API int pkgmgrinfo_pkginfo_get_icon(pkgmgrinfo_pkginfo_h handle, char **icon)
866 {
867         icon_x *ptr;
868         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
869
870         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
871         retvm_if(icon == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
872
873         if (info->pkg_info == NULL || info->pkg_info->icon == NULL)
874                 return PMINFO_R_ERROR;
875
876         ptr = (icon_x *)info->pkg_info->icon->data;
877         if (ptr == NULL)
878                 return PMINFO_R_ERROR;
879
880         /* TODO : should we return empty string if there was no icon? */
881         if (ptr->text == NULL)
882                 *icon = "";
883         else
884                 *icon = ptr->text;
885
886         return PMINFO_R_OK;
887 }
888
889 API int pkgmgrinfo_pkginfo_get_label(pkgmgrinfo_pkginfo_h handle, char **label)
890 {
891         label_x *ptr;
892         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
893
894         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
895         retvm_if(label == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
896
897         if (info->pkg_info == NULL || info->pkg_info->label == NULL)
898                 return PMINFO_R_ERROR;
899
900         ptr = (label_x *)info->pkg_info->label->data;
901         if (ptr == NULL)
902                 return PMINFO_R_ERROR;
903
904         /* TODO : should we return empty string if there was no label? */
905         if (ptr->text == NULL)
906                 *label = "";
907         else
908                 *label = ptr->text;
909
910         return PMINFO_R_OK;
911 }
912
913 API int pkgmgrinfo_pkginfo_get_description(pkgmgrinfo_pkginfo_h handle, char **description)
914 {
915         description_x *ptr;
916         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
917
918         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
919         retvm_if(description == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
920
921         if (info->pkg_info == NULL || info->pkg_info->description == NULL)
922                 return PMINFO_R_ERROR;
923
924         ptr = (description_x *)info->pkg_info->description->data;
925         if (ptr == NULL)
926                 return PMINFO_R_ERROR;
927
928         if (ptr->text == NULL)
929                 *description = "";
930         else
931                 *description = (char *)ptr->text;
932
933         return PMINFO_R_OK;
934 }
935
936 API int pkgmgrinfo_pkginfo_get_author_name(pkgmgrinfo_pkginfo_h handle, char **author_name)
937 {
938         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
939         author_x *author;
940
941         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
942         retvm_if(author_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
943
944         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
945                 return PMINFO_R_ERROR;
946
947         author = (author_x *)info->pkg_info->author->data;
948         if (author == NULL)
949                 return PMINFO_R_ERROR;
950
951         if (author->text == NULL)
952                 *author_name = "";
953         else
954                 *author_name = (char *)author->text;
955
956         return PMINFO_R_OK;
957 }
958
959 API int pkgmgrinfo_pkginfo_get_author_email(pkgmgrinfo_pkginfo_h handle, char **author_email)
960 {
961         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
962         author_x *author;
963
964         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
965         retvm_if(author_email == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
966
967         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
968                 return PMINFO_R_ERROR;
969
970         author = (author_x *)info->pkg_info->author->data;
971         if (author == NULL)
972                 return PMINFO_R_ERROR;
973
974         if (author->email == NULL)
975                 *author_email = "";
976         else
977                 *author_email = (char *)author->email;
978
979         return PMINFO_R_OK;
980 }
981
982 API int pkgmgrinfo_pkginfo_get_author_href(pkgmgrinfo_pkginfo_h handle, char **author_href)
983 {
984         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
985         author_x *author;
986
987         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
988         retvm_if(author_href == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
989
990         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
991                 return PMINFO_R_ERROR;
992
993         author = (author_x *)info->pkg_info->author->data;
994         if (author == NULL)
995                 return PMINFO_R_ERROR;
996
997         if (author->href == NULL)
998                 *author_href = "";
999         else
1000                 *author_href = (char *)author->href;
1001
1002         return PMINFO_R_OK;
1003 }
1004
1005 API int pkgmgrinfo_pkginfo_get_installed_storage(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_installed_storage *storage)
1006 {
1007         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1008
1009         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1010         retvm_if(storage == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1011
1012         if (info->pkg_info == NULL || info->pkg_info->installed_storage == NULL)
1013                 return PMINFO_R_ERROR;
1014
1015         if (strcmp(info->pkg_info->installed_storage, "installed_internal") == 0)
1016                 *storage = PMINFO_INTERNAL_STORAGE;
1017         else if (strcmp(info->pkg_info->installed_storage, "installed_external") == 0)
1018                 *storage = PMINFO_EXTERNAL_STORAGE;
1019         else
1020                 return PMINFO_R_ERROR;
1021
1022         return PMINFO_R_OK;
1023 }
1024
1025 API int pkgmgrinfo_pkginfo_get_installed_time(pkgmgrinfo_pkginfo_h handle, int *installed_time)
1026 {
1027         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1028
1029         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1030         retvm_if(installed_time == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1031
1032         if (info->pkg_info == NULL || info->pkg_info->installed_time == NULL)
1033                 return PMINFO_R_ERROR;
1034
1035         *installed_time = atoi(info->pkg_info->installed_time);
1036
1037         return PMINFO_R_OK;
1038 }
1039
1040 API int pkgmgrinfo_pkginfo_get_storeclientid(pkgmgrinfo_pkginfo_h handle, char **storeclientid)
1041 {
1042         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1043
1044         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1045         retvm_if(storeclientid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1046
1047         if (info->pkg_info == NULL)
1048                 return PMINFO_R_ERROR;
1049
1050         if (info->pkg_info->storeclient_id == NULL)
1051                 *storeclientid = "";
1052         else
1053                 *storeclientid = (char *)info->pkg_info->storeclient_id;
1054
1055         return PMINFO_R_OK;
1056 }
1057
1058 API int pkgmgrinfo_pkginfo_get_mainappid(pkgmgrinfo_pkginfo_h handle, char **mainappid)
1059 {
1060         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1061
1062         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1063         retvm_if(mainappid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1064
1065         if (info->pkg_info == NULL || info->pkg_info->mainapp_id == NULL)
1066                 return PMINFO_R_ERROR;
1067
1068         *mainappid = (char *)info->pkg_info->mainapp_id;
1069
1070         return PMINFO_R_OK;
1071 }
1072
1073 API int pkgmgrinfo_pkginfo_get_url(pkgmgrinfo_pkginfo_h handle, char **url)
1074 {
1075         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1076
1077         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1078         retvm_if(url == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1079
1080         if (info->pkg_info == NULL)
1081                 return PMINFO_R_ERROR;
1082
1083         if (info->pkg_info->package_url == NULL)
1084                 *url = "";
1085         else
1086                 *url = (char *)info->pkg_info->package_url;
1087
1088         return PMINFO_R_OK;
1089 }
1090
1091 API int pkgmgrinfo_pkginfo_get_root_path(pkgmgrinfo_pkginfo_h handle, char **path)
1092 {
1093         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1094
1095         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1096         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1097
1098         if (info->pkg_info == NULL || info->pkg_info->root_path == NULL)
1099                 return PMINFO_R_ERROR;
1100
1101         *path = (char *)info->pkg_info->root_path;
1102
1103         return PMINFO_R_OK;
1104 }
1105
1106 API int pkgmgrinfo_pkginfo_get_csc_path(pkgmgrinfo_pkginfo_h handle, char **path)
1107 {
1108         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1109
1110         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1111         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1112
1113         if (info->pkg_info == NULL)
1114                 return PMINFO_R_ERROR;
1115
1116         if (info->pkg_info->csc_path == NULL)
1117                 *path = "";
1118         else
1119                 *path = (char *)info->pkg_info->csc_path;
1120
1121         return PMINFO_R_OK;
1122 }
1123
1124
1125 API int pkgmgrinfo_pkginfo_is_accessible(pkgmgrinfo_pkginfo_h handle, bool *accessible)
1126 {
1127         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1128         retvm_if(accessible == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1129
1130 #if 0 /* smack issue occured, check later */
1131         char *pkgid = NULL;
1132         pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
1133         if (pkgid == NULL) {
1134                  _LOGD("invalid func parameters\n");
1135                  return PMINFO_R_ERROR;
1136         }
1137          _LOGD("pkgmgr_get_pkg_external_validation() called\n");
1138
1139         FILE *fp = NULL;
1140         char app_mmc_path[FILENAME_MAX] = { 0, };
1141         char app_dir_path[FILENAME_MAX] = { 0, };
1142         char app_mmc_internal_path[FILENAME_MAX] = { 0, };
1143         snprintf(app_dir_path, FILENAME_MAX, "%s%s", PKG_INSTALLATION_PATH, pkgid);
1144         snprintf(app_mmc_path, FILENAME_MAX, "%s%s", PKG_SD_PATH, pkgid);
1145         snprintf(app_mmc_internal_path, FILENAME_MAX, "%s%s/.mmc", PKG_INSTALLATION_PATH, pkgid);
1146
1147         /*check whether application is in external memory or not */
1148         fp = fopen(app_mmc_path, "r");
1149         if (fp == NULL) {
1150                 _LOGD(" app path in external memory not accesible\n");
1151         } else {
1152                 fclose(fp);
1153                 fp = NULL;
1154                 *accessible = 1;
1155                 _LOGD("pkgmgr_get_pkg_external_validation() : SD_CARD \n");
1156                 return PMINFO_R_OK;
1157         }
1158
1159         /*check whether application is in internal or not */
1160         if (fp == NULL) {
1161                 _LOGD(" app path in internal memory not accesible\n");
1162                 *accessible = 0;
1163                 return PMINFO_R_ERROR;
1164         } else {
1165                 fclose(fp);
1166                 /*check whether the application is installed in SD card
1167                 but SD card is not present*/
1168                 fp = fopen(app_mmc_internal_path, "r");
1169                 if (fp == NULL) {
1170                         *accessible = 1;
1171                         _LOGD("pkgmgr_get_pkg_external_validation() : INTERNAL_MEM \n");
1172                         return PMINFO_R_OK;
1173                 } else {
1174                         *accessible = 0;
1175                         _LOGD("pkgmgr_get_pkg_external_validation() : ERROR_MMC_STATUS \n");
1176                 }
1177                 fclose(fp);
1178         }
1179
1180         _LOGD("pkgmgr_get_pkg_external_validation() end\n");
1181 #endif
1182
1183         *accessible = 1;
1184         return PMINFO_R_OK;
1185 }
1186
1187 API int pkgmgrinfo_pkginfo_is_removable(pkgmgrinfo_pkginfo_h handle, bool *removable)
1188 {
1189         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1190
1191         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1192         retvm_if(removable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1193
1194         if (info->pkg_info == NULL || info->pkg_info->removable == NULL)
1195                 return PMINFO_R_ERROR;
1196
1197         *removable = _get_bool_value(info->pkg_info->removable);
1198
1199         return PMINFO_R_OK;
1200 }
1201
1202 API int pkgmgrinfo_pkginfo_is_movable(pkgmgrinfo_pkginfo_h handle, bool *movable)
1203 {
1204         char *val;
1205         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1206
1207         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1208         retvm_if(movable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1209
1210         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
1211                 return PMINFO_R_ERROR;
1212
1213         val = (char *)info->pkg_info->installlocation;
1214         if (strcmp(val, "internal-only") == 0)
1215                 *movable = 0;
1216         else if (strcmp(val, "prefer-external") == 0)
1217                 *movable = 1;
1218         else
1219                 *movable = 1;
1220
1221         return PMINFO_R_OK;
1222 }
1223
1224 API int pkgmgrinfo_pkginfo_is_preload(pkgmgrinfo_pkginfo_h handle, bool *preload)
1225 {
1226         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1227
1228         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1229         retvm_if(preload == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1230
1231         if (info->pkg_info == NULL || info->pkg_info->preload == NULL)
1232                 return PMINFO_R_ERROR;
1233
1234         *preload = _get_bool_value(info->pkg_info->preload);
1235
1236         return PMINFO_R_OK;
1237 }
1238
1239 API int pkgmgrinfo_pkginfo_is_system(pkgmgrinfo_pkginfo_h handle, bool *system)
1240 {
1241         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1242
1243         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1244         retvm_if(system == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1245
1246         if (info->pkg_info == NULL || info->pkg_info->system == NULL)
1247                 return PMINFO_R_ERROR;
1248
1249         *system = _get_bool_value(info->pkg_info->system);
1250
1251         return PMINFO_R_OK;
1252 }
1253
1254 API int pkgmgrinfo_pkginfo_is_readonly(pkgmgrinfo_pkginfo_h handle, bool *readonly)
1255 {
1256         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1257
1258         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1259         retvm_if(readonly == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1260
1261         if (info->pkg_info == NULL || info->pkg_info->readonly == NULL)
1262                 return PMINFO_R_ERROR;
1263
1264         *readonly = _get_bool_value(info->pkg_info->readonly);
1265
1266         return PMINFO_R_OK;
1267 }
1268
1269 API int pkgmgrinfo_pkginfo_is_update(pkgmgrinfo_pkginfo_h handle, bool *update)
1270 {
1271         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1272
1273         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1274         retvm_if(update == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1275
1276         if (info->pkg_info == NULL || info->pkg_info->update == NULL)
1277                 return PMINFO_R_ERROR;
1278
1279         *update = _get_bool_value(info->pkg_info->update);
1280
1281         return PMINFO_R_OK;
1282 }
1283
1284 API int pkgmgrinfo_pkginfo_is_support_disable(pkgmgrinfo_pkginfo_h handle, bool *support_disable)
1285 {
1286         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1287
1288         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1289         retvm_if(support_disable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1290
1291         if (info->pkg_info == NULL || info->pkg_info->support_disable == NULL)
1292                 return PMINFO_R_ERROR;
1293
1294         *support_disable = _get_bool_value(info->pkg_info->support_disable);
1295
1296         return PMINFO_R_OK;
1297 }
1298
1299 API int pkgmgrinfo_pkginfo_is_global(pkgmgrinfo_pkginfo_h handle, bool *global)
1300 {
1301         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1302
1303         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1304         retvm_if(global == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1305
1306         if (info->pkg_info == NULL || info->pkg_info->for_all_users == NULL)
1307                 return PMINFO_R_ERROR;
1308
1309         *global = _get_bool_value(info->pkg_info->for_all_users);
1310
1311         return PMINFO_R_OK;
1312 }
1313
1314 API int pkgmgrinfo_pkginfo_is_for_all_users(pkgmgrinfo_pkginfo_h handle, bool *for_all_users)
1315 {
1316         return pkgmgrinfo_pkginfo_is_global(handle, for_all_users);
1317 }
1318
1319 API int pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo_h handle)
1320 {
1321         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1322
1323         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1324
1325         __cleanup_pkginfo(info);
1326
1327         return PMINFO_R_OK;
1328 }
1329
1330 API int pkgmgrinfo_pkginfo_filter_create(pkgmgrinfo_pkginfo_filter_h *handle)
1331 {
1332         pkgmgrinfo_filter_x *filter;
1333
1334         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle output parameter is NULL\n");
1335
1336         filter = (pkgmgrinfo_filter_x*)calloc(1, sizeof(pkgmgrinfo_filter_x));
1337         if (filter == NULL) {
1338                 _LOGE("Out of Memory!!!");
1339                 return PMINFO_R_ERROR;
1340         }
1341
1342         *handle = filter;
1343
1344         return PMINFO_R_OK;
1345 }
1346
1347 API int pkgmgrinfo_pkginfo_filter_destroy(pkgmgrinfo_pkginfo_filter_h handle)
1348 {
1349         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1350
1351         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1352
1353         if (filter->list) {
1354                 g_slist_foreach(filter->list, __destroy_each_node, NULL);
1355                 g_slist_free(filter->list);
1356         }
1357
1358         free(filter);
1359
1360         return PMINFO_R_OK;
1361 }
1362
1363 API int pkgmgrinfo_pkginfo_filter_add_int(pkgmgrinfo_pkginfo_filter_h handle,
1364                                 const char *property, const int value)
1365 {
1366         char buf[PKG_VALUE_STRING_LEN_MAX] = {'\0'};
1367         char *val;
1368         GSList *link;
1369         int prop;
1370         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1371         pkgmgrinfo_node_x *node;
1372
1373         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1374         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1375
1376         prop = _pminfo_pkginfo_convert_to_prop_int(property);
1377         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_INT ||
1378                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_INT) {
1379                 _LOGE("Invalid Integer Property\n");
1380                 return PMINFO_R_EINVAL;
1381         }
1382         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1383         if (node == NULL) {
1384                 _LOGE("Out of Memory!!!\n");
1385                 return PMINFO_R_ERROR;
1386         }
1387         snprintf(buf, PKG_VALUE_STRING_LEN_MAX - 1, "%d", value);
1388         val = strndup(buf, PKG_VALUE_STRING_LEN_MAX - 1);
1389         if (val == NULL) {
1390                 _LOGE("Out of Memory\n");
1391                 free(node);
1392                 return PMINFO_R_ERROR;
1393         }
1394         node->prop = prop;
1395         node->value = val;
1396         /*If API is called multiple times for same property, we should override the previous values.
1397         Last value set will be used for filtering.*/
1398         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1399         if (link)
1400                 filter->list = g_slist_delete_link(filter->list, link);
1401         filter->list = g_slist_append(filter->list, (gpointer)node);
1402         return PMINFO_R_OK;
1403
1404 }
1405
1406 API int pkgmgrinfo_pkginfo_filter_add_bool(pkgmgrinfo_pkginfo_filter_h handle,
1407                                 const char *property, const bool value)
1408 {
1409         char *val;
1410         GSList *link;
1411         int prop;
1412         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1413         pkgmgrinfo_node_x *node;
1414
1415         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1416         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1417
1418         prop = _pminfo_pkginfo_convert_to_prop_bool(property);
1419         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_BOOL ||
1420                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_BOOL) {
1421                 _LOGE("Invalid Boolean Property\n");
1422                 return PMINFO_R_EINVAL;
1423         }
1424         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1425         if (node == NULL) {
1426                 _LOGE("Out of Memory!!!\n");
1427                 return PMINFO_R_ERROR;
1428         }
1429         if (value)
1430                 val = strndup("true", 4);
1431         else
1432                 val = strndup("false", 5);
1433         if (val == NULL) {
1434                 _LOGE("Out of Memory\n");
1435                 free(node);
1436                 return PMINFO_R_ERROR;
1437         }
1438         node->prop = prop;
1439         node->value = val;
1440         /*If API is called multiple times for same property, we should override the previous values.
1441         Last value set will be used for filtering.*/
1442         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1443         if (link)
1444                 filter->list = g_slist_delete_link(filter->list, link);
1445         filter->list = g_slist_append(filter->list, (gpointer)node);
1446         return PMINFO_R_OK;
1447
1448 }
1449
1450 API int pkgmgrinfo_pkginfo_filter_add_string(pkgmgrinfo_pkginfo_filter_h handle,
1451                                 const char *property, const char *value)
1452 {
1453         char *val;
1454         GSList *link;
1455         int prop;
1456         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1457         pkgmgrinfo_node_x *node;
1458
1459         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1460         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1461         retvm_if(value == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1462
1463         prop = _pminfo_pkginfo_convert_to_prop_str(property);
1464         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_STR ||
1465                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_STR) {
1466                 _LOGE("Invalid String Property\n");
1467                 return PMINFO_R_EINVAL;
1468         }
1469         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1470         if (node == NULL) {
1471                 _LOGE("Out of Memory!!!\n");
1472                 return PMINFO_R_ERROR;
1473         }
1474         if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_AUTO) == 0)
1475                 val = strndup("auto", PKG_STRING_LEN_MAX - 1);
1476         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_INTERNAL) == 0)
1477                 val = strndup("internal-only", PKG_STRING_LEN_MAX - 1);
1478         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_EXTERNAL) == 0)
1479                 val = strndup("prefer-external", PKG_STRING_LEN_MAX - 1);
1480         else if (strcmp(value, "installed_internal") == 0)
1481                 val = strndup("installed_internal", PKG_STRING_LEN_MAX - 1);
1482         else if (strcmp(value, "installed_external") == 0)
1483                 val = strndup("installed_external", PKG_STRING_LEN_MAX - 1);
1484         else
1485                 val = strndup(value, PKG_STRING_LEN_MAX - 1);
1486         if (val == NULL) {
1487                 _LOGE("Out of Memory\n");
1488                 free(node);
1489                 return PMINFO_R_ERROR;
1490         }
1491         node->prop = prop;
1492         node->value = val;
1493         /*If API is called multiple times for same property, we should override the previous values.
1494         Last value set will be used for filtering.*/
1495         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1496         if (link)
1497                 filter->list = g_slist_delete_link(filter->list, link);
1498         filter->list = g_slist_append(filter->list, (gpointer)node);
1499         return PMINFO_R_OK;
1500
1501 }
1502
1503 API int pkgmgrinfo_pkginfo_usr_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count, uid_t uid)
1504 {
1505         int ret;
1506         char *locale;
1507         GHashTable *list = NULL;
1508
1509         if (handle == NULL || count == NULL) {
1510                 _LOGE("invalid parameter");
1511                 return PMINFO_R_EINVAL;
1512         }
1513
1514         locale = _get_system_locale();
1515         if (locale == NULL)
1516                 return PMINFO_R_ERROR;
1517
1518         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
1519                         __free_packages);
1520         if (list == NULL) {
1521                 free(locale);
1522                 return PMINFO_R_ERROR;
1523         }
1524
1525         ret = _pkginfo_get_packages(uid, locale,
1526                         (pkgmgrinfo_filter_x *)handle, 0, list);
1527         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
1528                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, handle, 0,
1529                                 list);
1530
1531         if (ret != PMINFO_R_OK) {
1532                 g_hash_table_destroy(list);
1533                 free(locale);
1534                 return PMINFO_R_ERROR;
1535         }
1536
1537         *count = g_hash_table_size(list);
1538
1539         g_hash_table_destroy(list);
1540         free(locale);
1541
1542         return PMINFO_R_OK;
1543 }
1544
1545 API int pkgmgrinfo_pkginfo_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count)
1546 {
1547         return pkgmgrinfo_pkginfo_usr_filter_count(handle, count, _getuid());
1548 }
1549
1550 API int pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(
1551                 pkgmgrinfo_pkginfo_filter_h handle,
1552                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data, uid_t uid)
1553 {
1554         if (handle == NULL || pkg_cb == NULL) {
1555                 LOGE("invalid parameter");
1556                 return PMINFO_R_EINVAL;
1557         }
1558
1559         return _pkginfo_get_filtered_foreach_pkginfo(uid, handle,
1560                         PMINFO_PKGINFO_GET_ALL, pkg_cb, user_data);
1561 }
1562
1563 API int pkgmgrinfo_pkginfo_filter_foreach_pkginfo(pkgmgrinfo_pkginfo_filter_h handle,
1564                                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data)
1565 {
1566         return pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, pkg_cb, user_data, _getuid());
1567 }
1568
1569 API int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle,
1570                         pkgmgrinfo_pkg_privilege_list_cb privilege_func, void *user_data)
1571 {
1572         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1573         retvm_if(privilege_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
1574         int ret;
1575         const char *privilege;
1576         GList *tmp;
1577         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1578
1579         if (info->pkg_info == NULL)
1580                 return PMINFO_R_ERROR;
1581
1582         for (tmp = info->pkg_info->privileges; tmp; tmp = tmp->next) {
1583                 privilege = (const char *)tmp->data;
1584                 if (privilege == NULL)
1585                         continue;
1586                 ret = privilege_func(privilege, user_data);
1587                 if (ret < 0)
1588                         break;
1589         }
1590         return PMINFO_R_OK;
1591 }