Implement pkgmgr plugin execution info
[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;
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 (ep = readdir(dp); ep != NULL; ep = readdir(dp)) {
132                 if (!strcmp(ep->d_name, ".") ||
133                         !strcmp(ep->d_name, "..")) {
134                         continue;
135                 }
136                 snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
137                          ep->d_name);
138                 if (lstat(abs_filename, &fileinfo) < 0)
139                         perror(abs_filename);
140                 else {
141                         if (S_ISDIR(fileinfo.st_mode)) {
142                                 total += fileinfo.st_size;
143                                 if (strcmp(ep->d_name, ".")
144                                     && strcmp(ep->d_name, "..")) {
145                                         ret = _pkgmgr_calculate_dir_size
146                                             (abs_filename);
147                                         total = total + ret;
148                                 }
149                         } else if (S_ISLNK(fileinfo.st_mode)) {
150                                 continue;
151                         } else {
152                                 /*It is a file. Calculate the actual
153                                 size occupied (in terms of 4096 blocks)*/
154                         q = (fileinfo.st_size / BLOCK_SIZE);
155                         r = (fileinfo.st_size % BLOCK_SIZE);
156                         if (r)
157                                 q = q + 1;
158                         total += q * BLOCK_SIZE;
159                         }
160                 }
161         }
162         (void)closedir(dp);
163         return total;
164
165 }
166
167 static int _pkginfo_add_description_info_into_list(const char *locale,
168                 char *record, GList **description)
169 {
170         description_x *info;
171
172         info = calloc(1, sizeof(description_x));
173         if (info == NULL) {
174                 LOGE("out of memory");
175                 return PMINFO_R_ERROR;
176         }
177         info->lang = strdup(locale);
178         info->text = record;
179         *description = g_list_append(*description, info);
180
181         return PMINFO_R_OK;
182 }
183
184 static int _pkginfo_get_plugin_execution_info(sqlite3 *db, const char *pkgid,
185                 GList **plugins)
186 {
187         static const char query_raw[] =
188                 "SELECT appid, plugin_type, plugin_name FROM package_plugin_info "
189                 "WHERE pkgid=%Q";
190         int ret;
191         char *query;
192         sqlite3_stmt *stmt;
193         plugin_x *plugin;
194
195         query = sqlite3_mprintf(query_raw, pkgid);
196         if (query == NULL) {
197                 LOGE("out of memory");
198                 return PMINFO_R_ERROR;
199         }
200
201         ret = sqlite3_prepare_v2(db, query, strlen(query),
202                         &stmt, NULL);
203         sqlite3_free(query);
204         if (ret != SQLITE_OK) {
205                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
206                 return PMINFO_R_ERROR;
207         }
208
209         while (sqlite3_step(stmt) == SQLITE_ROW) {
210                 plugin = calloc(1, sizeof(plugin_x));
211                 if (!plugin) {
212                         LOGE("out of memory");
213                         sqlite3_finalize(stmt);
214                         return PMINFO_R_ERROR;
215                 }
216                 plugin->pkgid = strdup(pkgid);
217                 _save_column_str(stmt, 0, &plugin->appid);
218                 _save_column_str(stmt, 1, &plugin->plugin_type);
219                 _save_column_str(stmt, 2, &plugin->plugin_name);
220                 *plugins = g_list_append(*plugins,
221                                 (gpointer)plugin);
222         }
223
224         sqlite3_finalize(stmt);
225
226         return PMINFO_R_OK;
227 }
228
229 static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid,
230                 GList **privileges)
231 {
232         static const char query_raw[] =
233                 "SELECT DISTINCT privilege, type FROM package_privilege_info "
234                 "WHERE package=%Q";
235         int ret;
236         char *query;
237         sqlite3_stmt *stmt;
238         privilege_x *privilege;
239
240         query = sqlite3_mprintf(query_raw, pkgid);
241         if (query == NULL) {
242                 LOGE("out of memory");
243                 return PMINFO_R_ERROR;
244         }
245
246         ret = sqlite3_prepare_v2(db, query, strlen(query),
247                         &stmt, NULL);
248         sqlite3_free(query);
249         if (ret != SQLITE_OK) {
250                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
251                 return PMINFO_R_ERROR;
252         }
253
254         while (sqlite3_step(stmt) == SQLITE_ROW) {
255                 privilege = calloc(1, sizeof(privilege_x));
256                 _save_column_str(stmt, 0, &privilege->value);
257                 _save_column_str(stmt, 1, &privilege->type);
258                 *privileges = g_list_append(*privileges,
259                                 (gpointer)privilege);
260         }
261
262         sqlite3_finalize(stmt);
263
264         return PMINFO_R_OK;
265 }
266
267 static int _pkginfo_get_appdefined_privilege(sqlite3 *db, const char *pkgid,
268                 GList **privileges)
269 {
270         static const char query_raw[] =
271                 "SELECT DISTINCT privilege, license, type FROM "
272                 "package_appdefined_privilege_info WHERE package=%Q";
273         int ret;
274         char *query;
275         sqlite3_stmt *stmt;
276         appdefined_privilege_x *privilege;
277
278         query = sqlite3_mprintf(query_raw, pkgid);
279         if (query == NULL) {
280                 LOGE("out of memory");
281                 return PMINFO_R_ERROR;
282         }
283
284         ret = sqlite3_prepare_v2(db, query, strlen(query),
285                         &stmt, NULL);
286         sqlite3_free(query);
287         if (ret != SQLITE_OK) {
288                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
289                 return PMINFO_R_ERROR;
290         }
291
292         while (sqlite3_step(stmt) == SQLITE_ROW) {
293                 privilege = calloc(1, sizeof(appdefined_privilege_x));
294                 if (!privilege) {
295                         LOGE("failed to alloc memory");
296                         sqlite3_finalize(stmt);
297                         return PMINFO_R_ERROR;
298                 }
299                 _save_column_str(stmt, 0, &privilege->value);
300                 _save_column_str(stmt, 1, &privilege->license);
301                 _save_column_str(stmt, 2, &privilege->type);
302                 *privileges = g_list_append(*privileges,
303                                 (gpointer)privilege);
304         }
305
306         sqlite3_finalize(stmt);
307
308         return PMINFO_R_OK;
309 }
310
311 static int _pkginfo_get_dependency(sqlite3 *db, const char *pkgid,
312                 GList **dependencies)
313 {
314         static const char query[] =
315                 "SELECT DISTINCT depends_on, type, required_version "
316                 "FROM package_dependency_info WHERE package=?";
317         int ret;
318         sqlite3_stmt *stmt;
319         dependency_x *dependency;
320
321         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
322         if (ret != SQLITE_OK) {
323                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
324                 return PMINFO_R_ERROR;
325         }
326
327         while (sqlite3_step(stmt) == SQLITE_ROW) {
328                 dependency = calloc(1, sizeof(dependency_x));
329                 if (!dependency) {
330                         LOGE("failed to alloc memory");
331                         sqlite3_finalize(stmt);
332                         return PMINFO_R_ERROR;
333                 }
334                 _save_column_str(stmt, 0, &dependency->depends_on);
335                 _save_column_str(stmt, 1, &dependency->type);
336                 _save_column_str(stmt, 2, &dependency->required_version);
337                 *dependencies = g_list_append(*dependencies,
338                                 (gpointer)dependency);
339         }
340
341         sqlite3_finalize(stmt);
342
343         return PMINFO_R_OK;
344 }
345
346 static const char join_localized_info[] =
347         " LEFT OUTER JOIN package_localized_info"
348         "  ON pi.package=package_localized_info.package"
349         "  AND package_localized_info.package_locale=?";
350 static const char join_privilege_info[] =
351         " LEFT OUTER JOIN package_privilege_info"
352         "  ON pi.package=package_privilege_info.package";
353
354 static int _get_filtered_query(pkgmgrinfo_filter_x *filter,
355                 const char *locale, uid_t uid, char **query, GList **bind_params)
356 {
357         int joined = 0;
358         char buf[MAX_QUERY_LEN] = { '\0' };
359         char buf2[MAX_QUERY_LEN] = { '\0' };
360         char *condition = NULL;
361         GSList *list = NULL;
362
363         if (filter == NULL)
364                 return PMINFO_R_OK;
365
366         snprintf(buf, sizeof(buf), "%s", " WHERE 1=1 ");
367         for (list = filter->list; list; list = list->next) {
368                 joined |= __get_filter_condition(list->data, uid, &condition,
369                                 bind_params);
370                 if (condition == NULL)
371                         continue;
372
373                 strncat(buf, " AND ", sizeof(buf) - strlen(buf) - 1);
374
375                 strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
376                 free(condition);
377                 condition = NULL;
378         }
379
380         if (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) {
381                 strncat(buf2, join_localized_info, sizeof(buf2) - strlen(buf2) - 1);
382                 *bind_params = g_list_append(*bind_params, strdup(locale));
383         }
384         if (joined & E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO)
385                 strncat(buf2, join_privilege_info, sizeof(buf2) - strlen(buf2) - 1);
386         strncat(buf2, buf, sizeof(buf2) - strlen(buf2) - 1);
387
388         *query = strdup(buf2);
389         if (*query == NULL)
390                 return PMINFO_R_ERROR;
391
392         return PMINFO_R_OK;
393 }
394
395 static void __free_packages(gpointer data)
396 {
397         pkgmgrinfo_basic_free_package((package_x *)data);
398 }
399
400 static bool __check_disable_filter_exist(pkgmgrinfo_filter_x *filter)
401 {
402         GSList *link;
403
404         if (filter == NULL)
405                 return false;
406
407         link = g_slist_find_custom(filter->list, NULL, __pkg_disable_chk_func);
408         if (link)
409                 return true;
410
411         return false;
412 }
413
414 static int __bind_params(sqlite3_stmt *stmt, GList *params)
415 {
416         GList *tmp_list = NULL;
417         int idx = 0;
418         int ret;
419
420         if (stmt == NULL || params == NULL)
421                 return PMINFO_R_EINVAL;
422
423         tmp_list = params;
424         while (tmp_list) {
425                 ret = sqlite3_bind_text(stmt, ++idx, (char *)tmp_list->data, -1, SQLITE_STATIC);
426                 if (ret != SQLITE_OK)
427                         return PMINFO_R_ERROR;
428                 tmp_list = tmp_list->next;
429         }
430
431         return PMINFO_R_OK;
432 }
433
434 static bool __check_package_storage_status(pkgmgrinfo_filter_x *tmp_filter)
435 {
436         GSList *tmp_list = NULL;
437         pkgmgrinfo_node_x *tmp_node = NULL;
438         int property = -1;
439
440         property = _pminfo_pkginfo_convert_to_prop_bool(PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE);
441         for (tmp_list = tmp_filter->list; tmp_list != NULL;
442                         tmp_list = g_slist_next(tmp_list)) {
443                 tmp_node = (pkgmgrinfo_node_x *)tmp_list->data;
444                 if (property == tmp_node->prop) {
445                         if (strcmp(tmp_node->value, "true") == 0)
446                                 return true;
447                         else
448                                 return false;
449                 }
450         }
451         return true;
452 }
453
454 static int _pkginfo_get_packages(uid_t uid, const char *locale,
455                 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages)
456 {
457         static const char query_raw[] =
458                 "SELECT DISTINCT pi.package, pi.installed_storage, pi.external_path";
459         static const char query_basic[] =
460                 ", pi.package_version, pi.install_location, "
461                 "pi.package_removable, pi.package_preload, pi.package_readonly, "
462                 "pi.package_update, pi.package_appsetting, pi.package_system, "
463                 "pi.package_type, pi.package_size, pi.installed_time, "
464                 "pi.storeclient_id, pi.mainapp_id, pi.package_url, pi.root_path, "
465                 "pi.csc_path, pi.package_nodisplay, pi.package_api_version, "
466                 "pi.package_support_disable, pi.package_tep_name, "
467                 "pi.package_zip_mount_file, pi.package_support_mode";
468         static const char query_author[] =
469                 ", pi.author_name, pi.author_email, pi.author_href";
470         static const char query_label[] =
471                 ", COALESCE("
472                 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
473                 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
474         static const char query_icon[] =
475                 ", COALESCE("
476                 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
477                 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
478         static const char query_description[] =
479                 ", COALESCE("
480                 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
481                 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
482         static const char query_from_clause[] = " FROM package_info as pi";
483         int ret = PMINFO_R_ERROR;
484         int idx = 0;
485         char *dbpath;
486         char *tmp_record = NULL;
487         char *constraints = NULL;
488         char query[MAX_QUERY_LEN] = { '\0' };
489         package_x *info = NULL;
490         author_x *author = NULL;
491         GList *bind_params = NULL;
492         sqlite3 *db;
493         sqlite3_stmt *stmt = NULL;
494         pkgmgrinfo_filter_x *tmp_filter = NULL;
495         bool is_check_storage = true;
496         const uid_t global_user_uid = GLOBAL_USER;
497
498         dbpath = getUserPkgParserDBPathUID(uid);
499         if (dbpath == NULL)
500                 return PMINFO_R_ERROR;
501
502         ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
503         if (ret != SQLITE_OK) {
504                 _LOGD("failed to open db(%s): %d", dbpath, ret);
505                 free(dbpath);
506                 return PMINFO_R_ERROR;
507         }
508         free(dbpath);
509
510         if (filter != NULL) {
511                 tmp_filter = filter;
512         } else {
513                 ret = pkgmgrinfo_pkginfo_filter_create((void *)&tmp_filter);
514                 if (ret != PMINFO_R_OK) {
515                         _LOGE("Failed to create filter");
516                         return PMINFO_R_ERROR;
517                 }
518         }
519
520         is_check_storage = __check_package_storage_status(tmp_filter);
521
522         snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
523         if (flag & PMINFO_APPINFO_GET_BASICINFO)
524                 strncat(query, query_basic, sizeof(query) - strlen(query) - 1);
525         if (flag & PMINFO_PKGINFO_GET_AUTHOR)
526                 strncat(query, query_author, sizeof(query) - strlen(query) - 1);
527         if (flag & PMINFO_PKGINFO_GET_LABEL) {
528                 strncat(query, query_label, sizeof(query) - strlen(query) - 1);
529                 bind_params = g_list_append(bind_params, strdup(locale));
530         }
531         if (flag & PMINFO_PKGINFO_GET_ICON) {
532                 strncat(query, query_icon, sizeof(query) - strlen(query) - 1);
533                 bind_params = g_list_append(bind_params, strdup(locale));
534         }
535         if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
536                 strncat(query, query_description, sizeof(query) - strlen(query) - 1);
537                 bind_params = g_list_append(bind_params, strdup(locale));
538         }
539
540         strncat(query, query_from_clause, sizeof(query) - strlen(query) - 1);
541
542         ret = _get_filtered_query(tmp_filter, locale, uid, &constraints, &bind_params);
543         if (ret != PMINFO_R_OK) {
544                 LOGE("Failed to get WHERE clause");
545                 goto catch;
546         }
547
548         if (constraints)
549                 strncat(query, constraints, sizeof(query) - strlen(query) - 1);
550
551         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
552         if (ret != SQLITE_OK) {
553                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
554                 ret = PMINFO_R_ERROR;
555                 goto catch;
556         }
557
558         ret = __bind_params(stmt, bind_params);
559         if (ret != SQLITE_OK) {
560                 LOGE("Failed to bind parameters");
561                 goto catch;
562         }
563
564         while (sqlite3_step(stmt) == SQLITE_ROW) {
565                 info = calloc(1, sizeof(package_x));
566                 if (info == NULL) {
567                         LOGE("out of memory");
568                         ret = PMINFO_R_ERROR;
569                         goto catch;
570                 }
571                 idx = 0;
572                 _save_column_str(stmt, idx++, &info->package);
573                 _save_column_str(stmt, idx++, &info->installed_storage);
574                 _save_column_str(stmt, idx++, &info->external_path);
575
576                 if (flag & PMINFO_APPINFO_GET_BASICINFO) {
577                         _save_column_str(stmt, idx++, &info->version);
578                         _save_column_str(stmt, idx++, &info->installlocation);
579                         _save_column_str(stmt, idx++, &info->removable);
580                         _save_column_str(stmt, idx++, &info->preload);
581                         _save_column_str(stmt, idx++, &info->readonly);
582                         _save_column_str(stmt, idx++, &info->update);
583                         _save_column_str(stmt, idx++, &info->appsetting);
584                         _save_column_str(stmt, idx++, &info->system);
585                         _save_column_str(stmt, idx++, &info->type);
586                         _save_column_str(stmt, idx++, &info->package_size);
587                         _save_column_str(stmt, idx++, &info->installed_time);
588                         _save_column_str(stmt, idx++, &info->storeclient_id);
589                         _save_column_str(stmt, idx++, &info->mainapp_id);
590                         _save_column_str(stmt, idx++, &info->package_url);
591                         _save_column_str(stmt, idx++, &info->root_path);
592                         _save_column_str(stmt, idx++, &info->csc_path);
593                         _save_column_str(stmt, idx++, &info->nodisplay_setting);
594                         _save_column_str(stmt, idx++, &info->api_version);
595                         _save_column_str(stmt, idx++, &info->support_disable);
596                         _save_column_str(stmt, idx++, &info->tep_name);
597                         _save_column_str(stmt, idx++, &info->zip_mount_file);
598                         _save_column_str(stmt, idx++, &info->support_mode);
599                 }
600
601                 info->for_all_users =
602                         strdup((uid != global_user_uid) ? "false" : "true");
603
604                 if (_pkginfo_get_plugin_execution_info(db, info->package, &info->plugin)) {
605                         ret = PMINFO_R_ERROR;
606                         goto catch;
607                 }
608
609                 if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
610                         /* TODO : author should be retrieved at package_localized_info */
611                         author = calloc(1, sizeof(author_x));
612                         if (author == NULL) {
613                                 ret = PMINFO_R_ERROR;
614                                 goto catch;
615                         }
616                         _save_column_str(stmt, idx++, &author->text);
617                         _save_column_str(stmt, idx++, &author->email);
618                         _save_column_str(stmt, idx++, &author->href);
619                         info->author = g_list_append(info->author, author);
620                 }
621
622                 if (flag & PMINFO_PKGINFO_GET_LABEL) {
623                         tmp_record = NULL;
624                         _save_column_str(stmt, idx++, &tmp_record);
625
626                         if (_add_label_info_into_list(locale, tmp_record, &info->label)) {
627                                 ret = PMINFO_R_ERROR;
628                                 goto catch;
629                         }
630                 }
631
632                 if (flag & PMINFO_PKGINFO_GET_ICON) {
633                         tmp_record = NULL;
634                         _save_column_str(stmt, idx++, &tmp_record);
635                         if (_add_icon_info_into_list(locale, tmp_record, &info->icon)) {
636                                 ret = PMINFO_R_ERROR;
637                                 goto catch;
638                         }
639                 }
640
641                 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
642                         tmp_record = NULL;
643                         _save_column_str(stmt, idx++, &tmp_record);
644                         if (_pkginfo_add_description_info_into_list(locale, tmp_record,
645                                         &info->description)) {
646                                 ret = PMINFO_R_ERROR;
647                                 goto catch;
648                         }
649                 }
650
651                 if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) {
652                         if (_pkginfo_get_privilege(db, info->package,
653                                                 &info->privileges)) {
654                                 ret = PMINFO_R_ERROR;
655                                 goto catch;
656                         }
657                 }
658
659                 if (flag & PMINFO_PKGINFO_GET_APPDEFINED_PRIVILEGE) {
660                         if (_pkginfo_get_appdefined_privilege(db, info->package,
661                                                 &info->appdefined_privileges)) {
662                                 ret = PMINFO_R_ERROR;
663                                 goto catch;
664                         }
665                 }
666
667                 if (flag & PMINFO_PKGINFO_GET_DEPENDENCY) {
668                         if (_pkginfo_get_dependency(db, info->package,
669                                                 &info->dependencies)) {
670                                 ret = PMINFO_R_ERROR;
671                                 goto catch;
672                         }
673                 }
674
675                 if (is_check_storage &&
676                                 __pkginfo_check_installed_storage(info) != PMINFO_R_OK) {
677                         ret = PMINFO_R_ERROR;
678                         pkgmgrinfo_basic_free_package(info);
679                         info = NULL;
680                         continue;
681                 }
682
683                 g_hash_table_insert(packages, (gpointer)info->package,
684                                 (gpointer)info);
685         }
686
687         ret = PMINFO_R_OK;
688
689 catch:
690         sqlite3_finalize(stmt);
691         sqlite3_close_v2(db);
692
693         if (constraints)
694                 free(constraints);
695
696         if (ret != PMINFO_R_OK && info != NULL)
697                 pkgmgrinfo_basic_free_package(info);
698
699         if (filter == NULL)
700                 pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
701
702         g_list_free_full(bind_params, free);
703
704         return ret;
705 }
706
707 static int _pkginfo_get_filtered_foreach_pkginfo(uid_t uid,
708                 pkgmgrinfo_filter_x *filter, int flag,
709                 pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data)
710 {
711         int ret;
712         char *locale;
713         package_x *pkg;
714         pkgmgr_pkginfo_x info;
715         pkgmgrinfo_filter_x *tmp_filter = NULL;
716         GHashTable *list;
717         GHashTableIter iter;
718         gpointer value;
719
720         locale = _get_system_locale();
721         if (locale == NULL)
722                 return PMINFO_R_ERROR;
723
724         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
725                         __free_packages);
726         if (list == NULL) {
727                 free(locale);
728                 return PMINFO_R_ERROR;
729         }
730
731         if (filter != NULL) {
732                 tmp_filter = (pkgmgrinfo_filter_x *)filter;
733         } else {
734                 ret = pkgmgrinfo_pkginfo_filter_create((void *)&tmp_filter);
735                 if (ret != PMINFO_R_OK) {
736                         _LOGE("Failed to create filter");
737                         g_hash_table_destroy(list);
738                         free(locale);
739                         return PMINFO_R_ERROR;
740                 }
741         }
742
743         if (__check_disable_filter_exist(tmp_filter) == false) {
744                 ret = pkgmgrinfo_pkginfo_filter_add_bool(tmp_filter,
745                                 PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
746                 if (ret != PMINFO_R_OK) {
747                         _LOGE("Failed to add filter");
748                         g_hash_table_destroy(list);
749                         free(locale);
750                         if (filter == NULL)
751                                 pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
752                         return PMINFO_R_ERROR;
753                 }
754         }
755
756         ret = _pkginfo_get_packages(uid, locale, tmp_filter,
757                         flag | PMINFO_PKGINFO_GET_BASICINFO, list);
758         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
759                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, tmp_filter,
760                                 flag | PMINFO_PKGINFO_GET_BASICINFO, list);
761
762         if (ret != PMINFO_R_OK) {
763                 g_hash_table_destroy(list);
764                 free(locale);
765                 if (filter == NULL)
766                         pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
767                 return PMINFO_R_ERROR;
768         }
769
770         g_hash_table_iter_init(&iter, list);
771         while (g_hash_table_iter_next(&iter, NULL, &value)) {
772                 pkg = (package_x *)value;
773                 info.uid = uid;
774                 info.pkg_info = pkg;
775                 info.locale = locale;
776                 if (pkg_list_cb(&info, user_data) < 0)
777                         break;
778         }
779
780         g_hash_table_destroy(list);
781         free(locale);
782
783         if (filter == NULL)
784                 pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
785
786         return PMINFO_R_OK;
787 }
788
789 static int _pkgmgrinfo_get_pkginfo(const char *pkgid, uid_t uid,
790         pkgmgrinfo_pkginfo_filter_h filter, pkgmgrinfo_pkginfo_h *handle)
791 {
792         int ret;
793         char *locale;
794         GHashTable *list;
795         pkgmgr_pkginfo_x *info;
796
797         if (pkgid == NULL || filter == NULL || handle == NULL) {
798                         LOGE("invalid parameter");
799                         return PMINFO_R_EINVAL;
800         }
801
802         locale = _get_system_locale();
803         if (locale == NULL)
804                 return PMINFO_R_ERROR;
805
806         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
807                         __free_packages);
808         if (list == NULL) {
809                 free(locale);
810                 return PMINFO_R_ERROR;
811         }
812
813         ret = _pkginfo_get_packages(uid, locale, filter,
814                         PMINFO_PKGINFO_GET_ALL, list);
815         if (!g_hash_table_size(list) && uid != GLOBAL_USER)
816                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
817                                 PMINFO_PKGINFO_GET_ALL, list);
818
819         if (ret != PMINFO_R_OK) {
820                 g_hash_table_destroy(list);
821                 free(locale);
822                 return ret;
823         }
824
825         if (!g_hash_table_size(list)) {
826                 _LOGD("pkginfo for [%s] is not existed for user [%d]",
827                                 pkgid, uid);
828                 g_hash_table_destroy(list);
829                 free(locale);
830                 return PMINFO_R_ENOENT;
831         }
832
833         info = calloc(1, sizeof(pkgmgr_pkginfo_x));
834         if (info == NULL) {
835                 _LOGE("out of memory");
836                 g_hash_table_destroy(list);
837                 free(locale);
838                 return PMINFO_R_ERROR;
839         }
840
841         info->uid = uid;
842         info->pkg_info = (package_x *)g_hash_table_lookup(list, pkgid);
843         info->locale = locale;
844
845         /* just free list only */
846         g_hash_table_steal(list, (gconstpointer)pkgid);
847         g_hash_table_destroy(list);
848
849         *handle = info;
850
851         return ret;
852 }
853
854 API int pkgmgrinfo_pkginfo_get_usr_pkginfo(const char *pkgid, uid_t uid,
855                 pkgmgrinfo_pkginfo_h *handle)
856 {
857         int ret;
858         pkgmgrinfo_pkginfo_filter_h filter;
859
860         if (pkgid == NULL || handle == NULL) {
861                 LOGE("invalid parameter");
862                 return PMINFO_R_EINVAL;
863         }
864
865         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
866         if (ret != PMINFO_R_OK)
867                 return ret;
868
869         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
870                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
871         if (ret != PMINFO_R_OK) {
872                 pkgmgrinfo_pkginfo_filter_destroy(filter);
873                 return PMINFO_R_ERROR;
874         }
875
876         ret = pkgmgrinfo_pkginfo_filter_add_bool(filter,
877                         PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
878         if (ret != PMINFO_R_OK) {
879                 pkgmgrinfo_pkginfo_filter_destroy(filter);
880                 return PMINFO_R_ERROR;
881         }
882
883         ret = _pkgmgrinfo_get_pkginfo(pkgid, uid, filter, handle);
884         pkgmgrinfo_pkginfo_filter_destroy(filter);
885
886         return ret;
887 }
888
889 API int pkgmgrinfo_pkginfo_get_pkginfo(const char *pkgid,
890                 pkgmgrinfo_pkginfo_h *handle)
891 {
892         return pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, _getuid(), handle);
893 }
894
895 API int pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(const char *pkgid,
896                 uid_t uid, pkgmgrinfo_pkginfo_h *handle)
897 {
898         int ret;
899         char *locale;
900         GHashTable *list;
901         pkgmgrinfo_pkginfo_filter_h filter;
902         pkgmgr_pkginfo_x *info;
903
904         if (pkgid == NULL || handle == NULL) {
905                 LOGE("invalid parameter");
906                 return PMINFO_R_EINVAL;
907         }
908
909         locale = _get_system_locale();
910         if (locale == NULL)
911                 return PMINFO_R_ERROR;
912
913         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
914         if (ret != PMINFO_R_OK) {
915                 free(locale);
916                 return ret;
917         }
918
919         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
920                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
921         if (ret != PMINFO_R_OK) {
922                 pkgmgrinfo_pkginfo_filter_destroy(filter);
923                 free(locale);
924                 return PMINFO_R_ERROR;
925         }
926
927         ret = pkgmgrinfo_pkginfo_filter_add_bool(filter,
928                         PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, true);
929         if (ret != PMINFO_R_OK) {
930                 pkgmgrinfo_pkginfo_filter_destroy(filter);
931                 free(locale);
932                 return PMINFO_R_ERROR;
933         }
934
935         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
936                         __free_packages);
937         if (list == NULL) {
938                 pkgmgrinfo_pkginfo_filter_destroy(filter);
939                 free(locale);
940                 return PMINFO_R_ERROR;
941         }
942
943         ret = _pkginfo_get_packages(uid, locale, filter,
944                         PMINFO_PKGINFO_GET_ALL, list);
945         if (!g_hash_table_size(list) && uid != GLOBAL_USER)
946                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
947                                 PMINFO_PKGINFO_GET_ALL, list);
948
949         pkgmgrinfo_pkginfo_filter_destroy(filter);
950         if (ret != PMINFO_R_OK) {
951                 g_hash_table_destroy(list);
952                 free(locale);
953                 return ret;
954         }
955
956         if (!g_hash_table_size(list)) {
957                 _LOGD("disabled pkginfo for [%s] is not existed for user [%d]",
958                                 pkgid, uid);
959                 g_hash_table_destroy(list);
960                 free(locale);
961                 return PMINFO_R_ENOENT;
962         }
963
964         info = calloc(1, sizeof(pkgmgr_pkginfo_x));
965         if (info == NULL) {
966                 _LOGE("out of memory");
967                 g_hash_table_destroy(list);
968                 free(locale);
969                 return PMINFO_R_ERROR;
970         }
971
972         info->uid = uid;
973         info->pkg_info = (package_x *)g_hash_table_lookup(list, pkgid);
974         info->locale = locale;
975
976         /* just free list only */
977         g_hash_table_steal(list, (gconstpointer)pkgid);
978         g_hash_table_destroy(list);
979
980         *handle = info;
981
982         return ret;
983 }
984
985 API int pkgmgrinfo_pkginfo_get_usr_all_pkginfo(const char *pkgid, uid_t uid,
986                 pkgmgrinfo_pkginfo_h *handle)
987 {
988
989         int ret;
990         pkgmgrinfo_pkginfo_filter_h filter;
991
992         if (pkgid == NULL || handle == NULL) {
993                 LOGE("invalid parameter");
994                 return PMINFO_R_EINVAL;
995         }
996
997         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
998         if (ret != PMINFO_R_OK)
999                 return ret;
1000
1001         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
1002                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
1003         if (ret != PMINFO_R_OK) {
1004                 pkgmgrinfo_pkginfo_filter_destroy(filter);
1005                 return PMINFO_R_ERROR;
1006         }
1007
1008         ret = pkgmgrinfo_pkginfo_filter_add_bool(filter,
1009                         PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE, false);
1010         if (ret != PMINFO_R_OK) {
1011                 pkgmgrinfo_pkginfo_filter_destroy(filter);
1012                 return PMINFO_R_ERROR;
1013         }
1014
1015         ret = _pkgmgrinfo_get_pkginfo(pkgid, uid, filter, handle);
1016         pkgmgrinfo_pkginfo_filter_destroy(filter);
1017
1018         return ret;
1019 }
1020
1021 API int pkgmgrinfo_pkginfo_get_disabled_pkginfo(const char *pkgid,
1022                 pkgmgrinfo_pkginfo_h *handle)
1023 {
1024         return pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(pkgid, _getuid(),
1025                         handle);
1026 }
1027
1028 API int pkgmgrinfo_pkginfo_get_all_pkginfo(const char *pkgid,
1029                 pkgmgrinfo_pkginfo_h *handle)
1030 {
1031         return pkgmgrinfo_pkginfo_get_usr_all_pkginfo(pkgid, _getuid(), handle);
1032 }
1033
1034 API int pkgmgrinfo_pkginfo_get_usr_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
1035                 int flag, void *user_data, uid_t uid)
1036 {
1037         int ret;
1038         pkgmgrinfo_pkginfo_filter_h filter;
1039
1040         if (pkg_list_cb == NULL) {
1041                 LOGE("invalid parameter");
1042                 return PMINFO_R_EINVAL;
1043         }
1044
1045         /* create an empty filter */
1046         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
1047         if (ret != PMINFO_R_OK)
1048                 return ret;
1049
1050         ret = _pkginfo_get_filtered_foreach_pkginfo(uid, filter, flag,
1051                         pkg_list_cb, user_data);
1052
1053         pkgmgrinfo_pkginfo_filter_destroy(filter);
1054
1055         return ret;
1056 }
1057
1058 API int pkgmgrinfo_pkginfo_get_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
1059                 int flag, void *user_data)
1060 {
1061         return pkgmgrinfo_pkginfo_get_usr_list_full(pkg_list_cb, flag,
1062                         user_data, _getuid());
1063 }
1064
1065 API int pkgmgrinfo_pkginfo_get_usr_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
1066                 void *user_data, uid_t uid)
1067 {
1068         int ret;
1069         pkgmgrinfo_pkginfo_filter_h filter;
1070
1071         if (pkg_list_cb == NULL) {
1072                 LOGE("invalid parameter");
1073                 return PMINFO_R_EINVAL;
1074         }
1075
1076         /* create an empty filter */
1077         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
1078         if (ret != PMINFO_R_OK)
1079                 return ret;
1080
1081         ret = _pkginfo_get_filtered_foreach_pkginfo(uid, filter,
1082                         PMINFO_PKGINFO_GET_ALL, pkg_list_cb, user_data);
1083
1084         pkgmgrinfo_pkginfo_filter_destroy(filter);
1085
1086         return ret;
1087 }
1088
1089 API int pkgmgrinfo_pkginfo_get_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
1090                 void *user_data)
1091 {
1092         return pkgmgrinfo_pkginfo_get_usr_list(pkg_list_cb, user_data,
1093                         _getuid());
1094 }
1095
1096 API int pkgmgrinfo_pkginfo_get_usr_disabled_list(
1097                 pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data, uid_t uid)
1098 {
1099         int ret;
1100         pkgmgrinfo_pkginfo_filter_h filter;
1101
1102         if (pkg_list_cb == NULL) {
1103                 LOGE("invalid parameter");
1104                 return PMINFO_R_EINVAL;
1105         }
1106
1107         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
1108         if (ret != PMINFO_R_OK)
1109                 return ret;
1110
1111         ret = pkgmgrinfo_pkginfo_filter_add_bool(filter,
1112                         PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, true);
1113         if (ret != PMINFO_R_OK) {
1114                 pkgmgrinfo_pkginfo_filter_destroy(filter);
1115                 return PMINFO_R_ERROR;
1116         }
1117
1118         ret = _pkginfo_get_filtered_foreach_pkginfo(uid, filter,
1119                         PMINFO_PKGINFO_GET_ALL, pkg_list_cb, user_data);
1120
1121         pkgmgrinfo_pkginfo_filter_destroy(filter);
1122
1123         return ret;
1124 }
1125
1126 API int pkgmgrinfo_pkginfo_get_disabled_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
1127                 void *user_data)
1128 {
1129         return pkgmgrinfo_pkginfo_get_usr_disabled_list(pkg_list_cb, user_data,
1130                         _getuid());
1131 }
1132
1133 API int pkgmgrinfo_pkginfo_get_pkgname(pkgmgrinfo_pkginfo_h handle, char **pkg_name)
1134 {
1135         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1136
1137         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1138         retvm_if(pkg_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1139
1140         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
1141                 return PMINFO_R_ERROR;
1142
1143         *pkg_name = (char *)info->pkg_info->package;
1144
1145         return PMINFO_R_OK;
1146 }
1147
1148 API int pkgmgrinfo_pkginfo_get_pkgid(pkgmgrinfo_pkginfo_h handle, char **pkgid)
1149 {
1150         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1151
1152         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1153         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1154
1155         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
1156                 return PMINFO_R_ERROR;
1157
1158         *pkgid = (char *)info->pkg_info->package;
1159
1160         return PMINFO_R_OK;
1161 }
1162
1163 API int pkgmgrinfo_pkginfo_get_type(pkgmgrinfo_pkginfo_h handle, char **type)
1164 {
1165         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1166
1167         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1168         retvm_if(type == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1169
1170         if (info->pkg_info == NULL)
1171                 return PMINFO_R_ERROR;
1172
1173         if (info->pkg_info->type == NULL)
1174                 *type = "";
1175         else
1176                 *type = (char *)info->pkg_info->type;
1177
1178         return PMINFO_R_OK;
1179 }
1180
1181 API int pkgmgrinfo_pkginfo_get_version(pkgmgrinfo_pkginfo_h handle, char **version)
1182 {
1183         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1184
1185         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1186         retvm_if(version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1187
1188         if (info->pkg_info == NULL)
1189                 return PMINFO_R_ERROR;
1190
1191         if (info->pkg_info->version == NULL)
1192                 *version = "";
1193         else
1194                 *version = (char *)info->pkg_info->version;
1195
1196         return PMINFO_R_OK;
1197 }
1198
1199 API int pkgmgrinfo_pkginfo_get_api_version(pkgmgrinfo_pkginfo_h handle, char **api_version)
1200 {
1201         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1202
1203         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1204         retvm_if(api_version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1205
1206         if (info->pkg_info == NULL)
1207                 return PMINFO_R_ERROR;
1208
1209         if (info->pkg_info->api_version == NULL)
1210                 *api_version = "";
1211         else
1212                 *api_version = (char *)info->pkg_info->api_version;
1213
1214         return PMINFO_R_OK;
1215 }
1216
1217 API int pkgmgrinfo_pkginfo_get_tep_name(pkgmgrinfo_pkginfo_h handle, char **tep_name)
1218 {
1219         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1220
1221         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1222         retvm_if(tep_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1223
1224         if (info->pkg_info == NULL || info->pkg_info->tep_name == NULL)
1225                 return PMINFO_R_ERROR;
1226
1227         *tep_name = (char *)info->pkg_info->tep_name;
1228
1229         return PMINFO_R_OK;
1230 }
1231
1232 API int pkgmgrinfo_pkginfo_get_zip_mount_file(pkgmgrinfo_pkginfo_h handle, char **zip_mount_file)
1233 {
1234         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1235
1236         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1237         retvm_if(zip_mount_file == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1238
1239         if (info->pkg_info == NULL)
1240                 return PMINFO_R_ERROR;
1241
1242         if (info->pkg_info->zip_mount_file == NULL)
1243                 *zip_mount_file = "";
1244         else
1245                 *zip_mount_file = (char *)info->pkg_info->zip_mount_file;
1246
1247         return PMINFO_R_OK;
1248 }
1249
1250 API int pkgmgrinfo_pkginfo_get_external_image_path(pkgmgrinfo_pkginfo_h handle, char **ext_image_path)
1251 {
1252         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1253
1254         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1255         retvm_if(ext_image_path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1256
1257         if (info->pkg_info == NULL)
1258                 return PMINFO_R_ERROR;
1259
1260         if (info->pkg_info->external_path == NULL)
1261                 return PMINFO_R_ENOENT;
1262
1263         *ext_image_path = (char *)info->pkg_info->external_path;
1264
1265         return PMINFO_R_OK;
1266 }
1267
1268 API int pkgmgrinfo_pkginfo_get_install_location(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_install_location *location)
1269 {
1270         char *val;
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(location == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1275
1276         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
1277                 return PMINFO_R_ERROR;
1278
1279         val = (char *)info->pkg_info->installlocation;
1280         if (strcmp(val, "internal-only") == 0)
1281                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
1282         else if (strcmp(val, "prefer-external") == 0)
1283                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
1284         else
1285                 *location = PMINFO_INSTALL_LOCATION_AUTO;
1286
1287         return PMINFO_R_OK;
1288 }
1289
1290 API int pkgmgrinfo_pkginfo_get_package_size(pkgmgrinfo_pkginfo_h handle, int *size)
1291 {
1292         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1293         char *temp = NULL;
1294
1295         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1296         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1297
1298         if (info->pkg_info == NULL)
1299                 return PMINFO_R_ERROR;
1300
1301         if (info->pkg_info->package_size == NULL) {
1302                 temp = strdup("");
1303                 if (temp == NULL) {
1304                         _LOGE("out of memory");
1305                         return PMINFO_R_ERROR;
1306                 } else {
1307                         info->pkg_info->package_size = temp;
1308                 }
1309         }
1310
1311         *size = atoi((char *)info->pkg_info->package_size);
1312
1313         return PMINFO_R_OK;
1314 }
1315
1316 API int pkgmgrinfo_pkginfo_get_icon(pkgmgrinfo_pkginfo_h handle, char **icon)
1317 {
1318         icon_x *ptr;
1319         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1320
1321         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1322         retvm_if(icon == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1323
1324         if (info->pkg_info == NULL || info->pkg_info->icon == NULL)
1325                 return PMINFO_R_ERROR;
1326
1327         ptr = (icon_x *)info->pkg_info->icon->data;
1328         if (ptr == NULL)
1329                 return PMINFO_R_ERROR;
1330
1331         /* TODO : should we return empty string if there was no icon? */
1332         if (ptr->text == NULL)
1333                 *icon = "";
1334         else
1335                 *icon = ptr->text;
1336
1337         return PMINFO_R_OK;
1338 }
1339
1340 API int pkgmgrinfo_pkginfo_get_label(pkgmgrinfo_pkginfo_h handle, char **label)
1341 {
1342         label_x *ptr;
1343         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1344
1345         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1346         retvm_if(label == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1347
1348         if (info->pkg_info == NULL || info->pkg_info->label == NULL)
1349                 return PMINFO_R_ERROR;
1350
1351         ptr = (label_x *)info->pkg_info->label->data;
1352         if (ptr == NULL)
1353                 return PMINFO_R_ERROR;
1354
1355         /* TODO : should we return empty string if there was no label? */
1356         if (ptr->text == NULL)
1357                 *label = "";
1358         else
1359                 *label = ptr->text;
1360
1361         return PMINFO_R_OK;
1362 }
1363
1364 API int pkgmgrinfo_pkginfo_get_description(pkgmgrinfo_pkginfo_h handle, char **description)
1365 {
1366         description_x *ptr;
1367         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1368
1369         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1370         retvm_if(description == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1371
1372         if (info->pkg_info == NULL || info->pkg_info->description == NULL)
1373                 return PMINFO_R_ERROR;
1374
1375         ptr = (description_x *)info->pkg_info->description->data;
1376         if (ptr == NULL)
1377                 return PMINFO_R_ERROR;
1378
1379         if (ptr->text == NULL)
1380                 *description = "";
1381         else
1382                 *description = (char *)ptr->text;
1383
1384         return PMINFO_R_OK;
1385 }
1386
1387 API int pkgmgrinfo_pkginfo_get_author_name(pkgmgrinfo_pkginfo_h handle, char **author_name)
1388 {
1389         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1390         author_x *author;
1391
1392         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1393         retvm_if(author_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1394
1395         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1396                 return PMINFO_R_ERROR;
1397
1398         author = (author_x *)info->pkg_info->author->data;
1399         if (author == NULL)
1400                 return PMINFO_R_ERROR;
1401
1402         if (author->text == NULL)
1403                 *author_name = "";
1404         else
1405                 *author_name = (char *)author->text;
1406
1407         return PMINFO_R_OK;
1408 }
1409
1410 API int pkgmgrinfo_pkginfo_get_author_email(pkgmgrinfo_pkginfo_h handle, char **author_email)
1411 {
1412         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1413         author_x *author;
1414
1415         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1416         retvm_if(author_email == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1417
1418         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1419                 return PMINFO_R_ERROR;
1420
1421         author = (author_x *)info->pkg_info->author->data;
1422         if (author == NULL)
1423                 return PMINFO_R_ERROR;
1424
1425         if (author->email == NULL)
1426                 *author_email = "";
1427         else
1428                 *author_email = (char *)author->email;
1429
1430         return PMINFO_R_OK;
1431 }
1432
1433 API int pkgmgrinfo_pkginfo_get_author_href(pkgmgrinfo_pkginfo_h handle, char **author_href)
1434 {
1435         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1436         author_x *author;
1437
1438         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1439         retvm_if(author_href == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1440
1441         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1442                 return PMINFO_R_ERROR;
1443
1444         author = (author_x *)info->pkg_info->author->data;
1445         if (author == NULL)
1446                 return PMINFO_R_ERROR;
1447
1448         if (author->href == NULL)
1449                 *author_href = "";
1450         else
1451                 *author_href = (char *)author->href;
1452
1453         return PMINFO_R_OK;
1454 }
1455
1456 API int pkgmgrinfo_pkginfo_get_installed_storage(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_installed_storage *storage)
1457 {
1458         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1459
1460         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1461         retvm_if(storage == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1462
1463         if (info->pkg_info == NULL || info->pkg_info->installed_storage == NULL)
1464                 return PMINFO_R_ERROR;
1465
1466         if (strcmp(info->pkg_info->installed_storage, "installed_internal") == 0)
1467                 *storage = PMINFO_INTERNAL_STORAGE;
1468         else if (strcmp(info->pkg_info->installed_storage, "installed_external") == 0)
1469                 *storage = PMINFO_EXTERNAL_STORAGE;
1470         else if (strcmp(info->pkg_info->installed_storage, "installed_extended") == 0)
1471                 *storage = PMINFO_EXTENDED_STORAGE;
1472         else
1473                 return PMINFO_R_ERROR;
1474
1475         return PMINFO_R_OK;
1476 }
1477
1478 API int pkgmgrinfo_pkginfo_get_installed_time(pkgmgrinfo_pkginfo_h handle, int *installed_time)
1479 {
1480         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1481
1482         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1483         retvm_if(installed_time == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1484
1485         if (info->pkg_info == NULL || info->pkg_info->installed_time == NULL)
1486                 return PMINFO_R_ERROR;
1487
1488         *installed_time = atoi(info->pkg_info->installed_time);
1489
1490         return PMINFO_R_OK;
1491 }
1492
1493 API int pkgmgrinfo_pkginfo_get_storeclientid(pkgmgrinfo_pkginfo_h handle, char **storeclientid)
1494 {
1495         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1496
1497         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1498         retvm_if(storeclientid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1499
1500         if (info->pkg_info == NULL)
1501                 return PMINFO_R_ERROR;
1502
1503         if (info->pkg_info->storeclient_id == NULL)
1504                 *storeclientid = "";
1505         else
1506                 *storeclientid = (char *)info->pkg_info->storeclient_id;
1507
1508         return PMINFO_R_OK;
1509 }
1510
1511 API int pkgmgrinfo_pkginfo_get_mainappid(pkgmgrinfo_pkginfo_h handle, char **mainappid)
1512 {
1513         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1514
1515         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1516         retvm_if(mainappid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1517
1518         if (info->pkg_info == NULL || info->pkg_info->mainapp_id == NULL)
1519                 return PMINFO_R_ERROR;
1520
1521         *mainappid = (char *)info->pkg_info->mainapp_id;
1522
1523         return PMINFO_R_OK;
1524 }
1525
1526 API int pkgmgrinfo_pkginfo_get_url(pkgmgrinfo_pkginfo_h handle, char **url)
1527 {
1528         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1529
1530         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1531         retvm_if(url == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1532
1533         if (info->pkg_info == NULL)
1534                 return PMINFO_R_ERROR;
1535
1536         if (info->pkg_info->package_url == NULL)
1537                 *url = "";
1538         else
1539                 *url = (char *)info->pkg_info->package_url;
1540
1541         return PMINFO_R_OK;
1542 }
1543
1544 API int pkgmgrinfo_pkginfo_get_root_path(pkgmgrinfo_pkginfo_h handle, char **path)
1545 {
1546         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1547
1548         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1549         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1550
1551         if (info->pkg_info == NULL || info->pkg_info->root_path == NULL)
1552                 return PMINFO_R_ERROR;
1553
1554         *path = (char *)info->pkg_info->root_path;
1555
1556         return PMINFO_R_OK;
1557 }
1558
1559 API int pkgmgrinfo_pkginfo_get_csc_path(pkgmgrinfo_pkginfo_h handle, char **path)
1560 {
1561         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1562
1563         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1564         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1565
1566         if (info->pkg_info == NULL)
1567                 return PMINFO_R_ERROR;
1568
1569         if (info->pkg_info->csc_path == NULL)
1570                 *path = "";
1571         else
1572                 *path = (char *)info->pkg_info->csc_path;
1573
1574         return PMINFO_R_OK;
1575 }
1576
1577 API int pkgmgrinfo_pkginfo_get_support_mode(pkgmgrinfo_pkginfo_h handle, int *support_mode)
1578 {
1579         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1580         retvm_if(support_mode == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1581
1582         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1583         if (info->pkg_info->support_mode)
1584                 *support_mode = atoi(info->pkg_info->support_mode);
1585         else
1586                 *support_mode = 0;
1587
1588         return PMINFO_R_OK;
1589 }
1590
1591 API int pkgmgrinfo_pkginfo_is_accessible(pkgmgrinfo_pkginfo_h handle, bool *accessible)
1592 {
1593         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1594         retvm_if(accessible == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1595
1596 #if 0 /* smack issue occured, check later */
1597         char *pkgid = NULL;
1598         pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
1599         if (pkgid == NULL) {
1600                  _LOGD("invalid func parameters\n");
1601                  return PMINFO_R_ERROR;
1602         }
1603          _LOGD("pkgmgr_get_pkg_external_validation() called\n");
1604
1605         FILE *fp = NULL;
1606         char app_mmc_path[FILENAME_MAX] = { 0, };
1607         char app_dir_path[FILENAME_MAX] = { 0, };
1608         char app_mmc_internal_path[FILENAME_MAX] = { 0, };
1609         snprintf(app_dir_path, FILENAME_MAX, "%s%s", PKG_INSTALLATION_PATH, pkgid);
1610         snprintf(app_mmc_path, FILENAME_MAX, "%s%s", PKG_SD_PATH, pkgid);
1611         snprintf(app_mmc_internal_path, FILENAME_MAX, "%s%s/.mmc", PKG_INSTALLATION_PATH, pkgid);
1612
1613         /*check whether application is in external memory or not */
1614         fp = fopen(app_mmc_path, "r");
1615         if (fp == NULL) {
1616                 _LOGD(" app path in external memory not accesible\n");
1617         } else {
1618                 fclose(fp);
1619                 fp = NULL;
1620                 *accessible = 1;
1621                 _LOGD("pkgmgr_get_pkg_external_validation() : SD_CARD \n");
1622                 return PMINFO_R_OK;
1623         }
1624
1625         /*check whether application is in internal or not */
1626         if (fp == NULL) {
1627                 _LOGD(" app path in internal memory not accesible\n");
1628                 *accessible = 0;
1629                 return PMINFO_R_ERROR;
1630         } else {
1631                 fclose(fp);
1632                 /*check whether the application is installed in SD card
1633                 but SD card is not present*/
1634                 fp = fopen(app_mmc_internal_path, "r");
1635                 if (fp == NULL) {
1636                         *accessible = 1;
1637                         _LOGD("pkgmgr_get_pkg_external_validation() : INTERNAL_MEM \n");
1638                         return PMINFO_R_OK;
1639                 } else {
1640                         *accessible = 0;
1641                         _LOGD("pkgmgr_get_pkg_external_validation() : ERROR_MMC_STATUS \n");
1642                 }
1643                 fclose(fp);
1644         }
1645
1646         _LOGD("pkgmgr_get_pkg_external_validation() end\n");
1647 #endif
1648
1649         *accessible = 1;
1650         return PMINFO_R_OK;
1651 }
1652
1653 API int pkgmgrinfo_pkginfo_is_removable(pkgmgrinfo_pkginfo_h handle, bool *removable)
1654 {
1655         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1656
1657         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1658         retvm_if(removable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1659
1660         if (info->pkg_info == NULL || info->pkg_info->removable == NULL)
1661                 return PMINFO_R_ERROR;
1662
1663         *removable = _get_bool_value(info->pkg_info->removable);
1664
1665         return PMINFO_R_OK;
1666 }
1667
1668 API int pkgmgrinfo_pkginfo_is_movable(pkgmgrinfo_pkginfo_h handle, bool *movable)
1669 {
1670         char *val;
1671         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1672
1673         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1674         retvm_if(movable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1675
1676         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
1677                 return PMINFO_R_ERROR;
1678
1679         val = (char *)info->pkg_info->installlocation;
1680         if (strcmp(val, "internal-only") == 0)
1681                 *movable = 0;
1682         else
1683                 *movable = 1;
1684
1685         return PMINFO_R_OK;
1686 }
1687
1688 API int pkgmgrinfo_pkginfo_is_preload(pkgmgrinfo_pkginfo_h handle, bool *preload)
1689 {
1690         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1691
1692         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1693         retvm_if(preload == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1694
1695         if (info->pkg_info == NULL || info->pkg_info->preload == NULL)
1696                 return PMINFO_R_ERROR;
1697
1698         *preload = _get_bool_value(info->pkg_info->preload);
1699
1700         return PMINFO_R_OK;
1701 }
1702
1703 API int pkgmgrinfo_pkginfo_is_system(pkgmgrinfo_pkginfo_h handle, bool *system)
1704 {
1705         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1706
1707         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1708         retvm_if(system == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1709
1710         if (info->pkg_info == NULL || info->pkg_info->system == NULL)
1711                 return PMINFO_R_ERROR;
1712
1713         *system = _get_bool_value(info->pkg_info->system);
1714
1715         return PMINFO_R_OK;
1716 }
1717
1718 API int pkgmgrinfo_pkginfo_is_readonly(pkgmgrinfo_pkginfo_h handle, bool *readonly)
1719 {
1720         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1721
1722         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1723         retvm_if(readonly == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1724
1725         if (info->pkg_info == NULL || info->pkg_info->readonly == NULL)
1726                 return PMINFO_R_ERROR;
1727
1728         *readonly = _get_bool_value(info->pkg_info->readonly);
1729
1730         return PMINFO_R_OK;
1731 }
1732
1733 API int pkgmgrinfo_pkginfo_is_update(pkgmgrinfo_pkginfo_h handle, bool *update)
1734 {
1735         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1736
1737         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1738         retvm_if(update == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1739
1740         if (info->pkg_info == NULL || info->pkg_info->update == NULL)
1741                 return PMINFO_R_ERROR;
1742
1743         *update = _get_bool_value(info->pkg_info->update);
1744
1745         return PMINFO_R_OK;
1746 }
1747
1748 API int pkgmgrinfo_pkginfo_is_support_disable(pkgmgrinfo_pkginfo_h handle, bool *support_disable)
1749 {
1750         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1751
1752         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1753         retvm_if(support_disable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1754
1755         if (info->pkg_info == NULL || info->pkg_info->support_disable == NULL)
1756                 return PMINFO_R_ERROR;
1757
1758         *support_disable = _get_bool_value(info->pkg_info->support_disable);
1759
1760         return PMINFO_R_OK;
1761 }
1762
1763 API int pkgmgrinfo_pkginfo_is_global(pkgmgrinfo_pkginfo_h handle, bool *global)
1764 {
1765         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1766
1767         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1768         retvm_if(global == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1769
1770         if (info->pkg_info == NULL || info->pkg_info->for_all_users == NULL)
1771                 return PMINFO_R_ERROR;
1772
1773         *global = _get_bool_value(info->pkg_info->for_all_users);
1774
1775         return PMINFO_R_OK;
1776 }
1777
1778 API int pkgmgrinfo_pkginfo_is_for_all_users(pkgmgrinfo_pkginfo_h handle, bool *for_all_users)
1779 {
1780         return pkgmgrinfo_pkginfo_is_global(handle, for_all_users);
1781 }
1782
1783 API int pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo_h handle)
1784 {
1785         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1786
1787         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1788
1789         __cleanup_pkginfo(info);
1790
1791         return PMINFO_R_OK;
1792 }
1793
1794 API int pkgmgrinfo_pkginfo_filter_create(pkgmgrinfo_pkginfo_filter_h *handle)
1795 {
1796         pkgmgrinfo_filter_x *filter;
1797
1798         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle output parameter is NULL\n");
1799
1800         filter = (pkgmgrinfo_filter_x *)calloc(1, sizeof(pkgmgrinfo_filter_x));
1801         if (filter == NULL) {
1802                 _LOGE("Out of Memory!!!");
1803                 return PMINFO_R_ERROR;
1804         }
1805
1806         *handle = filter;
1807
1808         return PMINFO_R_OK;
1809 }
1810
1811 API int pkgmgrinfo_pkginfo_filter_destroy(pkgmgrinfo_pkginfo_filter_h handle)
1812 {
1813         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1814
1815         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1816
1817         if (filter->list) {
1818                 g_slist_foreach(filter->list, __destroy_each_node, NULL);
1819                 g_slist_free(filter->list);
1820         }
1821
1822         g_slist_free_full(filter->list_metadata, __destroy_metadata_node);
1823
1824         free(filter);
1825
1826         return PMINFO_R_OK;
1827 }
1828
1829 API int pkgmgrinfo_pkginfo_filter_add_int(pkgmgrinfo_pkginfo_filter_h handle,
1830                                 const char *property, const int value)
1831 {
1832         char buf[PKG_VALUE_STRING_LEN_MAX] = {'\0'};
1833         char *val;
1834         GSList *link;
1835         int prop;
1836         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1837         pkgmgrinfo_node_x *node;
1838
1839         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1840         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1841
1842         prop = _pminfo_pkginfo_convert_to_prop_int(property);
1843         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_INT ||
1844                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_INT) {
1845                 _LOGE("Invalid Integer Property\n");
1846                 return PMINFO_R_EINVAL;
1847         }
1848         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1849         if (node == NULL) {
1850                 _LOGE("Out of Memory!!!\n");
1851                 return PMINFO_R_ERROR;
1852         }
1853         snprintf(buf, PKG_VALUE_STRING_LEN_MAX - 1, "%d", value);
1854         val = strndup(buf, PKG_VALUE_STRING_LEN_MAX - 1);
1855         if (val == NULL) {
1856                 _LOGE("Out of Memory\n");
1857                 free(node);
1858                 return PMINFO_R_ERROR;
1859         }
1860         node->prop = prop;
1861         node->value = val;
1862         /*If API is called multiple times for same property, we should override the previous values.
1863         Last value set will be used for filtering.*/
1864         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1865         if (link)
1866                 filter->list = g_slist_delete_link(filter->list, link);
1867         filter->list = g_slist_append(filter->list, (gpointer)node);
1868         return PMINFO_R_OK;
1869
1870 }
1871
1872 API int pkgmgrinfo_pkginfo_filter_add_bool(pkgmgrinfo_pkginfo_filter_h handle,
1873                                 const char *property, const bool value)
1874 {
1875         char *val;
1876         GSList *link;
1877         int prop;
1878         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1879         pkgmgrinfo_node_x *node;
1880
1881         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1882         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1883
1884         prop = _pminfo_pkginfo_convert_to_prop_bool(property);
1885         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_BOOL ||
1886                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_BOOL) {
1887                 _LOGE("Invalid Boolean Property\n");
1888                 return PMINFO_R_EINVAL;
1889         }
1890         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1891         if (node == NULL) {
1892                 _LOGE("Out of Memory!!!\n");
1893                 return PMINFO_R_ERROR;
1894         }
1895         if (value)
1896                 val = strndup("true", 4);
1897         else
1898                 val = strndup("false", 5);
1899         if (val == NULL) {
1900                 _LOGE("Out of Memory\n");
1901                 free(node);
1902                 return PMINFO_R_ERROR;
1903         }
1904         node->prop = prop;
1905         node->value = val;
1906         /*If API is called multiple times for same property, we should override the previous values.
1907         Last value set will be used for filtering.*/
1908         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1909         if (link)
1910                 filter->list = g_slist_delete_link(filter->list, link);
1911         filter->list = g_slist_append(filter->list, (gpointer)node);
1912         return PMINFO_R_OK;
1913
1914 }
1915
1916 API int pkgmgrinfo_pkginfo_filter_add_string(pkgmgrinfo_pkginfo_filter_h handle,
1917                                 const char *property, const char *value)
1918 {
1919         char *val;
1920         GSList *link;
1921         int prop;
1922         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1923         pkgmgrinfo_node_x *node;
1924
1925         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1926         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1927         retvm_if(value == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1928
1929         prop = _pminfo_pkginfo_convert_to_prop_str(property);
1930         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_STR ||
1931                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_STR) {
1932                 _LOGE("Invalid String Property\n");
1933                 return PMINFO_R_EINVAL;
1934         }
1935         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1936         if (node == NULL) {
1937                 _LOGE("Out of Memory!!!\n");
1938                 return PMINFO_R_ERROR;
1939         }
1940         if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_AUTO) == 0)
1941                 val = strndup("auto", PKG_STRING_LEN_MAX - 1);
1942         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_INTERNAL) == 0)
1943                 val = strndup("internal-only", PKG_STRING_LEN_MAX - 1);
1944         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_EXTERNAL) == 0)
1945                 val = strndup("prefer-external", PKG_STRING_LEN_MAX - 1);
1946         else if (strcmp(value, "installed_internal") == 0)
1947                 val = strndup("installed_internal", PKG_STRING_LEN_MAX - 1);
1948         else if (strcmp(value, "installed_external") == 0)
1949                 val = strndup("installed_external", PKG_STRING_LEN_MAX - 1);
1950         else
1951                 val = strndup(value, PKG_STRING_LEN_MAX - 1);
1952         if (val == NULL) {
1953                 _LOGE("Out of Memory\n");
1954                 free(node);
1955                 return PMINFO_R_ERROR;
1956         }
1957         node->prop = prop;
1958         node->value = val;
1959         /*If API is called multiple times for same property, we should override the previous values.
1960         Last value set will be used for filtering.*/
1961         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1962         if (link)
1963                 filter->list = g_slist_delete_link(filter->list, link);
1964         filter->list = g_slist_append(filter->list, (gpointer)node);
1965         return PMINFO_R_OK;
1966
1967 }
1968
1969 API int pkgmgrinfo_pkginfo_usr_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count, uid_t uid)
1970 {
1971         int ret;
1972         char *locale;
1973         GHashTable *list = NULL;
1974
1975         if (handle == NULL || count == NULL) {
1976                 _LOGE("invalid parameter");
1977                 return PMINFO_R_EINVAL;
1978         }
1979
1980         locale = _get_system_locale();
1981         if (locale == NULL)
1982                 return PMINFO_R_ERROR;
1983
1984         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
1985                         __free_packages);
1986         if (list == NULL) {
1987                 free(locale);
1988                 return PMINFO_R_ERROR;
1989         }
1990
1991         if (__check_disable_filter_exist((pkgmgrinfo_filter_x *)handle) == false) {
1992                 ret = pkgmgrinfo_pkginfo_filter_add_bool(handle,
1993                                 PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
1994                 if (ret != PMINFO_R_OK) {
1995                         free(locale);
1996                         g_hash_table_destroy(list);
1997                         return PMINFO_R_ERROR;
1998                 }
1999         }
2000
2001         ret = _pkginfo_get_packages(uid, locale,
2002                         (pkgmgrinfo_filter_x *)handle, 0, list);
2003         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
2004                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, handle, 0,
2005                                 list);
2006
2007         if (ret != PMINFO_R_OK) {
2008                 g_hash_table_destroy(list);
2009                 free(locale);
2010                 return PMINFO_R_ERROR;
2011         }
2012
2013         *count = g_hash_table_size(list);
2014
2015         g_hash_table_destroy(list);
2016         free(locale);
2017
2018         return PMINFO_R_OK;
2019 }
2020
2021 API int pkgmgrinfo_pkginfo_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count)
2022 {
2023         return pkgmgrinfo_pkginfo_usr_filter_count(handle, count, _getuid());
2024 }
2025
2026 API int pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(
2027                 pkgmgrinfo_pkginfo_filter_h handle,
2028                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data, uid_t uid)
2029 {
2030         if (handle == NULL || pkg_cb == NULL) {
2031                 LOGE("invalid parameter");
2032                 return PMINFO_R_EINVAL;
2033         }
2034
2035         return _pkginfo_get_filtered_foreach_pkginfo(uid, handle,
2036                         PMINFO_PKGINFO_GET_ALL, pkg_cb, user_data);
2037 }
2038
2039 API int pkgmgrinfo_pkginfo_filter_foreach_pkginfo(pkgmgrinfo_pkginfo_filter_h handle,
2040                                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data)
2041 {
2042         return pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, pkg_cb, user_data, _getuid());
2043 }
2044
2045 API int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle,
2046                         pkgmgrinfo_pkg_privilege_list_cb privilege_func, void *user_data)
2047 {
2048         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
2049         retvm_if(privilege_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
2050         int ret;
2051         privilege_x *privilege;
2052         appdefined_privilege_x *appdefined_privilege;
2053         GList *tmp;
2054         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
2055
2056         if (info->pkg_info == NULL)
2057                 return PMINFO_R_ERROR;
2058
2059         for (tmp = info->pkg_info->privileges; tmp; tmp = tmp->next) {
2060                 privilege = (privilege_x *)tmp->data;
2061                 if (privilege == NULL)
2062                         continue;
2063                 ret = privilege_func(privilege->value, user_data);
2064                 if (ret < 0)
2065                         return PMINFO_R_OK;
2066         }
2067
2068         for (tmp = info->pkg_info->appdefined_privileges; tmp;
2069                         tmp = tmp->next) {
2070                 appdefined_privilege = (appdefined_privilege_x *)tmp->data;
2071                 if (appdefined_privilege == NULL)
2072                         continue;
2073                 ret = privilege_func(appdefined_privilege->value, user_data);
2074                 if (ret < 0)
2075                         return PMINFO_R_OK;
2076         }
2077         return PMINFO_R_OK;
2078 }
2079
2080 API int pkgmgrinfo_pkginfo_foreach_plugin(pkgmgrinfo_pkginfo_h handle,
2081                         pkgmgrinfo_plugin_list_cb plugin_func, void *user_data)
2082 {
2083         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
2084         retvm_if(plugin_func == NULL, PMINFO_R_EINVAL,
2085                         "Callback function is NULL");
2086         int ret;
2087         plugin_x *plugin;
2088         GList *tmp;
2089         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
2090
2091         if (info->pkg_info == NULL)
2092                 return PMINFO_R_ERROR;
2093
2094         for (tmp = info->pkg_info->plugin; tmp; tmp = tmp->next) {
2095                 plugin = (plugin_x *)tmp->data;
2096                 if (plugin == NULL)
2097                         continue;
2098                 ret = plugin_func(plugin->pkgid, plugin->appid,
2099                                 plugin->plugin_type, plugin->plugin_name, user_data);
2100                 if (ret < 0)
2101                         return PMINFO_R_OK;
2102         }
2103
2104         return PMINFO_R_OK;
2105 }
2106
2107 API int pkgmgrinfo_pkginfo_foreach_appdefined_privilege(
2108                 pkgmgrinfo_pkginfo_h handle,
2109                 pkgmgrinfo_pkg_appdefined_privilege_list_cb privilege_func,
2110                 void *user_data)
2111 {
2112         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
2113         retvm_if(privilege_func == NULL, PMINFO_R_EINVAL,
2114                         "Callback function is NULL");
2115         int ret;
2116         appdefined_privilege_x *privilege;
2117         GList *tmp;
2118         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
2119
2120         if (info->pkg_info == NULL)
2121                 return PMINFO_R_ERROR;
2122
2123         for (tmp = info->pkg_info->appdefined_privileges; tmp;
2124                         tmp = tmp->next) {
2125                 privilege = (appdefined_privilege_x *)tmp->data;
2126                 if (privilege == NULL)
2127                         continue;
2128                 ret = privilege_func(privilege->value, privilege->license,
2129                                 user_data);
2130                 if (ret < 0)
2131                         break;
2132         }
2133         return PMINFO_R_OK;
2134 }
2135
2136 API int pkgmgrinfo_pkginfo_foreach_dependency(pkgmgrinfo_pkginfo_h handle,
2137                 pkgmgrinfo_pkg_dependency_list_cb dependency_cb,
2138                 void *user_data)
2139 {
2140         int ret;
2141         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
2142         GList *tmp;
2143         dependency_x *dependency;
2144
2145         if (handle == NULL || dependency_cb == NULL) {
2146                 LOGE("invalid parameter");
2147                 return PMINFO_R_EINVAL;
2148         }
2149
2150         if (info->pkg_info == NULL)
2151                 return PMINFO_R_ERROR;
2152
2153         for (tmp = info->pkg_info->dependencies; tmp; tmp = tmp->next) {
2154                 dependency = (dependency_x *)tmp->data;
2155                 if (dependency == NULL)
2156                         continue;
2157                 ret = dependency_cb(dependency->depends_on, dependency->type,
2158                                 dependency->required_version, user_data);
2159                 if (ret < 0)
2160                         break;
2161         }
2162
2163         return PMINFO_R_OK;
2164 }
2165
2166 struct required_by {
2167         char *pkgid;
2168         char *type;
2169         char *version;
2170 };
2171
2172 static int _get_required_by(sqlite3 *db, const char *pkgid, GQueue **queue,
2173                 GHashTable **table, GList **pkg_list)
2174 {
2175         static const char query[] =
2176                 "SELECT package, type, required_version "
2177                 "FROM package_dependency_info WHERE depends_on=?";
2178         int ret;
2179         sqlite3_stmt *stmt;
2180         struct required_by *req;
2181
2182         /* already checked */
2183         if (!g_hash_table_insert(*table, strdup(pkgid), GINT_TO_POINTER(1)))
2184                 return PMINFO_R_OK;
2185
2186         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2187         if (ret != SQLITE_OK) {
2188                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
2189                 return PMINFO_R_ERROR;
2190         }
2191
2192         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
2193         if (ret != SQLITE_OK) {
2194                 LOGE("bind failed: %s", sqlite3_errmsg(db));
2195                 sqlite3_finalize(stmt);
2196                 return PMINFO_R_ERROR;
2197         }
2198
2199         while (sqlite3_step(stmt) == SQLITE_ROW) {
2200                 req = calloc(1, sizeof(struct required_by));
2201                 if (req == NULL) {
2202                         LOGE("out of memory");
2203                         sqlite3_finalize(stmt);
2204                         return PMINFO_R_ERROR;
2205                 }
2206                 _save_column_str(stmt, 0, &req->pkgid);
2207                 _save_column_str(stmt, 1, &req->type);
2208                 _save_column_str(stmt, 2, &req->version);
2209
2210                 *pkg_list = g_list_append(*pkg_list, req);
2211                 g_queue_push_tail(*queue, strdup(req->pkgid));
2212         }
2213
2214         sqlite3_finalize(stmt);
2215
2216         return PMINFO_R_OK;
2217 }
2218
2219 static int _pkginfo_foreach_required_by(uid_t uid, const char *pkgid,
2220                 GList **pkg_list)
2221 {
2222         int ret;
2223         char *dbpath;
2224         sqlite3 *db;
2225         GQueue *queue;
2226         GHashTable *table;
2227         char *item;
2228
2229         dbpath = getUserPkgParserDBPathUID(uid);
2230         if (dbpath == NULL)
2231                 return PMINFO_R_ERROR;
2232
2233         ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
2234         if (ret != SQLITE_OK) {
2235                 LOGD("failed to open db(%s): %d", dbpath, ret);
2236                 free(dbpath);
2237                 return PMINFO_R_ERROR;
2238         }
2239         free(dbpath);
2240
2241         queue = g_queue_new();
2242         if (queue == NULL) {
2243                 LOGE("out of memory");
2244                 sqlite3_close_v2(db);
2245                 return PMINFO_R_ERROR;
2246         }
2247
2248         table = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
2249
2250         g_queue_push_tail(queue, strdup(pkgid));
2251         while (!g_queue_is_empty(queue)) {
2252                 item = g_queue_pop_head(queue);
2253                 ret = _get_required_by(db, item, &queue, &table, pkg_list);
2254                 free(item);
2255                 if (ret != PMINFO_R_OK) {
2256                         LOGE("failed to get required by pkgs");
2257                         g_hash_table_destroy(table);
2258                         g_queue_free_full(queue, free);
2259                         sqlite3_close_v2(db);
2260                         return PMINFO_R_ERROR;
2261                 }
2262         }
2263
2264         g_hash_table_destroy(table);
2265         g_queue_free_full(queue, free);
2266         sqlite3_close_v2(db);
2267
2268         return PMINFO_R_OK;
2269 }
2270
2271 static void __free_required_by(gpointer data)
2272 {
2273         struct required_by *req = (struct required_by *)data;
2274
2275         free(req->pkgid);
2276         free(req->type);
2277         free(req->version);
2278         free(req);
2279 }
2280
2281 API int pkgmgrinfo_pkginfo_foreach_required_by(pkgmgrinfo_pkginfo_h handle,
2282                 pkgmgrinfo_pkg_dependency_list_cb dependency_cb,
2283                 void *user_data)
2284 {
2285         int ret;
2286         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
2287         GList *pkg_list = NULL;
2288         GList *l;
2289         struct required_by *req;
2290
2291         if (handle == NULL || dependency_cb == NULL || info->pkg_info == NULL) {
2292                 LOGE("invalid parameter");
2293                 return PMINFO_R_EINVAL;
2294         }
2295
2296         ret = _pkginfo_foreach_required_by(info->uid, info->pkg_info->package,
2297                         &pkg_list);
2298         if (ret == PMINFO_R_OK && info->uid != GLOBAL_USER)
2299                 ret = _pkginfo_foreach_required_by(GLOBAL_USER,
2300                                 info->pkg_info->package, &pkg_list);
2301
2302         if (ret != PMINFO_R_OK) {
2303                 g_list_free_full(pkg_list, __free_required_by);
2304                 return ret;
2305         }
2306
2307         for (l = pkg_list; l != NULL; l = l->next) {
2308                 req = (struct required_by *)l->data;
2309                 ret = dependency_cb(req->pkgid, req->type, req->version,
2310                                 user_data);
2311                 if (ret < 0)
2312                         break;
2313         }
2314
2315         g_list_free_full(pkg_list, __free_required_by);
2316
2317         return PMINFO_R_OK;
2318 }
2319
2320 int __compare_package_version(const char *version, int *major,
2321                 int *minor, int *macro, int *nano)
2322 {
2323         char *version_temp = NULL;
2324         char *major_str = NULL;
2325         char *minor_str = NULL;
2326         char *macro_str = NULL;
2327         char *nano_str = NULL;
2328         char *save_str = NULL;
2329
2330         if (version == NULL || major == NULL || minor == NULL ||
2331                 macro == NULL || nano == NULL) {
2332                 return PMINFO_R_EINVAL;
2333         }
2334
2335         version_temp = strdup(version);
2336         if (version_temp == NULL) {
2337                 LOGE("Out of memory");
2338                 return PMINFO_R_ERROR;
2339         }
2340
2341         major_str = strtok_r(version_temp, ".", &save_str);
2342         if (major_str == NULL) {
2343                 _LOGE("major version is NULL");
2344                 free(version_temp);
2345                 return PMINFO_R_ERROR;
2346         }
2347
2348         minor_str = strtok_r(NULL, ".", &save_str);
2349         if (minor_str == NULL) {
2350                 _LOGE("minor version is NULL");
2351                 free(version_temp);
2352                 return PMINFO_R_ERROR;
2353         }
2354
2355         *major = atoi(major_str);
2356         *minor = atoi(minor_str);
2357         *macro = 0;
2358         *nano = 0;
2359         macro_str = strtok_r(NULL, ".", &save_str);
2360         if (macro_str == NULL) {
2361                 _LOGD("macro version is NULL");
2362         } else {
2363                 *macro = atoi(macro_str);
2364                 nano_str = strtok_r(NULL, ".", &save_str);
2365                 if (nano_str) {
2366                         *nano = atoi(nano_str);
2367                         _LOGD("nano version exists");
2368                 }
2369         }
2370         _LOGD("version = [%s] -> major = [%d], minor = [%d]," \
2371                 " macro = [%d], nano = [%d]", version, *major,
2372                 *minor, *macro, *nano);
2373
2374         free(version_temp);
2375
2376         return PMINFO_R_OK;
2377 }
2378
2379 API int pkgmgrinfo_compare_package_version(const char *current_version,
2380                 const char *target_version,
2381                 pkgmgrinfo_version_compare_type *res)
2382 {
2383         int ret = 0;
2384         int current_version_major = 0;
2385         int current_version_minor = 0;
2386         int current_version_macro = 0;
2387         int current_version_nano = 0;
2388         int target_version_major = 0;
2389         int target_version_minor = 0;
2390         int target_version_macro = 0;
2391         int target_version_nano = 0;
2392
2393         if (current_version == NULL || target_version == NULL ||
2394                 res == NULL) {
2395                 _LOGE("Invalid parameter");
2396                 return PMINFO_R_EINVAL;
2397         }
2398
2399         ret = __compare_package_version(target_version,
2400                 &target_version_major, &target_version_minor,
2401                 &target_version_macro, &target_version_nano);
2402         if (ret < 0) {
2403                 _LOGE("Failed to compare target version(%d)", ret);
2404                 return PMINFO_R_ERROR;
2405         }
2406
2407         ret = __compare_package_version(current_version,
2408                 &current_version_major, &current_version_minor,
2409                 &current_version_macro, &current_version_nano);
2410         if (ret < 0) {
2411                 _LOGE("Failed to compare current version(%d)", ret);
2412                 return PMINFO_R_ERROR;
2413         }
2414
2415         _LOGD("new[%d.%d.%d.%d] old[%d.%d.%d.%d]", target_version_major,
2416                 target_version_minor, target_version_macro,
2417                 target_version_nano, current_version_major,
2418                 current_version_minor, current_version_macro,
2419                 target_version_nano);
2420
2421         if (target_version_major > current_version_major)
2422                 *res = PMINFO_VERSION_NEW;
2423         else if (target_version_major < current_version_major)
2424                 *res = PMINFO_VERSION_OLD;
2425         else if (target_version_minor > current_version_minor)
2426                 *res = PMINFO_VERSION_NEW;
2427         else if (target_version_minor < current_version_minor)
2428                 *res = PMINFO_VERSION_OLD;
2429         else if (target_version_macro > current_version_macro)
2430                 *res = PMINFO_VERSION_NEW;
2431         else if (target_version_macro < current_version_macro)
2432                 *res = PMINFO_VERSION_OLD;
2433         else if (target_version_nano > current_version_nano)
2434                 *res = PMINFO_VERSION_NEW;
2435         else if (target_version_nano < current_version_nano)
2436                 *res = PMINFO_VERSION_OLD;
2437         else
2438                 *res = PMINFO_VERSION_SAME;
2439
2440         return PMINFO_R_OK;
2441 }