Fix the crash issue.
[platform/framework/web/data-provider-master.git] / src / io.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 <dirent.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <ctype.h>
25
26 #include <dlog.h>
27 #include <Eina.h>
28 #include <sqlite3.h>
29 #include <db-util.h>
30 #include <livebox-errno.h>
31
32 #include "debug.h"
33 #include "conf.h"
34 #include "parser.h"
35 #include "group.h"
36 #include "util.h"
37 #include "client_life.h"
38 #include "slave_life.h"
39 #include "package.h"
40 #include "abi.h"
41 #include "io.h"
42
43 int errno;
44
45 static struct {
46         sqlite3 *handle;
47 } s_info = {
48         .handle = NULL,
49 };
50
51 static int load_abi_table(void)
52 {
53         FILE *fp;
54         int ch;
55         int idx = 0;
56         int tag_id = -1;
57         enum {
58                 INIT = 0x0,
59                 GROUP = 0x1,
60                 TAG = 0x02,
61                 VALUE = 0x03,
62                 ERROR = 0x05
63         } state;
64         enum {
65                 PKGNAME = 0x0,
66         };
67         static const char *field[] = {
68                 "package",
69                 NULL,
70         };
71         const char *ptr = NULL;
72
73         char group[MAX_ABI + 1];
74         char pkgname[MAX_PKGNAME + 1];
75
76         fp = fopen("/usr/share/"PACKAGE"/abi.ini", "rt");
77         if (!fp) {
78                 return LB_STATUS_ERROR_IO;
79         }
80
81         state = INIT;
82         while ((ch = getc(fp)) != EOF && state != ERROR) {
83                 switch (state) {
84                 case INIT:
85                         if (isspace(ch)) {
86                                 continue;
87                         }
88                         if (ch == '[') {
89                                 state = GROUP;
90                                 idx = 0;
91                         } else {
92                                 state = ERROR;
93                         }
94                         break;
95                 case GROUP:
96                         if (ch == ']') {
97                                 if (idx == 0) {
98                                         state = ERROR;
99                                 } else {
100                                         group[idx] = '\0';
101                                         state = TAG;
102                                         idx = 0;
103                                         ptr = NULL;
104                                 }
105                         } else if (idx < MAX_ABI) {
106                                 group[idx++] = ch;
107                         } else {
108                                 ErrPrint("Overflow\n");
109                                 state = ERROR;
110                         }
111                         break;
112                 case TAG:
113                         if (ptr == NULL) {
114                                 if (idx == 0) {
115                                         if (isspace(ch)) {
116                                                 continue;
117                                         }
118
119                                         /* New group started */
120                                         if (ch == '[') {
121                                                 ungetc(ch, fp);
122                                                 state = INIT;
123                                                 continue;
124                                         }
125                                 }
126
127                                 ptr = field[idx];
128                         }
129
130                         if (ptr == NULL) {
131                                 ErrPrint("unknown tag\n");
132                                 state = ERROR;
133                                 continue;
134                         }
135
136                         if (*ptr == '\0' && ch == '=') {
137                                 /* MATCHED */
138                                 state = VALUE;
139                                 tag_id = idx;
140                                 idx = 0;
141                                 ptr = NULL;
142                         } else if (*ptr == ch) {
143                                 ptr++;
144                         } else {
145                                 ungetc(ch, fp);
146                                 ptr--;
147                                 while (ptr >= field[idx]) {
148                                         ungetc(*ptr, fp);
149                                         ptr--;
150                                 }
151                                 ptr = NULL;
152                                 idx++;
153                         }
154                         break;
155                 case VALUE:
156                         switch (tag_id) {
157                         case PKGNAME:
158                                 if (idx == 0) { /* LTRIM */
159                                         if (isspace(ch)) {
160                                                 continue;
161                                         }
162
163                                         pkgname[idx] = ch;
164                                         idx++;
165                                 } else if (isspace(ch)) {
166                                         int ret;
167                                         pkgname[idx] = '\0';
168
169                                         ret = abi_add_entry(group, pkgname);
170                                         if (ret != 0) {
171                                                 ErrPrint("Failed to add %s for %s\n", pkgname, group);
172                                         }
173
174                                         state = TAG;
175                                         idx = 0;
176                                 } else if (idx < MAX_PKGNAME) {
177                                         pkgname[idx] = ch;
178                                         idx++;
179                                 } else {
180                                         ErrPrint("Overflow\n");
181                                         state = ERROR;
182                                 }
183                                 break;
184                         default:
185                                 break;
186                         }
187                         break;
188                 case ERROR:
189                 default:
190                         break;
191                 }
192         }
193
194         if (state == VALUE) {
195                 switch (tag_id) {
196                 case PKGNAME:
197                         if (idx) {
198                                 int ret;
199                                 pkgname[idx] = '\0';
200                                 ret = abi_add_entry(group, pkgname);
201                                 if (ret != 0) {
202                                         ErrPrint("Failed to add %s for %s\n", pkgname, group);
203                                 }
204                         }
205                         break;
206                 default:
207                         break;
208                 }
209         }
210
211         if (fclose(fp) != 0) {
212                 ErrPrint("fclose: %s\n", strerror(errno));
213         }
214         return LB_STATUS_SUCCESS;
215 }
216
217 static inline int build_client_info(struct pkg_info *info)
218 {
219         static const char *dml = "SELECT auto_launch, pd_size FROM client WHERE pkgid = ?";
220         sqlite3_stmt *stmt;
221         int width;
222         int height;
223         int ret;
224         const char *tmp;
225
226         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
227         if (ret != SQLITE_OK) {
228                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
229                 return LB_STATUS_ERROR_IO;
230         }
231
232         ret = sqlite3_bind_text(stmt, 1, package_name(info), -1, SQLITE_TRANSIENT);
233         if (ret != SQLITE_OK) {
234                 ErrPrint("Failed to bind a pkgname %s\n", package_name(info));
235                 sqlite3_finalize(stmt);
236                 return LB_STATUS_ERROR_IO;
237         }
238
239         if (sqlite3_step(stmt) != SQLITE_ROW) {
240                 ErrPrint("%s has no records (%s)\n", package_name(info), sqlite3_errmsg(s_info.handle));
241                 sqlite3_reset(stmt);
242                 sqlite3_clear_bindings(stmt);
243                 sqlite3_finalize(stmt);
244                 return LB_STATUS_ERROR_IO;
245         }
246
247         package_set_auto_launch(info, (const char *)sqlite3_column_text(stmt, 0));
248
249         tmp = (const char *)sqlite3_column_text(stmt, 1);
250         if (tmp && strlen(tmp)) {
251                 if (sscanf(tmp, "%dx%d", &width, &height) != 2) {
252                         ErrPrint("Failed to get PD width and Height (%s)\n", tmp);
253                 } else {
254                         package_set_pd_width(info, width);
255                         package_set_pd_height(info, height);
256                 }
257         }
258
259         sqlite3_reset(stmt);
260         sqlite3_clear_bindings(stmt);
261         sqlite3_finalize(stmt);
262         return LB_STATUS_SUCCESS;
263 }
264
265 static inline int build_provider_info(struct pkg_info *info)
266 {
267         static const char *dml = "SELECT provider.network, provider.abi, provider.secured, provider.box_type, provider.box_src, provider.box_group, provider.pd_type, provider.pd_src, provider.pd_group, provider.libexec, provider.timeout, provider.period, provider.script, provider.pinup, pkgmap.appid FROM provider, pkgmap WHERE pkgmap.pkgid = ? AND provider.pkgid = ?";
268         sqlite3_stmt *stmt;
269         int ret;
270         const char *tmp;
271         const char *appid;
272
273         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
274         if (ret != SQLITE_OK) {
275                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
276                 return LB_STATUS_ERROR_IO;
277         }
278
279         if (sqlite3_bind_text(stmt, 1, package_name(info), -1, SQLITE_TRANSIENT) != SQLITE_OK) {
280                 ErrPrint("Failed to bind a pkgname(%s) - %s\n", package_name(info), sqlite3_errmsg(s_info.handle));
281                 sqlite3_finalize(stmt);
282                 return LB_STATUS_ERROR_IO;
283         }
284
285         if (sqlite3_bind_text(stmt, 2, package_name(info), -1, SQLITE_TRANSIENT) != SQLITE_OK) {
286                 ErrPrint("Failed to bind a pkgname(%s) - %s\n", package_name(info), sqlite3_errmsg(s_info.handle));
287                 sqlite3_finalize(stmt);
288                 return LB_STATUS_ERROR_IO;
289         }
290
291         if (sqlite3_step(stmt) != SQLITE_ROW) {
292                 ErrPrint("%s has no record(%s)\n", package_name(info), sqlite3_errmsg(s_info.handle));
293                 sqlite3_reset(stmt);
294                 sqlite3_clear_bindings(stmt);
295                 sqlite3_finalize(stmt);
296                 return LB_STATUS_ERROR_IO;
297         }
298
299         appid = (const char *)sqlite3_column_text(stmt, 14);
300         if (!appid || !strlen(appid)) {
301                 ErrPrint("Failed to execute the DML for %s\n", package_name(info));
302                 sqlite3_reset(stmt);
303                 sqlite3_clear_bindings(stmt);
304                 sqlite3_finalize(stmt);
305                 return LB_STATUS_ERROR_IO;
306         }
307
308         package_set_network(info, sqlite3_column_int(stmt, 0));
309         package_set_secured(info, sqlite3_column_int(stmt, 2));
310
311         tmp = (const char *)sqlite3_column_text(stmt, 1);
312         if (tmp && strlen(tmp)) {
313                 package_set_abi(info, tmp);
314         }
315
316         package_set_lb_type(info, sqlite3_column_int(stmt, 3));
317         tmp = (const char *)sqlite3_column_text(stmt, 4);
318         if (tmp && strlen(tmp)) {
319                 package_set_lb_path(info, tmp);
320
321                 tmp = (const char *)sqlite3_column_text(stmt, 5);
322                 if (tmp && strlen(tmp)) {
323                         package_set_lb_group(info, tmp);
324                 }
325         }
326
327         package_set_pd_type(info, sqlite3_column_int(stmt, 6));
328         tmp = (const char *)sqlite3_column_text(stmt, 7);
329         if (tmp && strlen(tmp)) {
330                 package_set_pd_path(info, tmp);
331
332                 tmp = (const char *)sqlite3_column_text(stmt, 8);
333                 if (tmp && strlen(tmp)) {
334                         package_set_pd_group(info, tmp);
335                 }
336         }
337
338         tmp = (const char *)sqlite3_column_text(stmt, 9);
339         if (tmp && strlen(tmp)) {
340                 package_set_libexec(info, tmp);
341         }
342
343         package_set_timeout(info, sqlite3_column_int(stmt, 10));
344
345         tmp = (const char *)sqlite3_column_text(stmt, 11);
346         if (tmp && strlen(tmp)) {
347                 package_set_period(info, atof(tmp));
348         }
349
350         tmp = (const char *)sqlite3_column_text(stmt, 12);
351         if (tmp && strlen(tmp)) {
352                 package_set_script(info, tmp);
353         }
354
355         package_set_pinup(info, sqlite3_column_int(stmt, 13));
356
357         sqlite3_reset(stmt);
358         sqlite3_clear_bindings(stmt);
359         sqlite3_finalize(stmt);
360         return LB_STATUS_SUCCESS;
361 }
362
363 static inline int build_box_size_info(struct pkg_info *info)
364 {
365         static const char *dml = "SELECT size_type FROM box_size WHERE pkgid = ?";
366         sqlite3_stmt *stmt;
367         int ret;
368         unsigned int size_type;
369         unsigned int size_list;
370
371         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
372         if (ret != SQLITE_OK) {
373                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
374                 return LB_STATUS_ERROR_IO;
375         }
376
377         if (sqlite3_bind_text(stmt, 1, package_name(info), -1, SQLITE_TRANSIENT) != SQLITE_OK) {
378                 ErrPrint("Failed to bind a pkgname(%s) - %s\n", package_name(info), sqlite3_errmsg(s_info.handle));
379                 sqlite3_finalize(stmt);
380                 return LB_STATUS_ERROR_IO;
381         }
382
383         size_list = 0;
384         while (sqlite3_step(stmt) == SQLITE_ROW) {
385                 size_type = sqlite3_column_int(stmt, 0);
386                 size_list |= size_type;
387         }
388
389         package_set_size_list(info, size_list);
390
391         sqlite3_reset(stmt);
392         sqlite3_clear_bindings(stmt);
393         sqlite3_finalize(stmt);
394         return LB_STATUS_SUCCESS;
395 }
396
397 static inline int load_context_option(struct context_item *item, int id)
398 {
399         static const char *dml = "SELECT key, value FROM option WHERE option_id = ?";
400         sqlite3_stmt *stmt;
401         const char *key;
402         const char *value;
403         int ret;
404
405         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
406         if (ret != SQLITE_OK) {
407                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
408                 return LB_STATUS_ERROR_IO;
409         }
410
411         ret = sqlite3_bind_int(stmt, 1, id);
412         if (ret != SQLITE_OK) {
413                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
414                 ret = LB_STATUS_ERROR_IO;
415                 goto out;
416         }
417
418         ret = LB_STATUS_ERROR_NOT_EXIST;
419         while (sqlite3_step(stmt) == SQLITE_ROW) {
420                 key = (const char *)sqlite3_column_text(stmt, 0);
421                 if (!key || !strlen(key)) {
422                         ErrPrint("KEY is nil\n");
423                         continue;
424                 }
425
426                 value = (const char *)sqlite3_column_text(stmt, 1);
427                 if (!value || !strlen(value)) {
428                         ErrPrint("VALUE is nil\n");
429                         continue;
430                 }
431
432                 ret = group_add_option(item, key, value);
433                 if (ret < 0) {
434                         break;
435                 }
436         }
437
438 out:
439         sqlite3_reset(stmt);
440         sqlite3_clear_bindings(stmt);
441         sqlite3_finalize(stmt);
442         return ret;
443 }
444
445 static inline int load_context_item(struct context_info *info, int id)
446 {
447         static const char *dml = "SELECT ctx_item, option_id FROM groupmap WHERE id = ?";
448         struct context_item *item;
449         sqlite3_stmt *stmt;
450         const char *ctx_item;
451         int option_id;
452         int ret;
453
454         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
455         if (ret != SQLITE_OK) {
456                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
457                 return LB_STATUS_ERROR_IO;
458         }
459
460         ret = sqlite3_bind_int(stmt, 1, id);
461         if (ret != SQLITE_OK) {
462                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
463                 ret = LB_STATUS_ERROR_IO;
464                 goto out;
465         }
466
467         ret = LB_STATUS_ERROR_NOT_EXIST;
468         while (sqlite3_step(stmt) == SQLITE_ROW) {
469                 ctx_item = (const char *)sqlite3_column_text(stmt, 0);
470                 option_id = sqlite3_column_int(stmt, 1);
471
472                 item = group_add_context_item(info, ctx_item);
473                 if (!item) {
474                         ErrPrint("Failed to add a new context item\n");
475                         ret = LB_STATUS_ERROR_FAULT;
476                         break;
477                 }
478
479                 ret = load_context_option(item, option_id);
480                 if (ret < 0) {
481                         break;
482                 }
483         }
484
485 out:
486         sqlite3_reset(stmt);
487         sqlite3_clear_bindings(stmt);
488         sqlite3_finalize(stmt);
489         return ret;
490 }
491
492 static inline int build_group_info(struct pkg_info *info)
493 {
494         static const char *dml = "SELECT id, cluster, category FROM groupinfo WHERE pkgid = ?";
495         sqlite3_stmt *stmt;
496         int ret;
497         int id;
498         const char *cluster_name;
499         const char *category_name;
500         struct cluster *cluster;
501         struct category *category;
502         struct context_info *ctx_info;
503
504         ret = sqlite3_prepare_v2(s_info.handle, dml, -1, &stmt, NULL);
505         if (ret != SQLITE_OK) {
506                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
507                 return LB_STATUS_ERROR_IO;
508         }
509
510         ret = sqlite3_bind_text(stmt, 1, package_name(info), -1, SQLITE_TRANSIENT);
511         if (ret != SQLITE_OK) {
512                 ErrPrint("Failed to bind a package name(%s)\n", package_name(info));
513                 sqlite3_finalize(stmt);
514                 return LB_STATUS_ERROR_IO;
515         }
516
517         while (sqlite3_step(stmt) == SQLITE_ROW) {
518                 id = sqlite3_column_int(stmt, 0);
519                 cluster_name = (const char *)sqlite3_column_text(stmt, 1);
520                 if (!cluster_name || !strlen(cluster_name)) {
521                         DbgPrint("Cluster name is not valid\n");
522                         continue;
523                 }
524
525                 category_name = (const char *)sqlite3_column_text(stmt, 2);
526                 if (!category_name || !strlen(category_name)) {
527                         DbgPrint("Category name is not valid\n");
528                         continue;
529                 }
530
531                 cluster = group_find_cluster(cluster_name);
532                 if (!cluster) {
533                         cluster = group_create_cluster(cluster_name);
534                         if (!cluster) {
535                                 ErrPrint("Failed to create a cluster(%s)\n", cluster_name);
536                                 continue;
537                         }
538                 }
539
540                 category = group_find_category(cluster, category_name);
541                 if (!category) {
542                         category = group_create_category(cluster, category_name);
543                         if (!category) {
544                                 ErrPrint("Failed to create a category(%s)\n", category_name);
545                                 continue;
546                         }
547                 }
548
549                 /*!
550                  * \TODO
551                  * Step 1. Get the list of the context item from the DB using 'id'
552                  *         {context_item, option_id}
553                  * Step 2. Get the list of the options from the DB using option_id
554                  *         key, value
555                  */
556                 ctx_info = group_create_context_info(category, package_name(info));
557                 if (ctx_info) {
558                         ret = load_context_item(ctx_info, id);
559                         if (ret < 0) {
560                                 if (ret == LB_STATUS_ERROR_NOT_EXIST) {
561                                         DbgPrint("Has no specific context info\n");
562                                 } else {
563                                         DbgPrint("Context info is not valid\n");
564                                         group_destroy_context_info(ctx_info);
565                                         ctx_info = NULL;
566                                 }
567                         }
568
569                         if (ctx_info) {
570                                 package_add_ctx_info(info, ctx_info);
571                         }
572                 }
573         }
574
575         sqlite3_reset(stmt);
576         sqlite3_clear_bindings(stmt);
577         sqlite3_finalize(stmt);
578         return LB_STATUS_SUCCESS;
579 }
580
581 HAPI int io_is_exists(const char *lbid)
582 {
583         sqlite3_stmt *stmt;
584         int ret;
585
586         if (!s_info.handle) {
587                 ErrPrint("DB is not ready\n");
588                 return LB_STATUS_ERROR_IO;
589         }
590
591         ret = sqlite3_prepare_v2(s_info.handle, "SELECT COUNT(pkgid) FROM pkgmap WHERE pkgid = ?", -1, &stmt, NULL);
592         if (ret != SQLITE_OK) {
593                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
594                 return LB_STATUS_ERROR_IO;
595         }
596
597         ret = sqlite3_bind_text(stmt, 1, lbid, -1, SQLITE_TRANSIENT);
598         if (ret != SQLITE_OK) {
599                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
600                 ret = LB_STATUS_ERROR_IO;
601                 goto out;
602         }
603
604         if (sqlite3_step(stmt) != SQLITE_ROW) {
605                 ErrPrint("%s has no record (%s)\n", lbid, sqlite3_errmsg(s_info.handle));
606                 ret = LB_STATUS_ERROR_IO;
607                 goto out;
608         }
609
610         ret = sqlite3_column_int(stmt, 0);
611 out:
612         sqlite3_reset(stmt);
613         sqlite3_finalize(stmt);
614         return ret;
615 }
616
617 HAPI char *io_livebox_pkgname(const char *pkgname)
618 {
619         sqlite3_stmt *stmt;
620         char *pkgid;
621         char *tmp;
622         int ret;
623
624         pkgid = NULL;
625
626         if (!s_info.handle) {
627                 ErrPrint("DB is not ready\n");
628                 return NULL;
629         }
630
631         ret = sqlite3_prepare_v2(s_info.handle, "SELECT pkgid FROM pkgmap WHERE (appid = ? AND prime = 1) OR pkgid = ?", -1, &stmt, NULL);
632         if (ret != SQLITE_OK) {
633                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
634                 return NULL;
635         }
636
637         ret = sqlite3_bind_text(stmt, 1, pkgname, -1, SQLITE_TRANSIENT);
638         if (ret != SQLITE_OK) {
639                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
640                 goto out;
641         }
642
643         ret = sqlite3_bind_text(stmt, 2, pkgname, -1, SQLITE_TRANSIENT);
644         if (ret != SQLITE_OK) {
645                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
646                 goto out;
647         }
648
649         if (sqlite3_step(stmt) != SQLITE_ROW) {
650                 ErrPrint("%s has no record (%s)\n", pkgname, sqlite3_errmsg(s_info.handle));
651                 goto out;
652         }
653
654         tmp = (char *)sqlite3_column_text(stmt, 0);
655         if (tmp && strlen(tmp)) {
656                 pkgid = strdup(tmp);
657                 if (!pkgid) {
658                         ErrPrint("Heap: %s\n", strerror(errno));
659                 }
660         }
661
662 out:
663         sqlite3_reset(stmt);
664         sqlite3_finalize(stmt);
665         return pkgid;
666 }
667
668 HAPI int io_crawling_liveboxes(int (*cb)(const char *pkgid, const char *lbid, int prime, void *data), void *data)
669 {
670         DIR *dir;
671
672         if (!s_info.handle) {
673                 ErrPrint("DB is not ready\n");
674         } else {
675                 int ret;
676                 sqlite3_stmt *stmt;
677
678                 ret = sqlite3_prepare_v2(s_info.handle, "SELECT appid, pkgid, prime FROM pkgmap", -1, &stmt, NULL);
679                 if (ret != SQLITE_OK) {
680                         ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
681                 } else {
682                         const char *lbid;
683                         const char *pkgid;
684                         int prime;
685
686                         while (sqlite3_step(stmt) == SQLITE_ROW) {
687                                 pkgid = (const char *)sqlite3_column_text(stmt, 0);
688                                 if (!pkgid || !strlen(pkgid)) {
689                                         continue;
690                                 }
691
692                                 lbid = (const char *)sqlite3_column_text(stmt, 1);
693                                 if (!lbid || !strlen(lbid)) {
694                                         continue;
695                                 }
696
697                                 prime = (int)sqlite3_column_int(stmt, 1);
698
699                                 if (cb(pkgid, lbid, prime, data) < 0) {
700                                         sqlite3_reset(stmt);
701                                         sqlite3_finalize(stmt);
702                                         return LB_STATUS_ERROR_CANCEL;
703                                 }
704                         }
705
706                         sqlite3_reset(stmt);
707                         sqlite3_finalize(stmt);
708                 }
709         }
710
711         dir = opendir(ROOT_PATH);
712         if (!dir) {
713                 ErrPrint("Error: %s\n", strerror(errno));
714         } else {
715                 struct dirent *ent;
716
717                 while ((ent = readdir(dir))) {
718                         if (ent->d_name[0] == '.') {
719                                 continue;
720                         }
721
722                         if (cb(ent->d_name, ent->d_name, -2, data) < 0) {
723                                 if (closedir(dir) < 0) {
724                                         ErrPrint("closedir: %s\n", strerror(errno));
725                                 }
726                                 return LB_STATUS_ERROR_CANCEL;
727                         }
728                 }
729
730                 if (closedir(dir) < 0) {
731                         ErrPrint("closedir: %s\n", strerror(errno));
732                 }
733         }
734
735         return LB_STATUS_SUCCESS;
736 }
737
738 HAPI int io_update_livebox_package(const char *pkgid, int (*cb)(const char *pkgid, const char *lbid, int prime, void *data), void *data)
739 {
740         sqlite3_stmt *stmt;
741         char *lbid;
742         int prime;
743         int ret;
744
745         if (!cb || !pkgid) {
746                 return LB_STATUS_ERROR_INVALID;
747         }
748
749         if (!s_info.handle) {
750                 ErrPrint("DB is not ready\n");
751                 return LB_STATUS_ERROR_INVALID;
752         }
753
754         ret = sqlite3_prepare_v2(s_info.handle, "SELECT pkgid, prime FROM pkgmap WHERE appid = ?", -1, &stmt, NULL);
755         if (ret != SQLITE_OK) {
756                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
757                 return LB_STATUS_ERROR_FAULT;
758         }
759
760         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
761         if (ret != SQLITE_OK) {
762                 ErrPrint("Error: %s\n", sqlite3_errmsg(s_info.handle));
763                 ret = LB_STATUS_ERROR_FAULT;
764                 goto out;
765         }
766
767         ret = 0;
768         while (sqlite3_step(stmt) == SQLITE_ROW) {
769                 lbid = (char *)sqlite3_column_text(stmt, 0);
770                 if (!lbid || !strlen(lbid)) {
771                         continue;
772                 }
773
774                 prime = sqlite3_column_int(stmt, 1);
775
776                 if (cb(pkgid, lbid, prime, data) < 0) {
777                         DbgPrint("Callback canceled\n");
778                         break;
779                 }
780
781                 ret++;
782         }
783 out:
784         sqlite3_reset(stmt);
785         sqlite3_finalize(stmt);
786         return ret;
787 }
788
789 HAPI int io_load_package_db(struct pkg_info *info)
790 {
791         int ret;
792
793         if (!s_info.handle) {
794                 ErrPrint("DB is not ready\n");
795                 return LB_STATUS_ERROR_IO;
796         }
797
798         ret = build_provider_info(info);
799         if (ret < 0) {
800                 return ret;
801         }
802
803         ret = build_client_info(info);
804         if (ret < 0) {
805                 return ret;
806         }
807
808         ret = build_box_size_info(info);
809         if (ret < 0) {
810                 return ret;
811         }
812
813         ret = build_group_info(info);
814         if (ret < 0) {
815                 return ret;
816         }
817
818         return LB_STATUS_SUCCESS;
819 }
820
821 static inline int db_init(void)
822 {
823         int ret;
824         struct stat stat;
825
826         ret = db_util_open_with_options(DBFILE, &s_info.handle, SQLITE_OPEN_READONLY, NULL);
827         if (ret != SQLITE_OK) {
828                 ErrPrint("Failed to open a DB\n");
829                 return LB_STATUS_ERROR_IO;
830         }
831
832         if (lstat(DBFILE, &stat) < 0) {
833                 db_util_close(s_info.handle);
834                 s_info.handle = NULL;
835                 ErrPrint("%s\n", strerror(errno));
836                 return LB_STATUS_ERROR_IO;
837         }
838
839         if (!S_ISREG(stat.st_mode)) {
840                 ErrPrint("Invalid file\n");
841                 db_util_close(s_info.handle);
842                 s_info.handle = NULL;
843                 return LB_STATUS_ERROR_INVALID;
844         }
845
846         if (stat.st_size <= 0) {
847                 DbgPrint("Size is %d (But use this ;)\n", stat.st_size);
848         }
849
850         return LB_STATUS_SUCCESS;
851 }
852
853 static inline int db_fini(void)
854 {
855         if (!s_info.handle) {
856                 return LB_STATUS_SUCCESS;
857         }
858
859         db_util_close(s_info.handle);
860         s_info.handle = NULL;
861
862         return LB_STATUS_SUCCESS;
863 }
864
865 HAPI int io_init(void)
866 {
867         int ret;
868
869         ret = db_init();
870         DbgPrint("DB initialized: %d\n", ret);
871
872         ret = load_abi_table();
873         DbgPrint("ABI table is loaded: %d\n", ret);
874
875         return LB_STATUS_SUCCESS;
876 }
877
878 HAPI int io_fini(void)
879 {
880         int ret;
881
882         abi_del_all();
883
884         ret = db_fini();
885         DbgPrint("DB finalized: %d\n", ret);
886         return LB_STATUS_SUCCESS;
887 }
888
889 /* End of a file */