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