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