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>
31 #include <livebox-service.h>
36 #define DbgPrint(format, arg...) LOGD("[
\e[32m%s/%s
\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
37 #define ErrPrint(format, arg...) LOGE("[
\e[32m%s/%s
\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
46 * +-------+-------+---------+
47 * | appid | pkgid | prime |
48 * +-------+-------+---------+
50 * +-------+-------+---------+
51 * CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, prime INTEGER )
55 * +-------+---------+-----+---------+----------+---------+-----------+---------+--------+----------+---------+---------+--------+--------+-------+
56 * | pkgid | network | abi | secured | box_type | box_src | box_group | pd_type | pd_src | pd_group | libexec | timeout | period | script | pinup |
57 * +-------+---------+-----+---------+----------+---------+-----------+---------+--------+----------+---------+---------+--------+--------+-------+
58 * | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
59 * +-------+---------+-----+---------+----------+---------+-----------+---------+--------+----------+---------+---------+--------+--------+-------+
60 * 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))
62 * = box_type = { text | buffer | script | image }
63 * = pd_type = { text | buffer | script }
64 * = network = { 1 | 0 }
65 * = secured = { 1 | 0 }
69 * +-------+------+---------+-------------+---------+---------+-----------+-------+-------------+
70 * | pkgid | Icon | Name | auto_launch | pd_size | content | nodisplay | setup | mouse_event |
71 * +-------+------+---------+-------------+---------+---------+-----------+-------+-------------+
72 * | - | - | - | - | - | - | - | - | - }
73 * +-------+------+---------+-------------+---------+---------+-----------+-------+-------------+
74 * 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) )
76 * = auto_launch = UI-APPID
77 * = pd_size = WIDTHxHEIGHT
81 * +-------+------+------+------+
82 * | fk | lang | name | icon |
83 * +-------+------+------+------+
84 * | pkgid | - | - | - |
85 * +-------+------+------+------+
86 * CREATE TABLE i18n ( pkgid TEXT NOT NULL, lang TEXT COLLATE NOCASE, name TEXT, icon TEXT, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
90 * +-------+-----------+---------+
91 * | pkgid | size_type | preview |
92 * +-------+-----------+---------+
94 * +-------+-----------+---------+
95 * CREATE TABLE box_size ( pkgid TEXT NOT NULL, size_type INTEGER, preview TEXT, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
97 * = box_size_list = { WIDTHxHEIGHT; WIDTHxHEIGHT; ... }
100 * +----+---------+----------+-------+
101 * | id | cluster | category | pkgid |
102 * +----+---------+----------+-------+
104 * +----+---------+----------+-------|
105 * 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) ))
108 * +-------+----+----------+-----------+
109 * | pkgid | id | ctx_item | option_id |
110 * +-------+----+----------+-----------+
111 * 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) )
115 * +-------+-----------+-----+-------+
116 * | pkgid | option_id | key | value |
117 * +-------+-----------+-----+-------+
118 * 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) )
121 #if !defined(LIBXML_TREE_ENABLED)
122 #error "LIBXML is not supporting the tree"
129 #define LOG_TAG "PKGMGR_LIVEBOX"
158 xmlChar *auto_launch;
160 xmlChar *name; /* Default name */
161 xmlChar *icon; /* Default icon */
162 xmlChar *libexec; /* Path of the SO file */
163 xmlChar *timeout; /* INTEGER, timeout */
164 xmlChar *period; /* DOUBLE, update period */
165 xmlChar *script; /* Script engine */
166 xmlChar *content; /* Content information */
169 int pinup; /* Is this support the pinup feature? */
170 int primary; /* Is this primary livebox? */
172 int mouse_event; /* Mouse event processing option for livebox */
174 enum lb_type lb_type;
177 int size_list; /* 1x1, 2x1, 2x2, 4x1, 4x2, 4x3, 4x4 */
179 xmlChar *preview[10];
181 enum pd_type pd_type;
184 xmlChar *pd_size; /* Default PD size */
186 struct dlist *i18n_list;
187 struct dlist *group_list;
194 struct dlist *option_list;
206 .dbfile = "/opt/dbspace/.livebox.db",
210 static inline int begin_transaction(void)
215 ret = sqlite3_prepare_v2(s_info.handle, "BEGIN TRANSACTION", -1, &stmt, NULL);
217 if (ret != SQLITE_OK) {
218 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
222 if (sqlite3_step(stmt) != SQLITE_DONE) {
223 DbgPrint("Failed to do update (%s)\n",
224 sqlite3_errmsg(s_info.handle));
225 sqlite3_finalize(stmt);
229 sqlite3_finalize(stmt);
233 static inline int rollback_transaction(void)
238 ret = sqlite3_prepare_v2(s_info.handle, "ROLLBACK TRANSACTION", -1, &stmt, NULL);
239 if (ret != SQLITE_OK) {
240 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
244 if (sqlite3_step(stmt) != SQLITE_DONE) {
245 DbgPrint("Failed to do update (%s)\n",
246 sqlite3_errmsg(s_info.handle));
247 sqlite3_finalize(stmt);
251 sqlite3_finalize(stmt);
255 static inline int commit_transaction(void)
260 ret = sqlite3_prepare_v2(s_info.handle, "COMMIT TRANSACTION", -1, &stmt, NULL);
261 if (ret != SQLITE_OK) {
262 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
266 if (sqlite3_step(stmt) != SQLITE_DONE) {
267 DbgPrint("Failed to do update (%s)\n",
268 sqlite3_errmsg(s_info.handle));
269 sqlite3_finalize(stmt);
273 sqlite3_finalize(stmt);
277 static inline int db_create_pkgmap(void)
280 static const char *ddl;
282 ddl = "CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, prime INTEGER )";
283 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
284 ErrPrint("Failed to execute the DDL (%s)\n", err);
288 if (sqlite3_changes(s_info.handle) == 0)
289 ErrPrint("No changes to DB\n");
294 static inline int db_insert_pkgmap(const char *appid, const char *pkgid, int primary)
297 static const char *dml;
300 dml = "INSERT INTO pkgmap ( appid, pkgid, prime ) VALUES (? ,?, ?)";
301 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
302 if (ret != SQLITE_OK) {
303 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
307 ret = sqlite3_bind_text(stmt, 1, appid, -1, NULL);
308 if (ret != SQLITE_OK) {
309 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
314 ret = sqlite3_bind_text(stmt, 2, pkgid, -1, NULL);
315 if (ret != SQLITE_OK) {
316 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
321 ret = sqlite3_bind_int(stmt, 3, primary);
322 if (ret != SQLITE_OK) {
323 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
329 if (sqlite3_step(stmt) != SQLITE_DONE) {
330 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
336 sqlite3_clear_bindings(stmt);
337 sqlite3_finalize(stmt);
341 static inline int db_remove_pkgmap(const char *pkgid)
344 static const char *dml;
347 dml = "DELETE FROM pkgmap WHERE pkgid = ?";
348 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
349 if (ret != SQLITE_OK) {
350 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
354 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
355 if (ret != SQLITE_OK) {
356 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
362 if (sqlite3_step(stmt) != SQLITE_DONE) {
363 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
369 sqlite3_clear_bindings(stmt);
370 sqlite3_finalize(stmt);
374 static inline int db_create_provider(void)
377 static const char *ddl;
379 ddl = "CREATE TABLE provider (" \
380 "pkgid TEXT PRIMARY KEY NOT NULL, network INTEGER, " \
381 "abi TEXT, secured INTEGER, box_type INTEGER, " \
382 "box_src TEXT, box_group TEXT, pd_type INTEGER, " \
383 "pd_src TEXT, pd_group TEXT, libexec TEXT, timeout INTEGER, period TEXT, script TEXT, pinup INTEGER, "\
384 "FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
386 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
387 ErrPrint("Failed to execute the DDL (%s)\n", err);
391 if (sqlite3_changes(s_info.handle) == 0)
392 ErrPrint("No changes to DB\n");
397 static inline int db_remove_provider(const char *pkgid)
399 static const char *dml;
403 dml = "DELETE FROM provider WHERE pkgid = ?";
404 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
405 if (ret != SQLITE_OK) {
406 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
410 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
411 if (ret != SQLITE_OK) {
412 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
418 if (sqlite3_step(stmt) != SQLITE_DONE) {
419 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
425 sqlite3_clear_bindings(stmt);
426 sqlite3_finalize(stmt);
429 static inline int db_insert_provider(struct livebox *livebox)
431 static const char *dml;
434 char *abi = (char *)livebox->abi;
435 char *box_src = (char *)livebox->lb_src;
436 char *box_group = (char *)livebox->lb_group;
437 char *pd_src = (char *)livebox->pd_src;
438 char *pd_group = (char *)livebox->pd_group;
439 char *libexec = (char *)livebox->libexec;
440 char *timeout = (char *)livebox->timeout;
441 char *period = (char *)livebox->period;
442 char *script = (char *)livebox->script;
471 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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
472 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
473 if (ret != SQLITE_OK) {
474 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
478 ret = sqlite3_bind_text(stmt, 1, (char *)livebox->pkgid, -1, NULL);
479 if (ret != SQLITE_OK) {
480 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
486 ret = sqlite3_bind_int(stmt, 2, livebox->network);
487 if (ret != SQLITE_OK) {
488 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
493 ret = sqlite3_bind_text(stmt, 3, abi, -1, NULL);
494 if (ret != SQLITE_OK) {
495 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
499 ret = sqlite3_bind_int(stmt, 4, livebox->secured);
500 if (ret != SQLITE_OK) {
501 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
506 ret = sqlite3_bind_int(stmt, 5, livebox->lb_type);
507 if (ret != SQLITE_OK) {
508 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
513 ret = sqlite3_bind_text(stmt, 6, box_src, -1, NULL);
514 if (ret != SQLITE_OK) {
515 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
520 ret = sqlite3_bind_text(stmt, 7, box_group, -1, NULL);
521 if (ret != SQLITE_OK) {
522 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
527 ret = sqlite3_bind_int(stmt, 8, livebox->pd_type);
528 if (ret != SQLITE_OK) {
529 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
534 ret = sqlite3_bind_text(stmt, 9, pd_src, -1, NULL);
535 if (ret != SQLITE_OK) {
536 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
541 ret = sqlite3_bind_text(stmt, 10, pd_group, -1, NULL);
542 if (ret != SQLITE_OK) {
543 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
548 ret = sqlite3_bind_text(stmt, 11, libexec, -1, NULL);
549 if (ret != SQLITE_OK) {
550 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
555 ret = sqlite3_bind_int(stmt, 12, atoi(timeout));
556 if (ret != SQLITE_OK) {
557 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
562 ret = sqlite3_bind_text(stmt, 13, period, -1, NULL);
563 if (ret != SQLITE_OK) {
564 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
569 ret = sqlite3_bind_text(stmt, 14, script, -1, NULL);
570 if (ret != SQLITE_OK) {
571 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
576 ret = sqlite3_bind_int(stmt, 15, livebox->pinup);
577 if (ret != SQLITE_OK) {
578 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
584 if (sqlite3_step(stmt) != SQLITE_DONE) {
585 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
591 sqlite3_clear_bindings(stmt);
592 sqlite3_finalize(stmt);
596 static inline int db_create_client(void)
599 static const char *ddl;
601 ddl = "CREATE TABLE client (" \
602 "pkgid TEXT PRIMARY KEY NOT NULL, icon TEXT, name TEXT, " \
603 "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)";
604 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
605 ErrPrint("Failed to execute the DDL (%s)\n", err);
609 if (sqlite3_changes(s_info.handle) == 0)
610 ErrPrint("No changes to DB\n");
615 static inline int db_insert_client(struct livebox *livebox)
617 static const char *dml;
621 dml = "INSERT INTO client ( pkgid, icon, name, auto_launch, pd_size, content, nodisplay, setup, mouse_event ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
622 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
623 if (ret != SQLITE_OK) {
624 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
628 ret = sqlite3_bind_text(stmt, 1, (char *)livebox->pkgid, -1, NULL);
629 if (ret != SQLITE_OK) {
630 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
635 ret = sqlite3_bind_text(stmt, 2, (char *)livebox->icon, -1, NULL);
636 if (ret != SQLITE_OK) {
637 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
642 ret = sqlite3_bind_text(stmt, 3, (char *)livebox->name, -1, NULL);
643 if (ret != SQLITE_OK) {
644 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
649 ret = sqlite3_bind_text(stmt, 4, (char *)livebox->auto_launch, -1, NULL);
650 if (ret != SQLITE_OK) {
651 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
656 ret = sqlite3_bind_text(stmt, 5, (char *)livebox->pd_size, -1, NULL);
657 if (ret != SQLITE_OK) {
658 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
663 ret = sqlite3_bind_text(stmt, 6, livebox->content ? (char *)livebox->content : "default", -1, NULL);
664 if (ret != SQLITE_OK) {
665 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
670 ret = sqlite3_bind_int(stmt, 7, livebox->nodisplay);
671 if (ret != SQLITE_OK) {
672 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
677 ret = sqlite3_bind_text(stmt, 8, livebox->setup ? (char *)livebox->setup : "", -1, NULL);
678 if (ret != SQLITE_OK) {
679 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
684 ret = sqlite3_bind_int(stmt, 9, livebox->mouse_event);
685 if (ret != SQLITE_OK) {
686 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
692 if (sqlite3_step(stmt) != SQLITE_DONE) {
693 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
699 sqlite3_clear_bindings(stmt);
700 sqlite3_finalize(stmt);
704 static inline int db_remove_client(const char *pkgid)
706 static const char *dml;
710 dml = "DELETE FROM client WHERE pkgid = ?";
711 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
712 if (ret != SQLITE_OK) {
713 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
717 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
718 if (ret != SQLITE_OK) {
719 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
725 if (sqlite3_step(stmt) != SQLITE_DONE) {
726 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
732 sqlite3_clear_bindings(stmt);
733 sqlite3_finalize(stmt);
737 static inline int db_create_i18n(void)
740 static const char *ddl;
742 ddl = "CREATE TABLE i18n ( pkgid TEXT NOT NULL, lang TEXT COLLATE NOCASE, name TEXT, " \
743 "icon TEXT, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
744 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
745 ErrPrint("Failed to execute the DDL (%s)\n", err);
749 if (sqlite3_changes(s_info.handle) == 0)
750 ErrPrint("No changes to DB\n");
755 static inline int db_insert_i18n(const char *pkgid, const char *lang, const char *name, const char *icon)
757 static const char *dml;
761 DbgPrint("%s - lang[%s] name[%s] icon[%s]\n", pkgid, lang, name, icon);
762 dml = "INSERT INTO i18n ( pkgid, lang, name, icon ) VALUES (?, ?, ?, ?)";
763 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
764 if (ret != SQLITE_OK) {
765 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
769 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
770 if (ret != SQLITE_OK) {
771 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
776 ret = sqlite3_bind_text(stmt, 2, lang, -1, NULL);
777 if (ret != SQLITE_OK) {
778 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
783 ret = sqlite3_bind_text(stmt, 3, name, -1, NULL);
784 if (ret != SQLITE_OK) {
785 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
790 ret = sqlite3_bind_text(stmt, 4, icon, -1, NULL);
791 if (ret != SQLITE_OK) {
792 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
798 if (sqlite3_step(stmt) != SQLITE_DONE) {
799 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
805 sqlite3_clear_bindings(stmt);
806 sqlite3_finalize(stmt);
810 static inline int db_remove_i18n(const char *pkgid)
812 static const char *dml;
816 dml = "DELETE FROM i18n WHERE pkgid = ?";
817 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
818 if (ret != SQLITE_OK) {
819 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
823 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
824 if (ret != SQLITE_OK) {
825 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
831 if (sqlite3_step(stmt) != SQLITE_DONE) {
832 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
836 if (sqlite3_changes(s_info.handle) == 0)
837 DbgPrint("No changes\n");
841 sqlite3_clear_bindings(stmt);
842 sqlite3_finalize(stmt);
846 static inline int db_create_group(void)
849 static const char *ddl;
851 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)";
852 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
853 ErrPrint("Failed to execute the DDL (%s)\n", err);
857 if (sqlite3_changes(s_info.handle) == 0)
858 ErrPrint("No changes to DB\n");
863 static inline int db_insert_group(const char *pkgid, const char *cluster, const char *category)
865 static const char *dml;
869 dml = "INSERT INTO groupinfo ( cluster, category, pkgid ) VALUES (?, ?, ?)";
870 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
871 if (ret != SQLITE_OK) {
872 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
876 ret = sqlite3_bind_text(stmt, 1, cluster, -1, NULL);
877 if (ret != SQLITE_OK) {
878 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
883 ret = sqlite3_bind_text(stmt, 2, category, -1, NULL);
884 if (ret != SQLITE_OK) {
885 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
890 ret = sqlite3_bind_text(stmt, 3, pkgid, -1, NULL);
891 if (ret != SQLITE_OK) {
892 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
898 if (sqlite3_step(stmt) != SQLITE_DONE) {
899 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
905 sqlite3_clear_bindings(stmt);
906 sqlite3_finalize(stmt);
910 static inline int db_get_group_id(const char *cluster, const char *category)
912 static const char *dml = "SELECT id FROM groupinfo WHERE cluster = ? AND category = ?";
916 if (!cluster || !category) {
917 ErrPrint("Invalid argument\n");
921 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
922 if (ret != SQLITE_OK) {
923 ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
928 if (sqlite3_bind_text(stmt, 1, cluster, -1, NULL) != SQLITE_OK) {
929 ErrPrint("Failed to bind a cluster(%s) - %s\n", cluster, sqlite3_errmsg(s_info.handle));
933 if (sqlite3_bind_text(stmt, 2, category, -1, NULL) != SQLITE_OK) {
934 ErrPrint("Failed to bind a category(%s) - %s\n", category, sqlite3_errmsg(s_info.handle));
938 if (sqlite3_step(stmt) != SQLITE_ROW) {
939 ErrPrint("Failed to execute the DML for %s - %s\n", cluster, category);
943 ret = sqlite3_column_int(stmt, 0);
947 sqlite3_clear_bindings(stmt);
948 sqlite3_finalize(stmt);
952 static inline int db_remove_group(const char *pkgid)
954 static const char *dml;
958 dml = "DELETE FROM groupinfo WHERE pkgid = ?";
959 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
960 if (ret != SQLITE_OK) {
961 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
965 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
966 if (ret != SQLITE_OK) {
967 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
973 if (sqlite3_step(stmt) != SQLITE_DONE) {
974 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
978 if (sqlite3_changes(s_info.handle) == 0)
979 DbgPrint("No changes\n");
983 sqlite3_clear_bindings(stmt);
984 sqlite3_finalize(stmt);
988 static inline int db_create_groupmap(void)
991 static const char *ddl;
993 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)";
994 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
995 ErrPrint("Failed to execute the DDL (%s)\n", err);
999 if (sqlite3_changes(s_info.handle) == 0)
1000 ErrPrint("No changes to DB\n");
1005 static inline int db_get_option_id(int id, const char *pkgid, const char *ctx_item)
1007 static const char *dml;
1011 dml = "SELECT option_id FROM groupmap WHERE id = ? AND pkgid = ? AND ctx_item = ?";
1012 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1013 if (ret != SQLITE_OK) {
1014 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1018 ret = sqlite3_bind_int(stmt, 1, id);
1019 if (ret != SQLITE_OK) {
1020 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1025 ret = sqlite3_bind_text(stmt, 2, pkgid, -1, NULL);
1026 if (ret != SQLITE_OK) {
1027 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1032 ret = sqlite3_bind_text(stmt, 3, ctx_item, -1, NULL);
1033 if (ret != SQLITE_OK) {
1034 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1040 if (sqlite3_step(stmt) != SQLITE_ROW) {
1041 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1046 ret = sqlite3_column_int(stmt, 0);
1049 sqlite3_reset(stmt);
1050 sqlite3_clear_bindings(stmt);
1051 sqlite3_finalize(stmt);
1055 static inline int db_insert_groupmap(int id, const char *pkgid, const char *ctx_item)
1057 static const char *dml;
1061 DbgPrint("%d (%s) add to groupmap\n", id, pkgid);
1063 dml = "INSERT INTO groupmap ( id, pkgid, ctx_item ) VALUES (?, ?, ?)";
1064 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1065 if (ret != SQLITE_OK) {
1066 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1070 ret = sqlite3_bind_int(stmt, 1, id);
1071 if (ret != SQLITE_OK) {
1072 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1077 ret = sqlite3_bind_text(stmt, 2, pkgid, -1, NULL);
1078 if (ret != SQLITE_OK) {
1079 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1084 ret = sqlite3_bind_text(stmt, 3, ctx_item, -1, NULL);
1085 if (ret != SQLITE_OK) {
1086 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1092 if (sqlite3_step(stmt) != SQLITE_DONE) {
1093 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1098 sqlite3_reset(stmt);
1099 sqlite3_clear_bindings(stmt);
1100 sqlite3_finalize(stmt);
1104 static inline int db_remove_groupmap(const char *pkgid)
1106 static const char *dml;
1110 dml = "DELETE FROM groupmap WHERE pkgid = ?";
1111 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1112 if (ret != SQLITE_OK) {
1113 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1117 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1118 if (ret != SQLITE_OK) {
1119 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1125 if (sqlite3_step(stmt) != SQLITE_DONE) {
1126 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1130 if (sqlite3_changes(s_info.handle) == 0)
1131 DbgPrint("No changes\n");
1134 sqlite3_reset(stmt);
1135 sqlite3_clear_bindings(stmt);
1136 sqlite3_finalize(stmt);
1140 static inline int db_create_option(void)
1143 static const char *ddl;
1145 ddl = "CREATE TABLE option ( pkgid TEXT NOT NULL, option_id INTEGER, key TEXT NOT NULL, value TEXT NOT NULL, " \
1146 "FOREIGN KEY(option_id) REFERENCES groupmap(option_id), " \
1147 "FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
1148 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1149 ErrPrint("Failed to execute the DDL (%s)\n", err);
1153 if (sqlite3_changes(s_info.handle) == 0)
1154 ErrPrint("No changes to DB\n");
1159 static inline int db_insert_option(const char *pkgid, int option_id, const char *key, const char *value)
1161 static const char *dml;
1165 dml = "INSERT INTO option (pkgid, option_id, key, value) VALUES (?, ?, ?, ?)";
1166 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1167 if (ret != SQLITE_OK) {
1168 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1172 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1173 if (ret != SQLITE_OK) {
1174 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1179 ret = sqlite3_bind_int(stmt, 2, option_id);
1180 if (ret != SQLITE_OK) {
1181 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1186 ret = sqlite3_bind_text(stmt, 3, key, -1, NULL);
1187 if (ret != SQLITE_OK) {
1188 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1193 ret = sqlite3_bind_text(stmt, 4, value, -1, NULL);
1194 if (ret != SQLITE_OK) {
1195 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1201 if (sqlite3_step(stmt) != SQLITE_DONE) {
1202 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1206 sqlite3_reset(stmt);
1207 sqlite3_clear_bindings(stmt);
1208 sqlite3_finalize(stmt);
1212 static inline int db_remove_option(const char *pkgid)
1214 static const char *dml;
1218 dml = "DELETE FROM option WHERE pkgid = ?";
1219 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1220 if (ret != SQLITE_OK) {
1221 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1225 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1226 if (ret != SQLITE_OK) {
1227 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1233 if (sqlite3_step(stmt) != SQLITE_DONE) {
1234 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1238 if (sqlite3_changes(s_info.handle) == 0)
1239 DbgPrint("No changes\n");
1242 sqlite3_reset(stmt);
1243 sqlite3_clear_bindings(stmt);
1244 sqlite3_finalize(stmt);
1248 static inline int db_create_box_size(void)
1251 static const char *ddl;
1253 ddl = "CREATE TABLE box_size ( pkgid TEXT NOT NULL, size_type INTEGER, preview TEXT, " \
1254 "FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
1255 if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1256 ErrPrint("Failed to execute the DDL (%s)\n", err);
1260 if (sqlite3_changes(s_info.handle) == 0)
1261 ErrPrint("No changes to DB\n");
1266 static inline int db_insert_box_size(const char *pkgid, int size_type, const char *preview)
1268 static const char *dml;
1272 DbgPrint("box size: %s - %d (%s) is added\n", pkgid, size_type, preview);
1273 dml = "INSERT INTO box_size ( pkgid, size_type, preview ) VALUES (?, ?, ?)";
1274 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1275 if (ret != SQLITE_OK) {
1276 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1280 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1281 if (ret != SQLITE_OK) {
1282 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1287 ret = sqlite3_bind_int(stmt, 2, size_type);
1288 if (ret != SQLITE_OK) {
1289 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1294 ret = sqlite3_bind_text(stmt, 3, preview ? preview : "", -1, NULL);
1295 if (ret != SQLITE_OK) {
1296 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1302 if (sqlite3_step(stmt) != SQLITE_DONE) {
1303 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1308 sqlite3_reset(stmt);
1309 sqlite3_clear_bindings(stmt);
1310 sqlite3_finalize(stmt);
1314 static inline int db_remove_box_size(const char *pkgid)
1316 static const char *dml;
1320 dml = "DELETE FROM box_size WHERE pkgid = ?";
1321 ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1322 if (ret != SQLITE_OK) {
1323 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1327 ret = sqlite3_bind_text(stmt, 1, pkgid, -1, NULL);
1328 if (ret != SQLITE_OK) {
1329 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1335 if (sqlite3_step(stmt) != SQLITE_DONE) {
1336 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1340 if (sqlite3_changes(s_info.handle) == 0)
1341 DbgPrint("No changes\n");
1344 sqlite3_reset(stmt);
1345 sqlite3_clear_bindings(stmt);
1346 sqlite3_finalize(stmt);
1350 static inline void db_create_table(void)
1353 begin_transaction();
1355 ret = db_create_pkgmap();
1357 rollback_transaction();
1361 ret = db_create_provider();
1363 rollback_transaction();
1367 ret = db_create_client();
1369 rollback_transaction();
1373 ret = db_create_i18n();
1375 rollback_transaction();
1379 ret = db_create_box_size();
1381 rollback_transaction();
1385 ret = db_create_group();
1387 rollback_transaction();
1391 ret = db_create_option();
1393 rollback_transaction();
1397 ret = db_create_groupmap();
1399 rollback_transaction();
1403 commit_transaction();
1406 static inline int db_init(void)
1411 ret = db_util_open(s_info.dbfile, &s_info.handle, DB_UTIL_REGISTER_HOOK_METHOD);
1412 if (ret != SQLITE_OK) {
1413 ErrPrint("Failed to open a DB\n");
1417 if (lstat(s_info.dbfile, &stat) < 0) {
1418 ErrPrint("%s\n", strerror(errno));
1419 db_util_close(s_info.handle);
1420 s_info.handle = NULL;
1424 if (!S_ISREG(stat.st_mode)) {
1425 ErrPrint("Invalid file\n");
1426 db_util_close(s_info.handle);
1427 s_info.handle = NULL;
1437 static inline int db_fini(void)
1442 db_util_close(s_info.handle);
1443 s_info.handle = NULL;
1448 static inline int validate_pkgid(const char *appid, const char *pkgid)
1450 /* Just return 1 Always */
1451 return 1 || !strncmp(appid, pkgid, strlen(appid));
1454 static inline int livebox_destroy(struct livebox *livebox)
1459 struct group *group;
1460 struct option *option;
1464 xmlFree(livebox->auto_launch);
1465 xmlFree(livebox->pkgid);
1466 xmlFree(livebox->abi);
1467 xmlFree(livebox->name);
1468 xmlFree(livebox->icon);
1469 xmlFree(livebox->lb_src);
1470 xmlFree(livebox->lb_group);
1471 xmlFree(livebox->pd_src);
1472 xmlFree(livebox->pd_group);
1473 xmlFree(livebox->pd_size);
1474 xmlFree(livebox->libexec);
1475 xmlFree(livebox->script);
1476 xmlFree(livebox->period);
1477 xmlFree(livebox->content);
1478 xmlFree(livebox->setup);
1479 xmlFree(livebox->preview[0]); /* 1x1 */
1480 xmlFree(livebox->preview[1]); /* 2x1 */
1481 xmlFree(livebox->preview[2]); /* 2x2 */
1482 xmlFree(livebox->preview[3]); /* 4x1 */
1483 xmlFree(livebox->preview[4]); /* 4x2 */
1484 xmlFree(livebox->preview[5]); /* 4x3 */
1485 xmlFree(livebox->preview[6]); /* 4x4 */
1486 xmlFree(livebox->preview[7]); /* 21x21 */
1487 xmlFree(livebox->preview[8]); /* 23x21 */
1488 xmlFree(livebox->preview[9]); /* 23x23 */
1490 dlist_foreach_safe(livebox->i18n_list, l, n, i18n) {
1491 livebox->i18n_list = dlist_remove(livebox->i18n_list, l);
1492 xmlFree(i18n->name);
1493 xmlFree(i18n->icon);
1494 xmlFree(i18n->lang);
1498 dlist_foreach_safe(livebox->group_list, l, n, group) {
1499 livebox->group_list = dlist_remove(livebox->group_list, l);
1500 DbgPrint("Release %s/%s\n", group->cluster, group->category);
1502 if (group->ctx_item) {
1503 dlist_foreach_safe(group->option_list, il, in, option) {
1504 group->option_list = dlist_remove(group->option_list, il);
1505 DbgPrint("Release option %s(%s)\n", option->key, option->value);
1506 xmlFree(option->key);
1507 xmlFree(option->value);
1510 xmlFree(group->ctx_item);
1513 xmlFree(group->cluster);
1514 xmlFree(group->category);
1522 static inline void update_i18n_name(struct livebox *livebox, xmlNodePtr node)
1529 name = xmlNodeGetContent(node);
1531 ErrPrint("Invalid tag\n");
1535 lang = xmlNodeGetLang(node);
1537 if (livebox->name) {
1538 DbgPrint("Override default name: %s\n", livebox->name);
1539 xmlFree(livebox->name);
1542 livebox->name = name;
1546 dlist_foreach(livebox->i18n_list, l, i18n) {
1547 if (!xmlStrcasecmp(i18n->lang, lang)) {
1549 DbgPrint("Override name: %s\n", i18n->name);
1550 xmlFree(i18n->name);
1558 i18n = calloc(1, sizeof(*i18n));
1560 ErrPrint("Heap: %s\n", strerror(errno));
1568 DbgPrint("Label[%s] - [%s] added\n", i18n->lang, i18n->name);
1569 livebox->i18n_list = dlist_append(livebox->i18n_list, i18n);
1572 static inline void update_i18n_icon(struct livebox *livebox, xmlNodePtr node)
1579 icon = xmlNodeGetContent(node);
1581 ErrPrint("Invalid tag\n");
1585 lang = xmlNodeGetLang(node);
1587 if (livebox->icon) {
1588 DbgPrint("Override default icon: %s\n", livebox->icon);
1589 xmlFree(livebox->icon);
1592 livebox->icon = icon;
1596 dlist_foreach(livebox->i18n_list, l, i18n) {
1597 if (!xmlStrcasecmp(i18n->lang, lang)) {
1599 DbgPrint("Override icon %s for %s\n", i18n->icon, i18n->name);
1600 xmlFree(i18n->icon);
1608 i18n = calloc(1, sizeof(*i18n));
1610 ErrPrint("Heap: %s\n", strerror(errno));
1618 DbgPrint("Icon[%s] - [%s] added\n", i18n->lang, i18n->icon);
1619 livebox->i18n_list = dlist_append(livebox->i18n_list, i18n);
1622 static inline void update_launch(struct livebox *livebox, xmlNodePtr node)
1625 launch = xmlNodeGetContent(node);
1627 DbgPrint("Has no launch\n");
1631 livebox->auto_launch = xmlStrdup(launch);
1632 if (!livebox->auto_launch) {
1633 ErrPrint("Failed to duplicate string: %s\n", (char *)launch);
1638 static inline void update_setup(struct livebox *livebox, xmlNodePtr node)
1641 setup = xmlNodeGetContent(node);
1643 DbgPrint("Has no setup\n");
1647 livebox->setup = xmlStrdup(setup);
1648 if (!livebox->setup) {
1649 ErrPrint("Failed to duplicate string: %s\n", (char *)setup);
1654 static inline void update_content(struct livebox *livebox, xmlNodePtr node)
1657 content = xmlNodeGetContent(node);
1659 DbgPrint("Has no content\n");
1663 livebox->content = xmlStrdup(content);
1664 if (!livebox->content) {
1665 ErrPrint("Failed to duplicate string: %s\n", (char *)content);
1670 static inline void update_box(struct livebox *livebox, xmlNodePtr node)
1672 if (!xmlHasProp(node, (const xmlChar *)"type")) {
1673 livebox->lb_type = LB_TYPE_FILE;
1677 type = xmlGetProp(node, (const xmlChar *)"type");
1679 ErrPrint("Type is NIL\n");
1680 livebox->lb_type = LB_TYPE_FILE;
1682 if (!xmlStrcasecmp(type, (const xmlChar *)"text"))
1683 livebox->lb_type = LB_TYPE_TEXT;
1684 else if (!xmlStrcasecmp(type, (const xmlChar *)"buffer"))
1685 livebox->lb_type = LB_TYPE_BUFFER;
1686 else if (!xmlStrcasecmp(type, (const xmlChar *)"script"))
1687 livebox->lb_type = LB_TYPE_SCRIPT;
1689 livebox->lb_type = LB_TYPE_FILE;
1695 if (!xmlHasProp(node, (const xmlChar *)"mouse_event")) {
1696 livebox->mouse_event = 0;
1698 xmlChar *mouse_event;
1700 mouse_event = xmlGetProp(node, (const xmlChar *)"mouse_event");
1702 ErrPrint("mouse_event is NIL\n");
1703 livebox->mouse_event = 0;
1705 livebox->mouse_event = !xmlStrcasecmp(mouse_event, (const xmlChar *)"true");
1706 xmlFree(mouse_event);
1710 for (node = node->children; node; node = node->next) {
1711 if (!xmlStrcasecmp(node->name, (const xmlChar *)"size")) {
1714 size = xmlNodeGetContent(node);
1716 ErrPrint("Invalid size tag\n");
1720 if (!xmlStrcasecmp(size, (const xmlChar *)"1x1")) {
1721 livebox->size_list |= LB_SIZE_TYPE_1x1;
1722 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1723 livebox->preview[0] = xmlGetProp(node, (const xmlChar *)"preview");
1725 } else if (!xmlStrcasecmp(size, (const xmlChar *)"2x1")) {
1726 livebox->size_list |= LB_SIZE_TYPE_2x1;
1727 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1728 livebox->preview[1] = xmlGetProp(node, (const xmlChar *)"preview");
1730 } else if (!xmlStrcasecmp(size, (const xmlChar *)"2x2")) {
1731 livebox->size_list |= LB_SIZE_TYPE_2x2;
1732 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1733 livebox->preview[2] = xmlGetProp(node, (const xmlChar *)"preview");
1735 } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x1")) {
1736 livebox->size_list |= LB_SIZE_TYPE_4x1;
1737 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1738 livebox->preview[3] = xmlGetProp(node, (const xmlChar *)"preview");
1740 } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x2")) {
1741 livebox->size_list |= LB_SIZE_TYPE_4x2;
1742 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1743 livebox->preview[4] = xmlGetProp(node, (const xmlChar *)"preview");
1745 } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x3")) {
1746 livebox->size_list |= LB_SIZE_TYPE_4x3;
1747 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1748 livebox->preview[5] = xmlGetProp(node, (const xmlChar *)"preview");
1750 } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x4")) {
1751 livebox->size_list |= LB_SIZE_TYPE_4x4;
1752 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1753 livebox->preview[6] = xmlGetProp(node, (const xmlChar *)"preview");
1755 } else if (!xmlStrcasecmp(size, (const xmlChar *)"21x21")) {
1756 livebox->size_list |= LB_SIZE_TYPE_EASY_1x1;
1757 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1758 livebox->preview[7] = xmlGetProp(node, (const xmlChar *)"preview");
1760 } else if (!xmlStrcasecmp(size, (const xmlChar *)"23x21")) {
1761 livebox->size_list |= LB_SIZE_TYPE_EASY_3x1;
1762 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1763 livebox->preview[8] = xmlGetProp(node, (const xmlChar *)"preview");
1765 } else if (!xmlStrcasecmp(size, (const xmlChar *)"23x23")) {
1766 livebox->size_list |= LB_SIZE_TYPE_EASY_3x3;
1767 if (xmlHasProp(node, (const xmlChar *)"preview")) {
1768 livebox->preview[9] = xmlGetProp(node, (const xmlChar *)"preview");
1771 ErrPrint("Invalid size tag (%s)\n", size);
1775 } else if (!xmlStrcasecmp(node->name, (const xmlChar *)"script")) {
1778 if (!xmlHasProp(node, (const xmlChar *)"src")) {
1779 ErrPrint("Invalid script tag. has no src\n");
1783 src = xmlGetProp(node, (const xmlChar *)"src");
1785 ErrPrint("Invalid script tag. src is NIL\n");
1789 if (livebox->lb_src) {
1790 DbgPrint("Override lb src: %s\n", livebox->lb_src);
1791 xmlFree(livebox->lb_src);
1794 livebox->lb_src = src;
1796 if (xmlHasProp(node, (const xmlChar *)"group")) {
1798 group = xmlGetProp(node, (const xmlChar *)"group");
1800 ErrPrint("Group is NIL\n");
1802 if (livebox->lb_group) {
1803 DbgPrint("Override lb group: %s\n", livebox->lb_group);
1804 xmlFree(livebox->lb_group);
1807 livebox->lb_group = group;
1814 static inline void update_group(struct livebox *livebox, xmlNodePtr node)
1817 xmlNodePtr category;
1818 xmlNodePtr option_item;
1819 xmlChar *cluster_name;
1820 xmlChar *category_name;
1826 struct group *group;
1827 struct option *option;
1830 for (cluster = cluster->children; cluster; cluster = cluster->next) {
1831 if (xmlStrcasecmp(cluster->name, (const xmlChar *)"cluster")) {
1832 DbgPrint("Skip: %s\n", cluster->name);
1836 if (!xmlHasProp(cluster, (const xmlChar *)"name")) {
1837 ErrPrint("Invalid cluster, has no name\n");
1841 cluster_name = xmlGetProp(cluster, (const xmlChar *)"name");
1842 if (!cluster_name) {
1843 ErrPrint("Invalid cluster name. NIL\n");
1847 for (category = cluster->children; category; category = category->next) {
1848 if (xmlStrcasecmp(category->name, (const xmlChar *)"category")) {
1849 DbgPrint("Skip: %s\n", category->name);
1853 if (!xmlHasProp(category, (const xmlChar *)"name")) {
1854 ErrPrint("Invalid category, has no name\n");
1858 category_name = xmlGetProp(category, (const xmlChar *)"name");
1859 if (!category_name) {
1860 ErrPrint("Invalid category name. NIL\n");
1864 group = calloc(1, sizeof(*group));
1866 ErrPrint("Heap: %s\n", strerror(errno));
1867 xmlFree(category_name);
1871 group->cluster = xmlStrdup(cluster_name);
1872 if (!group->cluster) {
1873 ErrPrint("Heap: %s\n", strerror(errno));
1874 xmlFree(category_name);
1879 group->category = category_name;
1880 livebox->group_list = dlist_append(livebox->group_list, group);
1882 if (!xmlHasProp(category, (const xmlChar *)"context")) {
1883 DbgPrint("%s, %s has no ctx info\n", group->cluster, group->category);
1887 ctx_item = xmlGetProp(category, (const xmlChar *)"context");
1889 ErrPrint("Failed to get context ID (%s, %s)\n", group->cluster, group->category);
1893 group->ctx_item = ctx_item;
1894 DbgPrint("Build group item: %s - %s - %s\n", group->cluster, group->category, group->ctx_item);
1896 for (option_item = category->children; option_item; option_item = option_item->next) {
1897 if (xmlStrcasecmp(option_item->name, (const xmlChar *)"option")) {
1898 DbgPrint("Skip: %s\n", option_item->name);
1902 if (!xmlHasProp(option_item, (const xmlChar *)"key")) {
1903 ErrPrint("Invalid option, has no key\n");
1907 if (!xmlHasProp(option_item, (const xmlChar *)"value")) {
1908 ErrPrint("Invalid option, has no value\n");
1912 key = xmlGetProp(option_item, (const xmlChar *)"key");
1914 ErrPrint("Invalid key. NIL\n");
1918 value = xmlGetProp(option_item, (const xmlChar *)"value");
1920 ErrPrint("Invalid valid. NIL\n");
1925 option = calloc(1, sizeof(*option));
1927 ErrPrint("Heap: %s\n", strerror(errno));
1934 option->value = value;
1936 group->option_list = dlist_append(group->option_list, option);
1940 xmlFree(cluster_name);
1944 static inline void update_pd(struct livebox *livebox, xmlNodePtr node)
1946 if (!xmlHasProp(node, (const xmlChar *)"type")) {
1947 livebox->pd_type = PD_TYPE_SCRIPT;
1951 type = xmlGetProp(node, (const xmlChar *)"type");
1953 ErrPrint("type is NIL\n");
1957 if (!xmlStrcasecmp(type, (const xmlChar *)"text"))
1958 livebox->pd_type = PD_TYPE_TEXT;
1959 else if (!xmlStrcasecmp(type, (const xmlChar *)"buffer"))
1960 livebox->pd_type = PD_TYPE_BUFFER;
1962 livebox->pd_type = PD_TYPE_SCRIPT;
1967 for (node = node->children; node; node = node->next) {
1968 if (!xmlStrcasecmp(node->name, (const xmlChar *)"size")) {
1971 size = xmlNodeGetContent(node);
1973 ErrPrint("Invalid size tag\n");
1977 if (livebox->pd_size) {
1978 DbgPrint("Override pd size: %s\n", livebox->pd_size);
1979 xmlFree(livebox->pd_size);
1981 livebox->pd_size = size;
1982 } else if (!xmlStrcasecmp(node->name, (const xmlChar *)"script")) {
1985 if (!xmlHasProp(node, (const xmlChar *)"src")) {
1986 ErrPrint("Invalid script tag, has no src\n");
1990 src = xmlGetProp(node, (const xmlChar *)"src");
1992 ErrPrint("src is NIL\n");
1996 if (livebox->pd_src) {
1997 DbgPrint("Overide PD src: %s\n", livebox->pd_src);
1998 xmlFree(livebox->pd_src);
2001 livebox->pd_src = src;
2003 if (xmlHasProp(node, (const xmlChar *)"group")) {
2005 group = xmlGetProp(node, (const xmlChar *)"group");
2007 ErrPrint("Group is NIL\n");
2009 if (livebox->pd_group) {
2010 DbgPrint("Override PD group : %s\n", livebox->pd_group);
2011 xmlFree(livebox->pd_group);
2014 livebox->pd_group = group;
2021 static inline int db_insert_livebox(struct livebox *livebox, const char *appid)
2026 struct group *group;
2029 struct option *option;
2031 begin_transaction();
2032 ret = db_insert_pkgmap(appid, (char *)livebox->pkgid, livebox->primary);
2036 ret = db_insert_provider(livebox);
2040 ret = db_insert_client(livebox);
2044 dlist_foreach(livebox->i18n_list, l, i18n) {
2045 ret = db_insert_i18n((char *)livebox->pkgid, (char *)i18n->lang, (char *)i18n->name, (char *)i18n->icon);
2050 if (livebox->size_list & LB_SIZE_TYPE_1x1) {
2051 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_1x1, (char *)livebox->preview[0]);
2056 if (livebox->size_list & LB_SIZE_TYPE_2x1) {
2057 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_2x1, (char *)livebox->preview[1]);
2062 if (livebox->size_list & LB_SIZE_TYPE_2x2) {
2063 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_2x2, (char *)livebox->preview[2]);
2068 if (livebox->size_list & LB_SIZE_TYPE_4x1) {
2069 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_4x1, (char *)livebox->preview[3]);
2074 if (livebox->size_list & LB_SIZE_TYPE_4x2) {
2075 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_4x2, (char *)livebox->preview[4]);
2080 if (livebox->size_list & LB_SIZE_TYPE_4x3) {
2081 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_4x3, (char *)livebox->preview[5]);
2086 if (livebox->size_list & LB_SIZE_TYPE_4x4) {
2087 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_4x4, (char *)livebox->preview[6]);
2092 if (livebox->size_list & LB_SIZE_TYPE_EASY_1x1) {
2093 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_EASY_1x1, (char *)livebox->preview[7]);
2098 if (livebox->size_list & LB_SIZE_TYPE_EASY_3x1) {
2099 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_EASY_3x1, (char *)livebox->preview[8]);
2104 if (livebox->size_list & LB_SIZE_TYPE_EASY_3x3) {
2105 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_EASY_3x3, (char *)livebox->preview[9]);
2110 dlist_foreach(livebox->group_list, l, group) {
2112 id = db_get_group_id((char *)group->cluster, (char *)group->category);
2116 ret = db_insert_group((char *)livebox->pkgid, (char *)group->cluster, (char *)group->category);
2118 ErrPrint("[%s]-[%s] is not exists\n", group->cluster, group->category);
2122 DbgPrint("New group name is built - %s/%s\n", group->cluster, group->category);
2123 id = db_get_group_id((char *)group->cluster, (char *)group->category);
2125 ErrPrint("Failed to get group id for %s/%s\n", group->cluster, group->category);
2130 if (!group->ctx_item) {
2131 DbgPrint("%s, %s - has no ctx info\n", group->cluster, group->category);
2135 ret = db_insert_groupmap(id, (char *)livebox->pkgid, (char *)group->ctx_item);
2139 /* REUSE "id" from here , option ID */
2140 id = db_get_option_id(id, (char *)livebox->pkgid, (char *)group->ctx_item);
2144 dlist_foreach(group->option_list, il, option) {
2145 ret = db_insert_option((char *)livebox->pkgid, id, (char *)option->key, (char *)option->value);
2151 commit_transaction();
2152 livebox_destroy(livebox);
2156 ErrPrint("ROLLBACK\n");
2157 rollback_transaction();
2158 livebox_destroy(livebox);
2162 static inline int do_install(xmlNodePtr node, const char *appid)
2164 struct livebox *livebox;
2168 if (!xmlHasProp(node, (const xmlChar *)"appid")) {
2169 ErrPrint("Missing appid\n");
2173 pkgid = xmlGetProp(node, (const xmlChar *)"appid");
2174 if (!pkgid || !validate_pkgid(appid, (char *)pkgid)) {
2175 ErrPrint("Invalid appid\n");
2180 DbgPrint("appid: %s\n", (char *)pkgid);
2182 livebox = calloc(1, sizeof(*livebox));
2184 ErrPrint("Heap: %s\n", strerror(errno));
2189 livebox->pkgid = pkgid;
2191 if (xmlHasProp(node, (const xmlChar *)"primary")) {
2192 tmp = xmlGetProp(node, (const xmlChar *)"primary");
2193 livebox->primary = !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2197 if (xmlHasProp(node, (const xmlChar *)"script")) {
2198 livebox->script = xmlGetProp(node, (const xmlChar *)"script");
2199 if (!livebox->script)
2200 ErrPrint("script is NIL\n");
2203 if (xmlHasProp(node, (const xmlChar *)"nodisplay")) {
2204 tmp = xmlGetProp(node, (const xmlChar *)"nodisplay");
2205 livebox->nodisplay = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2209 if (xmlHasProp(node, (const xmlChar *)"pinup")) {
2210 tmp = xmlGetProp(node, (const xmlChar *)"pinup");
2211 livebox->pinup = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2215 if (xmlHasProp(node, (const xmlChar *)"period")) {
2216 livebox->period = xmlGetProp(node, (const xmlChar *)"period");
2217 if (!livebox->period)
2218 ErrPrint("Period is NIL\n");
2221 if (xmlHasProp(node, (const xmlChar *)"timeout")) {
2222 livebox->timeout = xmlGetProp(node, (const xmlChar *)"timeout");
2223 if (!livebox->timeout)
2224 ErrPrint("Timeout is NIL\n");
2227 if (xmlHasProp(node, (const xmlChar *)"secured")) {
2228 tmp = xmlGetProp(node, (const xmlChar *)"secured");
2229 livebox->secured = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2233 if (xmlHasProp(node, (const xmlChar *)"network")) {
2234 tmp = xmlGetProp(node, (const xmlChar *)"network");
2235 livebox->network = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2239 if (xmlHasProp(node, (const xmlChar *)"abi")) {
2240 livebox->abi = xmlGetProp(node, (const xmlChar *)"abi");
2241 if (!livebox->abi) {
2242 ErrPrint("ABI is NIL\n");
2243 livebox_destroy(livebox);
2247 livebox->abi = xmlStrdup((const xmlChar *)"c");
2248 if (!livebox->abi) {
2249 ErrPrint("Heap: %s\n", strerror(errno));
2250 livebox_destroy(livebox);
2255 if (xmlHasProp(node, (const xmlChar *)"libexec")) {
2256 livebox->libexec = xmlGetProp(node, (const xmlChar *)"libexec");
2257 if (!livebox->libexec) {
2258 ErrPrint("libexec is NIL\n");
2259 livebox_destroy(livebox);
2262 } else if (!xmlStrcasecmp(livebox->abi, (const xmlChar *)"c") || !xmlStrcasecmp(livebox->abi, (const xmlChar *)"cpp")) {
2266 len = strlen((char *)livebox->pkgid) + strlen("/libexec/liblive-.so") + 1;
2268 filename = malloc(len);
2270 livebox_destroy(livebox);
2274 snprintf(filename, len, "/libexec/liblive-%s.so", livebox->pkgid);
2275 livebox->libexec = xmlStrdup((xmlChar *)filename);
2276 DbgPrint("Use the default libexec: %s\n", filename);
2279 if (!livebox->libexec) {
2280 livebox_destroy(livebox);
2285 for (node = node->children; node; node = node->next) {
2286 if (!xmlStrcmp(node->name, (const xmlChar *)"text"))
2289 DbgPrint("Nodename: %s\n", node->name);
2290 if (!xmlStrcasecmp(node->name, (const xmlChar *)"label")) {
2291 update_i18n_name(livebox, node);
2295 if (!xmlStrcasecmp(node->name, (const xmlChar *)"icon")) {
2296 update_i18n_icon(livebox, node);
2300 if (!xmlStrcasecmp(node->name, (const xmlChar *)"box")) {
2301 update_box(livebox, node);
2305 if (!xmlStrcasecmp(node->name, (const xmlChar *)"pd")) {
2306 update_pd(livebox, node);
2310 if (!xmlStrcasecmp(node->name, (const xmlChar *)"group")) {
2311 update_group(livebox, node);
2315 if (!xmlStrcasecmp(node->name, (const xmlChar *)"content")) {
2316 update_content(livebox, node);
2320 if (!xmlStrcasecmp(node->name, (const xmlChar *)"setup")) {
2321 update_setup(livebox, node);
2325 if (!xmlStrcasecmp(node->name, (const xmlChar *)"launch")) {
2326 update_launch(livebox, node);
2331 return db_insert_livebox(livebox, appid);
2334 int PKGMGR_PARSER_PLUGIN_INSTALL(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 DbgPrint("node->name: %s\n", node->name);
2354 if (!xmlStrcasecmp(node->name, (const xmlChar *)"livebox")) {
2355 ret = do_install(node, appid);
2356 DbgPrint("Returns: %d\n", ret);
2363 int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr docPtr, const char *appid)
2367 if (!s_info.handle) {
2368 if (db_init() < 0) {
2369 ErrPrint("Failed to init DB\n");
2374 node = xmlDocGetRootElement(docPtr);
2376 ErrPrint("Invalid document\n");
2380 for (node = node->children; node; node = node->next) {
2381 if (!xmlStrcasecmp(node->name, (const xmlChar *)"livebox"))
2386 ErrPrint("Root has no livebox\n");
2393 static inline int do_uninstall(xmlNodePtr node, const char *appid)
2398 if (!xmlHasProp(node, (const xmlChar *)"appid")) {
2399 ErrPrint("Missing appid\n");
2403 pkgid = xmlGetProp(node, (const xmlChar *)"appid");
2404 if (!validate_pkgid(appid, (char *)pkgid)) {
2405 ErrPrint("Invalid package\n");
2410 begin_transaction();
2411 ret = db_remove_box_size((char *)pkgid);
2415 ret = db_remove_i18n((char *)pkgid);
2419 ret = db_remove_client((char *)pkgid);
2423 ret = db_remove_provider((char *)pkgid);
2427 ret = db_remove_option((char *)pkgid);
2428 DbgPrint("Remove option: %d\n", ret);
2430 ret = db_remove_groupmap((char *)pkgid);
2431 DbgPrint("Remove groupmap: %d\n", ret);
2433 ret = db_remove_group((char *)pkgid);
2437 ret = db_remove_pkgmap((char *)pkgid);
2441 commit_transaction();
2447 rollback_transaction();
2452 int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr docPtr, const char *appid)
2457 if (!s_info.handle) {
2458 if (db_init() < 0) {
2459 ErrPrint("Failed to init DB\n");
2464 node = xmlDocGetRootElement(docPtr);
2466 ErrPrint("Invalid document\n");
2470 for (node = node->children; node; node = node->next) {
2471 if (!xmlStrcasecmp(node->name, (const xmlChar *)"livebox")) {
2472 ret = do_uninstall(node, appid);
2473 DbgPrint("Returns: %d\n", ret);