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