2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (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://www.tizenopensource.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>
27 #include <libxml/parser.h>
28 #include <libxml/tree.h>
34 #define DbgPrint(format, arg...) LOGD("[
\e[32m%s/%s
\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
35 #define ErrPrint(format, arg...) LOGE("[
\e[32m%s/%s
\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
44 * +-------+-------+---------+
45 * | appid | pkgid | prime |
46 * +-------+-------+---------+
48 * +-------+-------+---------+
49 * CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, prime INTEGER )
53 * +-------+---------+-----+---------+----------+---------+-----------+---------+--------+----------+---------+---------+--------+--------+-------+
54 * | pkgid | network | abi | secured | box_type | box_src | box_group | pd_type | pd_src | pd_group | libexec | timeout | period | script | pinup |
55 * +-------+---------+-----+---------+----------+---------+-----------+---------+--------+----------+---------+---------+--------+--------+-------+
56 * | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
57 * +-------+---------+-----+---------+----------+---------+-----------+---------+--------+----------+---------+---------+--------+--------+-------+
58 * CREATE TABLE provider ( pkgid TEXT PRIMARY KEY NOT NULL, network INTEGER, abi TEXT, secured INTEGER, box_type INTEGER, box_src TEXT, box_group TEXT, pd_type TEXT, pd_src TEXT, pd_group TEXT, libexec TEXT, timeout INTEGER, period TEXT, script TEXT, pinup INTEGER, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid))
60 * = box_type = { text | buffer | script | image }
61 * = pd_type = { text | buffer | script }
62 * = network = { 1 | 0 }
63 * = secured = { 1 | 0 }
67 * +-------+------+---------+-------------+---------+---------+-----------+-------+-------------+
68 * | pkgid | Icon | Name | auto_launch | pd_size | content | nodisplay | setup | mouse_event |
69 * +-------+------+---------+-------------+---------+---------+-----------+-------+-------------+
70 * | - | - | - | - | - | - | - | - | - }
71 * +-------+------+---------+-------------+---------+---------+-----------+-------+-------------+
72 * CREATE TABLE client ( pkgid TEXT PRIMARY KEY NOT NULL, icon TEXT, name TEXT, auto_launch TEXT, pd_size TEXT, content TEXT DEFAULT "default", nodisplay INTEGER, setup TEXT, mouse_event INTEGER, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
74 * = auto_launch = UI-APPID
75 * = pd_size = WIDTHxHEIGHT
79 * +-------+------+------+------+
80 * | fk | lang | name | icon |
81 * +-------+------+------+------+
82 * | pkgid | - | - | - |
83 * +-------+------+------+------+
84 * CREATE TABLE i18n ( pkgid TEXT NOT NULL, lang TEXT COLLATE NOCASE, name TEXT, icon TEXT, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
88 * +-------+-----------+---------+
89 * | pkgid | size_type | preview |
90 * +-------+-----------+---------+
92 * +-------+-----------+---------+
93 * CREATE TABLE box_size ( pkgid TEXT NOT NULL, size_type INTEGER, preview TEXT, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
95 * = box_size_list = { WIDTHxHEIGHT; WIDTHxHEIGHT; ... }
98 * +----+---------+----------+-------+
99 * | id | cluster | category | pkgid |
100 * +----+---------+----------+-------+
102 * +----+---------+----------+-------|
103 * CREATE TABLE groupinfo ( id INTEGER PRIMARY KEY AUTOINCREMENT, cluster TEXT NOT NULL, category TEXT NOT NULL, appid TEXT NOT NULL, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ))
106 * +-------+----+----------+-----------+
107 * | pkgid | id | ctx_item | option_id |
108 * +-------+----+----------+-----------+
109 * CREATE TABLE groupmap ( option_id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER, pkgid TEXT NOT NULL, ctx_item TEXT NOT NULL, FOREIGN KEY(id) REFERENCES groupinfo(id), FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
113 * +-------+-----------+-----+-------+
114 * | pkgid | option_id | key | value |
115 * +-------+-----------+-----+-------+
116 * CREATE TABLE option ( pkgid TEXT NOT NULL, option_id INTEGER, key TEXT NOT NULL, value TEXT NOT NULL, FOREIGN KEY(option_id) REFERENCES groupmap(option_id), FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
119 #if !defined(LIBXML_TREE_ENABLED)
120 #error "LIBXML is not supporting the tree"
127 #define LOG_TAG "PKGMGR_LIVEBOX"
166 xmlChar *auto_launch;
168 xmlChar *name; /* Default name */
169 xmlChar *icon; /* Default icon */
170 xmlChar *libexec; /* Path of the SO file */
171 xmlChar *timeout; /* INTEGER, timeout */
172 xmlChar *period; /* DOUBLE, update period */
173 xmlChar *script; /* Script engine */
174 xmlChar *content; /* Content information */
177 int pinup; /* Is this support the pinup feature? */
178 int primary; /* Is this primary livebox? */
180 int mouse_event; /* Mouse event processing option for livebox */
182 enum lb_type lb_type;
185 int size_list; /* 1x1, 2x1, 2x2, 4x1, 4x2, 4x3, 4x4 */
189 enum pd_type pd_type;
192 xmlChar *pd_size; /* Default PD size */
194 struct dlist *i18n_list;
195 struct dlist *group_list;
202 struct dlist *option_list;
214 .dbfile = "/opt/dbspace/.livebox.db",
218 static inline int begin_transaction(void)
223 ret = sqlite3_prepare_v2(s_info.handle, "BEGIN TRANSACTION", -1, &stmt, NULL);
225 if (ret != SQLITE_OK) {
226 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
230 if (sqlite3_step(stmt) != SQLITE_DONE) {
231 DbgPrint("Failed to do update (%s)\n",
232 sqlite3_errmsg(s_info.handle));
233 sqlite3_finalize(stmt);
237 sqlite3_finalize(stmt);
241 static inline int rollback_transaction(void)
246 ret = sqlite3_prepare_v2(s_info.handle, "ROLLBACK TRANSACTION", -1, &stmt, NULL);
247 if (ret != SQLITE_OK) {
248 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
252 if (sqlite3_step(stmt) != SQLITE_DONE) {
253 DbgPrint("Failed to do update (%s)\n",
254 sqlite3_errmsg(s_info.handle));
255 sqlite3_finalize(stmt);
259 sqlite3_finalize(stmt);
263 static inline int commit_transaction(void)
268 ret = sqlite3_prepare_v2(s_info.handle, "COMMIT TRANSACTION", -1, &stmt, NULL);
269 if (ret != SQLITE_OK) {
270 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
274 if (sqlite3_step(stmt) != SQLITE_DONE) {
275 DbgPrint("Failed to do update (%s)\n",
276 sqlite3_errmsg(s_info.handle));
277 sqlite3_finalize(stmt);
281 sqlite3_finalize(stmt);
285 static inline int db_create_pkgmap(void)
288 static const char *ddl;
290 ddl = "CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, prime INTEGER )";
291 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
292 ErrPrint("Failed to execute the DDL (%s)\n", err);
296 if (sqlite3_changes(s_info.handle) == 0)
297 ErrPrint("No changes to DB\n");
302 static inline int db_insert_pkgmap(const char *appid, const char *pkgid, int primary)
305 static const char *dml;
308 dml = "INSERT INTO pkgmap ( appid, pkgid, prime ) VALUES (? ,?, ?)";
309 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
310 if (ret != SQLITE_OK) {
311 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
315 ret = sqlite3_bind_text(stmt, 1, appid, -1, NULL);
316 if (ret != SQLITE_OK) {
317 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
322 ret = sqlite3_bind_text(stmt, 2, pkgid, -1, NULL);
323 if (ret != SQLITE_OK) {
324 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
329 ret = sqlite3_bind_int(stmt, 3, primary);
330 if (ret != SQLITE_OK) {
331 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
337 if (sqlite3_step(stmt) != SQLITE_DONE) {
338 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
344 sqlite3_clear_bindings(stmt);
345 sqlite3_finalize(stmt);
349 static inline int db_remove_pkgmap(const char *pkgid)
352 static const char *dml;
355 dml = "DELETE FROM pkgmap WHERE pkgid = ?";
356 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
357 if (ret != SQLITE_OK) {
358 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
362 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
363 if (ret != SQLITE_OK) {
364 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
370 if (sqlite3_step(stmt) != SQLITE_DONE) {
371 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
377 sqlite3_clear_bindings(stmt);
378 sqlite3_finalize(stmt);
382 static inline int db_create_provider(void)
385 static const char *ddl;
387 ddl = "CREATE TABLE provider (" \
388 "pkgid TEXT PRIMARY KEY NOT NULL, network INTEGER, " \
389 "abi TEXT, secured INTEGER, box_type INTEGER, " \
390 "box_src TEXT, box_group TEXT, pd_type INTEGER, " \
391 "pd_src TEXT, pd_group TEXT, libexec TEXT, timeout INTEGER, period TEXT, script TEXT, pinup INTEGER, "\
392 "FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
394 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
395 ErrPrint("Failed to execute the DDL (%s)\n", err);
399 if (sqlite3_changes(s_info.handle) == 0)
400 ErrPrint("No changes to DB\n");
405 static inline int db_remove_provider(const char *pkgid)
407 static const char *dml;
411 dml = "DELETE FROM provider WHERE pkgid = ?";
412 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
413 if (ret != SQLITE_OK) {
414 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
418 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
419 if (ret != SQLITE_OK) {
420 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
426 if (sqlite3_step(stmt) != SQLITE_DONE) {
427 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
433 sqlite3_clear_bindings(stmt);
434 sqlite3_finalize(stmt);
437 static inline int db_insert_provider(struct livebox *livebox)
439 static const char *dml;
442 char *abi = (char *)livebox->abi;
443 char *box_src = (char *)livebox->lb_src;
444 char *box_group = (char *)livebox->lb_group;
445 char *pd_src = (char *)livebox->pd_src;
446 char *pd_group = (char *)livebox->pd_group;
447 char *libexec = (char *)livebox->libexec;
448 char *timeout = (char *)livebox->timeout;
449 char *period = (char *)livebox->period;
450 char *script = (char *)livebox->script;
479 dml = "INSERT INTO provider ( pkgid, network, abi, secured, box_type, box_src, box_group, pd_type, pd_src, pd_group, libexec, timeout, period, script, pinup ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
480 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
481 if (ret != SQLITE_OK) {
482 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
486 ret = sqlite3_bind_text(stmt, 1, (char *)livebox->pkgid, -1, NULL);
487 if (ret != SQLITE_OK) {
488 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
494 ret = sqlite3_bind_int(stmt, 2, livebox->network);
495 if (ret != SQLITE_OK) {
496 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
501 ret = sqlite3_bind_text(stmt, 3, abi, -1, NULL);
502 if (ret != SQLITE_OK) {
503 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
507 ret = sqlite3_bind_int(stmt, 4, livebox->secured);
508 if (ret != SQLITE_OK) {
509 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
514 ret = sqlite3_bind_int(stmt, 5, livebox->lb_type);
515 if (ret != SQLITE_OK) {
516 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
521 ret = sqlite3_bind_text(stmt, 6, box_src, -1, NULL);
522 if (ret != SQLITE_OK) {
523 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
528 ret = sqlite3_bind_text(stmt, 7, box_group, -1, NULL);
529 if (ret != SQLITE_OK) {
530 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
535 ret = sqlite3_bind_int(stmt, 8, livebox->pd_type);
536 if (ret != SQLITE_OK) {
537 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
542 ret = sqlite3_bind_text(stmt, 9, pd_src, -1, NULL);
543 if (ret != SQLITE_OK) {
544 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
549 ret = sqlite3_bind_text(stmt, 10, pd_group, -1, NULL);
550 if (ret != SQLITE_OK) {
551 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
556 ret = sqlite3_bind_text(stmt, 11, libexec, -1, NULL);
557 if (ret != SQLITE_OK) {
558 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
563 ret = sqlite3_bind_int(stmt, 12, atoi(timeout));
564 if (ret != SQLITE_OK) {
565 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
570 ret = sqlite3_bind_text(stmt, 13, period, -1, NULL);
571 if (ret != SQLITE_OK) {
572 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
577 ret = sqlite3_bind_text(stmt, 14, script, -1, NULL);
578 if (ret != SQLITE_OK) {
579 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
584 ret = sqlite3_bind_int(stmt, 15, livebox->pinup);
585 if (ret != SQLITE_OK) {
586 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
592 if (sqlite3_step(stmt) != SQLITE_DONE) {
593 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
599 sqlite3_clear_bindings(stmt);
600 sqlite3_finalize(stmt);
604 static inline int db_create_client(void)
607 static const char *ddl;
609 ddl = "CREATE TABLE client (" \
610 "pkgid TEXT PRIMARY KEY NOT NULL, icon TEXT, name TEXT, " \
611 "auto_launch TEXT, pd_size TEXT, content TEXT DEFAULT 'default', nodisplay INTEGER, setup TEXT, mouse_event INTEGER, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
612 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
613 ErrPrint("Failed to execute the DDL (%s)\n", err);
617 if (sqlite3_changes(s_info.handle) == 0)
618 ErrPrint("No changes to DB\n");
623 static inline int db_insert_client(struct livebox *livebox)
625 static const char *dml;
629 dml = "INSERT INTO client ( pkgid, icon, name, auto_launch, pd_size, content, nodisplay, setup, mouse_event ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
630 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
631 if (ret != SQLITE_OK) {
632 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
636 ret = sqlite3_bind_text(stmt, 1, (char *)livebox->pkgid, -1, NULL);
637 if (ret != SQLITE_OK) {
638 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
643 ret = sqlite3_bind_text(stmt, 2, (char *)livebox->icon, -1, NULL);
644 if (ret != SQLITE_OK) {
645 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
650 ret = sqlite3_bind_text(stmt, 3, (char *)livebox->name, -1, NULL);
651 if (ret != SQLITE_OK) {
652 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
657 ret = sqlite3_bind_text(stmt, 4, (char *)livebox->auto_launch, -1, NULL);
658 if (ret != SQLITE_OK) {
659 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
664 ret = sqlite3_bind_text(stmt, 5, (char *)livebox->pd_size, -1, NULL);
665 if (ret != SQLITE_OK) {
666 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
671 ret = sqlite3_bind_text(stmt, 6, livebox->content ? (char *)livebox->content : "default", -1, NULL);
672 if (ret != SQLITE_OK) {
673 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
678 ret = sqlite3_bind_int(stmt, 7, livebox->nodisplay);
679 if (ret != SQLITE_OK) {
680 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
685 ret = sqlite3_bind_text(stmt, 8, livebox->setup ? (char *)livebox->setup : "", -1, NULL);
686 if (ret != SQLITE_OK) {
687 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
692 ret = sqlite3_bind_int(stmt, 9, livebox->mouse_event);
693 if (ret != SQLITE_OK) {
694 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
700 if (sqlite3_step(stmt) != SQLITE_DONE) {
701 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
707 sqlite3_clear_bindings(stmt);
708 sqlite3_finalize(stmt);
712 static inline int db_remove_client(const char *pkgid)
714 static const char *dml;
718 dml = "DELETE FROM client WHERE pkgid = ?";
719 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
720 if (ret != SQLITE_OK) {
721 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
725 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
726 if (ret != SQLITE_OK) {
727 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
733 if (sqlite3_step(stmt) != SQLITE_DONE) {
734 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
740 sqlite3_clear_bindings(stmt);
741 sqlite3_finalize(stmt);
745 static inline int db_create_i18n(void)
748 static const char *ddl;
750 ddl = "CREATE TABLE i18n ( pkgid TEXT NOT NULL, lang TEXT COLLATE NOCASE, name TEXT, " \
751 "icon TEXT, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
752 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
753 ErrPrint("Failed to execute the DDL (%s)\n", err);
757 if (sqlite3_changes(s_info.handle) == 0)
758 ErrPrint("No changes to DB\n");
763 static inline int db_insert_i18n(const char *pkgid, const char *lang, const char *name, const char *icon)
765 static const char *dml;
769 DbgPrint("%s - lang[%s] name[%s] icon[%s]\n", pkgid, lang, name, icon);
770 dml = "INSERT INTO i18n ( pkgid, lang, name, icon ) VALUES (?, ?, ?, ?)";
771 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
772 if (ret != SQLITE_OK) {
773 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
777 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
778 if (ret != SQLITE_OK) {
779 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
784 ret = sqlite3_bind_text(stmt, 2, lang, -1, NULL);
785 if (ret != SQLITE_OK) {
786 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
791 ret = sqlite3_bind_text(stmt, 3, name, -1, NULL);
792 if (ret != SQLITE_OK) {
793 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
798 ret = sqlite3_bind_text(stmt, 4, icon, -1, NULL);
799 if (ret != SQLITE_OK) {
800 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
806 if (sqlite3_step(stmt) != SQLITE_DONE) {
807 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
813 sqlite3_clear_bindings(stmt);
814 sqlite3_finalize(stmt);
818 static inline int db_remove_i18n(const char *pkgid)
820 static const char *dml;
824 dml = "DELETE FROM i18n WHERE pkgid = ?";
825 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
826 if (ret != SQLITE_OK) {
827 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
831 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
832 if (ret != SQLITE_OK) {
833 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
839 if (sqlite3_step(stmt) != SQLITE_DONE) {
840 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
844 if (sqlite3_changes(s_info.handle) == 0)
845 DbgPrint("No changes\n");
849 sqlite3_clear_bindings(stmt);
850 sqlite3_finalize(stmt);
854 static inline int db_create_group(void)
857 static const char *ddl;
859 ddl = "CREATE TABLE groupinfo ( id INTEGER PRIMARY KEY AUTOINCREMENT, cluster TEXT NOT NULL, category TEXT NOT NULL, pkgid TEXT NOT NULL, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
860 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
861 ErrPrint("Failed to execute the DDL (%s)\n", err);
865 if (sqlite3_changes(s_info.handle) == 0)
866 ErrPrint("No changes to DB\n");
871 static inline int db_insert_group(const char *pkgid, const char *cluster, const char *category)
873 static const char *dml;
877 dml = "INSERT INTO groupinfo ( cluster, category, pkgid ) VALUES (?, ?, ?)";
878 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
879 if (ret != SQLITE_OK) {
880 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
884 ret = sqlite3_bind_text(stmt, 1, cluster, -1, NULL);
885 if (ret != SQLITE_OK) {
886 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
891 ret = sqlite3_bind_text(stmt, 2, category, -1, NULL);
892 if (ret != SQLITE_OK) {
893 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
898 ret = sqlite3_bind_text(stmt, 3, pkgid, -1, NULL);
899 if (ret != SQLITE_OK) {
900 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
906 if (sqlite3_step(stmt) != SQLITE_DONE) {
907 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
913 sqlite3_clear_bindings(stmt);
914 sqlite3_finalize(stmt);
918 static inline int db_get_group_id(const char *cluster, const char *category)
920 static const char *dml = "SELECT id FROM groupinfo WHERE cluster = ? AND category = ?";
924 if (!cluster || !category) {
925 ErrPrint("Invalid argument\n");
929 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
930 if (ret != SQLITE_OK) {
931 ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
936 if (sqlite3_bind_text(stmt, 1, cluster, -1, NULL) != SQLITE_OK) {
937 ErrPrint("Failed to bind a cluster(%s) - %s\n", cluster, sqlite3_errmsg(s_info.handle));
941 if (sqlite3_bind_text(stmt, 2, category, -1, NULL) != SQLITE_OK) {
942 ErrPrint("Failed to bind a category(%s) - %s\n", category, sqlite3_errmsg(s_info.handle));
946 if (sqlite3_step(stmt) != SQLITE_ROW) {
947 ErrPrint("Failed to execute the DML for %s - %s\n", cluster, category);
951 ret = sqlite3_column_int(stmt, 0);
955 sqlite3_clear_bindings(stmt);
956 sqlite3_finalize(stmt);
960 static inline int db_remove_group(const char *pkgid)
962 static const char *dml;
966 dml = "DELETE FROM groupinfo WHERE pkgid = ?";
967 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
968 if (ret != SQLITE_OK) {
969 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
973 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
974 if (ret != SQLITE_OK) {
975 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
981 if (sqlite3_step(stmt) != SQLITE_DONE) {
982 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
986 if (sqlite3_changes(s_info.handle) == 0)
987 DbgPrint("No changes\n");
991 sqlite3_clear_bindings(stmt);
992 sqlite3_finalize(stmt);
996 static inline int db_create_groupmap(void)
999 static const char *ddl;
1001 ddl = "CREATE TABLE groupmap (option_id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER, pkgid TEXT NOT NULL, ctx_item TEXT NOT NULL, FOREIGN KEY(id) REFERENCES groupinfo(id), FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
1002 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1003 ErrPrint("Failed to execute the DDL (%s)\n", err);
1007 if (sqlite3_changes(s_info.handle) == 0)
1008 ErrPrint("No changes to DB\n");
1013 static inline int db_get_option_id(int id, const char *pkgid, const char *ctx_item)
1015 static const char *dml;
1019 dml = "SELECT option_id FROM groupmap WHERE id = ? AND pkgid = ? AND ctx_item = ?";
1020 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1021 if (ret != SQLITE_OK) {
1022 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1026 ret = sqlite3_bind_int(stmt, 1, id);
1027 if (ret != SQLITE_OK) {
1028 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1033 ret = sqlite3_bind_text(stmt, 2, pkgid, -1, NULL);
1034 if (ret != SQLITE_OK) {
1035 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1040 ret = sqlite3_bind_text(stmt, 3, ctx_item, -1, NULL);
1041 if (ret != SQLITE_OK) {
1042 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1048 if (sqlite3_step(stmt) != SQLITE_ROW) {
1049 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1054 ret = sqlite3_column_int(stmt, 0);
1057 sqlite3_reset(stmt);
1058 sqlite3_clear_bindings(stmt);
1059 sqlite3_finalize(stmt);
1063 static inline int db_insert_groupmap(int id, const char *pkgid, const char *ctx_item)
1065 static const char *dml;
1069 DbgPrint("%d (%s) add to groupmap\n", id, pkgid);
1071 dml = "INSERT INTO groupmap ( id, pkgid, ctx_item ) VALUES (?, ?, ?)";
1072 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1073 if (ret != SQLITE_OK) {
1074 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1078 ret = sqlite3_bind_int(stmt, 1, id);
1079 if (ret != SQLITE_OK) {
1080 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1085 ret = sqlite3_bind_text(stmt, 2, pkgid, -1, NULL);
1086 if (ret != SQLITE_OK) {
1087 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1092 ret = sqlite3_bind_text(stmt, 3, ctx_item, -1, NULL);
1093 if (ret != SQLITE_OK) {
1094 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1100 if (sqlite3_step(stmt) != SQLITE_DONE) {
1101 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1106 sqlite3_reset(stmt);
1107 sqlite3_clear_bindings(stmt);
1108 sqlite3_finalize(stmt);
1112 static inline int db_remove_groupmap(const char *pkgid)
1114 static const char *dml;
1118 dml = "DELETE FROM groupmap WHERE pkgid = ?";
1119 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1120 if (ret != SQLITE_OK) {
1121 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1125 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1126 if (ret != SQLITE_OK) {
1127 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1133 if (sqlite3_step(stmt) != SQLITE_DONE) {
1134 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1138 if (sqlite3_changes(s_info.handle) == 0)
1139 DbgPrint("No changes\n");
1142 sqlite3_reset(stmt);
1143 sqlite3_clear_bindings(stmt);
1144 sqlite3_finalize(stmt);
1148 static inline int db_create_option(void)
1151 static const char *ddl;
1153 ddl = "CREATE TABLE option ( pkgid TEXT NOT NULL, option_id INTEGER, key TEXT NOT NULL, value TEXT NOT NULL, " \
1154 "FOREIGN KEY(option_id) REFERENCES groupmap(option_id), " \
1155 "FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
1156 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1157 ErrPrint("Failed to execute the DDL (%s)\n", err);
1161 if (sqlite3_changes(s_info.handle) == 0)
1162 ErrPrint("No changes to DB\n");
1167 static inline int db_insert_option(const char *pkgid, int option_id, const char *key, const char *value)
1169 static const char *dml;
1173 dml = "INSERT INTO option (pkgid, option_id, key, value) VALUES (?, ?, ?, ?)";
1174 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1175 if (ret != SQLITE_OK) {
1176 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1180 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1181 if (ret != SQLITE_OK) {
1182 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1187 ret = sqlite3_bind_int(stmt, 2, option_id);
1188 if (ret != SQLITE_OK) {
1189 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1194 ret = sqlite3_bind_text(stmt, 3, key, -1, NULL);
1195 if (ret != SQLITE_OK) {
1196 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1201 ret = sqlite3_bind_text(stmt, 4, value, -1, NULL);
1202 if (ret != SQLITE_OK) {
1203 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1209 if (sqlite3_step(stmt) != SQLITE_DONE) {
1210 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1214 sqlite3_reset(stmt);
1215 sqlite3_clear_bindings(stmt);
1216 sqlite3_finalize(stmt);
1220 static inline int db_remove_option(const char *pkgid)
1222 static const char *dml;
1226 dml = "DELETE FROM option WHERE pkgid = ?";
1227 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1228 if (ret != SQLITE_OK) {
1229 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1233 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1234 if (ret != SQLITE_OK) {
1235 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1241 if (sqlite3_step(stmt) != SQLITE_DONE) {
1242 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1246 if (sqlite3_changes(s_info.handle) == 0)
1247 DbgPrint("No changes\n");
1250 sqlite3_reset(stmt);
1251 sqlite3_clear_bindings(stmt);
1252 sqlite3_finalize(stmt);
1256 static inline int db_create_box_size(void)
1259 static const char *ddl;
1261 ddl = "CREATE TABLE box_size ( pkgid TEXT NOT NULL, size_type INTEGER, preview TEXT, " \
1262 "FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
1263 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1264 ErrPrint("Failed to execute the DDL (%s)\n", err);
1268 if (sqlite3_changes(s_info.handle) == 0)
1269 ErrPrint("No changes to DB\n");
1274 static inline int db_insert_box_size(const char *pkgid, int size_type, const char *preview)
1276 static const char *dml;
1280 DbgPrint("box size: %s - %d (%s) is added\n", pkgid, size_type, preview);
1281 dml = "INSERT INTO box_size ( pkgid, size_type, preview ) VALUES (?, ?, ?)";
1282 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1283 if (ret != SQLITE_OK) {
1284 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1288 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1289 if (ret != SQLITE_OK) {
1290 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1295 ret = sqlite3_bind_int(stmt, 2, size_type);
1296 if (ret != SQLITE_OK) {
1297 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1302 ret = sqlite3_bind_text(stmt, 3, preview ? preview : "", -1, NULL);
1303 if (ret != SQLITE_OK) {
1304 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1310 if (sqlite3_step(stmt) != SQLITE_DONE) {
1311 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1316 sqlite3_reset(stmt);
1317 sqlite3_clear_bindings(stmt);
1318 sqlite3_finalize(stmt);
1322 static inline int db_remove_box_size(const char *pkgid)
1324 static const char *dml;
1328 dml = "DELETE FROM box_size WHERE pkgid = ?";
1329 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1330 if (ret != SQLITE_OK) {
1331 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1335 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1336 if (ret != SQLITE_OK) {
1337 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1343 if (sqlite3_step(stmt) != SQLITE_DONE) {
1344 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1348 if (sqlite3_changes(s_info.handle) == 0)
1349 DbgPrint("No changes\n");
1352 sqlite3_reset(stmt);
1353 sqlite3_clear_bindings(stmt);
1354 sqlite3_finalize(stmt);
1358 static inline void db_create_table(void)
1361 begin_transaction();
1363 ret = db_create_pkgmap();
1365 rollback_transaction();
1369 ret = db_create_provider();
1371 rollback_transaction();
1375 ret = db_create_client();
1377 rollback_transaction();
1381 ret = db_create_i18n();
1383 rollback_transaction();
1387 ret = db_create_box_size();
1389 rollback_transaction();
1393 ret = db_create_group();
1395 rollback_transaction();
1399 ret = db_create_option();
1401 rollback_transaction();
1405 ret = db_create_groupmap();
1407 rollback_transaction();
1411 commit_transaction();
1414 static inline int db_init(void)
1419 ret = db_util_open(s_info.dbfile, &s_info.handle, DB_UTIL_REGISTER_HOOK_METHOD);
1420 if (ret != SQLITE_OK) {
1421 ErrPrint("Failed to open a DB\n");
1425 if (lstat(s_info.dbfile, &stat) < 0) {
1426 ErrPrint("%s\n", strerror(errno));
1427 db_util_close(s_info.handle);
1428 s_info.handle = NULL;
1432 if (!S_ISREG(stat.st_mode)) {
1433 ErrPrint("Invalid file\n");
1434 db_util_close(s_info.handle);
1435 s_info.handle = NULL;
1445 static inline int db_fini(void)
1450 db_util_close(s_info.handle);
1451 s_info.handle = NULL;
1456 static inline int validate_pkgid(const char *appid, const char *pkgid)
1458 /* Just return 1 Always */
1459 return 1 || !strncmp(appid, pkgid, strlen(appid));
1462 static inline int livebox_destroy(struct livebox *livebox)
1467 struct group *group;
1468 struct option *option;
1472 xmlFree(livebox->auto_launch);
1473 xmlFree(livebox->pkgid);
1474 xmlFree(livebox->abi);
1475 xmlFree(livebox->name);
1476 xmlFree(livebox->icon);
1477 xmlFree(livebox->lb_src);
1478 xmlFree(livebox->lb_group);
1479 xmlFree(livebox->pd_src);
1480 xmlFree(livebox->pd_group);
1481 xmlFree(livebox->pd_size);
1482 xmlFree(livebox->libexec);
1483 xmlFree(livebox->script);
1484 xmlFree(livebox->period);
1485 xmlFree(livebox->content);
1486 xmlFree(livebox->setup);
1487 xmlFree(livebox->preview[0]); /* 1x1 */
1488 xmlFree(livebox->preview[1]); /* 2x1 */
1489 xmlFree(livebox->preview[2]); /* 2x2 */
1490 xmlFree(livebox->preview[3]); /* 4x1 */
1491 xmlFree(livebox->preview[4]); /* 4x2 */
1492 xmlFree(livebox->preview[5]); /* 4x3 */
1493 xmlFree(livebox->preview[6]); /* 4x4 */
1495 dlist_foreach_safe(livebox->i18n_list, l, n, i18n) {
1496 livebox->i18n_list = dlist_remove(livebox->i18n_list, l);
1497 xmlFree(i18n->name);
1498 xmlFree(i18n->icon);
1499 xmlFree(i18n->lang);
1503 dlist_foreach_safe(livebox->group_list, l, n, group) {
1504 livebox->group_list = dlist_remove(livebox->group_list, l);
1505 DbgPrint("Release %s/%s\n", group->cluster, group->category);
1507 if (group->ctx_item) {
1508 dlist_foreach_safe(group->option_list, il, in, option) {
1509 group->option_list = dlist_remove(group->option_list, il);
1510 DbgPrint("Release option %s(%s)\n", option->key, option->value);
1511 xmlFree(option->key);
1512 xmlFree(option->value);
1515 xmlFree(group->ctx_item);
1518 xmlFree(group->cluster);
1519 xmlFree(group->category);
1527 static inline void update_i18n_name(struct livebox *livebox, xmlNodePtr node)
1534 name = xmlNodeGetContent(node);
1536 ErrPrint("Invalid tag\n");
1540 lang = xmlNodeGetLang(node);
1542 if (livebox->name) {
1543 DbgPrint("Override default name: %s\n", livebox->name);
1544 xmlFree(livebox->name);
1547 livebox->name = name;
1551 dlist_foreach(livebox->i18n_list, l, i18n) {
1552 if (!xmlStrcasecmp(i18n->lang, lang)) {
1554 DbgPrint("Override name: %s\n", i18n->name);
1555 xmlFree(i18n->name);
1563 i18n = calloc(1, sizeof(*i18n));
1565 ErrPrint("Heap: %s\n", strerror(errno));
1573 DbgPrint("Label[%s] - [%s] added\n", i18n->lang, i18n->name);
1574 livebox->i18n_list = dlist_append(livebox->i18n_list, i18n);
1577 static inline void update_i18n_icon(struct livebox *livebox, xmlNodePtr node)
1584 icon = xmlNodeGetContent(node);
1586 ErrPrint("Invalid tag\n");
1590 lang = xmlNodeGetLang(node);
1592 if (livebox->icon) {
1593 DbgPrint("Override default icon: %s\n", livebox->icon);
1594 xmlFree(livebox->icon);
1597 livebox->icon = icon;
1601 dlist_foreach(livebox->i18n_list, l, i18n) {
1602 if (!xmlStrcasecmp(i18n->lang, lang)) {
1604 DbgPrint("Override icon %s for %s\n", i18n->icon, i18n->name);
1605 xmlFree(i18n->icon);
1613 i18n = calloc(1, sizeof(*i18n));
1615 ErrPrint("Heap: %s\n", strerror(errno));
1623 DbgPrint("Icon[%s] - [%s] added\n", i18n->lang, i18n->icon);
1624 livebox->i18n_list = dlist_append(livebox->i18n_list, i18n);
1627 static inline void update_launch(struct livebox *livebox, xmlNodePtr node)
1630 launch = xmlNodeGetContent(node);
1632 DbgPrint("Has no launch\n");
1636 livebox->auto_launch = xmlStrdup(launch);
1637 if (!livebox->auto_launch) {
1638 ErrPrint("Failed to duplicate string: %s\n", (char *)launch);
1643 static inline void update_setup(struct livebox *livebox, xmlNodePtr node)
1646 setup = xmlNodeGetContent(node);
1648 DbgPrint("Has no setup\n");
1652 livebox->setup = xmlStrdup(setup);
1653 if (!livebox->setup) {
1654 ErrPrint("Failed to duplicate string: %s\n", (char *)setup);
1659 static inline void update_content(struct livebox *livebox, xmlNodePtr node)
1662 content = xmlNodeGetContent(node);
1664 DbgPrint("Has no content\n");
1668 livebox->content = xmlStrdup(content);
1669 if (!livebox->content) {
1670 ErrPrint("Failed to duplicate string: %s\n", (char *)content);
1675 static inline void update_box(struct livebox *livebox, xmlNodePtr node)
1677 if (!xmlHasProp(node, (const xmlChar *)"type")) {
1678 livebox->lb_type = LB_TYPE_FILE;
1682 type = xmlGetProp(node, (const xmlChar *)"type");
1684 ErrPrint("Type is NIL\n");
1685 livebox->lb_type = LB_TYPE_FILE;
1687 if (!xmlStrcasecmp(type, (const xmlChar *)"text"))
1688 livebox->lb_type = LB_TYPE_TEXT;
1689 else if (!xmlStrcasecmp(type, (const xmlChar *)"buffer"))
1690 livebox->lb_type = LB_TYPE_BUFFER;
1691 else if (!xmlStrcasecmp(type, (const xmlChar *)"script"))
1692 livebox->lb_type = LB_TYPE_SCRIPT;
1694 livebox->lb_type = LB_TYPE_FILE;
1700 if (!xmlHasProp(node, (const xmlChar *)"mouse_event")) {
1701 livebox->mouse_event = 0;
1703 xmlChar *mouse_event;
1705 mouse_event = xmlGetProp(node, (const xmlChar *)"mouse_event");
1707 ErrPrint("mouse_event is NIL\n");
1708 livebox->mouse_event = 0;
1710 livebox->mouse_event = !xmlStrcasecmp(mouse_event, (const xmlChar *)"true");
1711 xmlFree(mouse_event);
1715 for (node = node->children; node; node = node->next) {
1716 if (!xmlStrcasecmp(node->name, (const xmlChar *)"size")) {
1719 size = xmlNodeGetContent(node);
1721 ErrPrint("Invalid size tag\n");
1725 if (!xmlStrcasecmp(size, (const xmlChar *)"1x1")) {
1726 livebox->size_list |= LB_SIZE_1x1;
1727 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1728 livebox->preview[0] = xmlGetProp(node, (const xmlChar *)"preview");
1730 } else if (!xmlStrcasecmp(size, (const xmlChar *)"2x1")) {
1731 livebox->size_list |= LB_SIZE_2x1;
1732 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1733 livebox->preview[1] = xmlGetProp(node, (const xmlChar *)"preview");
1735 } else if (!xmlStrcasecmp(size, (const xmlChar *)"2x2")) {
1736 livebox->size_list |= LB_SIZE_2x2;
1737 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1738 livebox->preview[2] = xmlGetProp(node, (const xmlChar *)"preview");
1740 } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x1")) {
1741 livebox->size_list |= LB_SIZE_4x1;
1742 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1743 livebox->preview[3] = xmlGetProp(node, (const xmlChar *)"preview");
1745 } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x2")) {
1746 livebox->size_list |= LB_SIZE_4x2;
1747 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1748 livebox->preview[4] = xmlGetProp(node, (const xmlChar *)"preview");
1750 } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x3")) {
1751 livebox->size_list |= LB_SIZE_4x3;
1752 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1753 livebox->preview[5] = xmlGetProp(node, (const xmlChar *)"preview");
1755 } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x4")) {
1756 livebox->size_list |= LB_SIZE_4x4;
1757 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1758 livebox->preview[6] = xmlGetProp(node, (const xmlChar *)"preview");
1761 ErrPrint("Invalid size tag (%s)\n", size);
1765 } else if (!xmlStrcasecmp(node->name, (const xmlChar *)"script")) {
1768 if (!xmlHasProp(node, (const xmlChar *)"src")) {
1769 ErrPrint("Invalid script tag. has no src\n");
1773 src = xmlGetProp(node, (const xmlChar *)"src");
1775 ErrPrint("Invalid script tag. src is NIL\n");
1779 if (livebox->lb_src) {
1780 DbgPrint("Override lb src: %s\n", livebox->lb_src);
1781 xmlFree(livebox->lb_src);
1784 livebox->lb_src = src;
1786 if (xmlHasProp(node, (const xmlChar *)"group")) {
1788 group = xmlGetProp(node, (const xmlChar *)"group");
1790 ErrPrint("Group is NIL\n");
1792 if (livebox->lb_group) {
1793 DbgPrint("Override lb group: %s\n", livebox->lb_group);
1794 xmlFree(livebox->lb_group);
1797 livebox->lb_group = group;
1804 static inline void update_group(struct livebox *livebox, xmlNodePtr node)
1807 xmlNodePtr category;
1808 xmlNodePtr option_item;
1809 xmlChar *cluster_name;
1810 xmlChar *category_name;
1816 struct group *group;
1817 struct option *option;
1820 for (cluster = cluster->children; cluster; cluster = cluster->next) {
1821 if (xmlStrcasecmp(cluster->name, (const xmlChar *)"cluster")) {
1822 DbgPrint("Skip: %s\n", cluster->name);
1826 if (!xmlHasProp(cluster, (const xmlChar *)"name")) {
1827 ErrPrint("Invalid cluster, has no name\n");
1831 cluster_name = xmlGetProp(cluster, (const xmlChar *)"name");
1832 if (!cluster_name) {
1833 ErrPrint("Invalid cluster name. NIL\n");
1837 for (category = cluster->children; category; category = category->next) {
1838 if (xmlStrcasecmp(category->name, (const xmlChar *)"category")) {
1839 DbgPrint("Skip: %s\n", category->name);
1843 if (!xmlHasProp(category, (const xmlChar *)"name")) {
1844 ErrPrint("Invalid category, has no name\n");
1848 category_name = xmlGetProp(category, (const xmlChar *)"name");
1849 if (!category_name) {
1850 ErrPrint("Invalid category name. NIL\n");
1854 group = calloc(1, sizeof(*group));
1856 ErrPrint("Heap: %s\n", strerror(errno));
1857 xmlFree(category_name);
1861 group->cluster = xmlStrdup(cluster_name);
1862 if (!group->cluster) {
1863 ErrPrint("Heap: %s\n", strerror(errno));
1864 xmlFree(category_name);
1869 group->category = category_name;
1870 livebox->group_list = dlist_append(livebox->group_list, group);
1872 if (!xmlHasProp(category, (const xmlChar *)"context")) {
1873 DbgPrint("%s, %s has no ctx info\n", group->cluster, group->category);
1877 ctx_item = xmlGetProp(category, (const xmlChar *)"context");
1879 ErrPrint("Failed to get context ID (%s, %s)\n", group->cluster, group->category);
1883 group->ctx_item = ctx_item;
1884 DbgPrint("Build group item: %s - %s - %s\n", group->cluster, group->category, group->ctx_item);
1886 for (option_item = category->children; option_item; option_item = option_item->next) {
1887 if (xmlStrcasecmp(option_item->name, (const xmlChar *)"option")) {
1888 DbgPrint("Skip: %s\n", option_item->name);
1892 if (!xmlHasProp(option_item, (const xmlChar *)"key")) {
1893 ErrPrint("Invalid option, has no key\n");
1897 if (!xmlHasProp(option_item, (const xmlChar *)"value")) {
1898 ErrPrint("Invalid option, has no value\n");
1902 key = xmlGetProp(option_item, (const xmlChar *)"key");
1904 ErrPrint("Invalid key. NIL\n");
1908 value = xmlGetProp(option_item, (const xmlChar *)"value");
1910 ErrPrint("Invalid valid. NIL\n");
1915 option = calloc(1, sizeof(*option));
1917 ErrPrint("Heap: %s\n", strerror(errno));
1924 option->value = value;
1926 group->option_list = dlist_append(group->option_list, option);
1930 xmlFree(cluster_name);
1934 static inline void update_pd(struct livebox *livebox, xmlNodePtr node)
1936 if (!xmlHasProp(node, (const xmlChar *)"type")) {
1937 livebox->pd_type = PD_TYPE_SCRIPT;
1941 type = xmlGetProp(node, (const xmlChar *)"type");
1943 ErrPrint("type is NIL\n");
1947 if (!xmlStrcasecmp(type, (const xmlChar *)"text"))
1948 livebox->pd_type = PD_TYPE_TEXT;
1949 else if (!xmlStrcasecmp(type, (const xmlChar *)"buffer"))
1950 livebox->pd_type = PD_TYPE_BUFFER;
1952 livebox->pd_type = PD_TYPE_SCRIPT;
1957 for (node = node->children; node; node = node->next) {
1958 if (!xmlStrcasecmp(node->name, (const xmlChar *)"size")) {
1961 size = xmlNodeGetContent(node);
1963 ErrPrint("Invalid size tag\n");
1967 if (livebox->pd_size) {
1968 DbgPrint("Override pd size: %s\n", livebox->pd_size);
1969 xmlFree(livebox->pd_size);
1971 livebox->pd_size = size;
1972 } else if (!xmlStrcasecmp(node->name, (const xmlChar *)"script")) {
1975 if (!xmlHasProp(node, (const xmlChar *)"src")) {
1976 ErrPrint("Invalid script tag, has no src\n");
1980 src = xmlGetProp(node, (const xmlChar *)"src");
1982 ErrPrint("src is NIL\n");
1986 if (livebox->pd_src) {
1987 DbgPrint("Overide PD src: %s\n", livebox->pd_src);
1988 xmlFree(livebox->pd_src);
1991 livebox->pd_src = src;
1993 if (xmlHasProp(node, (const xmlChar *)"group")) {
1995 group = xmlGetProp(node, (const xmlChar *)"group");
1997 ErrPrint("Group is NIL\n");
1999 if (livebox->pd_group) {
2000 DbgPrint("Override PD group : %s\n", livebox->pd_group);
2001 xmlFree(livebox->pd_group);
2004 livebox->pd_group = group;
2011 static inline int db_insert_livebox(struct livebox *livebox, const char *appid)
2016 struct group *group;
2019 struct option *option;
2021 begin_transaction();
2022 ret = db_insert_pkgmap(appid, (char *)livebox->pkgid, livebox->primary);
2026 ret = db_insert_provider(livebox);
2030 ret = db_insert_client(livebox);
2034 dlist_foreach(livebox->i18n_list, l, i18n) {
2035 ret = db_insert_i18n((char *)livebox->pkgid, (char *)i18n->lang, (char *)i18n->name, (char *)i18n->icon);
2040 if (livebox->size_list & LB_SIZE_1x1) {
2041 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_1x1, (char *)livebox->preview[0]);
2046 if (livebox->size_list & LB_SIZE_2x1) {
2047 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_2x1, (char *)livebox->preview[1]);
2052 if (livebox->size_list & LB_SIZE_2x2) {
2053 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_2x2, (char *)livebox->preview[2]);
2058 if (livebox->size_list & LB_SIZE_4x1) {
2059 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_4x1, (char *)livebox->preview[3]);
2064 if (livebox->size_list & LB_SIZE_4x2) {
2065 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_4x2, (char *)livebox->preview[4]);
2070 if (livebox->size_list & LB_SIZE_4x3) {
2071 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_4x3, (char *)livebox->preview[5]);
2076 if (livebox->size_list & LB_SIZE_4x4) {
2077 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_4x4, (char *)livebox->preview[6]);
2082 dlist_foreach(livebox->group_list, l, group) {
2084 id = db_get_group_id((char *)group->cluster, (char *)group->category);
2088 ret = db_insert_group((char *)livebox->pkgid, (char *)group->cluster, (char *)group->category);
2090 ErrPrint("[%s]-[%s] is not exists\n", group->cluster, group->category);
2094 DbgPrint("New group name is built - %s/%s\n", group->cluster, group->category);
2095 id = db_get_group_id((char *)group->cluster, (char *)group->category);
2097 ErrPrint("Failed to get group id for %s/%s\n", group->cluster, group->category);
2102 if (!group->ctx_item) {
2103 DbgPrint("%s, %s - has no ctx info\n", group->cluster, group->category);
2107 ret = db_insert_groupmap(id, (char *)livebox->pkgid, (char *)group->ctx_item);
2111 /* REUSE "id" from here , option ID */
2112 id = db_get_option_id(id, (char *)livebox->pkgid, (char *)group->ctx_item);
2116 dlist_foreach(group->option_list, il, option) {
2117 ret = db_insert_option((char *)livebox->pkgid, id, (char *)option->key, (char *)option->value);
2123 commit_transaction();
2124 livebox_destroy(livebox);
2128 ErrPrint("ROLLBACK\n");
2129 rollback_transaction();
2130 livebox_destroy(livebox);
2134 static inline int do_install(xmlNodePtr node, const char *appid)
2136 struct livebox *livebox;
2140 if (!xmlHasProp(node, (const xmlChar *)"appid")) {
2141 ErrPrint("Missing appid\n");
2145 pkgid = xmlGetProp(node, (const xmlChar *)"appid");
2146 if (!pkgid || !validate_pkgid(appid, (char *)pkgid)) {
2147 ErrPrint("Invalid appid\n");
2152 DbgPrint("appid: %s\n", (char *)pkgid);
2154 livebox = calloc(1, sizeof(*livebox));
2156 ErrPrint("Heap: %s\n", strerror(errno));
2161 livebox->pkgid = pkgid;
2163 if (xmlHasProp(node, (const xmlChar *)"primary")) {
2164 tmp = xmlGetProp(node, (const xmlChar *)"primary");
2165 livebox->primary = !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2169 if (xmlHasProp(node, (const xmlChar *)"script")) {
2170 livebox->script = xmlGetProp(node, (const xmlChar *)"script");
2171 if (!livebox->script)
2172 ErrPrint("script is NIL\n");
2175 if (xmlHasProp(node, (const xmlChar *)"nodisplay")) {
2176 tmp = xmlGetProp(node, (const xmlChar *)"nodisplay");
2177 livebox->nodisplay = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2181 if (xmlHasProp(node, (const xmlChar *)"pinup")) {
2182 tmp = xmlGetProp(node, (const xmlChar *)"pinup");
2183 livebox->pinup = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2187 if (xmlHasProp(node, (const xmlChar *)"period")) {
2188 livebox->period = xmlGetProp(node, (const xmlChar *)"period");
2189 if (!livebox->period)
2190 ErrPrint("Period is NIL\n");
2193 if (xmlHasProp(node, (const xmlChar *)"timeout")) {
2194 livebox->timeout = xmlGetProp(node, (const xmlChar *)"timeout");
2195 if (!livebox->timeout)
2196 ErrPrint("Timeout is NIL\n");
2199 if (xmlHasProp(node, (const xmlChar *)"secured")) {
2200 tmp = xmlGetProp(node, (const xmlChar *)"secured");
2201 livebox->secured = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2205 if (xmlHasProp(node, (const xmlChar *)"network")) {
2206 tmp = xmlGetProp(node, (const xmlChar *)"network");
2207 livebox->network = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2211 if (xmlHasProp(node, (const xmlChar *)"abi")) {
2212 livebox->abi = xmlGetProp(node, (const xmlChar *)"abi");
2213 if (!livebox->abi) {
2214 ErrPrint("ABI is NIL\n");
2215 livebox_destroy(livebox);
2219 livebox->abi = xmlStrdup((const xmlChar *)"c");
2220 if (!livebox->abi) {
2221 ErrPrint("Heap: %s\n", strerror(errno));
2222 livebox_destroy(livebox);
2227 if (xmlHasProp(node, (const xmlChar *)"libexec")) {
2228 livebox->libexec = xmlGetProp(node, (const xmlChar *)"libexec");
2229 if (!livebox->libexec) {
2230 ErrPrint("libexec is NIL\n");
2231 livebox_destroy(livebox);
2234 } else if (!xmlStrcasecmp(livebox->abi, (const xmlChar *)"c") || !xmlStrcasecmp(livebox->abi, (const xmlChar *)"cpp")) {
2238 len = strlen((char *)livebox->pkgid) + strlen("/libexec/liblive-.so") + 1;
2240 filename = malloc(len);
2242 livebox_destroy(livebox);
2246 snprintf(filename, len, "/libexec/liblive-%s.so", livebox->pkgid);
2247 livebox->libexec = xmlStrdup((xmlChar *)filename);
2248 DbgPrint("Use the default libexec: %s\n", filename);
2251 if (!livebox->libexec) {
2252 livebox_destroy(livebox);
2257 for (node = node->children; node; node = node->next) {
2258 if (!xmlStrcmp(node->name, (const xmlChar *)"text"))
2261 DbgPrint("Nodename: %s\n", node->name);
2262 if (!xmlStrcasecmp(node->name, (const xmlChar *)"label")) {
2263 update_i18n_name(livebox, node);
2267 if (!xmlStrcasecmp(node->name, (const xmlChar *)"icon")) {
2268 update_i18n_icon(livebox, node);
2272 if (!xmlStrcasecmp(node->name, (const xmlChar *)"box")) {
2273 update_box(livebox, node);
2277 if (!xmlStrcasecmp(node->name, (const xmlChar *)"pd")) {
2278 update_pd(livebox, node);
2282 if (!xmlStrcasecmp(node->name, (const xmlChar *)"group")) {
2283 update_group(livebox, node);
2287 if (!xmlStrcasecmp(node->name, (const xmlChar *)"content")) {
2288 update_content(livebox, node);
2292 if (!xmlStrcasecmp(node->name, (const xmlChar *)"setup")) {
2293 update_setup(livebox, node);
2297 if (!xmlStrcasecmp(node->name, (const xmlChar *)"launch")) {
2298 update_launch(livebox, node);
2303 return db_insert_livebox(livebox, appid);
2306 int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr docPtr, const char *appid)
2311 if (!s_info.handle) {
2312 if (db_init() < 0) {
2313 ErrPrint("Failed to init DB\n");
2318 node = xmlDocGetRootElement(docPtr);
2320 ErrPrint("Invalid document\n");
2324 for (node = node->children; node; node = node->next) {
2325 DbgPrint("node->name: %s\n", node->name);
2326 if (!xmlStrcasecmp(node->name, (const xmlChar *)"livebox")) {
2327 ret = do_install(node, appid);
2328 DbgPrint("Returns: %d\n", ret);
2335 int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr docPtr, const char *appid)
2339 if (!s_info.handle) {
2340 if (db_init() < 0) {
2341 ErrPrint("Failed to init DB\n");
2346 node = xmlDocGetRootElement(docPtr);
2348 ErrPrint("Invalid document\n");
2352 for (node = node->children; node; node = node->next) {
2353 if (!xmlStrcasecmp(node->name, (const xmlChar *)"livebox"))
2358 ErrPrint("Root has no livebox\n");
2365 static inline int do_uninstall(xmlNodePtr node, const char *appid)
2370 if (!xmlHasProp(node, (const xmlChar *)"appid")) {
2371 ErrPrint("Missing appid\n");
2375 pkgid = xmlGetProp(node, (const xmlChar *)"appid");
2376 if (!validate_pkgid(appid, (char *)pkgid)) {
2377 ErrPrint("Invalid package\n");
2382 begin_transaction();
2383 ret = db_remove_box_size((char *)pkgid);
2387 ret = db_remove_i18n((char *)pkgid);
2391 ret = db_remove_client((char *)pkgid);
2395 ret = db_remove_provider((char *)pkgid);
2399 ret = db_remove_option((char *)pkgid);
2400 DbgPrint("Remove option: %d\n", ret);
2402 ret = db_remove_groupmap((char *)pkgid);
2403 DbgPrint("Remove groupmap: %d\n", ret);
2405 ret = db_remove_group((char *)pkgid);
2409 ret = db_remove_pkgmap((char *)pkgid);
2413 commit_transaction();
2419 rollback_transaction();
2424 int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr docPtr, const char *appid)
2429 if (!s_info.handle) {
2430 if (db_init() < 0) {
2431 ErrPrint("Failed to init DB\n");
2436 node = xmlDocGetRootElement(docPtr);
2438 ErrPrint("Invalid document\n");
2442 for (node = node->children; node; node = node->next) {
2443 if (!xmlStrcasecmp(node->name, (const xmlChar *)"livebox")) {
2444 ret = do_uninstall(node, appid);
2445 DbgPrint("Returns: %d\n", ret);
2453 int main(int argc, char *argv[])
2459 ErrPRint("Invalid argument: %s XML_FILENAME\n", argv[0]);
2463 doc = xmlReadFile(argv[1], NULL, 0);
2465 ErrPrint("Failed to parse %s\n", argv[1]);
2469 root = xmlDocGetRootElement(doc);
2472 install_shortcut("", root);