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