Update SMACK, Fix a crash of terminating sequence, etc, ...
[apps/livebox/data-provider-master.git] / pkgmgr_livebox / src / service_register.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
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.
15  */
16
17 #include <stdio.h>
18 #include <errno.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include <libgen.h>
23 #include <string.h>
24
25 #include <sqlite3.h>
26 #include <db-util.h>
27 #include <libxml/parser.h>
28 #include <libxml/tree.h>
29 #include <dlog.h>
30
31 #include <livebox-service.h>
32
33 #include "dlist.h"
34
35 #if !defined(SECURE_LOGD)
36 #define SECURE_LOGD LOGD
37 #endif
38
39 #if !defined(SECURE_LOGE)
40 #define SECURE_LOGE LOGE
41 #endif
42
43 #if !defined(SECURE_LOGW)
44 #define SECURE_LOGW LOGW
45 #endif
46
47 #if !defined(FLOG)
48 #define DbgPrint(format, arg...)        SECURE_LOGD("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
49 #define ErrPrint(format, arg...)        SECURE_LOGE("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
50 #endif
51 /* End of a file */
52
53 /*!
54  * \note
55  * DB Table schema
56  *
57  * pkgmap
58  * +-------+-------+-------+-------+
59  * | appid | pkgid | uiapp | prime |
60  * +-------+-------+-------+-------+
61  * |   -   |   -   |   -   |   -   |
62  * +-------+-------+-------+-------+
63  * CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, uiapp TEXT, prime INTEGER )
64  *
65  *
66  * provider
67  * +-------+---------+-----+---------+----------+---------+-----------+---------+--------+----------+---------+---------+--------+--------+-------+
68  * | pkgid | network | abi | secured | box_type | box_src | box_group | pd_type | pd_src | pd_group | libexec | timeout | period | script | pinup |
69  * +-------+---------+-----+---------+----------+---------+-----------+---------+--------+----------+---------+---------+--------+--------+-------+
70  * |   -   |    -    |  -  |    -    |     -    |    -    |     -     |    -    |    -   |     -    |     -   |    -    |    -   |    -   |   -   |
71  * +-------+---------+-----+---------+----------+---------+-----------+---------+--------+----------+---------+---------+--------+--------+-------+
72  * 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))
73  *
74  * = box_type = { text | buffer | script | image }
75  * = pd_type = { text | buffer | script }
76  * = network = { 1 | 0 }
77  * = secured = { 1 | 0 }
78  *
79  *
80  * client
81  * +-------+------+---------+-------------+---------+---------+-----------+-------+-------------+
82  * | pkgid | Icon |  Name   | auto_launch | pd_size | content | nodisplay | setup | mouse_event |
83  * +-------+------+---------+-------------+---------+---------+-----------+-------+-------------+
84  * |   -   |   -  |    -    |      -      |    -    |    -    |     -     |   -   |      -      }
85  * +-------+------+---------+-------------+---------+---------+-----------+-------+-------------+
86  * 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, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
87  *
88  * = auto_launch = UI-APPID
89  * = pd_size = WIDTHxHEIGHT
90  *
91  *
92  * i18n
93  * +-------+------+------+------+
94  * |   fk  | lang | name | icon |
95  * +-------+------+------+------+
96  * | pkgid |   -  |   -  |   -  |
97  * +-------+------+------+------+
98  * CREATE TABLE i18n ( pkgid TEXT NOT NULL, lang TEXT COLLATE NOCASE, name TEXT, icon TEXT, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
99  *
100  *
101  * box_size
102  * +-------+-----------+---------+--------------+------------+
103  * | pkgid | size_type | preview | touch_effect | need_frame |
104  * +-------+-----------+---------+--------------+------------+
105  * |   -   |     -     |    -    |       -      |     -      |
106  * +-------+-----------+---------+--------------+------------+
107  * CREATE TABLE box_size ( pkgid TEXT NOT NULL, size_type INTEGER, preview TEXT, INTEGER, touch_effect INTEGER, need_frame INTEGER, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) )
108  *
109  * = box_size_list = { WIDTHxHEIGHT; WIDTHxHEIGHT; ... }
110  *
111  * groupinfo
112  * +----+---------+----------+-------+
113  * | id | cluster | category | pkgid |
114  * +----+---------+----------+-------+
115  * |  - |    -    |    -     |   -   |
116  * +----+---------+----------+-------|
117  * 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) ))
118  *
119  * groupmap
120  * +-------+----+----------+-----------+
121  * | pkgid | id | ctx_item | option_id |
122  * +-------+----+----------+-----------+
123  * 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) )
124  *
125  *
126  * option
127  * +-------+-----------+-----+-------+
128  * | pkgid | option_id | key | value |
129  * +-------+-----------+-----+-------+
130  * 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)  )
131  */
132
133 #if !defined(LIBXML_TREE_ENABLED)
134         #error "LIBXML is not supporting the tree"
135 #endif
136
137 #if defined(LOG_TAG)
138 #undef LOG_TAG
139 #endif
140
141 #define LOG_TAG "PKGMGR_LIVEBOX"
142
143 int errno;
144
145 struct i18n {
146         xmlChar *lang;
147         xmlChar *name;
148         xmlChar *icon;
149 };
150
151 enum lb_type {
152         LB_TYPE_NONE = 0x0,
153         LB_TYPE_SCRIPT,
154         LB_TYPE_FILE,
155         LB_TYPE_TEXT,
156         LB_TYPE_BUFFER,
157 };
158
159 enum pd_type {
160         PD_TYPE_NONE = 0x0,
161         PD_TYPE_SCRIPT,
162         PD_TYPE_TEXT,
163         PD_TYPE_BUFFER,
164 };
165
166 struct livebox {
167         xmlChar *pkgid;
168         int secured;
169         int network;
170         xmlChar *auto_launch;
171         xmlChar *abi;
172         xmlChar *name; /* Default name */
173         xmlChar *icon; /* Default icon */
174         xmlChar *libexec; /* Path of the SO file */
175         xmlChar *timeout; /* INTEGER, timeout */
176         xmlChar *period; /* DOUBLE, update period */
177         xmlChar *script; /* Script engine */
178         xmlChar *content; /* Content information */
179         xmlChar *setup;
180         xmlChar *uiapp; /* UI App Id */
181
182         int pinup; /* Is this support the pinup feature? */
183         int primary; /* Is this primary livebox? */
184         int nodisplay;
185         int mouse_event; /* Mouse event processing option for livebox */
186
187         int default_touch_effect;
188         int default_need_frame;
189
190         enum lb_type lb_type;
191         xmlChar *lb_src;
192         xmlChar *lb_group;
193         int size_list; /* 1x1, 2x1, 2x2, 4x1, 4x2, 4x3, 4x4 */
194
195         xmlChar *preview[NR_OF_SIZE_LIST];
196         int touch_effect[NR_OF_SIZE_LIST]; /* Touch effect of a livebox */
197         int need_frame[NR_OF_SIZE_LIST]; /* Box needs frame which should be cared by viewer */
198
199         enum pd_type pd_type;
200         xmlChar *pd_src;
201         xmlChar *pd_group;
202         xmlChar *pd_size; /* Default PD size */
203
204         struct dlist *i18n_list;
205         struct dlist *group_list;
206 };
207
208 struct group {
209         xmlChar *cluster;
210         xmlChar *category;
211         xmlChar *ctx_item;
212         struct dlist *option_list;
213 };
214
215 struct option {
216         xmlChar *key;
217         xmlChar *value;
218 };
219
220 static struct {
221         const char *dbfile;
222         sqlite3 *handle;
223 } s_info = {
224         .dbfile = "/opt/dbspace/.livebox.db",
225         .handle = NULL,
226 };
227
228 static inline int begin_transaction(void)
229 {
230         sqlite3_stmt *stmt;
231         int ret;
232
233         ret = sqlite3_prepare_v2(s_info.handle, "BEGIN TRANSACTION", -1, &stmt, NULL);
234
235         if (ret != SQLITE_OK) {
236                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
237                 return EXIT_FAILURE;
238         }
239
240         if (sqlite3_step(stmt) != SQLITE_DONE) {
241                 DbgPrint("Failed to do update (%s)\n",
242                                         sqlite3_errmsg(s_info.handle));
243                 sqlite3_finalize(stmt);
244                 return EXIT_FAILURE;
245         }
246
247         sqlite3_finalize(stmt);
248         return EXIT_SUCCESS;
249 }
250
251 static inline int rollback_transaction(void)
252 {
253         int ret;
254         sqlite3_stmt *stmt;
255
256         ret = sqlite3_prepare_v2(s_info.handle, "ROLLBACK TRANSACTION", -1, &stmt, NULL);
257         if (ret != SQLITE_OK) {
258                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
259                 return EXIT_FAILURE;
260         }
261
262         if (sqlite3_step(stmt) != SQLITE_DONE) {
263                 DbgPrint("Failed to do update (%s)\n",
264                                 sqlite3_errmsg(s_info.handle));
265                 sqlite3_finalize(stmt);
266                 return EXIT_FAILURE;
267         }
268
269         sqlite3_finalize(stmt);
270         return EXIT_SUCCESS;
271 }
272
273 static inline int commit_transaction(void)
274 {
275         sqlite3_stmt *stmt;
276         int ret;
277
278         ret = sqlite3_prepare_v2(s_info.handle, "COMMIT TRANSACTION", -1, &stmt, NULL);
279         if (ret != SQLITE_OK) {
280                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
281                 return EXIT_FAILURE;
282         }
283
284         if (sqlite3_step(stmt) != SQLITE_DONE) {
285                 DbgPrint("Failed to do update (%s)\n",
286                                         sqlite3_errmsg(s_info.handle));
287                 sqlite3_finalize(stmt);
288                 return EXIT_FAILURE;
289         }
290
291         sqlite3_finalize(stmt);
292         return EXIT_SUCCESS;
293 }
294
295 static inline int db_create_pkgmap(void)
296 {
297         char *err;
298         static const char *ddl;
299
300         ddl = "CREATE TABLE pkgmap ( pkgid TEXT PRIMARY KEY NOT NULL, appid TEXT, uiapp TEXT, prime INTEGER )";
301         if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
302                 ErrPrint("Failed to execute the DDL (%s)\n", err);
303                 return -EIO;
304         }
305
306         if (sqlite3_changes(s_info.handle) == 0)
307                 ErrPrint("No changes to DB\n");
308
309         return 0;
310 }
311
312 static inline int db_insert_pkgmap(const char *appid, const char *pkgid, const char *uiappid, int primary)
313 {
314         int ret;
315         static const char *dml;
316         sqlite3_stmt *stmt;
317
318         if (!uiappid)
319                 uiappid = ""; /*!< Could we replace this with Main AppId of this package? */
320
321         dml = "INSERT INTO pkgmap ( appid, pkgid, uiapp, prime ) VALUES (? ,?, ?, ?)";
322         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
323         if (ret != SQLITE_OK) {
324                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
325                 return -EIO;
326         }
327
328         ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT);
329         if (ret != SQLITE_OK) {
330                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
331                 ret = -EIO;
332                 goto out;
333         }
334
335         ret = sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
336         if (ret != SQLITE_OK) {
337                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
338                 ret = -EIO;
339                 goto out;
340         }
341
342         ret = sqlite3_bind_text(stmt, 3, uiappid, -1, SQLITE_TRANSIENT);
343         if (ret != SQLITE_OK) {
344                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
345                 ret = -EIO;
346                 goto out;
347         }
348
349         ret = sqlite3_bind_int(stmt, 4, primary);
350         if (ret != SQLITE_OK) {
351                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
352                 ret = -EIO;
353                 goto out;
354         }
355
356         ret = 0;
357         if (sqlite3_step(stmt) != SQLITE_DONE) {
358                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
359                 ret = -EIO;
360         }
361
362 out:
363         sqlite3_reset(stmt);
364         sqlite3_clear_bindings(stmt);
365         sqlite3_finalize(stmt);
366         return ret;
367 }
368
369 static inline int db_remove_pkgmap(const char *pkgid)
370 {
371         int ret;
372         static const char *dml;
373         sqlite3_stmt *stmt;
374
375         dml = "DELETE FROM pkgmap WHERE pkgid = ?";
376         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
377         if (ret != SQLITE_OK) {
378                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
379                 return -EIO;
380         }
381
382         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
383         if (ret != SQLITE_OK) {
384                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
385                 ret = -EIO;
386                 goto out;
387         }
388
389         ret = 0;
390         if (sqlite3_step(stmt) != SQLITE_DONE) {
391                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
392                 ret = -EIO;
393         }
394
395 out:
396         sqlite3_reset(stmt);
397         sqlite3_clear_bindings(stmt);
398         sqlite3_finalize(stmt);
399         return ret;
400 }
401
402 static inline int db_create_provider(void)
403 {
404         char *err;
405         static const char *ddl;
406
407         ddl = "CREATE TABLE provider (" \
408                 "pkgid TEXT PRIMARY KEY NOT NULL, network INTEGER, " \
409                 "abi TEXT, secured INTEGER, box_type INTEGER, " \
410                 "box_src TEXT, box_group TEXT, pd_type INTEGER, " \
411                 "pd_src TEXT, pd_group TEXT, libexec TEXT, timeout INTEGER, period TEXT, script TEXT, pinup INTEGER, "\
412                 "FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
413
414         if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
415                 ErrPrint("Failed to execute the DDL (%s)\n", err);
416                 return -EIO;
417         }
418
419         if (sqlite3_changes(s_info.handle) == 0)
420                 ErrPrint("No changes to DB\n");
421
422         return 0;
423 }
424
425 static inline int db_remove_provider(const char *pkgid)
426 {
427         static const char *dml;
428         int ret;
429         sqlite3_stmt *stmt;
430
431         dml = "DELETE FROM provider WHERE pkgid = ?";
432         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
433         if (ret != SQLITE_OK) {
434                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
435                 return -EIO;
436         }
437
438         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
439         if (ret != SQLITE_OK) {
440                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
441                 ret = -EIO;
442                 goto out;
443         }
444
445         ret = 0;
446         if (sqlite3_step(stmt) != SQLITE_DONE) {
447                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
448                 ret = -EIO;
449         }
450
451 out:
452         sqlite3_reset(stmt);
453         sqlite3_clear_bindings(stmt);
454         sqlite3_finalize(stmt);
455         return ret;
456 }
457 static inline int db_insert_provider(struct livebox *livebox)
458 {
459         static const char *dml;
460         int ret;
461         sqlite3_stmt *stmt;
462         char *abi = (char *)livebox->abi;
463         char *box_src = (char *)livebox->lb_src;
464         char *box_group = (char *)livebox->lb_group;
465         char *pd_src = (char *)livebox->pd_src;
466         char *pd_group = (char *)livebox->pd_group;
467         char *libexec = (char *)livebox->libexec;
468         char *timeout = (char *)livebox->timeout;
469         char *period = (char *)livebox->period;
470         char *script = (char *)livebox->script;
471
472         if (!abi)
473                 abi = "c";
474
475         if (!box_src)
476                 box_src = "";
477
478         if (!box_group)
479                 box_group = "";
480
481         if (!pd_src)
482                 pd_src = "";
483
484         if (!pd_group)
485                 pd_group = "";
486
487         if (!libexec)
488                 libexec = "";
489
490         if (!timeout)
491                 timeout = "10";
492
493         if (!period)
494                 period = "0.0";
495
496         if (!script)
497                 script = "edje";
498
499         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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
500         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
501         if (ret != SQLITE_OK) {
502                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
503                 return -EIO;
504         }
505
506         ret = sqlite3_bind_text(stmt, 1, (char *)livebox->pkgid, -1, SQLITE_TRANSIENT);
507         if (ret != SQLITE_OK) {
508                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
509                 ret = -EIO;
510                 goto out;
511         }
512
513
514         ret = sqlite3_bind_int(stmt, 2, livebox->network);
515         if (ret != SQLITE_OK) {
516                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
517                 ret = -EIO;
518                 goto out;
519         }
520
521         ret = sqlite3_bind_text(stmt, 3, abi, -1, SQLITE_TRANSIENT);
522         if (ret != SQLITE_OK) {
523                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
524                 ret = -EIO;
525                 goto out;
526         }
527         ret = sqlite3_bind_int(stmt, 4, livebox->secured);
528         if (ret != SQLITE_OK) {
529                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
530                 ret = -EIO;
531                 goto out;
532         }
533
534         ret = sqlite3_bind_int(stmt, 5, livebox->lb_type);
535         if (ret != SQLITE_OK) {
536                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
537                 ret = -EIO;
538                 goto out;
539         }
540
541         ret = sqlite3_bind_text(stmt, 6, box_src, -1, SQLITE_TRANSIENT);
542         if (ret != SQLITE_OK) {
543                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
544                 ret = -EIO;
545                 goto out;
546         }
547
548         ret = sqlite3_bind_text(stmt, 7, box_group, -1, SQLITE_TRANSIENT);
549         if (ret != SQLITE_OK) {
550                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
551                 ret = -EIO;
552                 goto out;
553         }
554
555         ret = sqlite3_bind_int(stmt, 8, livebox->pd_type);
556         if (ret != SQLITE_OK) {
557                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
558                 ret = -EIO;
559                 goto out;
560         }
561
562         ret = sqlite3_bind_text(stmt, 9, pd_src, -1, SQLITE_TRANSIENT);
563         if (ret != SQLITE_OK) {
564                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
565                 ret = -EIO;
566                 goto out;
567         }
568
569         ret = sqlite3_bind_text(stmt, 10, pd_group, -1, SQLITE_TRANSIENT);
570         if (ret != SQLITE_OK) {
571                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
572                 ret = -EIO;
573                 goto out;
574         }
575
576         ret = sqlite3_bind_text(stmt, 11, libexec, -1, SQLITE_TRANSIENT);
577         if (ret != SQLITE_OK) {
578                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
579                 ret = -EIO;
580                 goto out;
581         }
582
583         ret = sqlite3_bind_int(stmt, 12, atoi(timeout));
584         if (ret != SQLITE_OK) {
585                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
586                 ret = -EIO;
587                 goto out;
588         }
589
590         ret = sqlite3_bind_text(stmt, 13, period, -1, SQLITE_TRANSIENT);
591         if (ret != SQLITE_OK) {
592                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
593                 ret = -EIO;
594                 goto out;
595         }
596
597         ret = sqlite3_bind_text(stmt, 14, script, -1, SQLITE_TRANSIENT);
598         if (ret != SQLITE_OK) {
599                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
600                 ret = -EIO;
601                 goto out;
602         }
603
604         ret = sqlite3_bind_int(stmt, 15, livebox->pinup);
605         if (ret != SQLITE_OK) {
606                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
607                 ret = -EIO;
608                 goto out;
609         }
610
611         ret = 0;
612         if (sqlite3_step(stmt) != SQLITE_DONE) {
613                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
614                 ret = -EIO;
615         }
616
617 out:
618         sqlite3_reset(stmt);
619         sqlite3_clear_bindings(stmt);
620         sqlite3_finalize(stmt);
621         return ret;
622 }
623
624 static inline int db_create_client(void)
625 {
626         char *err;
627         static const char *ddl;
628
629         ddl = "CREATE TABLE client (" \
630                 "pkgid TEXT PRIMARY KEY NOT NULL, icon TEXT, name TEXT, " \
631                 "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)";
632         if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
633                 ErrPrint("Failed to execute the DDL (%s)\n", err);
634                 return -EIO;
635         }
636
637         if (sqlite3_changes(s_info.handle) == 0)
638                 ErrPrint("No changes to DB\n");
639
640         return 0;
641 }
642
643 static inline int db_insert_client(struct livebox *livebox)
644 {
645         static const char *dml;
646         int ret;
647         sqlite3_stmt *stmt;
648
649         dml = "INSERT INTO client ( pkgid, icon, name, auto_launch, pd_size, content, nodisplay, setup, mouse_event ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
650         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
651         if (ret != SQLITE_OK) {
652                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
653                 return -EIO;
654         }
655
656         ret = sqlite3_bind_text(stmt, 1, (char *)livebox->pkgid, -1, SQLITE_TRANSIENT);
657         if (ret != SQLITE_OK) {
658                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
659                 ret = -EIO;
660                 goto out;
661         }
662
663         ret = sqlite3_bind_text(stmt, 2, (char *)livebox->icon, -1, SQLITE_TRANSIENT);
664         if (ret != SQLITE_OK) {
665                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
666                 ret = -EIO;
667                 goto out;
668         }
669
670         ret = sqlite3_bind_text(stmt, 3, (char *)livebox->name, -1, SQLITE_TRANSIENT);
671         if (ret != SQLITE_OK) {
672                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
673                 ret = -EIO;
674                 goto out;
675         }
676
677         ret = sqlite3_bind_text(stmt, 4, (char *)livebox->auto_launch, -1, SQLITE_TRANSIENT);
678         if (ret != SQLITE_OK) {
679                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
680                 ret = -EIO;
681                 goto out;
682         }
683
684         ret = sqlite3_bind_text(stmt, 5, (char *)livebox->pd_size, -1, SQLITE_TRANSIENT);
685         if (ret != SQLITE_OK) {
686                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
687                 ret = -EIO;
688                 goto out;
689         }
690
691         ret = sqlite3_bind_text(stmt, 6, livebox->content ? (char *)livebox->content : "default", -1, SQLITE_TRANSIENT);
692         if (ret != SQLITE_OK) {
693                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
694                 ret = -EIO;
695                 goto out;
696         }
697
698         ret = sqlite3_bind_int(stmt, 7, livebox->nodisplay);
699         if (ret != SQLITE_OK) {
700                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
701                 ret = -EIO;
702                 goto out;
703         }
704
705         ret = sqlite3_bind_text(stmt, 8, livebox->setup ? (char *)livebox->setup : "", -1, SQLITE_TRANSIENT);
706         if (ret != SQLITE_OK) {
707                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
708                 ret = -EIO;
709                 goto out;
710         }
711
712         ret = sqlite3_bind_int(stmt, 9, livebox->mouse_event);
713         if (ret != SQLITE_OK) {
714                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
715                 ret = -EIO;
716                 goto out;
717         }
718
719         ret = 0;
720         if (sqlite3_step(stmt) != SQLITE_DONE) {
721                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
722                 ret = -EIO;
723         }
724
725 out:
726         sqlite3_reset(stmt);
727         sqlite3_clear_bindings(stmt);
728         sqlite3_finalize(stmt);
729         return ret;
730 }
731
732 static inline int db_remove_client(const char *pkgid)
733 {
734         static const char *dml;
735         int ret;
736         sqlite3_stmt *stmt;
737
738         dml = "DELETE FROM client WHERE pkgid = ?";
739         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
740         if (ret != SQLITE_OK) {
741                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
742                 return -EIO;
743         }
744
745         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
746         if (ret != SQLITE_OK) {
747                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
748                 ret = -EIO;
749                 goto out;
750         }
751
752         ret = 0;
753         if (sqlite3_step(stmt) != SQLITE_DONE) {
754                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
755                 ret = -EIO;
756         }
757
758 out:
759         sqlite3_reset(stmt);
760         sqlite3_clear_bindings(stmt);
761         sqlite3_finalize(stmt);
762         return ret;
763 }
764
765 static inline int db_create_i18n(void)
766 {
767         char *err;
768         static const char *ddl;
769
770         ddl = "CREATE TABLE i18n ( pkgid TEXT NOT NULL, lang TEXT COLLATE NOCASE, name TEXT, " \
771                 "icon TEXT, FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
772         if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
773                 ErrPrint("Failed to execute the DDL (%s)\n", err);
774                 return -EIO;
775         }
776
777         if (sqlite3_changes(s_info.handle) == 0)
778                 ErrPrint("No changes to DB\n");
779
780         return 0;
781 }
782
783 static inline int db_insert_i18n(const char *pkgid, const char *lang, const char *name, const char *icon)
784 {
785         static const char *dml;
786         int ret;
787         sqlite3_stmt *stmt;
788
789         DbgPrint("%s - lang[%s] name[%s] icon[%s]\n", pkgid, lang, name, icon);
790         dml = "INSERT INTO i18n ( pkgid, lang, name, icon ) VALUES (?, ?, ?, ?)";
791         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
792         if (ret != SQLITE_OK) {
793                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
794                 return -EIO;
795         }
796
797         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
798         if (ret != SQLITE_OK) {
799                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
800                 ret = -EIO;
801                 goto out;
802         }
803
804         ret = sqlite3_bind_text(stmt, 2, lang, -1, SQLITE_TRANSIENT);
805         if (ret != SQLITE_OK) {
806                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
807                 ret = -EIO;
808                 goto out;
809         }
810
811         ret = sqlite3_bind_text(stmt, 3, name, -1, SQLITE_TRANSIENT);
812         if (ret != SQLITE_OK) {
813                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
814                 ret = -EIO;
815                 goto out;
816         }
817
818         ret = sqlite3_bind_text(stmt, 4, icon, -1, SQLITE_TRANSIENT);
819         if (ret != SQLITE_OK) {
820                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
821                 ret = -EIO;
822                 goto out;
823         }
824
825         ret = 0;
826         if (sqlite3_step(stmt) != SQLITE_DONE) {
827                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
828                 ret = -EIO;
829         }
830
831 out:
832         sqlite3_reset(stmt);
833         sqlite3_clear_bindings(stmt);
834         sqlite3_finalize(stmt);
835         return ret;
836 }
837
838 static inline int db_remove_i18n(const char *pkgid)
839 {
840         static const char *dml;
841         int ret;
842         sqlite3_stmt *stmt;
843
844         dml = "DELETE FROM i18n WHERE pkgid = ?";
845         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
846         if (ret != SQLITE_OK) {
847                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
848                 return -EIO;
849         }
850
851         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
852         if (ret != SQLITE_OK) {
853                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
854                 ret = -EIO;
855                 goto out;
856         }
857
858         ret = 0;
859         if (sqlite3_step(stmt) != SQLITE_DONE) {
860                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
861                 ret = -EIO;
862         }
863
864         if (sqlite3_changes(s_info.handle) == 0)
865                 DbgPrint("No changes\n");
866
867 out:
868         sqlite3_reset(stmt);
869         sqlite3_clear_bindings(stmt);
870         sqlite3_finalize(stmt);
871         return ret;
872 }
873
874 static inline int db_create_group(void)
875 {
876         char *err;
877         static const char *ddl;
878
879         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)";
880         if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
881                 ErrPrint("Failed to execute the DDL (%s)\n", err);
882                 return -EIO;
883         }
884
885         if (sqlite3_changes(s_info.handle) == 0)
886                 ErrPrint("No changes to DB\n");
887
888         return 0;
889 }
890
891 static inline int db_insert_group(const char *pkgid, const char *cluster, const char *category)
892 {
893         static const char *dml;
894         int ret;
895         sqlite3_stmt *stmt;
896
897         dml = "INSERT INTO groupinfo ( cluster, category, pkgid ) VALUES (?, ?, ?)";
898         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
899         if (ret != SQLITE_OK) {
900                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
901                 return -EIO;
902         }
903
904         ret = sqlite3_bind_text(stmt, 1, cluster, -1, SQLITE_TRANSIENT);
905         if (ret != SQLITE_OK) {
906                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
907                 ret = -EIO;
908                 goto out;
909         }
910
911         ret = sqlite3_bind_text(stmt, 2, category, -1, SQLITE_TRANSIENT);
912         if (ret != SQLITE_OK) {
913                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
914                 ret = -EIO;
915                 goto out;
916         }
917
918         ret = sqlite3_bind_text(stmt, 3, pkgid, -1, SQLITE_TRANSIENT);
919         if (ret != SQLITE_OK) {
920                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
921                 ret = -EIO;
922                 goto out;
923         }
924
925         ret = 0;
926         if (sqlite3_step(stmt) != SQLITE_DONE) {
927                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
928                 ret = -EIO;
929         }
930
931 out:
932         sqlite3_reset(stmt);
933         sqlite3_clear_bindings(stmt);
934         sqlite3_finalize(stmt);
935         return ret;
936 }
937
938 static inline int db_get_group_id(const char *cluster, const char *category)
939 {
940         static const char *dml = "SELECT id FROM groupinfo WHERE cluster = ? AND category = ?";
941         sqlite3_stmt *stmt;
942         int ret;
943
944         if (!cluster || !category) {
945                 ErrPrint("Invalid argument\n");
946                 return -EINVAL;
947         }
948
949         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
950         if (ret != SQLITE_OK) {
951                 ErrPrint("Failed to prepare the initial DML(%s)\n", sqlite3_errmsg(s_info.handle));
952                 return -EIO;
953         }
954
955         ret = -EIO;
956         if (sqlite3_bind_text(stmt, 1, cluster, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
957                 ErrPrint("Failed to bind a cluster(%s) - %s\n", cluster, sqlite3_errmsg(s_info.handle));
958                 goto out;
959         }
960
961         if (sqlite3_bind_text(stmt, 2, category, -1, SQLITE_TRANSIENT) != SQLITE_OK) {
962                 ErrPrint("Failed to bind a category(%s) - %s\n", category, sqlite3_errmsg(s_info.handle));
963                 goto out;
964         }
965
966         if (sqlite3_step(stmt) != SQLITE_ROW) {
967                 ErrPrint("Failed to execute the DML for %s - %s\n", cluster, category);
968                 goto out;
969         }
970
971         ret = sqlite3_column_int(stmt, 0);
972
973 out:
974         sqlite3_reset(stmt);
975         sqlite3_clear_bindings(stmt);
976         sqlite3_finalize(stmt);
977         return ret;
978 }
979
980 static inline int db_remove_group(const char *pkgid)
981 {
982         static const char *dml;
983         int ret;
984         sqlite3_stmt *stmt;
985
986         dml = "DELETE FROM groupinfo WHERE pkgid = ?";
987         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
988         if (ret != SQLITE_OK) {
989                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
990                 return -EIO;
991         }
992
993         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
994         if (ret != SQLITE_OK) {
995                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
996                 ret = -EIO;
997                 goto out;
998         }
999
1000         ret = 0;
1001         if (sqlite3_step(stmt) != SQLITE_DONE) {
1002                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1003                 ret = -EIO;
1004         }
1005
1006         if (sqlite3_changes(s_info.handle) == 0)
1007                 DbgPrint("No changes\n");
1008
1009 out:
1010         sqlite3_reset(stmt);
1011         sqlite3_clear_bindings(stmt);
1012         sqlite3_finalize(stmt);
1013         return ret;
1014 }
1015
1016 static inline int db_create_groupmap(void)
1017 {
1018         char *err;
1019         static const char *ddl;
1020
1021         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)";
1022         if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1023                 ErrPrint("Failed to execute the DDL (%s)\n", err);
1024                 return -EIO;
1025         }
1026
1027         if (sqlite3_changes(s_info.handle) == 0)
1028                 ErrPrint("No changes to DB\n");
1029
1030         return 0;
1031 }
1032
1033 static inline int db_get_option_id(int id, const char *pkgid, const char *ctx_item)
1034 {
1035         static const char *dml;
1036         int ret;
1037         sqlite3_stmt *stmt;
1038
1039         dml = "SELECT option_id FROM groupmap WHERE id = ? AND pkgid = ? AND ctx_item = ?";
1040         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1041         if (ret != SQLITE_OK) {
1042                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1043                 return -EIO;
1044         }
1045
1046         ret = sqlite3_bind_int(stmt, 1, id);
1047         if (ret != SQLITE_OK) {
1048                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1049                 ret = -EIO;
1050                 goto out;
1051         }
1052
1053         ret = sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
1054         if (ret != SQLITE_OK) {
1055                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1056                 ret = -EIO;
1057                 goto out;
1058         }
1059
1060         ret = sqlite3_bind_text(stmt, 3, ctx_item, -1, SQLITE_TRANSIENT);
1061         if (ret != SQLITE_OK) {
1062                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1063                 ret = -EIO;
1064                 goto out;
1065         }
1066
1067         ret = 0;
1068         if (sqlite3_step(stmt) != SQLITE_ROW) {
1069                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1070                 ret = -EIO;
1071                 goto out;
1072         }
1073
1074         ret = sqlite3_column_int(stmt, 0);
1075
1076 out:
1077         sqlite3_reset(stmt);
1078         sqlite3_clear_bindings(stmt);
1079         sqlite3_finalize(stmt);
1080         return ret;
1081 }
1082
1083 static inline int db_insert_groupmap(int id, const char *pkgid, const char *ctx_item)
1084 {
1085         static const char *dml;
1086         int ret;
1087         sqlite3_stmt *stmt;
1088
1089         DbgPrint("%d (%s) add to groupmap\n", id, pkgid);
1090
1091         dml = "INSERT INTO groupmap ( id, pkgid, ctx_item ) VALUES (?, ?, ?)";
1092         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1093         if (ret != SQLITE_OK) {
1094                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1095                 return -EIO;
1096         }
1097
1098         ret = sqlite3_bind_int(stmt, 1, id);
1099         if (ret != SQLITE_OK) {
1100                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1101                 ret = -EIO;
1102                 goto out;
1103         }
1104
1105         ret = sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_TRANSIENT);
1106         if (ret != SQLITE_OK) {
1107                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1108                 ret = -EIO;
1109                 goto out;
1110         }
1111
1112         ret = sqlite3_bind_text(stmt, 3, ctx_item, -1, SQLITE_TRANSIENT);
1113         if (ret != SQLITE_OK) {
1114                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1115                 ret = -EIO;
1116                 goto out;
1117         }
1118
1119         ret = 0;
1120         if (sqlite3_step(stmt) != SQLITE_DONE) {
1121                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1122                 ret = -EIO;
1123         }
1124
1125 out:
1126         sqlite3_reset(stmt);
1127         sqlite3_clear_bindings(stmt);
1128         sqlite3_finalize(stmt);
1129         return ret;
1130 }
1131
1132 static inline int db_remove_groupmap(const char *pkgid)
1133 {
1134         static const char *dml;
1135         int ret;
1136         sqlite3_stmt *stmt;
1137
1138         dml = "DELETE FROM groupmap WHERE pkgid = ?";
1139         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1140         if (ret != SQLITE_OK) {
1141                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1142                 return -EIO;
1143         }
1144
1145         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1146         if (ret != SQLITE_OK) {
1147                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1148                 ret = -EIO;
1149                 goto out;
1150         }
1151
1152         ret = 0;
1153         if (sqlite3_step(stmt) != SQLITE_DONE) {
1154                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1155                 ret = -EIO;
1156         }
1157
1158         if (sqlite3_changes(s_info.handle) == 0)
1159                 DbgPrint("No changes\n");
1160
1161 out:
1162         sqlite3_reset(stmt);
1163         sqlite3_clear_bindings(stmt);
1164         sqlite3_finalize(stmt);
1165         return ret;
1166 }
1167
1168 static inline int db_create_option(void)
1169 {
1170         char *err;
1171         static const char *ddl;
1172
1173         ddl = "CREATE TABLE option ( pkgid TEXT NOT NULL, option_id INTEGER, key TEXT NOT NULL, value TEXT NOT NULL, " \
1174                 "FOREIGN KEY(option_id) REFERENCES groupmap(option_id), " \
1175                 "FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
1176         if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1177                 ErrPrint("Failed to execute the DDL (%s)\n", err);
1178                 return -EIO;
1179         }
1180
1181         if (sqlite3_changes(s_info.handle) == 0)
1182                 ErrPrint("No changes to DB\n");
1183
1184         return 0;
1185 }
1186
1187 static inline int db_insert_option(const char *pkgid, int option_id, const char *key, const char *value)
1188 {
1189         static const char *dml;
1190         int ret;
1191         sqlite3_stmt *stmt;
1192
1193         dml = "INSERT INTO option (pkgid, option_id, key, value) VALUES (?, ?, ?, ?)";
1194         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1195         if (ret != SQLITE_OK) {
1196                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1197                 return -EIO;
1198         }
1199
1200         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1201         if (ret != SQLITE_OK) {
1202                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1203                 ret = -EIO;
1204                 goto out;
1205         }
1206
1207         ret = sqlite3_bind_int(stmt, 2, option_id);
1208         if (ret != SQLITE_OK) {
1209                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1210                 ret = -EIO;
1211                 goto out;
1212         }
1213
1214         ret = sqlite3_bind_text(stmt, 3, key, -1, SQLITE_TRANSIENT);
1215         if (ret != SQLITE_OK) {
1216                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1217                 ret = -EIO;
1218                 goto out;
1219         }
1220
1221         ret = sqlite3_bind_text(stmt, 4, value, -1, SQLITE_TRANSIENT);
1222         if (ret != SQLITE_OK) {
1223                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1224                 ret = -EIO;
1225                 goto out;
1226         }
1227
1228         ret = 0;
1229         if (sqlite3_step(stmt) != SQLITE_DONE) {
1230                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1231                 ret = -EIO;
1232         }
1233 out:
1234         sqlite3_reset(stmt);
1235         sqlite3_clear_bindings(stmt);
1236         sqlite3_finalize(stmt);
1237         return ret;
1238 }
1239
1240 static inline int db_remove_option(const char *pkgid)
1241 {
1242         static const char *dml;
1243         int ret;
1244         sqlite3_stmt *stmt;
1245
1246         dml = "DELETE FROM option WHERE pkgid = ?";
1247         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1248         if (ret != SQLITE_OK) {
1249                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1250                 return -EIO;
1251         }
1252
1253         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1254         if (ret != SQLITE_OK) {
1255                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1256                 ret = -EIO;
1257                 goto out;
1258         }
1259
1260         ret = 0;
1261         if (sqlite3_step(stmt) != SQLITE_DONE) {
1262                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1263                 ret = -EIO;
1264         }
1265
1266         if (sqlite3_changes(s_info.handle) == 0)
1267                 DbgPrint("No changes\n");
1268
1269 out:
1270         sqlite3_reset(stmt);
1271         sqlite3_clear_bindings(stmt);
1272         sqlite3_finalize(stmt);
1273         return ret;
1274 }
1275
1276 static inline int db_create_box_size(void)
1277 {
1278         char *err;
1279         static const char *ddl;
1280
1281         ddl = "CREATE TABLE box_size ( pkgid TEXT NOT NULL, size_type INTEGER, preview TEXT, touch_effect INTEGER, need_frame INTEGER, " \
1282                 "FOREIGN KEY(pkgid) REFERENCES pkgmap(pkgid) ON DELETE CASCADE)";
1283         if (sqlite3_exec(s_info.handle, ddl, NULL, NULL, &err) != SQLITE_OK) {
1284                 ErrPrint("Failed to execute the DDL (%s)\n", err);
1285                 return -EIO;
1286         }
1287
1288         if (sqlite3_changes(s_info.handle) == 0)
1289                 ErrPrint("No changes to DB\n");
1290
1291         return 0;
1292 }
1293
1294 static inline int db_insert_box_size(const char *pkgid, int size_type, const char *preview, int touch_effect, int need_frame)
1295 {
1296         static const char *dml;
1297         int ret;
1298         sqlite3_stmt *stmt;
1299
1300         DbgPrint("box size: %s - %d (%s) is added\n", pkgid, size_type, preview);
1301         dml = "INSERT INTO box_size ( pkgid, size_type, preview, touch_effect, need_frame ) VALUES (?, ?, ?, ?, ?)";
1302         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1303         if (ret != SQLITE_OK) {
1304                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1305                 return -EIO;
1306         }
1307
1308         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1309         if (ret != SQLITE_OK) {
1310                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1311                 ret = -EIO;
1312                 goto out;
1313         }
1314
1315         ret = sqlite3_bind_int(stmt, 2, size_type);
1316         if (ret != SQLITE_OK) {
1317                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1318                 ret = -EIO;
1319                 goto out;
1320         }
1321
1322         ret = sqlite3_bind_text(stmt, 3, preview ? preview : "", -1, SQLITE_TRANSIENT);
1323         if (ret != SQLITE_OK) {
1324                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1325                 ret = -EIO;
1326                 goto out;
1327         }
1328
1329         ret = sqlite3_bind_int(stmt, 4, touch_effect);
1330         if (ret != SQLITE_OK) {
1331                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1332                 ret = -EIO;
1333                 goto out;
1334         }
1335
1336         ret =  sqlite3_bind_int(stmt, 5, need_frame);
1337         if (ret != SQLITE_OK) {
1338                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1339                 ret = -EIO;
1340                 goto out;
1341         }
1342
1343         ret = 0;
1344         if (sqlite3_step(stmt) != SQLITE_DONE) {
1345                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1346                 ret = -EIO;
1347         }
1348
1349 out:
1350         sqlite3_reset(stmt);
1351         sqlite3_clear_bindings(stmt);
1352         sqlite3_finalize(stmt);
1353         return ret;
1354 }
1355
1356 static inline int db_remove_box_size(const char *pkgid)
1357 {
1358         static const char *dml;
1359         int ret;
1360         sqlite3_stmt *stmt;
1361
1362         dml = "DELETE FROM box_size WHERE pkgid = ?";
1363         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
1364         if (ret != SQLITE_OK) {
1365                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1366                 return -EIO;
1367         }
1368
1369         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
1370         if (ret != SQLITE_OK) {
1371                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1372                 ret = -EIO;
1373                 goto out;
1374         }
1375
1376         ret = 0;
1377         if (sqlite3_step(stmt) != SQLITE_DONE) {
1378                 DbgPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
1379                 ret = -EIO;
1380         }
1381
1382         if (sqlite3_changes(s_info.handle) == 0)
1383                 DbgPrint("No changes\n");
1384
1385 out:
1386         sqlite3_reset(stmt);
1387         sqlite3_clear_bindings(stmt);
1388         sqlite3_finalize(stmt);
1389         return ret;
1390 }
1391
1392 static inline void db_create_table(void)
1393 {
1394         int ret;
1395         begin_transaction();
1396
1397         ret = db_create_pkgmap();
1398         if (ret < 0) {
1399                 rollback_transaction();
1400                 return;
1401         }
1402
1403         ret = db_create_provider();
1404         if (ret < 0) {
1405                 rollback_transaction();
1406                 return;
1407         }
1408
1409         ret = db_create_client();
1410         if (ret < 0) {
1411                 rollback_transaction();
1412                 return;
1413         }
1414
1415         ret = db_create_i18n();
1416         if (ret < 0) {
1417                 rollback_transaction();
1418                 return;
1419         }
1420
1421         ret = db_create_box_size();
1422         if (ret < 0) {
1423                 rollback_transaction();
1424                 return;
1425         }
1426
1427         ret = db_create_group();
1428         if (ret < 0) {
1429                 rollback_transaction();
1430                 return;
1431         }
1432
1433         ret = db_create_option();
1434         if (ret < 0) {
1435                 rollback_transaction();
1436                 return;
1437         }
1438
1439         ret = db_create_groupmap();
1440         if (ret < 0) {
1441                 rollback_transaction();
1442                 return;
1443         }
1444
1445         commit_transaction();
1446 }
1447
1448 static inline int db_init(void)
1449 {
1450         int ret;
1451         struct stat stat;
1452
1453         ret = db_util_open(s_info.dbfile, &s_info.handle, DB_UTIL_REGISTER_HOOK_METHOD);
1454         if (ret != SQLITE_OK) {
1455                 ErrPrint("Failed to open a DB\n");
1456                 return -EIO;
1457         }
1458
1459         if (lstat(s_info.dbfile, &stat) < 0) {
1460                 ErrPrint("%s\n", strerror(errno));
1461                 db_util_close(s_info.handle);
1462                 s_info.handle = NULL;
1463                 return -EIO;
1464         }
1465
1466         if (!S_ISREG(stat.st_mode)) {
1467                 ErrPrint("Invalid file\n");
1468                 db_util_close(s_info.handle);
1469                 s_info.handle = NULL;
1470                 return -EINVAL;
1471         }
1472
1473         if (!stat.st_size)
1474                 db_create_table();
1475
1476         return 0;
1477 }
1478
1479 static inline int db_fini(void)
1480 {
1481         if (!s_info.handle)
1482                 return 0;
1483
1484         db_util_close(s_info.handle);
1485         s_info.handle = NULL;
1486
1487         return 0;
1488 }
1489
1490 static inline int validate_pkgid(const char *appid, const char *pkgid)
1491 {
1492         /* Just return 1 Always */
1493         return 1 || !strncmp(appid, pkgid, strlen(appid));
1494 }
1495
1496 static inline int livebox_destroy(struct livebox *livebox)
1497 {
1498         struct dlist *l;
1499         struct dlist *n;
1500         struct i18n *i18n;
1501         struct group *group;
1502         struct option *option;
1503         struct dlist *il;
1504         struct dlist *in;
1505
1506         xmlFree(livebox->auto_launch);
1507         xmlFree(livebox->pkgid);
1508         xmlFree(livebox->abi);
1509         xmlFree(livebox->name);
1510         xmlFree(livebox->icon);
1511         xmlFree(livebox->lb_src);
1512         xmlFree(livebox->lb_group);
1513         xmlFree(livebox->pd_src);
1514         xmlFree(livebox->pd_group);
1515         xmlFree(livebox->pd_size);
1516         xmlFree(livebox->libexec);
1517         xmlFree(livebox->script);
1518         xmlFree(livebox->period);
1519         xmlFree(livebox->content);
1520         xmlFree(livebox->setup);
1521         xmlFree(livebox->preview[0]); /* 1x1 */
1522         xmlFree(livebox->preview[1]); /* 2x1 */
1523         xmlFree(livebox->preview[2]); /* 2x2 */
1524         xmlFree(livebox->preview[3]); /* 4x1 */
1525         xmlFree(livebox->preview[4]); /* 4x2 */
1526         xmlFree(livebox->preview[5]); /* 4x3 */
1527         xmlFree(livebox->preview[6]); /* 4x4 */
1528         xmlFree(livebox->preview[7]); /* 4x5 */
1529         xmlFree(livebox->preview[8]); /* 4x6 */
1530         xmlFree(livebox->preview[9]); /* easy 1x1 */
1531         xmlFree(livebox->preview[10]); /* easy 3x1 */
1532         xmlFree(livebox->preview[11]); /* easy 3x3 */
1533         xmlFree(livebox->preview[12]); /* full */
1534
1535         dlist_foreach_safe(livebox->i18n_list, l, n, i18n) {
1536                 livebox->i18n_list = dlist_remove(livebox->i18n_list, l);
1537                 xmlFree(i18n->name);
1538                 xmlFree(i18n->icon);
1539                 xmlFree(i18n->lang);
1540                 free(i18n);
1541         }
1542
1543         dlist_foreach_safe(livebox->group_list, l, n, group) {
1544                 livebox->group_list = dlist_remove(livebox->group_list, l);
1545                 DbgPrint("Release %s/%s\n", group->cluster, group->category);
1546
1547                 if (group->ctx_item) {
1548                         dlist_foreach_safe(group->option_list, il, in, option) {
1549                                 group->option_list = dlist_remove(group->option_list, il);
1550                                 DbgPrint("Release option %s(%s)\n", option->key, option->value);
1551                                 xmlFree(option->key);
1552                                 xmlFree(option->value);
1553                                 free(option);
1554                         }
1555                         xmlFree(group->ctx_item);
1556                 }
1557
1558                 xmlFree(group->cluster);
1559                 xmlFree(group->category);
1560                 free(group);
1561         }
1562
1563         free(livebox);
1564         return 0;
1565 }
1566
1567 static inline void update_i18n_name(struct livebox *livebox, xmlNodePtr node)
1568 {
1569         struct i18n *i18n;
1570         struct dlist *l;
1571         xmlChar *lang;
1572         xmlChar *name;
1573
1574         name = xmlNodeGetContent(node);
1575         if (!name) {
1576                 ErrPrint("Invalid tag\n");
1577                 return;
1578         }
1579
1580         lang = xmlNodeGetLang(node);
1581         if (!lang) {
1582                 if (livebox->name) {
1583                         DbgPrint("Override default name: %s\n", livebox->name);
1584                         xmlFree(livebox->name);
1585                 }
1586
1587                 livebox->name = name;
1588                 return;
1589         }
1590
1591         dlist_foreach(livebox->i18n_list, l, i18n) {
1592                 if (!xmlStrcasecmp(i18n->lang, lang)) {
1593                         if (i18n->name) {
1594                                 DbgPrint("Override name: %s\n", i18n->name);
1595                                 xmlFree(i18n->name);
1596                         }
1597
1598                         i18n->name = name;
1599                         return;
1600                 }
1601         }
1602
1603         i18n = calloc(1, sizeof(*i18n));
1604         if (!i18n) {
1605                 ErrPrint("Heap: %s\n", strerror(errno));
1606                 xmlFree(name);
1607                 xmlFree(lang);
1608                 return;
1609         }
1610
1611         i18n->name = name;
1612         i18n->lang = lang;
1613         DbgPrint("Label[%s] - [%s] added\n", i18n->lang, i18n->name);
1614         livebox->i18n_list = dlist_append(livebox->i18n_list, i18n);
1615 }
1616
1617 static inline void update_i18n_icon(struct livebox *livebox, xmlNodePtr node)
1618 {
1619         struct i18n *i18n;
1620         struct dlist *l;
1621         xmlChar *lang;
1622         xmlChar *icon;
1623
1624         icon = xmlNodeGetContent(node);
1625         if (!icon) {
1626                 ErrPrint("Invalid tag\n");
1627                 return;
1628         }
1629
1630         lang = xmlNodeGetLang(node);
1631         if (!lang) {
1632                 if (livebox->icon) {
1633                         DbgPrint("Override default icon: %s\n", livebox->icon);
1634                         xmlFree(livebox->icon);
1635                 }
1636
1637                 livebox->icon = icon;
1638                 return;
1639         }
1640
1641         dlist_foreach(livebox->i18n_list, l, i18n) {
1642                 if (!xmlStrcasecmp(i18n->lang, lang)) {
1643                         if (i18n->icon) {
1644                                 DbgPrint("Override icon %s for %s\n", i18n->icon, i18n->name);
1645                                 xmlFree(i18n->icon);
1646                         }
1647
1648                         i18n->icon = icon;
1649                         return;
1650                 }
1651         }
1652
1653         i18n = calloc(1, sizeof(*i18n));
1654         if (!i18n) {
1655                 ErrPrint("Heap: %s\n", strerror(errno));
1656                 xmlFree(icon);
1657                 xmlFree(lang);
1658                 return;
1659         }
1660
1661         i18n->icon = icon;
1662         i18n->lang = lang;
1663         DbgPrint("Icon[%s] - [%s] added\n", i18n->lang, i18n->icon);
1664         livebox->i18n_list = dlist_append(livebox->i18n_list, i18n);
1665 }
1666
1667 static inline void update_launch(struct livebox *livebox, xmlNodePtr node)
1668 {
1669         xmlChar *launch;
1670         launch = xmlNodeGetContent(node);
1671         if (!launch) {
1672                 DbgPrint("Has no launch\n");
1673                 return;
1674         }
1675
1676         livebox->auto_launch = xmlStrdup(launch);
1677         if (!livebox->auto_launch) {
1678                 ErrPrint("Failed to duplicate string: %s\n", (char *)launch);
1679                 return;
1680         }
1681 }
1682
1683 static inline void update_ui_appid(struct livebox *livebox, xmlNodePtr node)
1684 {
1685         xmlChar *uiapp;
1686         uiapp = xmlNodeGetContent(node);
1687         if (!uiapp) {
1688                 DbgPrint("Has no valid ui-appid\n");
1689                 return;
1690         }
1691
1692         livebox->uiapp = xmlStrdup(uiapp);
1693         if (!livebox->uiapp) {
1694                 ErrPrint("Failed to duplicate string: %s\n", (char *)uiapp);
1695                 return;
1696         }
1697 }
1698
1699 static inline void update_setup(struct livebox *livebox, xmlNodePtr node)
1700 {
1701         xmlChar *setup;
1702         setup = xmlNodeGetContent(node);
1703         if (!setup) {
1704                 DbgPrint("Has no setup\n");
1705                 return;
1706         }
1707
1708         livebox->setup = xmlStrdup(setup);
1709         if (!livebox->setup) {
1710                 ErrPrint("Failed to duplicate string: %s\n", (char *)setup);
1711                 return;
1712         }
1713 }
1714
1715 static inline void update_content(struct livebox *livebox, xmlNodePtr node)
1716 {
1717         xmlChar *content;
1718         content = xmlNodeGetContent(node);
1719         if (!content) {
1720                 DbgPrint("Has no content\n");
1721                 return;
1722         }
1723
1724         livebox->content = xmlStrdup(content);
1725         if (!livebox->content) {
1726                 ErrPrint("Failed to duplicate string: %s\n", (char *)content);
1727                 return;
1728         }
1729 }
1730
1731 static inline void update_size_info(struct livebox *livebox, int idx, xmlNodePtr node)
1732 {
1733         if (xmlHasProp(node, (const xmlChar *)"preview")) {
1734                 livebox->preview[idx] = xmlGetProp(node, (const xmlChar *)"preview");
1735         }
1736
1737         if (xmlHasProp(node, (const xmlChar *)"need_frame")) {
1738                 xmlChar *need_frame;
1739
1740                 need_frame = xmlGetProp(node, (const xmlChar *)"need_frame");
1741                 if (need_frame) {
1742                         livebox->need_frame[idx] = !xmlStrcasecmp(need_frame, (const xmlChar *)"true");
1743                         xmlFree(need_frame);
1744                 } else {
1745                         livebox->need_frame[idx] = livebox->default_need_frame;
1746                 }
1747         } else {
1748                 livebox->need_frame[idx] = livebox->default_need_frame;
1749         }
1750
1751         if (xmlHasProp(node, (const xmlChar *)"touch_effect")) {
1752                 xmlChar *touch_effect;
1753
1754                 touch_effect = xmlGetProp(node, (const xmlChar *)"touch_effect");
1755                 if (touch_effect) {
1756                         livebox->touch_effect[idx] = !xmlStrcasecmp(touch_effect, (const xmlChar *)"true");
1757                         xmlFree(touch_effect);
1758                 } else {
1759                         livebox->touch_effect[idx] = livebox->default_touch_effect;
1760                 }
1761         } else {
1762                 livebox->touch_effect[idx] = livebox->default_touch_effect;
1763         }
1764 }
1765
1766 static inline void update_box(struct livebox *livebox, xmlNodePtr node)
1767 {
1768         if (!xmlHasProp(node, (const xmlChar *)"type")) {
1769                 livebox->lb_type = LB_TYPE_FILE;
1770         } else {
1771                 xmlChar *type;
1772
1773                 type = xmlGetProp(node, (const xmlChar *)"type");
1774                 if (!type) {
1775                         ErrPrint("Type is NIL\n");
1776                         livebox->lb_type = LB_TYPE_FILE;
1777                 } else {
1778                         if (!xmlStrcasecmp(type, (const xmlChar *)"text"))
1779                                 livebox->lb_type = LB_TYPE_TEXT;
1780                         else if (!xmlStrcasecmp(type, (const xmlChar *)"buffer"))
1781                                 livebox->lb_type = LB_TYPE_BUFFER;
1782                         else if (!xmlStrcasecmp(type, (const xmlChar *)"script"))
1783                                 livebox->lb_type = LB_TYPE_SCRIPT;
1784                         else /* Default */
1785                                 livebox->lb_type = LB_TYPE_FILE;
1786
1787                         xmlFree(type);
1788                 }
1789         }
1790
1791         if (!xmlHasProp(node, (const xmlChar *)"mouse_event")) {
1792                 livebox->mouse_event = 0;
1793         } else {
1794                 xmlChar *mouse_event;
1795
1796                 mouse_event = xmlGetProp(node, (const xmlChar *)"mouse_event");
1797                 if (!mouse_event) {
1798                         ErrPrint("mouse_event is NIL\n");
1799                         livebox->mouse_event = 0;
1800                 } else {
1801                         livebox->mouse_event = !xmlStrcasecmp(mouse_event, (const xmlChar *)"true");
1802                         xmlFree(mouse_event);
1803                 }
1804         }
1805
1806         if (!xmlHasProp(node, (const xmlChar *)"touch_effect")) {
1807                 livebox->default_touch_effect = 1;
1808         } else {
1809                 xmlChar *touch_effect;
1810
1811                 touch_effect = xmlGetProp(node, (const xmlChar *)"touch_effect");
1812                 if (!touch_effect) {
1813                         ErrPrint("default touch_effect is NIL\n");
1814                         livebox->default_touch_effect = 1;
1815                 } else {
1816                         livebox->default_touch_effect = !xmlStrcasecmp(touch_effect, (const xmlChar *)"true");
1817                         xmlFree(touch_effect);
1818                 }
1819         }
1820
1821         if (!xmlHasProp(node, (const xmlChar *)"need_frame")) {
1822                 livebox->default_need_frame = 0;
1823         } else {
1824                 xmlChar *need_frame;
1825
1826                 need_frame = xmlGetProp(node, (const xmlChar *)"need_frame");
1827                 if (!need_frame) {
1828                         ErrPrint("default need_frame is NIL\n");
1829                         livebox->default_need_frame = 0;
1830                 } else {
1831                         livebox->default_need_frame = !xmlStrcasecmp(need_frame, (const xmlChar *)"true");
1832                         xmlFree(need_frame);
1833                 }
1834         }
1835
1836         for (node = node->children; node; node = node->next) {
1837                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"size")) {
1838                         xmlChar *size;
1839                         int is_easy = 0;
1840
1841                         size = xmlNodeGetContent(node);
1842                         if (!size) {
1843                                 ErrPrint("Invalid size tag\n");
1844                                 continue;
1845                         }
1846
1847                         if (xmlHasProp(node, (const xmlChar *)"mode")) {
1848                                 xmlChar *mode;
1849                                 mode = xmlGetProp(node, (const xmlChar *)"mode");
1850                                 if (mode) {
1851                                         DbgPrint("Easy mode: %s\n", mode);
1852                                         is_easy = !xmlStrcasecmp(mode, (const xmlChar *)"easy");
1853                                         xmlFree(mode);
1854                                 }
1855                         }
1856
1857                         if (!xmlStrcasecmp(size, (const xmlChar *)"1x1")) {
1858                                 if (is_easy) {
1859                                         livebox->size_list |= LB_SIZE_TYPE_EASY_1x1;
1860                                         update_size_info(livebox, 9, node);
1861                                 } else {
1862                                         livebox->size_list |= LB_SIZE_TYPE_1x1;
1863                                         update_size_info(livebox, 0, node);
1864                                 }
1865                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"3x1")) {
1866                                 if (is_easy) {
1867                                         livebox->size_list |= LB_SIZE_TYPE_EASY_3x1;
1868                                         update_size_info(livebox, 10, node);
1869                                 } else {
1870                                         ErrPrint("Invalid size tag (%s)\n", size);
1871                                 }
1872                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"3x3")) {
1873                                 if (is_easy) {
1874                                         livebox->size_list |= LB_SIZE_TYPE_EASY_3x3;
1875                                         update_size_info(livebox, 11, node);
1876                                 } else {
1877                                         ErrPrint("Invalid size tag (%s)\n", size);
1878                                 }
1879                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"2x1")) {
1880                                 livebox->size_list |= LB_SIZE_TYPE_2x1;
1881                                 update_size_info(livebox, 1, node);
1882                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"2x2")) {
1883                                 livebox->size_list |= LB_SIZE_TYPE_2x2;
1884                                 update_size_info(livebox, 2, node);
1885                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x1")) {
1886                                 livebox->size_list |= LB_SIZE_TYPE_4x1;
1887                                 update_size_info(livebox, 3, node);
1888                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x2")) {
1889                                 livebox->size_list |= LB_SIZE_TYPE_4x2;
1890                                 update_size_info(livebox, 4, node);
1891                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x3")) {
1892                                 livebox->size_list |= LB_SIZE_TYPE_4x3;
1893                                 update_size_info(livebox, 5, node);
1894                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x4")) {
1895                                 livebox->size_list |= LB_SIZE_TYPE_4x4;
1896                                 update_size_info(livebox, 6, node);
1897                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x5")) {
1898                                 livebox->size_list |= LB_SIZE_TYPE_4x5;
1899                                 update_size_info(livebox, 7, node);
1900                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"4x6")) {
1901                                 livebox->size_list |= LB_SIZE_TYPE_4x6;
1902                                 update_size_info(livebox, 8, node);
1903                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"21x21")) {
1904                                 livebox->size_list |= LB_SIZE_TYPE_EASY_1x1;
1905                                 update_size_info(livebox, 9, node);
1906                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"23x21")) {
1907                                 livebox->size_list |= LB_SIZE_TYPE_EASY_3x1;
1908                                 update_size_info(livebox, 10, node);
1909                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"23x23")) {
1910                                 livebox->size_list |= LB_SIZE_TYPE_EASY_3x3;
1911                                 update_size_info(livebox, 11, node);
1912                         } else if (!xmlStrcasecmp(size, (const xmlChar *)"0x0")) {
1913                                 livebox->size_list |= LB_SIZE_TYPE_0x0;
1914                                 update_size_info(livebox, 12, node);
1915                         } else {
1916                                 ErrPrint("Invalid size tag (%s)\n", size);
1917                         }
1918
1919                         xmlFree(size);
1920                 } else if (!xmlStrcasecmp(node->name, (const xmlChar *)"script")) {
1921                         xmlChar *src;
1922
1923                         if (!xmlHasProp(node, (const xmlChar *)"src")) {
1924                                 ErrPrint("Invalid script tag. has no src\n");
1925                                 continue;
1926                         }
1927
1928                         src = xmlGetProp(node, (const xmlChar *)"src");
1929                         if (!src) {
1930                                 ErrPrint("Invalid script tag. src is NIL\n");
1931                                 continue;
1932                         }
1933
1934                         if (livebox->lb_src) {
1935                                 DbgPrint("Override lb src: %s\n", livebox->lb_src);
1936                                 xmlFree(livebox->lb_src);
1937                         }
1938
1939                         livebox->lb_src = src;
1940
1941                         if (xmlHasProp(node, (const xmlChar *)"group")) {
1942                                 xmlChar *group;
1943                                 group = xmlGetProp(node, (const xmlChar *)"group");
1944                                 if (!group) {
1945                                         ErrPrint("Group is NIL\n");
1946                                 } else {
1947                                         if (livebox->lb_group) {
1948                                                 DbgPrint("Override lb group: %s\n", livebox->lb_group);
1949                                                 xmlFree(livebox->lb_group);
1950                                         }
1951
1952                                         livebox->lb_group = group;
1953                                 }
1954                         }
1955                 }
1956         }
1957 }
1958
1959 static inline void update_group(struct livebox *livebox, xmlNodePtr node)
1960 {
1961         xmlNodePtr cluster;
1962         xmlNodePtr category;
1963         xmlNodePtr option_item;
1964         xmlChar *cluster_name;
1965         xmlChar *category_name;
1966         xmlChar *ctx_item;
1967
1968         xmlChar *key;
1969         xmlChar *value;
1970
1971         struct group *group;
1972         struct option *option;
1973
1974         cluster = node;
1975         for (cluster = cluster->children; cluster; cluster = cluster->next) {
1976                 if (xmlStrcasecmp(cluster->name, (const xmlChar *)"cluster")) {
1977                         DbgPrint("Skip: %s\n", cluster->name);
1978                         continue;
1979                 }
1980
1981                 if (!xmlHasProp(cluster, (const xmlChar *)"name")) {
1982                         ErrPrint("Invalid cluster, has no name\n");
1983                         continue;
1984                 }
1985
1986                 cluster_name = xmlGetProp(cluster, (const xmlChar *)"name");
1987                 if (!cluster_name) {
1988                         ErrPrint("Invalid cluster name. NIL\n");
1989                         continue;
1990                 }
1991
1992                 for (category = cluster->children; category; category = category->next) {
1993                         if (xmlStrcasecmp(category->name, (const xmlChar *)"category")) {
1994                                 DbgPrint("Skip: %s\n", category->name);
1995                                 continue;
1996                         }
1997
1998                         if (!xmlHasProp(category, (const xmlChar *)"name")) {
1999                                 ErrPrint("Invalid category, has no name\n");
2000                                 continue;
2001                         }
2002
2003                         category_name = xmlGetProp(category, (const xmlChar *)"name");
2004                         if (!category_name) {
2005                                 ErrPrint("Invalid category name. NIL\n");
2006                                 continue;
2007                         }
2008
2009                         group = calloc(1, sizeof(*group));
2010                         if (!group) {
2011                                 ErrPrint("Heap: %s\n", strerror(errno));
2012                                 xmlFree(category_name);
2013                                 continue;
2014                         }
2015
2016                         group->cluster = xmlStrdup(cluster_name);
2017                         if (!group->cluster) {
2018                                 ErrPrint("Heap: %s\n", strerror(errno));
2019                                 xmlFree(category_name);
2020                                 free(group);
2021                                 continue;
2022                         }
2023
2024                         group->category = category_name;
2025                         livebox->group_list = dlist_append(livebox->group_list, group);
2026
2027                         if (!xmlHasProp(category, (const xmlChar *)"context")) {
2028                                 DbgPrint("%s, %s has no ctx info\n", group->cluster, group->category);
2029                                 continue;
2030                         }
2031
2032                         ctx_item = xmlGetProp(category, (const xmlChar *)"context");
2033                         if (!ctx_item) {
2034                                 ErrPrint("Failed to get context ID (%s, %s)\n", group->cluster, group->category);
2035                                 continue;
2036                         }
2037
2038                         group->ctx_item = ctx_item;
2039                         DbgPrint("Build group item: %s - %s - %s\n", group->cluster, group->category, group->ctx_item);
2040
2041                         for (option_item = category->children; option_item; option_item = option_item->next) {
2042                                 if (xmlStrcasecmp(option_item->name, (const xmlChar *)"option")) {
2043                                         DbgPrint("Skip: %s\n", option_item->name);
2044                                         continue;
2045                                 }
2046
2047                                 if (!xmlHasProp(option_item, (const xmlChar *)"key")) {
2048                                         ErrPrint("Invalid option, has no key\n");
2049                                         continue;
2050                                 }
2051
2052                                 if (!xmlHasProp(option_item, (const xmlChar *)"value")) {
2053                                         ErrPrint("Invalid option, has no value\n");
2054                                         continue;
2055                                 }
2056
2057                                 key = xmlGetProp(option_item, (const xmlChar *)"key");
2058                                 if (!key) {
2059                                         ErrPrint("Invalid key. NIL\n");
2060                                         continue;
2061                                 }
2062
2063                                 value = xmlGetProp(option_item, (const xmlChar *)"value");
2064                                 if (!value) {
2065                                         ErrPrint("Invalid valid. NIL\n");
2066                                         xmlFree(key);
2067                                         continue;
2068                                 }
2069
2070                                 option = calloc(1, sizeof(*option));
2071                                 if (!option) {
2072                                         ErrPrint("Heap: %s\n", strerror(errno));
2073                                         xmlFree(key);
2074                                         xmlFree(value);
2075                                         continue;
2076                                 }
2077
2078                                 option->key = key;
2079                                 option->value = value;
2080
2081                                 group->option_list = dlist_append(group->option_list, option);
2082                         }
2083                 }
2084
2085                 xmlFree(cluster_name);
2086         }
2087 }
2088
2089 static inline void update_pd(struct livebox *livebox, xmlNodePtr node)
2090 {
2091         if (!xmlHasProp(node, (const xmlChar *)"type")) {
2092                 livebox->pd_type = PD_TYPE_SCRIPT;
2093         } else {
2094                 xmlChar *type;
2095
2096                 type = xmlGetProp(node, (const xmlChar *)"type");
2097                 if (!type) {
2098                         ErrPrint("type is NIL\n");
2099                         return;
2100                 }
2101
2102                 if (!xmlStrcasecmp(type, (const xmlChar *)"text"))
2103                         livebox->pd_type = PD_TYPE_TEXT;
2104                 else if (!xmlStrcasecmp(type, (const xmlChar *)"buffer"))
2105                         livebox->pd_type = PD_TYPE_BUFFER;
2106                 else
2107                         livebox->pd_type = PD_TYPE_SCRIPT;
2108
2109                 xmlFree(type);
2110         }
2111
2112         for (node = node->children; node; node = node->next) {
2113                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"size")) {
2114                         xmlChar *size;
2115
2116                         size = xmlNodeGetContent(node);
2117                         if (!size) {
2118                                 ErrPrint("Invalid size tag\n");
2119                                 continue;
2120                         }
2121
2122                         if (livebox->pd_size) {
2123                                 DbgPrint("Override pd size: %s\n", livebox->pd_size);
2124                                 xmlFree(livebox->pd_size);
2125                         }
2126                         livebox->pd_size = size;
2127                 } else if (!xmlStrcasecmp(node->name, (const xmlChar *)"script")) {
2128                         xmlChar *src;
2129
2130                         if (!xmlHasProp(node, (const xmlChar *)"src")) {
2131                                 ErrPrint("Invalid script tag, has no src\n");
2132                                 continue;
2133                         }
2134
2135                         src = xmlGetProp(node, (const xmlChar *)"src");
2136                         if (!src) {
2137                                 ErrPrint("src is NIL\n");
2138                                 continue;
2139                         }
2140
2141                         if (livebox->pd_src) {
2142                                 DbgPrint("Overide PD src: %s\n", livebox->pd_src);
2143                                 xmlFree(livebox->pd_src);
2144                         }
2145
2146                         livebox->pd_src = src;
2147
2148                         if (xmlHasProp(node, (const xmlChar *)"group")) {
2149                                 xmlChar *group;
2150                                 group = xmlGetProp(node, (const xmlChar *)"group");
2151                                 if (!group) {
2152                                         ErrPrint("Group is NIL\n");
2153                                 } else {
2154                                         if (livebox->pd_group) {
2155                                                 DbgPrint("Override PD group : %s\n", livebox->pd_group);
2156                                                 xmlFree(livebox->pd_group);
2157                                         }
2158
2159                                         livebox->pd_group = group;
2160                                 }
2161                         }
2162                 }
2163         }
2164 }
2165
2166 static inline int db_insert_livebox(struct livebox *livebox, const char *appid)
2167 {
2168         struct dlist *l;
2169         struct dlist *il;
2170         struct i18n *i18n;
2171         struct group *group;
2172         int ret;
2173         int id;
2174         struct option *option;
2175
2176         begin_transaction();
2177         ret = db_insert_pkgmap(appid, (char *)livebox->pkgid, (char *)livebox->uiapp, livebox->primary);
2178         if (ret < 0)
2179                 goto errout;
2180
2181         ret = db_insert_provider(livebox);
2182         if (ret < 0)
2183                 goto errout;
2184
2185         ret = db_insert_client(livebox);
2186         if (ret < 0)
2187                 goto errout;
2188
2189         dlist_foreach(livebox->i18n_list, l, i18n) {
2190                 ret = db_insert_i18n((char *)livebox->pkgid, (char *)i18n->lang, (char *)i18n->name, (char *)i18n->icon);
2191                 if (ret < 0)
2192                         goto errout;
2193         }
2194
2195         if (livebox->size_list & LB_SIZE_TYPE_1x1) {
2196                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_1x1, (char *)livebox->preview[0], livebox->touch_effect[0], livebox->need_frame[0]);
2197                 if (ret < 0)
2198                         goto errout;
2199         }
2200
2201         if (livebox->size_list & LB_SIZE_TYPE_2x1) {
2202                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_2x1, (char *)livebox->preview[1], livebox->touch_effect[1], livebox->need_frame[1]);
2203                 if (ret < 0)
2204                         goto errout;
2205         }
2206
2207         if (livebox->size_list & LB_SIZE_TYPE_2x2) {
2208                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_2x2, (char *)livebox->preview[2], livebox->touch_effect[2], livebox->need_frame[2]);
2209                 if (ret < 0)
2210                         goto errout;
2211         }
2212
2213         if (livebox->size_list & LB_SIZE_TYPE_4x1) {
2214                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_4x1, (char *)livebox->preview[3], livebox->touch_effect[3], livebox->need_frame[3]);
2215                 if (ret < 0)
2216                         goto errout;
2217         }
2218
2219         if (livebox->size_list & LB_SIZE_TYPE_4x2) {
2220                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_4x2, (char *)livebox->preview[4], livebox->touch_effect[4], livebox->need_frame[4]);
2221                 if (ret < 0)
2222                         goto errout;
2223         }
2224
2225         if (livebox->size_list & LB_SIZE_TYPE_4x3) {
2226                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_4x3, (char *)livebox->preview[5], livebox->touch_effect[5], livebox->need_frame[5]);
2227                 if (ret < 0)
2228                         goto errout;
2229         }
2230
2231         if (livebox->size_list & LB_SIZE_TYPE_4x4) {
2232                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_4x4, (char *)livebox->preview[6], livebox->touch_effect[6], livebox->need_frame[6]);
2233                 if (ret < 0)
2234                         goto errout;
2235         }
2236
2237         if (livebox->size_list & LB_SIZE_TYPE_4x5) {
2238                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_4x5, (char *)livebox->preview[7], livebox->touch_effect[7], livebox->need_frame[7]);
2239                 if (ret < 0)
2240                         goto errout;
2241         }
2242
2243         if (livebox->size_list & LB_SIZE_TYPE_4x6) {
2244                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_4x6, (char *)livebox->preview[8], livebox->touch_effect[8], livebox->need_frame[8]);
2245                 if (ret < 0)
2246                         goto errout;
2247         }
2248
2249         if (livebox->size_list & LB_SIZE_TYPE_EASY_1x1) {
2250                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_EASY_1x1, (char *)livebox->preview[9], livebox->touch_effect[9], livebox->need_frame[9]);
2251                 if (ret < 0)
2252                         goto errout;
2253         }
2254
2255         if (livebox->size_list & LB_SIZE_TYPE_EASY_3x1) {
2256                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_EASY_3x1, (char *)livebox->preview[10], livebox->touch_effect[10], livebox->need_frame[10]);
2257                 if (ret < 0)
2258                         goto errout;
2259         }
2260
2261         if (livebox->size_list & LB_SIZE_TYPE_EASY_3x3) {
2262                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_EASY_3x3, (char *)livebox->preview[11], livebox->touch_effect[11], livebox->need_frame[11]);
2263                 if (ret < 0)
2264                         goto errout;
2265         }
2266
2267         if (livebox->size_list & LB_SIZE_TYPE_0x0) {
2268                 ret = db_insert_box_size((char *)livebox->pkgid, LB_SIZE_TYPE_0x0, (char *)livebox->preview[12], livebox->touch_effect[12], livebox->need_frame[12]);
2269                 if (ret < 0)
2270                         goto errout;
2271         }
2272
2273         dlist_foreach(livebox->group_list, l, group) {
2274                 /* group ID "id" */
2275                 id = db_get_group_id((char *)group->cluster, (char *)group->category);
2276                 if (id < 0) {
2277                         int ret;
2278                         
2279                         ret = db_insert_group((char *)livebox->pkgid, (char *)group->cluster, (char *)group->category);
2280                         if (ret < 0) {
2281                                 ErrPrint("[%s]-[%s] is not exists\n", group->cluster, group->category);
2282                                 continue;
2283                         }
2284
2285                         DbgPrint("New group name is built - %s/%s\n", group->cluster, group->category);
2286                         id = db_get_group_id((char *)group->cluster, (char *)group->category);
2287                         if (id < 0) {
2288                                 ErrPrint("Failed to get group id for %s/%s\n", group->cluster, group->category);
2289                                 continue;
2290                         }
2291                 }
2292
2293                 if (!group->ctx_item) {
2294                         DbgPrint("%s, %s - has no ctx info\n", group->cluster, group->category);
2295                         continue;
2296                 }
2297
2298                 ret = db_insert_groupmap(id, (char *)livebox->pkgid, (char *)group->ctx_item);
2299                 if (ret < 0)
2300                         goto errout;
2301
2302                 /* REUSE "id" from here , option ID */
2303                 id = db_get_option_id(id, (char *)livebox->pkgid, (char *)group->ctx_item);
2304                 if (id < 0)
2305                         goto errout;
2306
2307                 dlist_foreach(group->option_list, il, option) {
2308                         ret = db_insert_option((char *)livebox->pkgid, id, (char *)option->key, (char *)option->value);
2309                         if (ret < 0)
2310                                 goto errout;
2311                 }
2312         }
2313
2314         commit_transaction();
2315         livebox_destroy(livebox);
2316         return 0;
2317
2318 errout:
2319         ErrPrint("ROLLBACK\n");
2320         rollback_transaction();
2321         livebox_destroy(livebox);
2322         return ret;
2323 }
2324
2325 static inline int do_install(xmlNodePtr node, const char *appid)
2326 {
2327         struct livebox *livebox;
2328         xmlChar *pkgid;
2329         xmlChar *tmp;
2330
2331         if (!xmlHasProp(node, (const xmlChar *)"appid")) {
2332                 ErrPrint("Missing appid\n");
2333                 return -EINVAL;
2334         }
2335
2336         pkgid = xmlGetProp(node, (const xmlChar *)"appid");
2337         if (!pkgid || !validate_pkgid(appid, (char *)pkgid)) {
2338                 ErrPrint("Invalid appid\n");
2339                 xmlFree(pkgid);
2340                 return -EINVAL;
2341         }
2342
2343         DbgPrint("appid: %s\n", (char *)pkgid);
2344
2345         livebox = calloc(1, sizeof(*livebox));
2346         if (!livebox) {
2347                 ErrPrint("Heap: %s\n", strerror(errno));
2348                 xmlFree(pkgid);
2349                 return -ENOMEM;
2350         }
2351
2352         livebox->pkgid = pkgid;
2353
2354         if (xmlHasProp(node, (const xmlChar *)"primary")) {
2355                 tmp = xmlGetProp(node, (const xmlChar *)"primary");
2356                 livebox->primary = !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2357                 xmlFree(tmp);
2358         }
2359
2360         if (xmlHasProp(node, (const xmlChar *)"script")) {
2361                 livebox->script = xmlGetProp(node, (const xmlChar *)"script");
2362                 if (!livebox->script)
2363                         ErrPrint("script is NIL\n");
2364         }
2365
2366         if (xmlHasProp(node, (const xmlChar *)"nodisplay")) {
2367                 tmp = xmlGetProp(node, (const xmlChar *)"nodisplay");
2368                 livebox->nodisplay = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2369                 xmlFree(tmp);
2370         }
2371
2372         if (xmlHasProp(node, (const xmlChar *)"pinup")) {
2373                 tmp = xmlGetProp(node, (const xmlChar *)"pinup");
2374                 livebox->pinup = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2375                 xmlFree(tmp);
2376         }
2377
2378         if (xmlHasProp(node, (const xmlChar *)"period")) {
2379                 livebox->period = xmlGetProp(node, (const xmlChar *)"period");
2380                 if (!livebox->period)
2381                         ErrPrint("Period is NIL\n");
2382         }
2383
2384         if (xmlHasProp(node, (const xmlChar *)"timeout")) {
2385                 livebox->timeout = xmlGetProp(node, (const xmlChar *)"timeout");
2386                 if (!livebox->timeout)
2387                         ErrPrint("Timeout is NIL\n");
2388         }
2389
2390         if (xmlHasProp(node, (const xmlChar *)"secured")) {
2391                 tmp = xmlGetProp(node, (const xmlChar *)"secured");
2392                 livebox->secured = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2393                 xmlFree(tmp);
2394         }
2395
2396         if (xmlHasProp(node, (const xmlChar *)"network")) {
2397                 tmp = xmlGetProp(node, (const xmlChar *)"network");
2398                 livebox->network = tmp && !xmlStrcasecmp(tmp, (const xmlChar *)"true");
2399                 xmlFree(tmp);
2400         }
2401
2402         if (xmlHasProp(node, (const xmlChar *)"abi")) {
2403                 livebox->abi = xmlGetProp(node, (const xmlChar *)"abi");
2404                 if (!livebox->abi) {
2405                         ErrPrint("ABI is NIL\n");
2406                         livebox_destroy(livebox);
2407                         return -EFAULT;
2408                 }
2409         } else {
2410                 livebox->abi = xmlStrdup((const xmlChar *)"c");
2411                 if (!livebox->abi) {
2412                         ErrPrint("Heap: %s\n", strerror(errno));
2413                         livebox_destroy(livebox);
2414                         return -ENOMEM;
2415                 }
2416         }
2417
2418         if (xmlHasProp(node, (const xmlChar *)"libexec")) {
2419                 livebox->libexec = xmlGetProp(node, (const xmlChar *)"libexec");
2420                 if (!livebox->libexec) {
2421                         ErrPrint("libexec is NIL\n");
2422                         livebox_destroy(livebox);
2423                         return -EFAULT;
2424                 }
2425         } else if (!xmlStrcasecmp(livebox->abi, (const xmlChar *)"c") || !xmlStrcasecmp(livebox->abi, (const xmlChar *)"cpp")) {
2426                 char *filename;
2427                 int len;
2428
2429                 len = strlen((char *)livebox->pkgid) + strlen("/libexec/liblive-.so") + 1;
2430
2431                 filename = malloc(len);
2432                 if (!filename) {
2433                         livebox_destroy(livebox);
2434                         return -ENOMEM;
2435                 }
2436
2437                 snprintf(filename, len, "/libexec/liblive-%s.so", livebox->pkgid);
2438                 livebox->libexec = xmlStrdup((xmlChar *)filename);
2439                 DbgPrint("Use the default libexec: %s\n", filename);
2440                 free(filename);
2441
2442                 if (!livebox->libexec) {
2443                         livebox_destroy(livebox);
2444                         return -ENOMEM;
2445                 }
2446         }
2447
2448         for (node = node->children; node; node = node->next) {
2449                 if (!xmlStrcmp(node->name, (const xmlChar *)"text"))
2450                         continue;
2451
2452                 DbgPrint("Nodename: %s\n", node->name);
2453                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"label")) {
2454                         update_i18n_name(livebox, node);
2455                         continue;
2456                 }
2457
2458                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"icon")) {
2459                         update_i18n_icon(livebox, node);
2460                         continue;
2461                 }
2462
2463                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"box")) {
2464                         update_box(livebox, node);
2465                         continue;
2466                 }
2467
2468                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"pd")) {
2469                         update_pd(livebox, node);
2470                         continue;
2471                 }
2472
2473                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"group")) {
2474                         update_group(livebox, node);
2475                         continue;
2476                 }
2477
2478                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"content")) {
2479                         update_content(livebox, node);
2480                         continue;
2481                 }
2482
2483                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"setup")) {
2484                         update_setup(livebox, node);
2485                         continue;
2486                 }
2487
2488                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"launch")) {
2489                         update_launch(livebox, node);
2490                         continue;
2491                 }
2492
2493                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"ui-appid")) {
2494                         update_ui_appid(livebox, node);
2495                         continue;
2496                 }
2497         }
2498
2499         return db_insert_livebox(livebox, appid);
2500 }
2501
2502 int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr docPtr, const char *appid)
2503 {
2504         xmlNodePtr node;
2505         int ret;
2506
2507         if (!s_info.handle) {
2508                 if (db_init() < 0) {
2509                         ErrPrint("Failed to init DB\n");
2510                         return -EIO;
2511                 }
2512         }
2513
2514         node = xmlDocGetRootElement(docPtr);
2515         if (!node) {
2516                 ErrPrint("Invalid document\n");
2517                 return -EINVAL;
2518         }
2519
2520         for (node = node->children; node; node = node->next) {
2521                 DbgPrint("node->name: %s\n", node->name);
2522                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"livebox")) {
2523                         ret = do_install(node, appid);
2524                         DbgPrint("Returns: %d\n", ret);
2525                 }
2526         }
2527
2528         return 0;
2529 }
2530
2531 static inline int do_uninstall(xmlNodePtr node, const char *appid)
2532 {
2533         xmlChar *pkgid;
2534         int ret;
2535
2536         if (!xmlHasProp(node, (const xmlChar *)"appid")) {
2537                 ErrPrint("Missing appid\n");
2538                 return -EINVAL;
2539         }
2540
2541         pkgid = xmlGetProp(node, (const xmlChar *)"appid");
2542         if (!validate_pkgid(appid, (char *)pkgid)) {
2543                 ErrPrint("Invalid package\n");
2544                 xmlFree(pkgid);
2545                 return -EINVAL;
2546         }
2547
2548         begin_transaction();
2549         ret = db_remove_box_size((char *)pkgid);
2550         if (ret < 0)
2551                 goto errout;
2552
2553         ret = db_remove_i18n((char *)pkgid);
2554         if (ret < 0)
2555                 goto errout;
2556
2557         ret = db_remove_client((char *)pkgid);
2558         if (ret < 0)
2559                 goto errout;
2560
2561         ret = db_remove_provider((char *)pkgid);
2562         if (ret < 0)
2563                 goto errout;
2564
2565         ret = db_remove_option((char *)pkgid);
2566         DbgPrint("Remove option: %d\n", ret);
2567
2568         ret = db_remove_groupmap((char *)pkgid);
2569         DbgPrint("Remove groupmap: %d\n", ret);
2570
2571         ret = db_remove_group((char *)pkgid);
2572         if (ret < 0)
2573                 goto errout;
2574
2575         ret = db_remove_pkgmap((char *)pkgid);
2576         if (ret < 0)
2577                 goto errout;
2578
2579         commit_transaction();
2580         xmlFree(pkgid);
2581
2582         return 0;
2583
2584 errout:
2585         rollback_transaction();
2586         xmlFree(pkgid);
2587         return ret;
2588 }
2589
2590 int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr docPtr, const char *appid)
2591 {
2592         xmlNodePtr node;
2593         int ret;
2594
2595         if (!s_info.handle) {
2596                 if (db_init() < 0) {
2597                         ErrPrint("Failed to init DB\n");
2598                         return -EIO;
2599                 }
2600         }
2601
2602         node = xmlDocGetRootElement(docPtr);
2603         if (!node) {
2604                 ErrPrint("Invalid document\n");
2605                 return -EINVAL;
2606         }
2607
2608         for (node = node->children; node; node = node->next) {
2609                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"livebox")) {
2610                         ret = do_uninstall(node, appid);
2611                         ret = do_install(node, appid);
2612                         DbgPrint("Returns: %d\n", ret);
2613                 }
2614         }
2615
2616         return 0;
2617 }
2618
2619 int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr docPtr, const char *appid)
2620 {
2621         xmlNodePtr node;
2622         int ret;
2623
2624         if (!s_info.handle) {
2625                 if (db_init() < 0) {
2626                         ErrPrint("Failed to init DB\n");
2627                         return -EIO;
2628                 }
2629         }
2630
2631         node = xmlDocGetRootElement(docPtr);
2632         if (!node) {
2633                 ErrPrint("Invalid document\n");
2634                 return -EINVAL;
2635         }
2636
2637         for (node = node->children; node; node = node->next) {
2638                 if (!xmlStrcasecmp(node->name, (const xmlChar *)"livebox")) {
2639                         ret = do_uninstall(node, appid);
2640                         DbgPrint("Returns: %d\n", ret);
2641                 }
2642         }
2643
2644         return 0;
2645 }
2646
2647 /* End of a file */