10 #include <sys/smack.h>
11 #include <linux/limits.h>
18 #include "pkgmgrinfo_basic.h"
19 #include "pkgmgrinfo_private.h"
20 #include "pkgmgrinfo_debug.h"
21 #include "pkgmgr-info.h"
23 #define __BEGIN_TRANSACTION(db) \
25 if (sqlite3_exec(db, "BEGIN DEFERRED", NULL, NULL, NULL) != \
27 _LOGE("begin transaction failed: %s", sqlite3_errmsg(db)); \
32 #define __DO_TRANSACTION(db, func) \
35 _LOGE("transaction failed: %s, rollback", sqlite3_errmsg(db)); \
36 if (sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL) != \
38 _LOGE("roll back transaction failed: %s", \
39 sqlite3_errmsg(db)); \
44 #define __END_TRANSACTION(db) \
46 if (sqlite3_exec(db, "COMMIT", NULL, NULL, NULL) != \
48 _LOGE("commit failed: %s, rollback", sqlite3_errmsg(db)); \
49 if (sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL) != \
51 _LOGE("roll back transaction failed: %s", \
52 sqlite3_errmsg(db)); \
57 static int __free_packages(gpointer key, gpointer value,
60 pkgmgrinfo_basic_free_package((package_x *)value);
65 static const char join_localized_info[] =
66 " LEFT OUTER JOIN package_localized_info"
67 " ON pi.package=package_localized_info.package"
68 " AND package_localized_info.package_locale=?";
69 static const char join_privilege_info[] =
70 " LEFT OUTER JOIN package_privilege_info"
71 " ON pi.package=package_privilege_info.package";
73 static int _get_filtered_query(pkgmgrinfo_filter_x *filter,
74 const char *locale, uid_t uid, char **query, GList **bind_params)
78 char buf[MAX_QUERY_LEN] = { '\0' };
79 char buf2[MAX_QUERY_LEN] = { '\0' };
80 char *condition = NULL;
86 snprintf(buf, sizeof(buf), "%s", " WHERE 1=1 ");
87 for (list = filter->list; list; list = list->next) {
88 joined |= __get_filter_condition(list->data, uid, &condition,
90 if (condition == NULL)
93 strncat(buf, " AND ", sizeof(buf) - strlen(buf) - 1);
95 strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
100 if (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) {
101 strncat(buf2, join_localized_info, sizeof(buf2) - strlen(buf2) - 1);
102 *bind_params = g_list_append(*bind_params, strdup(locale));
104 if (joined & E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO)
105 strncat(buf2, join_privilege_info, sizeof(buf2) - strlen(buf2) - 1);
107 size = strlen(buf2) + strlen(buf) + 1;
108 *query = (char *)calloc(1, size);
110 return PMINFO_R_ERROR;
111 snprintf(*query, size, "%s%s", buf2, buf);
116 static int __bind_params(sqlite3_stmt *stmt, GList *params)
118 GList *tmp_list = NULL;
122 if (stmt == NULL || params == NULL)
123 return PMINFO_R_EINVAL;
127 ret = sqlite3_bind_text(stmt, ++idx, (char *)tmp_list->data, -1, SQLITE_STATIC);
128 if (ret != SQLITE_OK)
129 return PMINFO_R_ERROR;
130 tmp_list = tmp_list->next;
136 static bool __check_package_storage_status(pkgmgrinfo_filter_x *tmp_filter)
138 GSList *tmp_list = NULL;
139 pkgmgrinfo_node_x *tmp_node = NULL;
142 property = _pminfo_pkginfo_convert_to_prop_bool(PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE);
143 for (tmp_list = tmp_filter->list; tmp_list != NULL;
144 tmp_list = g_slist_next(tmp_list)) {
145 tmp_node = (pkgmgrinfo_node_x *)tmp_list->data;
146 if (property == tmp_node->prop) {
147 if (strcmp(tmp_node->value, "true") == 0)
156 static int _pkginfo_add_description_info_into_list(const char *locale,
157 char *record, GList **description)
161 info = calloc(1, sizeof(description_x));
163 LOGE("out of memory");
164 return PMINFO_R_ERROR;
166 info->lang = strdup(locale);
168 *description = g_list_prepend(*description, info);
173 static int _pkginfo_get_plugin_execution_info(sqlite3 *db, const char *pkgid,
176 static const char query_raw[] =
177 "SELECT appid, plugin_type, plugin_name FROM package_plugin_info "
184 query = sqlite3_mprintf(query_raw, pkgid);
186 LOGE("out of memory");
187 return PMINFO_R_ERROR;
190 ret = sqlite3_prepare_v2(db, query, strlen(query),
193 if (ret != SQLITE_OK) {
194 LOGE("prepare failed: %s", sqlite3_errmsg(db));
195 return PMINFO_R_ERROR;
198 while (sqlite3_step(stmt) == SQLITE_ROW) {
199 plugin = calloc(1, sizeof(plugin_x));
201 LOGE("out of memory");
202 sqlite3_finalize(stmt);
203 return PMINFO_R_ERROR;
205 plugin->pkgid = strdup(pkgid);
206 _save_column_str(stmt, 0, &plugin->appid);
207 _save_column_str(stmt, 1, &plugin->plugin_type);
208 _save_column_str(stmt, 2, &plugin->plugin_name);
209 *plugins = g_list_prepend(*plugins,
213 sqlite3_finalize(stmt);
218 static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid,
221 static const char query_raw[] =
222 "SELECT DISTINCT privilege, type FROM package_privilege_info "
227 privilege_x *privilege;
229 query = sqlite3_mprintf(query_raw, pkgid);
231 LOGE("out of memory");
232 return PMINFO_R_ERROR;
235 ret = sqlite3_prepare_v2(db, query, strlen(query),
238 if (ret != SQLITE_OK) {
239 LOGE("prepare failed: %s", sqlite3_errmsg(db));
240 return PMINFO_R_ERROR;
243 while (sqlite3_step(stmt) == SQLITE_ROW) {
244 privilege = calloc(1, sizeof(privilege_x));
246 LOGE("failed to alloc memory");
247 sqlite3_finalize(stmt);
248 return PMINFO_R_ERROR;
250 _save_column_str(stmt, 0, &privilege->value);
251 _save_column_str(stmt, 1, &privilege->type);
252 *privileges = g_list_prepend(*privileges,
253 (gpointer)privilege);
256 sqlite3_finalize(stmt);
261 static int _pkginfo_get_appdefined_privilege(sqlite3 *db, const char *pkgid,
264 static const char query_raw[] =
265 "SELECT DISTINCT privilege, license, type FROM "
266 "package_appdefined_privilege_info WHERE package=%Q";
270 appdefined_privilege_x *privilege;
272 query = sqlite3_mprintf(query_raw, pkgid);
274 LOGE("out of memory");
275 return PMINFO_R_ERROR;
278 ret = sqlite3_prepare_v2(db, query, strlen(query),
281 if (ret != SQLITE_OK) {
282 LOGE("prepare failed: %s", sqlite3_errmsg(db));
283 return PMINFO_R_ERROR;
286 while (sqlite3_step(stmt) == SQLITE_ROW) {
287 privilege = calloc(1, sizeof(appdefined_privilege_x));
289 LOGE("failed to alloc memory");
290 sqlite3_finalize(stmt);
291 return PMINFO_R_ERROR;
293 _save_column_str(stmt, 0, &privilege->value);
294 _save_column_str(stmt, 1, &privilege->license);
295 _save_column_str(stmt, 2, &privilege->type);
296 *privileges = g_list_prepend(*privileges,
297 (gpointer)privilege);
300 sqlite3_finalize(stmt);
305 static int _pkginfo_get_dependency(sqlite3 *db, const char *pkgid,
306 GList **dependencies)
308 static const char query_raw[] =
309 "SELECT DISTINCT depends_on, type, required_version "
310 "FROM package_dependency_info WHERE package=%Q";
314 dependency_x *dependency;
316 query = sqlite3_mprintf(query_raw, pkgid);
318 LOGE("out of memory");
319 return PMINFO_R_ERROR;
322 ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
324 if (ret != SQLITE_OK) {
325 LOGE("prepare failed: %s", sqlite3_errmsg(db));
326 return PMINFO_R_ERROR;
329 while (sqlite3_step(stmt) == SQLITE_ROW) {
330 dependency = calloc(1, sizeof(dependency_x));
332 LOGE("failed to alloc memory");
333 sqlite3_finalize(stmt);
334 return PMINFO_R_ERROR;
336 _save_column_str(stmt, 0, &dependency->depends_on);
337 _save_column_str(stmt, 1, &dependency->type);
338 _save_column_str(stmt, 2, &dependency->required_version);
339 *dependencies = g_list_prepend(*dependencies,
340 (gpointer)dependency);
343 sqlite3_finalize(stmt);
348 static int _pkginfo_get_packages(sqlite3 *db, uid_t uid, const char *locale,
349 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages)
351 static const char query_raw[] =
352 "SELECT DISTINCT pi.package, pi.installed_storage, pi.external_path";
353 static const char query_basic[] =
354 ", pi.package_version, pi.install_location, "
355 "pi.package_removable, pi.package_preload, pi.package_readonly, "
356 "pi.package_update, pi.package_appsetting, pi.package_system, "
357 "pi.package_type, pi.package_size, pi.installed_time, "
358 "pi.storeclient_id, pi.mainapp_id, pi.package_url, pi.root_path, "
359 "pi.csc_path, pi.package_nodisplay, pi.package_api_version, "
360 "pi.package_support_disable, pi.package_tep_name, "
361 "pi.package_zip_mount_file, pi.package_support_mode";
362 static const char query_author[] =
363 ", pi.author_name, pi.author_email, pi.author_href";
364 static const char query_label[] =
366 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
367 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
368 static const char query_icon[] =
370 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
371 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
372 static const char query_description[] =
374 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
375 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
376 static const char query_from_clause[] = " FROM package_info as pi";
377 int ret = PMINFO_R_ERROR;
380 char *tmp_record = NULL;
381 char *constraints = NULL;
382 char query[MAX_QUERY_LEN] = { '\0' };
383 package_x *info = NULL;
384 author_x *author = NULL;
385 GList *bind_params = NULL;
387 sqlite3_stmt *stmt = NULL;
388 bool is_check_storage = true;
389 const uid_t global_user_uid = GLOBAL_USER;
391 dbpath = getUserPkgParserDBPathUID(uid);
393 return PMINFO_R_ERROR;
395 ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
396 if (ret != SQLITE_OK) {
397 _LOGD("failed to open db(%s): %d", dbpath, ret);
399 return PMINFO_R_ERROR;
403 is_check_storage = __check_package_storage_status(filter);
405 snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
406 if (flag & PMINFO_APPINFO_GET_BASICINFO)
407 strncat(query, query_basic, sizeof(query) - strlen(query) - 1);
408 if (flag & PMINFO_PKGINFO_GET_AUTHOR)
409 strncat(query, query_author, sizeof(query) - strlen(query) - 1);
410 if (flag & PMINFO_PKGINFO_GET_LABEL) {
411 strncat(query, query_label, sizeof(query) - strlen(query) - 1);
412 bind_params = g_list_append(bind_params, strdup(locale));
414 if (flag & PMINFO_PKGINFO_GET_ICON) {
415 strncat(query, query_icon, sizeof(query) - strlen(query) - 1);
416 bind_params = g_list_append(bind_params, strdup(locale));
418 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
419 strncat(query, query_description, sizeof(query) - strlen(query) - 1);
420 bind_params = g_list_append(bind_params, strdup(locale));
423 strncat(query, query_from_clause, sizeof(query) - strlen(query) - 1);
425 ret = _get_filtered_query(filter, locale, uid, &constraints, &bind_params);
426 if (ret != PMINFO_R_OK) {
427 LOGE("Failed to get WHERE clause");
432 strncat(query, constraints, sizeof(query) - strlen(query) - 1);
434 ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
435 if (ret != SQLITE_OK) {
436 LOGE("prepare failed: %s", sqlite3_errmsg(db));
437 ret = PMINFO_R_ERROR;
441 ret = __bind_params(stmt, bind_params);
442 if (ret != SQLITE_OK) {
443 LOGE("Failed to bind parameters");
447 while (sqlite3_step(stmt) == SQLITE_ROW) {
448 info = calloc(1, sizeof(package_x));
450 LOGE("out of memory");
451 ret = PMINFO_R_ERROR;
454 info->locale = strdup(locale);
455 if (info->locale == NULL) {
456 LOGE("Out of memory");
457 ret = PMINFO_R_ERROR;
462 _save_column_str(stmt, idx++, &info->package);
463 _save_column_str(stmt, idx++, &info->installed_storage);
464 _save_column_str(stmt, idx++, &info->external_path);
466 if (flag & PMINFO_APPINFO_GET_BASICINFO) {
467 _save_column_str(stmt, idx++, &info->version);
468 _save_column_str(stmt, idx++, &info->installlocation);
469 _save_column_str(stmt, idx++, &info->removable);
470 _save_column_str(stmt, idx++, &info->preload);
471 _save_column_str(stmt, idx++, &info->readonly);
472 _save_column_str(stmt, idx++, &info->update);
473 _save_column_str(stmt, idx++, &info->appsetting);
474 _save_column_str(stmt, idx++, &info->system);
475 _save_column_str(stmt, idx++, &info->type);
476 _save_column_str(stmt, idx++, &info->package_size);
477 _save_column_str(stmt, idx++, &info->installed_time);
478 _save_column_str(stmt, idx++, &info->storeclient_id);
479 _save_column_str(stmt, idx++, &info->mainapp_id);
480 _save_column_str(stmt, idx++, &info->package_url);
481 _save_column_str(stmt, idx++, &info->root_path);
482 _save_column_str(stmt, idx++, &info->csc_path);
483 _save_column_str(stmt, idx++, &info->nodisplay_setting);
484 _save_column_str(stmt, idx++, &info->api_version);
485 _save_column_str(stmt, idx++, &info->support_disable);
486 _save_column_str(stmt, idx++, &info->tep_name);
487 _save_column_str(stmt, idx++, &info->zip_mount_file);
488 _save_column_str(stmt, idx++, &info->support_mode);
491 info->for_all_users =
492 strdup((uid != global_user_uid) ? "false" : "true");
494 if (_pkginfo_get_plugin_execution_info(db, info->package, &info->plugin)) {
495 ret = PMINFO_R_ERROR;
499 if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
500 /* TODO : author should be retrieved at package_localized_info */
501 author = calloc(1, sizeof(author_x));
502 if (author == NULL) {
503 ret = PMINFO_R_ERROR;
506 _save_column_str(stmt, idx++, &author->text);
507 _save_column_str(stmt, idx++, &author->email);
508 _save_column_str(stmt, idx++, &author->href);
509 info->author = g_list_prepend(info->author, author);
512 if (flag & PMINFO_PKGINFO_GET_LABEL) {
514 _save_column_str(stmt, idx++, &tmp_record);
516 if (_add_label_info_into_list(locale, tmp_record, &info->label)) {
517 ret = PMINFO_R_ERROR;
522 if (flag & PMINFO_PKGINFO_GET_ICON) {
524 _save_column_str(stmt, idx++, &tmp_record);
525 if (_add_icon_info_into_list(locale, tmp_record, &info->icon)) {
526 ret = PMINFO_R_ERROR;
531 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
533 _save_column_str(stmt, idx++, &tmp_record);
534 if (_pkginfo_add_description_info_into_list(locale, tmp_record,
535 &info->description)) {
536 ret = PMINFO_R_ERROR;
541 if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) {
542 if (_pkginfo_get_privilege(db, info->package,
543 &info->privileges)) {
544 ret = PMINFO_R_ERROR;
549 if (flag & PMINFO_PKGINFO_GET_APPDEFINED_PRIVILEGE) {
550 if (_pkginfo_get_appdefined_privilege(db, info->package,
551 &info->appdefined_privileges)) {
552 ret = PMINFO_R_ERROR;
557 if (flag & PMINFO_PKGINFO_GET_DEPENDENCY) {
558 if (_pkginfo_get_dependency(db, info->package,
559 &info->dependencies)) {
560 ret = PMINFO_R_ERROR;
565 if (is_check_storage &&
566 __pkginfo_check_installed_storage(info) != PMINFO_R_OK) {
567 ret = PMINFO_R_ERROR;
568 pkgmgrinfo_basic_free_package(info);
573 g_hash_table_insert(packages, (gpointer)info->package,
580 sqlite3_finalize(stmt);
585 if (ret != PMINFO_R_OK && info != NULL)
586 pkgmgrinfo_basic_free_package(info);
588 g_list_free_full(bind_params, free);
593 API int pkginfo_internal_filter_get_list(
594 sqlite3 *db, pkgmgrinfo_pkginfo_filter_h filter,
595 uid_t uid, const char *locale, GHashTable **pkginfo_list) {
599 if (filter == NULL || pkginfo_list == NULL) {
600 // TODO: print error log
601 return PMINFO_R_EINVAL;
604 list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
607 return PMINFO_R_ERROR;
609 ret = _pkginfo_get_packages(db, uid, locale, filter,
610 PMINFO_PKGINFO_GET_ALL, list);
611 if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
612 ret = _pkginfo_get_packages(db, GLOBAL_USER, locale, filter,
613 PMINFO_PKGINFO_GET_ALL, list);
615 if (ret != PMINFO_R_OK) {
616 g_hash_table_foreach_remove(list, __free_packages, NULL);
617 g_hash_table_destroy(list);
621 *pkginfo_list = list;
625 API int get_query_result(sqlite3 *db, const char *query,
626 GList **list, int *row, int *col) {
631 sqlite3_stmt *stmt = NULL;
634 ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
635 if (ret != SQLITE_OK) {
636 LOGE("prepare failed: %s", sqlite3_errmsg(db));
637 return PMINFO_R_ERROR;
640 col_cnt = sqlite3_column_count(stmt);
642 while (sqlite3_step(stmt) == SQLITE_ROW) {
644 for (idx = 0; idx < col_cnt; ++idx) {
645 _save_column_str(stmt, idx, &result);
646 *list = g_list_append(*list, result);
654 sqlite3_finalize(stmt);
659 static int _get_depends_on(sqlite3 *db, const char *pkgid, GQueue **queue,
660 GHashTable **table, GList **pkg_list)
662 static const char query[] =
663 "SELECT package, depends_on, type, required_version "
664 "FROM package_dependency_info WHERE depends_on=?";
669 /* already checked */
670 if (!g_hash_table_insert(*table, strdup(pkgid), GINT_TO_POINTER(1)))
673 ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
674 if (ret != SQLITE_OK) {
675 LOGE("prepare failed: %s", sqlite3_errmsg(db));
676 return PMINFO_R_ERROR;
679 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
680 if (ret != SQLITE_OK) {
681 LOGE("bind failed: %s", sqlite3_errmsg(db));
682 sqlite3_finalize(stmt);
683 return PMINFO_R_ERROR;
686 while (sqlite3_step(stmt) == SQLITE_ROW) {
687 req = calloc(1, sizeof(dependency_x));
689 LOGE("out of memory");
690 sqlite3_finalize(stmt);
691 return PMINFO_R_ERROR;
693 _save_column_str(stmt, 0, &req->pkgid);
694 _save_column_str(stmt, 1, &req->depends_on);
695 _save_column_str(stmt, 2, &req->type);
696 _save_column_str(stmt, 3, &req->required_version);
698 *pkg_list = g_list_prepend(*pkg_list, req);
699 g_queue_push_tail(*queue, strdup(req->pkgid));
702 sqlite3_finalize(stmt);
707 static void __free_depends_on(gpointer data)
709 struct dependency_x *dep = (struct dependency_x *)data;
711 free(dep->depends_on);
713 free(dep->required_version);
717 API int pkginfo_internal_filter_get_depends_on(sqlite3 *db, const char *pkgid,
724 queue = g_queue_new();
726 LOGE("out of memory");
727 return PMINFO_R_ERROR;
729 table = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
731 g_queue_push_tail(queue, strdup(pkgid));
732 while (!g_queue_is_empty(queue)) {
733 item = g_queue_pop_head(queue);
734 ret = _get_depends_on(db, item, &queue, &table, list);
736 if (ret != PMINFO_R_OK) {
737 LOGE("failed to get pkgs depends on %s", pkgid);
738 g_hash_table_destroy(table);
739 g_list_free_full(*list, __free_depends_on);
740 g_queue_free_full(queue, free);
741 return PMINFO_R_ERROR;
745 g_hash_table_destroy(table);
746 g_queue_free_full(queue, free);
750 static int __execute_query(sqlite3 *db, const char *query) {
752 sqlite3_stmt *stmt = NULL;
754 ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
755 if (ret != SQLITE_OK) {
756 LOGE("prepare failed: %s", sqlite3_errmsg(db));
760 ret = sqlite3_step(stmt);
761 if (ret != SQLITE_DONE) {
762 LOGE("step failed: %s", sqlite3_errmsg(db));
763 sqlite3_finalize(stmt);
767 sqlite3_finalize(stmt);
772 API int execute_write_queries(sqlite3 *db, const char **queries, int len) {
775 __BEGIN_TRANSACTION(db);
776 for (i = 0; i < len; ++i) {
777 __DO_TRANSACTION(db, __execute_query(db, queries[i]));
779 __END_TRANSACTION(db);
781 // Is db handel freed by AbstractDBHandler?
782 // sqlite3_close_v2(db);