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 static void __free_packages(gpointer data)
25 pkgmgrinfo_basic_free_package((package_x *)data);
28 static const char join_localized_info[] =
29 " LEFT OUTER JOIN package_localized_info"
30 " ON pi.package=package_localized_info.package"
31 " AND package_localized_info.package_locale=?";
32 static const char join_privilege_info[] =
33 " LEFT OUTER JOIN package_privilege_info"
34 " ON pi.package=package_privilege_info.package";
36 static int _get_filtered_query(pkgmgrinfo_filter_x *filter,
37 const char *locale, uid_t uid, char **query, GList **bind_params)
41 char buf[MAX_QUERY_LEN] = { '\0' };
42 char buf2[MAX_QUERY_LEN] = { '\0' };
43 char *condition = NULL;
49 snprintf(buf, sizeof(buf), "%s", " WHERE 1=1 ");
50 for (list = filter->list; list; list = list->next) {
51 joined |= __get_filter_condition(list->data, uid, &condition,
53 if (condition == NULL)
56 strncat(buf, " AND ", sizeof(buf) - strlen(buf) - 1);
58 strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
63 if (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) {
64 strncat(buf2, join_localized_info, sizeof(buf2) - strlen(buf2) - 1);
65 *bind_params = g_list_append(*bind_params, strdup(locale));
67 if (joined & E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO)
68 strncat(buf2, join_privilege_info, sizeof(buf2) - strlen(buf2) - 1);
70 size = strlen(buf2) + strlen(buf) + 1;
71 *query = (char *)calloc(1, size);
73 return PMINFO_R_ERROR;
74 snprintf(*query, size, "%s%s", buf2, buf);
79 static int __bind_params(sqlite3_stmt *stmt, GList *params)
81 GList *tmp_list = NULL;
85 if (stmt == NULL || params == NULL)
86 return PMINFO_R_EINVAL;
90 ret = sqlite3_bind_text(stmt, ++idx, (char *)tmp_list->data, -1, SQLITE_STATIC);
92 return PMINFO_R_ERROR;
93 tmp_list = tmp_list->next;
99 static bool __check_package_storage_status(pkgmgrinfo_filter_x *tmp_filter)
101 GSList *tmp_list = NULL;
102 pkgmgrinfo_node_x *tmp_node = NULL;
105 property = _pminfo_pkginfo_convert_to_prop_bool(PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE);
106 for (tmp_list = tmp_filter->list; tmp_list != NULL;
107 tmp_list = g_slist_next(tmp_list)) {
108 tmp_node = (pkgmgrinfo_node_x *)tmp_list->data;
109 if (property == tmp_node->prop) {
110 if (strcmp(tmp_node->value, "true") == 0)
119 static int _pkginfo_add_description_info_into_list(const char *locale,
120 char *record, GList **description)
124 info = calloc(1, sizeof(description_x));
126 LOGE("out of memory");
127 return PMINFO_R_ERROR;
129 info->lang = strdup(locale);
131 *description = g_list_prepend(*description, info);
136 static int _pkginfo_get_plugin_execution_info(sqlite3 *db, const char *pkgid,
139 static const char query_raw[] =
140 "SELECT appid, plugin_type, plugin_name FROM package_plugin_info "
147 query = sqlite3_mprintf(query_raw, pkgid);
149 LOGE("out of memory");
150 return PMINFO_R_ERROR;
153 ret = sqlite3_prepare_v2(db, query, strlen(query),
156 if (ret != SQLITE_OK) {
157 LOGE("prepare failed: %s", sqlite3_errmsg(db));
158 return PMINFO_R_ERROR;
161 while (sqlite3_step(stmt) == SQLITE_ROW) {
162 plugin = calloc(1, sizeof(plugin_x));
164 LOGE("out of memory");
165 sqlite3_finalize(stmt);
166 return PMINFO_R_ERROR;
168 plugin->pkgid = strdup(pkgid);
169 _save_column_str(stmt, 0, &plugin->appid);
170 _save_column_str(stmt, 1, &plugin->plugin_type);
171 _save_column_str(stmt, 2, &plugin->plugin_name);
172 *plugins = g_list_prepend(*plugins,
176 sqlite3_finalize(stmt);
181 static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid,
184 static const char query_raw[] =
185 "SELECT DISTINCT privilege, type FROM package_privilege_info "
190 privilege_x *privilege;
192 query = sqlite3_mprintf(query_raw, pkgid);
194 LOGE("out of memory");
195 return PMINFO_R_ERROR;
198 ret = sqlite3_prepare_v2(db, query, strlen(query),
201 if (ret != SQLITE_OK) {
202 LOGE("prepare failed: %s", sqlite3_errmsg(db));
203 return PMINFO_R_ERROR;
206 while (sqlite3_step(stmt) == SQLITE_ROW) {
207 privilege = calloc(1, sizeof(privilege_x));
209 LOGE("failed to alloc memory");
210 sqlite3_finalize(stmt);
211 return PMINFO_R_ERROR;
213 _save_column_str(stmt, 0, &privilege->value);
214 _save_column_str(stmt, 1, &privilege->type);
215 *privileges = g_list_prepend(*privileges,
216 (gpointer)privilege);
219 sqlite3_finalize(stmt);
224 static int _pkginfo_get_appdefined_privilege(sqlite3 *db, const char *pkgid,
227 static const char query_raw[] =
228 "SELECT DISTINCT privilege, license, type FROM "
229 "package_appdefined_privilege_info WHERE package=%Q";
233 appdefined_privilege_x *privilege;
235 query = sqlite3_mprintf(query_raw, pkgid);
237 LOGE("out of memory");
238 return PMINFO_R_ERROR;
241 ret = sqlite3_prepare_v2(db, query, strlen(query),
244 if (ret != SQLITE_OK) {
245 LOGE("prepare failed: %s", sqlite3_errmsg(db));
246 return PMINFO_R_ERROR;
249 while (sqlite3_step(stmt) == SQLITE_ROW) {
250 privilege = calloc(1, sizeof(appdefined_privilege_x));
252 LOGE("failed to alloc memory");
253 sqlite3_finalize(stmt);
254 return PMINFO_R_ERROR;
256 _save_column_str(stmt, 0, &privilege->value);
257 _save_column_str(stmt, 1, &privilege->license);
258 _save_column_str(stmt, 2, &privilege->type);
259 *privileges = g_list_prepend(*privileges,
260 (gpointer)privilege);
263 sqlite3_finalize(stmt);
268 static int _pkginfo_get_dependency(sqlite3 *db, const char *pkgid,
269 GList **dependencies)
271 static const char query_raw[] =
272 "SELECT DISTINCT depends_on, type, required_version "
273 "FROM package_dependency_info WHERE package=%Q";
277 dependency_x *dependency;
279 query = sqlite3_mprintf(query_raw, pkgid);
281 LOGE("out of memory");
282 return PMINFO_R_ERROR;
285 ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
287 if (ret != SQLITE_OK) {
288 LOGE("prepare failed: %s", sqlite3_errmsg(db));
289 return PMINFO_R_ERROR;
292 while (sqlite3_step(stmt) == SQLITE_ROW) {
293 dependency = calloc(1, sizeof(dependency_x));
295 LOGE("failed to alloc memory");
296 sqlite3_finalize(stmt);
297 return PMINFO_R_ERROR;
299 _save_column_str(stmt, 0, &dependency->depends_on);
300 _save_column_str(stmt, 1, &dependency->type);
301 _save_column_str(stmt, 2, &dependency->required_version);
302 *dependencies = g_list_prepend(*dependencies,
303 (gpointer)dependency);
306 sqlite3_finalize(stmt);
311 static int _pkginfo_get_packages(sqlite3 *db, uid_t uid, const char *locale,
312 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages)
314 static const char query_raw[] =
315 "SELECT DISTINCT pi.package, pi.installed_storage, pi.external_path";
316 static const char query_basic[] =
317 ", pi.package_version, pi.install_location, "
318 "pi.package_removable, pi.package_preload, pi.package_readonly, "
319 "pi.package_update, pi.package_appsetting, pi.package_system, "
320 "pi.package_type, pi.package_size, pi.installed_time, "
321 "pi.storeclient_id, pi.mainapp_id, pi.package_url, pi.root_path, "
322 "pi.csc_path, pi.package_nodisplay, pi.package_api_version, "
323 "pi.package_support_disable, pi.package_tep_name, "
324 "pi.package_zip_mount_file, pi.package_support_mode";
325 static const char query_author[] =
326 ", pi.author_name, pi.author_email, pi.author_href";
327 static const char query_label[] =
329 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
330 "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
331 static const char query_icon[] =
333 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
334 "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
335 static const char query_description[] =
337 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
338 "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
339 static const char query_from_clause[] = " FROM package_info as pi";
340 int ret = PMINFO_R_ERROR;
343 char *tmp_record = NULL;
344 char *constraints = NULL;
345 char query[MAX_QUERY_LEN] = { '\0' };
346 package_x *info = NULL;
347 author_x *author = NULL;
348 GList *bind_params = NULL;
350 sqlite3_stmt *stmt = NULL;
351 bool is_check_storage = true;
352 const uid_t global_user_uid = GLOBAL_USER;
354 dbpath = getUserPkgParserDBPathUID(uid);
356 return PMINFO_R_ERROR;
358 ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
359 if (ret != SQLITE_OK) {
360 _LOGD("failed to open db(%s): %d", dbpath, ret);
362 return PMINFO_R_ERROR;
366 is_check_storage = __check_package_storage_status(filter);
368 snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
369 if (flag & PMINFO_APPINFO_GET_BASICINFO)
370 strncat(query, query_basic, sizeof(query) - strlen(query) - 1);
371 if (flag & PMINFO_PKGINFO_GET_AUTHOR)
372 strncat(query, query_author, sizeof(query) - strlen(query) - 1);
373 if (flag & PMINFO_PKGINFO_GET_LABEL) {
374 strncat(query, query_label, sizeof(query) - strlen(query) - 1);
375 bind_params = g_list_append(bind_params, strdup(locale));
377 if (flag & PMINFO_PKGINFO_GET_ICON) {
378 strncat(query, query_icon, sizeof(query) - strlen(query) - 1);
379 bind_params = g_list_append(bind_params, strdup(locale));
381 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
382 strncat(query, query_description, sizeof(query) - strlen(query) - 1);
383 bind_params = g_list_append(bind_params, strdup(locale));
386 strncat(query, query_from_clause, sizeof(query) - strlen(query) - 1);
388 ret = _get_filtered_query(filter, locale, uid, &constraints, &bind_params);
389 if (ret != PMINFO_R_OK) {
390 LOGE("Failed to get WHERE clause");
395 strncat(query, constraints, sizeof(query) - strlen(query) - 1);
397 ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
398 if (ret != SQLITE_OK) {
399 LOGE("prepare failed: %s", sqlite3_errmsg(db));
400 ret = PMINFO_R_ERROR;
404 ret = __bind_params(stmt, bind_params);
405 if (ret != SQLITE_OK) {
406 LOGE("Failed to bind parameters");
410 while (sqlite3_step(stmt) == SQLITE_ROW) {
411 info = calloc(1, sizeof(package_x));
413 LOGE("out of memory");
414 ret = PMINFO_R_ERROR;
418 _save_column_str(stmt, idx++, &info->package);
419 _save_column_str(stmt, idx++, &info->installed_storage);
420 _save_column_str(stmt, idx++, &info->external_path);
422 if (flag & PMINFO_APPINFO_GET_BASICINFO) {
423 _save_column_str(stmt, idx++, &info->version);
424 _save_column_str(stmt, idx++, &info->installlocation);
425 _save_column_str(stmt, idx++, &info->removable);
426 _save_column_str(stmt, idx++, &info->preload);
427 _save_column_str(stmt, idx++, &info->readonly);
428 _save_column_str(stmt, idx++, &info->update);
429 _save_column_str(stmt, idx++, &info->appsetting);
430 _save_column_str(stmt, idx++, &info->system);
431 _save_column_str(stmt, idx++, &info->type);
432 _save_column_str(stmt, idx++, &info->package_size);
433 _save_column_str(stmt, idx++, &info->installed_time);
434 _save_column_str(stmt, idx++, &info->storeclient_id);
435 _save_column_str(stmt, idx++, &info->mainapp_id);
436 _save_column_str(stmt, idx++, &info->package_url);
437 _save_column_str(stmt, idx++, &info->root_path);
438 _save_column_str(stmt, idx++, &info->csc_path);
439 _save_column_str(stmt, idx++, &info->nodisplay_setting);
440 _save_column_str(stmt, idx++, &info->api_version);
441 _save_column_str(stmt, idx++, &info->support_disable);
442 _save_column_str(stmt, idx++, &info->tep_name);
443 _save_column_str(stmt, idx++, &info->zip_mount_file);
444 _save_column_str(stmt, idx++, &info->support_mode);
447 info->for_all_users =
448 strdup((uid != global_user_uid) ? "false" : "true");
450 if (_pkginfo_get_plugin_execution_info(db, info->package, &info->plugin)) {
451 ret = PMINFO_R_ERROR;
455 if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
456 /* TODO : author should be retrieved at package_localized_info */
457 author = calloc(1, sizeof(author_x));
458 if (author == NULL) {
459 ret = PMINFO_R_ERROR;
462 _save_column_str(stmt, idx++, &author->text);
463 _save_column_str(stmt, idx++, &author->email);
464 _save_column_str(stmt, idx++, &author->href);
465 info->author = g_list_prepend(info->author, author);
468 if (flag & PMINFO_PKGINFO_GET_LABEL) {
470 _save_column_str(stmt, idx++, &tmp_record);
472 if (_add_label_info_into_list(locale, tmp_record, &info->label)) {
473 ret = PMINFO_R_ERROR;
478 if (flag & PMINFO_PKGINFO_GET_ICON) {
480 _save_column_str(stmt, idx++, &tmp_record);
481 if (_add_icon_info_into_list(locale, tmp_record, &info->icon)) {
482 ret = PMINFO_R_ERROR;
487 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
489 _save_column_str(stmt, idx++, &tmp_record);
490 if (_pkginfo_add_description_info_into_list(locale, tmp_record,
491 &info->description)) {
492 ret = PMINFO_R_ERROR;
497 if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) {
498 if (_pkginfo_get_privilege(db, info->package,
499 &info->privileges)) {
500 ret = PMINFO_R_ERROR;
505 if (flag & PMINFO_PKGINFO_GET_APPDEFINED_PRIVILEGE) {
506 if (_pkginfo_get_appdefined_privilege(db, info->package,
507 &info->appdefined_privileges)) {
508 ret = PMINFO_R_ERROR;
513 if (flag & PMINFO_PKGINFO_GET_DEPENDENCY) {
514 if (_pkginfo_get_dependency(db, info->package,
515 &info->dependencies)) {
516 ret = PMINFO_R_ERROR;
521 if (is_check_storage &&
522 __pkginfo_check_installed_storage(info) != PMINFO_R_OK) {
523 ret = PMINFO_R_ERROR;
524 pkgmgrinfo_basic_free_package(info);
529 g_hash_table_insert(packages, (gpointer)info->package,
536 sqlite3_finalize(stmt);
541 if (ret != PMINFO_R_OK && info != NULL)
542 pkgmgrinfo_basic_free_package(info);
544 g_list_free_full(bind_params, free);
549 API int pkginfo_internal_filter_get_list(
550 sqlite3 *db, pkgmgrinfo_pkginfo_filter_h filter,
551 uid_t uid, const char *locale, GHashTable **pkginfo_list) {
555 if (filter == NULL || pkginfo_list == NULL) {
556 // TODO: print error log
557 return PMINFO_R_EINVAL;
560 list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
563 return PMINFO_R_ERROR;
565 ret = _pkginfo_get_packages(db, uid, locale, filter,
566 PMINFO_PKGINFO_GET_ALL, list);
567 if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
568 ret = _pkginfo_get_packages(db, GLOBAL_USER, locale, filter,
569 PMINFO_PKGINFO_GET_ALL, list);
571 if (ret != PMINFO_R_OK) {
572 g_hash_table_destroy(list);
573 return PMINFO_R_ERROR;
576 *pkginfo_list = list;