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