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