2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <sys/types.h>
30 #include <dynamicbox_errno.h>
31 #include <dynamicbox_service.h>
32 #include <dynamicbox_conf.h>
39 #include "client_life.h"
40 #include "slave_life.h"
48 #define MAX_PKGNAME 512
56 static int load_abi_table(void)
72 static const char *field[] = {
76 const char *ptr = NULL;
78 char group[MAX_ABI + 1];
79 char pkgname[MAX_PKGNAME + 1];
81 fp = fopen("/usr/share/"PACKAGE"/abi.ini", "rt");
83 return DBOX_STATUS_ERROR_IO_ERROR;
87 while ((ch = getc(fp)) != EOF && state != ERROR) {
110 } else if (idx < MAX_ABI) {
113 ErrPrint("Overflow\n");
124 /* New group started */
136 ErrPrint("unknown tag\n");
141 if (*ptr == '\0' && ch == '=') {
147 } else if (*ptr == ch) {
152 while (ptr >= field[idx]) {
163 if (idx == 0) { /* LTRIM */
170 } else if (isspace(ch)) {
174 ret = abi_add_entry(group, pkgname);
176 ErrPrint("Failed to add %s for %s\n", pkgname, group);
181 } else if (idx < MAX_PKGNAME) {
185 ErrPrint("Overflow\n");
199 if (state == VALUE) {
205 ret = abi_add_entry(group, pkgname);
207 ErrPrint("Failed to add %s for %s\n", pkgname, group);
216 if (fclose(fp) != 0) {
217 ErrPrint("fclose: %s\n", strerror(errno));
219 return DBOX_STATUS_ERROR_NONE;
222 static inline int build_client_info(struct pkg_info *info)
224 static const char *dml = "SELECT auto_launch, gbar_size FROM client WHERE pkgid = ?";
231 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
232 if (ret != SQLITE_OK) {
233 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
234 return DBOX_STATUS_ERROR_IO_ERROR;
237 ret = sqlite3_bind_text(stmt, 1, package_name(info), -1, SQLITE_TRANSIENT);
238 if (ret != SQLITE_OK) {
239 ErrPrint("Failed to bind a pkgname %s\n", package_name(info));
240 sqlite3_finalize(stmt);
241 return DBOX_STATUS_ERROR_IO_ERROR;
244 if (sqlite3_step(stmt) != SQLITE_ROW) {
245 ErrPrint("%s has no records (%s)\n", package_name(info), sqlite3_errmsg(s_info.handle));
247 sqlite3_clear_bindings(stmt);
248 sqlite3_finalize(stmt);
249 return DBOX_STATUS_ERROR_IO_ERROR;
252 package_set_auto_launch(info, (const char *)sqlite3_column_text(stmt, 0));
254 tmp = (const char *)sqlite3_column_text(stmt, 1);
255 if (tmp && strlen(tmp)) {
256 if (sscanf(tmp, "%dx%d", &width, &height) != 2) {
257 ErrPrint("Failed to get GBAR width and Height (%s)\n", tmp);
259 package_set_gbar_width(info, width);
260 package_set_gbar_height(info, height);
265 sqlite3_clear_bindings(stmt);
266 sqlite3_finalize(stmt);
267 return DBOX_STATUS_ERROR_NONE;
270 static inline int build_provider_info(struct pkg_info *info)
272 static const char *dml = "SELECT provider.network, provider.abi, provider.secured, provider.box_type, provider.box_src, provider.box_group, provider.gbar_type, provider.gbar_src, provider.gbar_group, provider.libexec, provider.timeout, provider.period, provider.script, provider.pinup, pkgmap.appid, provider.direct_input, provider.hw_acceleration FROM provider, pkgmap WHERE pkgmap.pkgid = ? AND provider.pkgid = ?";
278 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
279 if (ret != SQLITE_OK) {
280 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
281 return DBOX_STATUS_ERROR_IO_ERROR;
284 if (sqlite3_bind_text(stmt, 1, package_name(info), -1, SQLITE_TRANSIENT) != SQLITE_OK) {
285 ErrPrint("Failed to bind a pkgname(%s) - %s\n", package_name(info), sqlite3_errmsg(s_info.handle));
286 sqlite3_finalize(stmt);
287 return DBOX_STATUS_ERROR_IO_ERROR;
290 if (sqlite3_bind_text(stmt, 2, package_name(info), -1, SQLITE_TRANSIENT) != SQLITE_OK) {
291 ErrPrint("Failed to bind a pkgname(%s) - %s\n", package_name(info), sqlite3_errmsg(s_info.handle));
292 sqlite3_finalize(stmt);
293 return DBOX_STATUS_ERROR_IO_ERROR;
296 if (sqlite3_step(stmt) != SQLITE_ROW) {
297 ErrPrint("%s has no record(%s)\n", package_name(info), sqlite3_errmsg(s_info.handle));
299 sqlite3_clear_bindings(stmt);
300 sqlite3_finalize(stmt);
301 return DBOX_STATUS_ERROR_IO_ERROR;
304 appid = (const char *)sqlite3_column_text(stmt, 14);
305 if (!appid || !strlen(appid)) {
306 ErrPrint("Failed to execute the DML for %s\n", package_name(info));
308 sqlite3_clear_bindings(stmt);
309 sqlite3_finalize(stmt);
310 return DBOX_STATUS_ERROR_IO_ERROR;
313 package_set_network(info, sqlite3_column_int(stmt, 0));
314 package_set_secured(info, sqlite3_column_int(stmt, 2));
316 tmp = (const char *)sqlite3_column_text(stmt, 1);
317 if (tmp && strlen(tmp)) {
318 package_set_abi(info, tmp);
321 package_set_dbox_type(info, sqlite3_column_int(stmt, 3));
322 tmp = (const char *)sqlite3_column_text(stmt, 4);
323 if (tmp && strlen(tmp)) {
324 package_set_dbox_path(info, tmp);
326 tmp = (const char *)sqlite3_column_text(stmt, 5);
327 if (tmp && strlen(tmp)) {
328 package_set_dbox_group(info, tmp);
332 package_set_gbar_type(info, sqlite3_column_int(stmt, 6));
333 tmp = (const char *)sqlite3_column_text(stmt, 7);
334 if (tmp && strlen(tmp)) {
335 package_set_gbar_path(info, tmp);
337 tmp = (const char *)sqlite3_column_text(stmt, 8);
338 if (tmp && strlen(tmp)) {
339 package_set_gbar_group(info, tmp);
343 tmp = (const char *)sqlite3_column_text(stmt, 9);
344 if (tmp && strlen(tmp)) {
345 package_set_libexec(info, tmp);
348 package_set_timeout(info, sqlite3_column_int(stmt, 10));
350 tmp = (const char *)sqlite3_column_text(stmt, 11);
351 if (tmp && strlen(tmp)) {
352 package_set_period(info, atof(tmp));
355 tmp = (const char *)sqlite3_column_text(stmt, 12);
356 if (tmp && strlen(tmp)) {
357 package_set_script(info, tmp);
360 package_set_pinup(info, sqlite3_column_int(stmt, 13));
361 package_set_direct_input(info, sqlite3_column_int(stmt, 15));
362 package_set_hw_acceleration(info, (const char *)sqlite3_column_text(stmt, 16));
365 sqlite3_clear_bindings(stmt);
366 sqlite3_finalize(stmt);
367 return DBOX_STATUS_ERROR_NONE;
370 static inline int build_box_size_info(struct pkg_info *info)
372 static const char *dml = "SELECT size_type FROM box_size WHERE pkgid = ?";
375 unsigned int size_type;
376 unsigned int size_list;
378 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
379 if (ret != SQLITE_OK) {
380 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
381 return DBOX_STATUS_ERROR_IO_ERROR;
384 if (sqlite3_bind_text(stmt, 1, package_name(info), -1, SQLITE_TRANSIENT) != SQLITE_OK) {
385 ErrPrint("Failed to bind a pkgname(%s) - %s\n", package_name(info), sqlite3_errmsg(s_info.handle));
386 sqlite3_finalize(stmt);
387 return DBOX_STATUS_ERROR_IO_ERROR;
391 while (sqlite3_step(stmt) == SQLITE_ROW) {
392 size_type = sqlite3_column_int(stmt, 0);
393 size_list |= size_type;
396 package_set_size_list(info, size_list);
399 sqlite3_clear_bindings(stmt);
400 sqlite3_finalize(stmt);
401 return DBOX_STATUS_ERROR_NONE;
404 static inline int load_context_option(struct context_item *item, int id)
406 static const char *dml = "SELECT key, value FROM option WHERE option_id = ?";
412 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
413 if (ret != SQLITE_OK) {
414 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
415 return DBOX_STATUS_ERROR_IO_ERROR;
418 ret = sqlite3_bind_int(stmt, 1, id);
419 if (ret != SQLITE_OK) {
420 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
421 ret = DBOX_STATUS_ERROR_IO_ERROR;
425 ret = DBOX_STATUS_ERROR_NOT_EXIST;
426 while (sqlite3_step(stmt) == SQLITE_ROW) {
427 key = (const char *)sqlite3_column_text(stmt, 0);
428 if (!key || !strlen(key)) {
429 ErrPrint("KEY is nil\n");
433 value = (const char *)sqlite3_column_text(stmt, 1);
434 if (!value || !strlen(value)) {
435 ErrPrint("VALUE is nil\n");
439 ret = group_add_option(item, key, value);
447 sqlite3_clear_bindings(stmt);
448 sqlite3_finalize(stmt);
452 static inline int load_context_item(struct context_info *info, int id)
454 static const char *dml = "SELECT ctx_item, option_id FROM groupmap WHERE id = ?";
455 struct context_item *item;
457 const char *ctx_item;
461 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
462 if (ret != SQLITE_OK) {
463 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
464 return DBOX_STATUS_ERROR_IO_ERROR;
467 ret = sqlite3_bind_int(stmt, 1, id);
468 if (ret != SQLITE_OK) {
469 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
470 ret = DBOX_STATUS_ERROR_IO_ERROR;
474 ret = DBOX_STATUS_ERROR_NOT_EXIST;
475 while (sqlite3_step(stmt) == SQLITE_ROW) {
476 ctx_item = (const char *)sqlite3_column_text(stmt, 0);
477 option_id = sqlite3_column_int(stmt, 1);
479 item = group_add_context_item(info, ctx_item);
481 ErrPrint("Failed to add a new context item\n");
482 ret = DBOX_STATUS_ERROR_FAULT;
486 ret = load_context_option(item, option_id);
494 sqlite3_clear_bindings(stmt);
495 sqlite3_finalize(stmt);
499 static inline int build_group_info(struct pkg_info *info)
501 static const char *dml = "SELECT id, cluster, category FROM groupinfo WHERE pkgid = ?";
505 const char *cluster_name;
506 const char *category_name;
507 struct cluster *cluster;
508 struct category *category;
509 struct context_info *ctx_info;
511 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
512 if (ret != SQLITE_OK) {
513 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
514 return DBOX_STATUS_ERROR_IO_ERROR;
517 ret = sqlite3_bind_text(stmt, 1, package_name(info), -1, SQLITE_TRANSIENT);
518 if (ret != SQLITE_OK) {
519 ErrPrint("Failed to bind a package name(%s)\n", package_name(info));
520 sqlite3_finalize(stmt);
521 return DBOX_STATUS_ERROR_IO_ERROR;
524 while (sqlite3_step(stmt) == SQLITE_ROW) {
525 id = sqlite3_column_int(stmt, 0);
526 cluster_name = (const char *)sqlite3_column_text(stmt, 1);
527 if (!cluster_name || !strlen(cluster_name)) {
528 DbgPrint("Cluster name is not valid\n");
532 category_name = (const char *)sqlite3_column_text(stmt, 2);
533 if (!category_name || !strlen(category_name)) {
534 DbgPrint("Category name is not valid\n");
538 cluster = group_find_cluster(cluster_name);
540 cluster = group_create_cluster(cluster_name);
542 ErrPrint("Failed to create a cluster(%s)\n", cluster_name);
547 category = group_find_category(cluster, category_name);
549 category = group_create_category(cluster, category_name);
551 ErrPrint("Failed to create a category(%s)\n", category_name);
558 * Step 1. Get the list of the context item from the DB using 'id'
559 * {context_item, option_id}
560 * Step 2. Get the list of the options from the DB using option_id
563 ctx_info = group_create_context_info(category, package_name(info));
565 ret = load_context_item(ctx_info, id);
567 if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST) {
568 DbgPrint("Has no specific context info\n");
570 DbgPrint("Context info is not valid\n");
571 group_destroy_context_info(ctx_info);
577 package_add_ctx_info(info, ctx_info);
583 sqlite3_clear_bindings(stmt);
584 sqlite3_finalize(stmt);
585 return DBOX_STATUS_ERROR_NONE;
588 HAPI int io_is_exists(const char *lbid)
593 if (!s_info.handle) {
594 ErrPrint("DB is not ready\n");
595 return DBOX_STATUS_ERROR_IO_ERROR;
598 ret = sqlite3_prepare_v2(s_info.handle, "SELECT COUNT(pkgid) FROM pkgmap WHERE pkgid = ?", -1, &stmt, NULL);
599 if (ret != SQLITE_OK) {
600 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
601 return DBOX_STATUS_ERROR_IO_ERROR;
604 ret = sqlite3_bind_text(stmt, 1, lbid, -1, SQLITE_TRANSIENT);
605 if (ret != SQLITE_OK) {
606 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
607 ret = DBOX_STATUS_ERROR_IO_ERROR;
611 if (sqlite3_step(stmt) != SQLITE_ROW) {
612 ErrPrint("%s has no record (%s)\n", lbid, sqlite3_errmsg(s_info.handle));
613 ret = DBOX_STATUS_ERROR_IO_ERROR;
617 ret = sqlite3_column_int(stmt, 0);
620 sqlite3_finalize(stmt);
624 HAPI char *io_dynamicbox_pkgname(const char *pkgname)
633 if (!s_info.handle) {
634 ErrPrint("DB is not ready\n");
638 ret = sqlite3_prepare_v2(s_info.handle, "SELECT pkgid FROM pkgmap WHERE (appid = ? AND prime = 1) OR pkgid = ?", -1, &stmt, NULL);
639 if (ret != SQLITE_OK) {
640 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
644 ret = sqlite3_bind_text(stmt, 1, pkgname, -1, SQLITE_TRANSIENT);
645 if (ret != SQLITE_OK) {
646 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
650 ret = sqlite3_bind_text(stmt, 2, pkgname, -1, SQLITE_TRANSIENT);
651 if (ret != SQLITE_OK) {
652 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
656 if (sqlite3_step(stmt) != SQLITE_ROW) {
657 ErrPrint("%s has no record (%s)\n", pkgname, sqlite3_errmsg(s_info.handle));
661 tmp = (char *)sqlite3_column_text(stmt, 0);
662 if (tmp && strlen(tmp)) {
665 ErrPrint("Heap: %s\n", strerror(errno));
671 sqlite3_finalize(stmt);
675 HAPI int io_crawling_dynamicboxes(int (*cb)(const char *pkgid, const char *lbid, int prime, void *data), void *data)
679 if (!s_info.handle) {
680 ErrPrint("DB is not ready\n");
685 ret = sqlite3_prepare_v2(s_info.handle, "SELECT appid, pkgid, prime FROM pkgmap", -1, &stmt, NULL);
686 if (ret != SQLITE_OK) {
687 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
693 while (sqlite3_step(stmt) == SQLITE_ROW) {
694 pkgid = (const char *)sqlite3_column_text(stmt, 0);
695 if (!pkgid || !strlen(pkgid)) {
699 lbid = (const char *)sqlite3_column_text(stmt, 1);
700 if (!lbid || !strlen(lbid)) {
704 prime = (int)sqlite3_column_int(stmt, 1);
706 if (cb(pkgid, lbid, prime, data) < 0) {
708 sqlite3_finalize(stmt);
709 return DBOX_STATUS_ERROR_CANCEL;
714 sqlite3_finalize(stmt);
718 dir = opendir(DYNAMICBOX_CONF_ROOT_PATH);
720 ErrPrint("Error: %s\n", strerror(errno));
724 while ((ent = readdir(dir))) {
725 if (ent->d_name[0] == '.') {
729 if (cb(ent->d_name, ent->d_name, -2, data) < 0) {
730 if (closedir(dir) < 0) {
731 ErrPrint("closedir: %s\n", strerror(errno));
733 return DBOX_STATUS_ERROR_CANCEL;
737 if (closedir(dir) < 0) {
738 ErrPrint("closedir: %s\n", strerror(errno));
742 return DBOX_STATUS_ERROR_NONE;
745 HAPI int io_update_dynamicbox_package(const char *pkgid, int (*cb)(const char *pkgid, const char *lbid, int prime, void *data), void *data)
753 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
756 if (!s_info.handle) {
757 ErrPrint("DB is not ready\n");
758 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
761 ret = sqlite3_prepare_v2(s_info.handle, "SELECT pkgid, prime FROM pkgmap WHERE appid = ?", -1, &stmt, NULL);
762 if (ret != SQLITE_OK) {
763 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
764 return DBOX_STATUS_ERROR_FAULT;
767 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
768 if (ret != SQLITE_OK) {
769 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
770 ret = DBOX_STATUS_ERROR_FAULT;
775 while (sqlite3_step(stmt) == SQLITE_ROW) {
776 lbid = (char *)sqlite3_column_text(stmt, 0);
777 if (!lbid || !strlen(lbid)) {
781 prime = sqlite3_column_int(stmt, 1);
783 if (cb(pkgid, lbid, prime, data) < 0) {
784 DbgPrint("Callback canceled\n");
792 sqlite3_finalize(stmt);
796 HAPI int io_load_package_db(struct pkg_info *info)
800 if (!s_info.handle) {
801 ErrPrint("DB is not ready\n");
802 return DBOX_STATUS_ERROR_IO_ERROR;
805 ret = build_provider_info(info);
810 ret = build_client_info(info);
815 ret = build_box_size_info(info);
820 ret = build_group_info(info);
825 return DBOX_STATUS_ERROR_NONE;
828 static inline int db_init(void)
833 ret = db_util_open_with_options(DYNAMICBOX_CONF_DBFILE, &s_info.handle, SQLITE_OPEN_READONLY, NULL);
834 if (ret != SQLITE_OK) {
835 ErrPrint("Failed to open a DB\n");
836 return DBOX_STATUS_ERROR_IO_ERROR;
839 if (lstat(DYNAMICBOX_CONF_DBFILE, &stat) < 0) {
840 db_util_close(s_info.handle);
841 s_info.handle = NULL;
842 ErrPrint("%s\n", strerror(errno));
843 return DBOX_STATUS_ERROR_IO_ERROR;
846 if (!S_ISREG(stat.st_mode)) {
847 ErrPrint("Invalid file\n");
848 db_util_close(s_info.handle);
849 s_info.handle = NULL;
850 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
853 if (stat.st_size <= 0) {
854 DbgPrint("Size is %d (But use this ;)\n", stat.st_size);
857 return DBOX_STATUS_ERROR_NONE;
860 static inline int db_fini(void)
862 if (!s_info.handle) {
863 return DBOX_STATUS_ERROR_NONE;
866 db_util_close(s_info.handle);
867 s_info.handle = NULL;
869 return DBOX_STATUS_ERROR_NONE;
872 HAPI int io_init(void)
878 DbgPrint("DB initialized: %d\n", ret);
881 ret = load_abi_table();
883 DbgPrint("ABI table is loaded: %d\n", ret);
886 return DBOX_STATUS_ERROR_NONE;
889 HAPI int io_fini(void)
897 DbgPrint("DB finalized: %d\n", ret);
899 return DBOX_STATUS_ERROR_NONE;