Add changed callback call logic when register service
[platform/core/appfw/badge.git] / src / badge_internal.c
1 /*
2  *  libbadge
3  *
4  * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngjoo Park <yjoo93.park@samsung.com>,
7  *      Seungtaek Chung <seungtaek.chung@samsung.com>, Youngsub Ko <ys4610.ko@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the License);
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an AS IS BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include <string.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <glib.h>
29 #include <dbus/dbus.h>
30 #include <dbus/dbus-glib-lowlevel.h>
31 #include <aul.h>
32 #include <sqlite3.h>
33 #include <db-util.h>
34 #include <package_manager.h>
35 #include <tzplatform_config.h>
36
37 #include "badge_log.h"
38 #include "badge_error.h"
39 #include "badge_internal.h"
40 #include "badge_ipc.h"
41 #include "badge_db.h"
42
43 #define BADGE_DB_PATH tzplatform_mkpath(TZ_SYS_DB, ".badge.db")
44
45 #define BADGE_PKGNAME_LEN 512
46 #define BADGE_TABLE_NAME "badge_data"
47 #define BADGE_OPTION_TABLE_NAME "badge_option"
48
49 #define BADGE_CHANGED_NOTI      "badge_changed"
50
51 struct _badge_h {
52         char *pkgname;
53         char *writable_pkgs;
54 };
55
56 struct _badge_cb_data {
57         badge_change_cb callback;
58         void *data;
59 };
60
61 static GList *g_badge_cb_list;
62
63 static inline long _get_max_len(void)
64 {
65         long max = 0;
66         long path_max_len = 4096;
67
68 #ifdef _PC_PATH_MAX
69         max = (pathconf("/", _PC_PATH_MAX) < 1 ? path_max_len
70                                 : pathconf("/", _PC_PATH_MAX));
71 #else /* _PC_PATH_MAX */
72         max = path_max_len;
73 #endif /* _PC_PATH_MAX */
74         return max;
75 }
76
77 char *_badge_get_pkgname_by_pid(void)
78 {
79         char *pkgname = NULL;
80         int pid = 0;
81         int ret = AUL_R_OK;
82         int fd = 0;
83         long max = 0;
84
85         pid = getpid();
86         max = _get_max_len();
87         pkgname = malloc(max);
88         if (!pkgname) {
89                 ERR("fail to alloc memory");
90                 return NULL;
91         }
92         memset(pkgname, 0x00, max);
93
94         ret = aul_app_get_pkgname_bypid(pid, pkgname, max);
95         if (ret != AUL_R_OK) {
96                 fd = open("/proc/self/cmdline", O_RDONLY);
97                 if (fd < 0) {
98                         free(pkgname);
99                         return NULL;
100                 }
101
102                 ret = read(fd, pkgname, max - 1);
103                 if (ret <= 0) {
104                         close(fd);
105                         free(pkgname);
106                         return NULL;
107                 }
108
109                 close(fd);
110         }
111
112         if (pkgname[0] == '\0') {
113                 free(pkgname);
114                 return NULL;
115         } else
116                 return pkgname;
117 }
118
119 static int _badge_check_data_inserted(const char *pkgname,
120                                         sqlite3 *db)
121 {
122         sqlite3_stmt *stmt = NULL;
123         int count = 0;
124         int result = BADGE_ERROR_NONE;
125         char *sqlbuf = NULL;
126         int sqlret;
127
128         if (!pkgname)
129                 return BADGE_ERROR_INVALID_PARAMETER;
130
131         if (!db)
132                 return BADGE_ERROR_INVALID_PARAMETER;
133
134         sqlbuf = sqlite3_mprintf("SELECT count(*) FROM %q WHERE " \
135                          "pkgname = %Q",
136                          BADGE_TABLE_NAME, pkgname);
137
138         if (!sqlbuf) {
139                 ERR("fail to alloc sql query");
140                 return BADGE_ERROR_OUT_OF_MEMORY;
141         }
142
143         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
144         if (sqlret != SQLITE_OK) {
145                 ERR("DB err [%s]", sqlite3_errmsg(db));
146                 ERR("query[%s]", sqlbuf);
147                 result = BADGE_ERROR_FROM_DB;
148                 goto free_and_return;
149         }
150
151         sqlret = sqlite3_step(stmt);
152         if (sqlret == SQLITE_ROW)
153                 count = sqlite3_column_int(stmt, 0);
154         else
155                 count = 0;
156
157         DBG("[%s], count[%d]", sqlbuf, count);
158
159         if (count > 0)
160                 result = BADGE_ERROR_ALREADY_EXIST;
161         else
162                 result = BADGE_ERROR_NOT_EXIST;
163
164 free_and_return:
165         if (sqlbuf)
166                 sqlite3_free(sqlbuf);
167
168         if (stmt)
169                 sqlite3_finalize(stmt);
170
171         return result;
172 }
173
174 static int _badge_check_option_inserted(const char *pkgname,
175                                         sqlite3 *db)
176 {
177         sqlite3_stmt *stmt = NULL;
178         int count = 0;
179         int result = BADGE_ERROR_NONE;
180         char *sqlbuf = NULL;
181         int sqlret;
182
183         if (!pkgname)
184                 return BADGE_ERROR_INVALID_PARAMETER;
185
186         if (!db)
187                 return BADGE_ERROR_INVALID_PARAMETER;
188
189         sqlbuf = sqlite3_mprintf("SELECT count(*) FROM %q WHERE " \
190                          "pkgname = %Q",
191                          BADGE_OPTION_TABLE_NAME, pkgname);
192
193         if (!sqlbuf) {
194                 ERR("fail to alloc sql query");
195                 return BADGE_ERROR_OUT_OF_MEMORY;
196         }
197
198         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
199         if (sqlret != SQLITE_OK) {
200                 ERR("DB err [%s]", sqlite3_errmsg(db));
201                 ERR("query[%s]", sqlbuf);
202                 result = BADGE_ERROR_FROM_DB;
203                 goto free_and_return;
204         }
205
206         sqlret = sqlite3_step(stmt);
207         if (sqlret == SQLITE_ROW)
208                 count = sqlite3_column_int(stmt, 0);
209         else
210                 count = 0;
211
212         DBG("[%s], count[%d]", sqlbuf, count);
213
214         if (count > 0)
215                 result = BADGE_ERROR_ALREADY_EXIST;
216         else
217                 result = BADGE_ERROR_NOT_EXIST;
218
219 free_and_return:
220         if (sqlbuf)
221                 sqlite3_free(sqlbuf);
222
223         if (stmt)
224                 sqlite3_finalize(stmt);
225
226         return result;
227 }
228
229 static int _is_same_certinfo(const char *caller, const char *pkgname)
230 {
231         int ret = PACKAGE_MANAGER_ERROR_NONE;
232         package_manager_compare_result_type_e compare_result = PACKAGE_MANAGER_COMPARE_MISMATCH;
233
234         if (!caller)
235                 return 0;
236
237         if (!pkgname)
238                 return 0;
239
240         ret = package_manager_compare_package_cert_info(pkgname, caller, &compare_result);
241         if (ret == PACKAGE_MANAGER_ERROR_NONE &&
242                 compare_result == PACKAGE_MANAGER_COMPARE_MATCH)
243                 return 1;
244
245         return 0;
246 }
247
248 static int _badge_check_writable(const char *caller,
249                         const char *pkgname, sqlite3 *db)
250 {
251         sqlite3_stmt *stmt = NULL;
252         int count = 0;
253         int result = BADGE_ERROR_NONE;
254         char *sqlbuf = NULL;
255         int sqlret;
256
257         if (!db)
258                 return BADGE_ERROR_INVALID_PARAMETER;
259
260         if (!caller)
261                 return BADGE_ERROR_INVALID_PARAMETER;
262
263         if (!pkgname)
264                 return BADGE_ERROR_INVALID_PARAMETER;
265
266         if (g_strcmp0(caller, pkgname) == 0)
267                 return BADGE_ERROR_NONE;
268
269         if (_is_same_certinfo(caller, pkgname) == 1)
270                 return BADGE_ERROR_NONE;
271
272         sqlbuf = sqlite3_mprintf("SELECT COUNT(*) FROM %q WHERE " \
273                          "pkgname = %Q AND writable_pkgs LIKE '%%%q%%'",
274                          BADGE_TABLE_NAME,
275                          pkgname, caller);
276         if (!sqlbuf) {
277                 ERR("fail to alloc sql query");
278                 return BADGE_ERROR_OUT_OF_MEMORY;
279         }
280
281         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
282         if (sqlret != SQLITE_OK) {
283                 ERR("DB err [%s]", sqlite3_errmsg(db));
284                 ERR("query[%s]", sqlbuf);
285                 result = BADGE_ERROR_FROM_DB;
286                 goto free_and_return;
287         }
288
289         sqlret = sqlite3_step(stmt);
290         if (sqlret == SQLITE_ROW)
291                 count = sqlite3_column_int(stmt, 0);
292         else
293                 count = 0;
294
295         DBG("[%s], count[%d]", sqlbuf, count);
296
297         if (count <= 0)
298                 result = BADGE_ERROR_PERMISSION_DENIED;
299
300 free_and_return:
301         if (sqlbuf)
302                 sqlite3_free(sqlbuf);
303
304         if (stmt)
305                 sqlite3_finalize(stmt);
306
307         return result;
308 }
309
310
311 int _badge_is_existing(const char *pkgname, bool *existing)
312 {
313         sqlite3 *db = NULL;
314         int sqlret;
315         int result = BADGE_ERROR_NONE;
316
317         if (!pkgname || !existing) {
318                 ERR("pkgname : %s, existing : %p", pkgname, existing);
319                 return BADGE_ERROR_INVALID_PARAMETER;
320         }
321
322         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
323         if (sqlret != SQLITE_OK || !db) {
324                 ERR("fail to db_util_open - [%d]", sqlret);
325                 if (sqlret == SQLITE_PERM)
326                         return BADGE_ERROR_PERMISSION_DENIED;
327                 return BADGE_ERROR_FROM_DB;
328         }
329
330         result = _badge_check_data_inserted(pkgname, db);
331         if (result == BADGE_ERROR_ALREADY_EXIST) {
332                 *existing = TRUE;
333                 result = BADGE_ERROR_NONE;
334         } else if (result == BADGE_ERROR_NOT_EXIST) {
335                 *existing = FALSE;
336                 result = BADGE_ERROR_NONE;
337         }
338
339         sqlret = db_util_close(db);
340         if (sqlret != SQLITE_OK)
341                 WARN("fail to db_util_close - [%d]", sqlret);
342
343         return result;
344 }
345
346 int _badge_foreach_existed(badge_foreach_cb callback, void *data)
347 {
348         sqlite3 *db = NULL;
349         int result = BADGE_ERROR_NONE;
350         char *sqlbuf = NULL;
351         sqlite3_stmt *stmt = NULL;
352         int sqlret;
353         const char *pkg;
354         unsigned int badge_count;
355
356         if (!callback)
357                 return BADGE_ERROR_INVALID_PARAMETER;
358
359         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
360         if (sqlret != SQLITE_OK || !db) {
361                 ERR("fail to db_util_open - [%d]", sqlret);
362                 return BADGE_ERROR_FROM_DB;
363         }
364
365         sqlbuf = sqlite3_mprintf("SELECT pkgname, badge FROM %q",
366                                 BADGE_TABLE_NAME);
367         if (!sqlbuf) {
368                 ERR("fail to alloc sql query");
369                 result = BADGE_ERROR_OUT_OF_MEMORY;
370                 goto free_and_return;
371         }
372
373         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
374         if (sqlret != SQLITE_OK) {
375                 ERR("fail to sqlite3_prepare_v2 - [%s]", sqlite3_errmsg(db));
376                 ERR("query[%s]", sqlbuf);
377                 result = BADGE_ERROR_FROM_DB;
378                 goto free_and_return;
379         }
380
381         sqlret = sqlite3_step(stmt);
382         if (sqlret == SQLITE_DONE) {
383                 INFO("badge db has no data");
384                 result = BADGE_ERROR_NOT_EXIST;
385                 goto free_and_return;
386         } else if (sqlret == SQLITE_ROW) {
387                 pkg = (const char *)sqlite3_column_text(stmt, 0);
388                 badge_count = (unsigned int)sqlite3_column_int(stmt, 1);
389
390                 if (pkg)
391                         callback(pkg, badge_count, data);
392                 else
393                         ERR("db has invaild data");
394         } else {
395                 ERR("fail to sqlite3_step : %d", sqlret);
396                 result = BADGE_ERROR_FROM_DB;
397                 goto free_and_return;
398         }
399
400         while (sqlite3_step(stmt) == SQLITE_ROW) {
401                 pkg = (const char *)sqlite3_column_text(stmt, 0);
402                 badge_count = (unsigned int)sqlite3_column_int(stmt, 1);
403
404                 if (pkg)
405                         callback(pkg, badge_count, data);
406                 else
407                         ERR("db has invaild data");
408         }
409
410 free_and_return:
411         if (sqlbuf)
412                 sqlite3_free(sqlbuf);
413
414         if (stmt)
415                 sqlite3_finalize(stmt);
416
417         sqlret = db_util_close(db);
418         if (sqlret != SQLITE_OK)
419                 WARN("fail to db_util_close - [%d]", sqlret);
420
421         return result;
422 }
423
424 int _badge_insert(badge_h *badge)
425 {
426         sqlite3 *db = NULL;
427         int sqlret;
428         int ret = BADGE_ERROR_NONE;
429         int result = BADGE_ERROR_NONE;
430         char *sqlbuf = NULL;
431
432         if (!badge || !badge->pkgname || !badge->writable_pkgs)
433                 return BADGE_ERROR_INVALID_PARAMETER;
434
435         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
436         if (sqlret != SQLITE_OK || !db) {
437                 ERR("fail to db_util_open - [%s][%d]", BADGE_DB_PATH, sqlret);
438                 return BADGE_ERROR_FROM_DB;
439         }
440
441         /* Check pkgname & id */
442         ret = _badge_check_data_inserted(badge->pkgname, db);
443         if (ret != BADGE_ERROR_NOT_EXIST) {
444                 result = ret;
445                 goto return_close_db;
446         }
447
448         sqlbuf = sqlite3_mprintf("INSERT INTO %q " \
449                         "(pkgname, " \
450                         "writable_pkgs) " \
451                         "VALUES "
452                         "(%Q, %Q);",
453                          BADGE_TABLE_NAME,
454                          badge->pkgname, badge->writable_pkgs);
455         if (!sqlbuf) {
456                 ERR("fail to alloc query");
457                 result = BADGE_ERROR_OUT_OF_MEMORY;
458                 goto return_close_db;
459         }
460
461         ret = badge_db_exec(db, sqlbuf, NULL);
462         if (ret != BADGE_ERROR_NONE) {
463                 ERR("failed to insert badge[%s], err[%d]",
464                                         badge->pkgname, ret);
465                 result = ret;
466                 goto return_close_db;
467         }
468
469         /* inserting badge options */
470         ret = _badge_check_option_inserted(badge->pkgname, db);
471         if (ret != BADGE_ERROR_NOT_EXIST) {
472                 result = ret;
473                 goto return_close_db;
474         }
475
476         sqlbuf = sqlite3_mprintf("INSERT INTO %q " \
477                         "(pkgname) " \
478                         "VALUES "
479                         "(%Q);",
480                         BADGE_OPTION_TABLE_NAME,
481                          badge->pkgname);
482         if (!sqlbuf) {
483                 ERR("fail to alloc query");
484                 result = BADGE_ERROR_OUT_OF_MEMORY;
485                 goto return_close_db;
486         }
487
488         ret = badge_db_exec(db, sqlbuf, NULL);
489         if (ret != BADGE_ERROR_NONE) {
490                 ERR("failed to insert badge option[%s], err[%d]",
491                                         badge->pkgname, sqlret);
492                 result = ret;
493                 goto return_close_db;
494         }
495
496 return_close_db:
497         if (sqlbuf)
498                 sqlite3_free(sqlbuf);
499
500         sqlret = db_util_close(db);
501         if (sqlret != SQLITE_OK)
502                 WARN("fail to db_util_close - [%d]", sqlret);
503
504         return result;
505 }
506
507 int _badge_remove(const char *caller, const char *pkgname)
508 {
509         int ret = BADGE_ERROR_NONE;
510         int result = BADGE_ERROR_NONE;
511         sqlite3 *db = NULL;
512         int sqlret;
513         char *sqlbuf = NULL;
514
515         if (!caller)
516                 return BADGE_ERROR_INVALID_PARAMETER;
517
518         if (!pkgname)
519                 return BADGE_ERROR_INVALID_PARAMETER;
520
521         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
522         if (sqlret != SQLITE_OK || !db) {
523                 ERR("fail to db_util_open - [%d]", sqlret);
524                 return BADGE_ERROR_FROM_DB;
525         }
526
527         ret = _badge_check_data_inserted(pkgname, db);
528         if (ret != BADGE_ERROR_ALREADY_EXIST) {
529                 result = ret;
530                 goto return_close_db;
531         }
532
533         ret = _badge_check_writable(caller, pkgname, db);
534         if (ret != BADGE_ERROR_NONE) {
535                 result = ret;
536                 goto return_close_db;
537         }
538
539         sqlbuf = sqlite3_mprintf("DELETE FROM %q WHERE pkgname = %Q",
540                          BADGE_TABLE_NAME, pkgname);
541         if (!sqlbuf) {
542                 ERR("fail to alloc query");
543                 result = BADGE_ERROR_OUT_OF_MEMORY;
544                 goto return_close_db;
545         }
546
547         ret = badge_db_exec(db, sqlbuf, NULL);
548         if (ret != BADGE_ERROR_NONE) {
549                 ERR("failed to remove badge[%s], err[%d]",
550                                 pkgname, ret);
551                 result = ret;
552                 goto return_close_db;
553         }
554
555         /* treating option table */
556         ret = _badge_check_option_inserted(pkgname, db);
557         if (ret != BADGE_ERROR_ALREADY_EXIST) {
558                 result = ret;
559                 goto return_close_db;
560         }
561
562         sqlbuf = sqlite3_mprintf("DELETE FROM %q WHERE pkgname = %Q",
563                         BADGE_OPTION_TABLE_NAME, pkgname);
564         if (!sqlbuf) {
565                 ERR("fail to alloc query");
566                 result = BADGE_ERROR_OUT_OF_MEMORY;
567                 goto return_close_db;
568         }
569
570         ret = badge_db_exec(db, sqlbuf, NULL);
571         if (ret != BADGE_ERROR_NONE) {
572                 ERR("failed to remove badge option[%s], err[%d]",
573                                 pkgname, ret);
574                 result = ret;
575                 goto return_close_db;
576         }
577
578 return_close_db:
579         if (sqlbuf)
580                 sqlite3_free(sqlbuf);
581
582         sqlret = db_util_close(db);
583         if (sqlret != SQLITE_OK)
584                 WARN("fail to db_util_close - [%d]", sqlret);
585
586         return result;
587 }
588
589 int _badget_set_count(const char *caller, const char *pkgname,
590                         unsigned int count)
591 {
592         int ret = BADGE_ERROR_NONE;
593         int result = BADGE_ERROR_NONE;
594         sqlite3 *db = NULL;
595         char *sqlbuf = NULL;
596         int sqlret;
597
598         if (!caller)
599                 return BADGE_ERROR_INVALID_PARAMETER;
600
601         if (!pkgname)
602                 return BADGE_ERROR_INVALID_PARAMETER;
603
604         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
605         if (sqlret != SQLITE_OK || !db) {
606                 ERR("fail to db_util_open - [%d]", sqlret);
607                 return BADGE_ERROR_FROM_DB;
608         }
609
610         ret = _badge_check_data_inserted(pkgname, db);
611         if (ret != BADGE_ERROR_ALREADY_EXIST) {
612                 result = ret;
613                 goto return_close_db;
614         }
615
616         ret = _badge_check_writable(caller, pkgname, db);
617         if (ret != BADGE_ERROR_NONE) {
618                 result = ret;
619                 goto return_close_db;
620         }
621
622         sqlbuf = sqlite3_mprintf("UPDATE %q SET badge = %d " \
623                         "WHERE pkgname = %Q",
624                          BADGE_TABLE_NAME, count, pkgname);
625         if (!sqlbuf) {
626                 ERR("fail to alloc query");
627                 result = BADGE_ERROR_OUT_OF_MEMORY;
628                 goto return_close_db;
629         }
630
631         ret = badge_db_exec(db, sqlbuf, NULL);
632         if (ret != BADGE_ERROR_NONE) {
633                 ERR("failed to set badge[%s] count[%d], err[%d]",
634                                 pkgname, count, ret);
635                 result = ret;
636                 goto return_close_db;
637         }
638
639 return_close_db:
640         if (sqlbuf)
641                 sqlite3_free(sqlbuf);
642
643         sqlret = db_util_close(db);
644         if (sqlret != SQLITE_OK)
645                 WARN("fail to db_util_close - [%d]", sqlret);
646
647         return result;
648 }
649
650 int _badget_get_count(const char *pkgname, unsigned int *count)
651 {
652         int ret = BADGE_ERROR_NONE;
653         int result = BADGE_ERROR_NONE;
654         sqlite3 *db = NULL;
655         char *sqlbuf = NULL;
656         sqlite3_stmt *stmt = NULL;
657         int sqlret;
658
659         if (!pkgname)
660                 return BADGE_ERROR_INVALID_PARAMETER;
661
662         if (!count)
663                 return BADGE_ERROR_INVALID_PARAMETER;
664
665         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
666         if (sqlret != SQLITE_OK || !db) {
667                 ERR("fail to db_util_open - [%d]", sqlret);
668                 if (sqlret == SQLITE_PERM)
669                         return BADGE_ERROR_PERMISSION_DENIED;
670                 else
671                         return BADGE_ERROR_FROM_DB;
672         }
673
674         ret = _badge_check_data_inserted(pkgname, db);
675         if (ret != BADGE_ERROR_ALREADY_EXIST) {
676                 result = ret;
677                 goto return_close_db;
678         }
679
680         sqlbuf = sqlite3_mprintf("SELECT badge FROM %q " \
681                         "WHERE pkgname = %Q",
682                          BADGE_TABLE_NAME, pkgname);
683         if (!sqlbuf) {
684                 ERR("fail to alloc query");
685                 result = BADGE_ERROR_OUT_OF_MEMORY;
686                 goto return_close_db;
687         }
688
689         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
690         if (sqlret != SQLITE_OK) {
691                 ERR("fail to prepare %s - [%s]",
692                                 sqlbuf, sqlite3_errmsg(db));
693                 result = BADGE_ERROR_FROM_DB;
694                 goto return_close_db;
695         }
696
697         sqlret = sqlite3_step(stmt);
698         if (sqlret == SQLITE_ROW)
699                 *count = (unsigned int)sqlite3_column_int(stmt, 0);
700         else
701                 *count = (unsigned int)0;
702
703 return_close_db:
704         if (sqlbuf)
705                 sqlite3_free(sqlbuf);
706
707         if (stmt)
708                 sqlite3_finalize(stmt);
709
710         sqlret = db_util_close(db);
711         if (sqlret != SQLITE_OK)
712                 WARN("fail to db_util_close - [%d]", sqlret);
713
714         return result;
715 }
716
717 int _badget_set_display(const char *pkgname,
718                         unsigned int is_display)
719 {
720         int ret = BADGE_ERROR_NONE;
721         int result = BADGE_ERROR_NONE;
722         sqlite3 *db = NULL;
723         char *sqlbuf = NULL;
724         int sqlret;
725
726         if (!pkgname)
727                 return BADGE_ERROR_INVALID_PARAMETER;
728
729         if (is_display != 0 && is_display != 1)
730                 return BADGE_ERROR_INVALID_PARAMETER;
731
732         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
733         if (sqlret != SQLITE_OK || !db) {
734                 ERR("fail to db_util_open - [%d]", sqlret);
735                 return BADGE_ERROR_FROM_DB;
736         }
737
738         ret = _badge_check_data_inserted(pkgname, db);
739         if (ret != BADGE_ERROR_ALREADY_EXIST) {
740                 result = ret;
741                 goto return_close_db;
742         }
743
744         ret = _badge_check_option_inserted(pkgname, db);
745         if (ret == BADGE_ERROR_ALREADY_EXIST) {
746                 sqlbuf = sqlite3_mprintf("UPDATE %q SET display = %d " \
747                                 "WHERE pkgname = %Q",
748                                 BADGE_OPTION_TABLE_NAME, is_display, pkgname);
749                 if (!sqlbuf) {
750                         ERR("fail to alloc query");
751                         result = BADGE_ERROR_OUT_OF_MEMORY;
752                         goto return_close_db;
753                 }
754
755                 ret = badge_db_exec(db, sqlbuf, NULL);
756                 if (ret != BADGE_ERROR_NONE) {
757                         ERR("failed to set badge[%s] option[%d], err[%d]",
758                                         pkgname, is_display, ret);
759                         result = ret;
760                         goto return_close_db;
761                 }
762
763         } else if (ret == BADGE_ERROR_NOT_EXIST) {
764                 sqlbuf = sqlite3_mprintf("INSERT INTO %q " \
765                                 "(pkgname, " \
766                                 "display) " \
767                                 "VALUES "
768                                 "(%Q, %d);",
769                                 BADGE_OPTION_TABLE_NAME,
770                                 pkgname, is_display);
771                 if (!sqlbuf) {
772                         ERR("fail to alloc query");
773                         result = BADGE_ERROR_OUT_OF_MEMORY;
774                         goto return_close_db;
775                 }
776
777                 ret = badge_db_exec(db, sqlbuf, NULL);
778                 if (ret != BADGE_ERROR_NONE) {
779                         ERR("failed to set badge[%s] option[%d], err[%d]",
780                                         pkgname, is_display, ret);
781                         result = ret;
782                         goto return_close_db;
783                 }
784         } else {
785                 result = ret;
786                 goto return_close_db;
787         }
788
789 return_close_db:
790         if (sqlbuf)
791                 sqlite3_free(sqlbuf);
792
793         sqlret = db_util_close(db);
794         if (sqlret != SQLITE_OK)
795                 WARN("fail to db_util_close - [%d]", sqlret);
796
797         return result;
798 }
799
800 int _badget_get_display(const char *pkgname, unsigned int *is_display)
801 {
802         int ret = BADGE_ERROR_NONE;
803         int result = BADGE_ERROR_NONE;
804         sqlite3 *db = NULL;
805         char *sqlbuf = NULL;
806         sqlite3_stmt *stmt = NULL;
807         int sqlret;
808
809         if (!pkgname)
810                 return BADGE_ERROR_INVALID_PARAMETER;
811
812         if (!is_display)
813                 return BADGE_ERROR_INVALID_PARAMETER;
814
815         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
816         if (sqlret != SQLITE_OK || !db) {
817                 ERR("fail to db_util_open - [%d]", sqlret);
818                 if (sqlret == SQLITE_PERM)
819                         return BADGE_ERROR_PERMISSION_DENIED;
820                 else
821                         return BADGE_ERROR_FROM_DB;
822         }
823
824         ret = _badge_check_option_inserted(pkgname, db);
825         if (ret != BADGE_ERROR_ALREADY_EXIST) {
826                 if (ret == BADGE_ERROR_NOT_EXIST)
827                         *is_display = 1;
828
829                 result = ret;
830                 goto return_close_db;
831         }
832
833         sqlbuf = sqlite3_mprintf("SELECT display FROM %q " \
834                         "WHERE pkgname = %Q",
835                         BADGE_OPTION_TABLE_NAME, pkgname);
836         if (!sqlbuf) {
837                 ERR("fail to alloc query");
838                 result = BADGE_ERROR_OUT_OF_MEMORY;
839                 goto return_close_db;
840         }
841
842         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
843         if (sqlret != SQLITE_OK) {
844                 ERR("fail to prepare %s - [%s]",
845                                 sqlbuf, sqlite3_errmsg(db));
846                 result = BADGE_ERROR_FROM_DB;
847                 goto return_close_db;
848         }
849
850         sqlret = sqlite3_step(stmt);
851         if (sqlret == SQLITE_ROW)
852                 *is_display = (unsigned int)sqlite3_column_int(stmt, 0);
853         else
854                 *is_display = (unsigned int)1;
855
856 return_close_db:
857         if (sqlbuf)
858                 sqlite3_free(sqlbuf);
859
860         if (stmt)
861                 sqlite3_finalize(stmt);
862
863         sqlret = db_util_close(db);
864         if (sqlret != SQLITE_OK)
865                 WARN("fail to db_util_close - [%d]", sqlret);
866
867         return result;
868 }
869
870 void badge_changed_cb_call(unsigned int action, const char *pkgname,
871                         unsigned int count)
872 {
873         DBG("call badge_change_cb");
874         GList *list = g_badge_cb_list;
875         struct _badge_cb_data *bd = NULL;
876
877         while (list) {
878                 bd = g_list_nth_data(list, 0);
879                 if (!bd)
880                         continue;
881
882                 if (bd->callback) {
883                         DBG("call badge_change_cb : action %d, pkgname %s, count %d",
884                                         action, pkgname, count);
885                         bd->callback(action, pkgname, count, bd->data);
886                 }
887
888                 list = g_list_next(list);
889         }
890 }
891
892 static int _badge_changed_monitor_init()
893 {
894         return badge_ipc_monitor_init();
895 }
896
897 static void _badge_chanaged_monitor_fini()
898 {
899         badge_ipc_monitor_fini();
900 }
901
902 static gint _badge_data_compare(gconstpointer a, gconstpointer b)
903 {
904         const struct _badge_cb_data *bd = NULL;
905
906         if (!a)
907                 return -1;
908         bd = a;
909
910         if (bd->callback == b)
911                 return 0;
912
913         return 1;
914 }
915
916 int _badge_register_changed_cb(badge_change_cb callback, void *data)
917 {
918         struct _badge_cb_data *bd = NULL;
919         GList *found = NULL;
920         int ret;
921
922         if (!callback)
923                 return BADGE_ERROR_INVALID_PARAMETER;
924
925         found = g_list_find_custom(g_badge_cb_list, (gconstpointer)callback,
926                         _badge_data_compare);
927
928         if (found) {
929                 bd = g_list_nth_data(found, 0);
930                 bd->data = data;
931         } else {
932
933                 bd = malloc(sizeof(struct _badge_cb_data));
934                 if (!bd)
935                         return BADGE_ERROR_OUT_OF_MEMORY;
936
937
938                 bd->callback = callback;
939                 bd->data = data;
940
941                 g_badge_cb_list = g_list_append(g_badge_cb_list, bd);
942         }
943
944         ret = _badge_changed_monitor_init();
945         if (ret != BADGE_ERROR_NONE) {
946                 ERR("badge_ipc_monitor_init err : %d", ret);
947                 _badge_unregister_changed_cb(callback);
948                 return ret;
949         }
950         return BADGE_ERROR_NONE;
951 }
952
953 int _badge_unregister_changed_cb(badge_change_cb callback)
954 {
955         GList *found = NULL;
956         struct _badge_cb_data *bd = NULL;
957
958         if (!callback)
959                 return BADGE_ERROR_INVALID_PARAMETER;
960
961         found = g_list_find_custom(g_badge_cb_list, (gconstpointer)callback,
962                                 _badge_data_compare);
963
964         if (found) {
965                 bd = g_list_nth_data(found, 0);
966                 g_badge_cb_list = g_list_delete_link(g_badge_cb_list, found);
967                 free(bd);
968         }
969
970         if (!g_badge_cb_list)
971                 _badge_chanaged_monitor_fini();
972
973         if (found != NULL)
974                 return BADGE_ERROR_NONE;
975         else
976                 return BADGE_ERROR_INVALID_PARAMETER;
977
978 }
979
980 int _badge_free(badge_h *badge)
981 {
982         if (!badge)
983                 return BADGE_ERROR_INVALID_PARAMETER;
984
985         if (badge->pkgname)
986                 free(badge->pkgname);
987
988         if (badge->writable_pkgs)
989                 free(badge->writable_pkgs);
990
991         free(badge);
992
993         return BADGE_ERROR_NONE;
994 }
995
996 badge_h *_badge_new(const char *pkgname, const char *writable_pkgs,
997                 int *err)
998 {
999         badge_h *badge = NULL;
1000
1001         if (!pkgname) {
1002                 ERR("PKGNAME is NULL");
1003                 if (err)
1004                         *err = BADGE_ERROR_INVALID_PARAMETER;
1005                 return NULL;
1006         }
1007
1008         if (!writable_pkgs) {
1009                 ERR("writable_pkgs is NULL");
1010                 if (err)
1011                         *err = BADGE_ERROR_INVALID_PARAMETER;
1012                 return NULL;
1013         }
1014
1015
1016         badge = (badge_h *)malloc(sizeof(struct _badge_h));
1017         if (!badge) {
1018                 ERR("fail to alloc handle");
1019                 if (err)
1020                         *err = BADGE_ERROR_OUT_OF_MEMORY;
1021                 return NULL;
1022         }
1023
1024         badge->pkgname = strdup(pkgname);
1025         badge->writable_pkgs = strdup(writable_pkgs);
1026         if (err)
1027                 *err = BADGE_ERROR_NONE;
1028
1029         return badge;
1030 }
1031
1032 char *_badge_pkgs_new(int *err, const char *pkg1, ...)
1033 {
1034         char *caller_pkgname = NULL;
1035         char *s = NULL;
1036         char *result = NULL;
1037         char *ptr = NULL;
1038         gsize length;
1039         va_list args;
1040         char *new_pkgs = NULL;
1041
1042
1043         if (err)
1044                 *err = BADGE_ERROR_NONE;
1045
1046         caller_pkgname = _badge_get_pkgname_by_pid();
1047         if (!caller_pkgname) {
1048                 ERR("fail to get caller pkgname");
1049                 if (err)
1050                         *err = BADGE_ERROR_PERMISSION_DENIED;
1051                 return NULL;
1052         }
1053
1054         if (!pkg1) {
1055                 WARN("pkg1 is NULL");
1056                 return caller_pkgname;
1057         }
1058
1059         length = strlen(pkg1);
1060         va_start(args, pkg1);
1061         s = va_arg(args, char *);
1062         while (s) {
1063                 length += strlen(s) ;
1064                 s = va_arg(args, char *);
1065         }
1066         va_end(args);
1067
1068         if (length <= 0) {
1069                 WARN("length is %d", length);
1070                 return caller_pkgname;
1071         }
1072
1073         result = g_new0(char, length + 1); /* 1 for null terminate */
1074         if (!result) {
1075                 ERR("fail to alloc memory");
1076                 if (err)
1077                         *err = BADGE_ERROR_OUT_OF_MEMORY;
1078                 free(caller_pkgname);
1079                 return NULL;
1080         }
1081
1082         ptr = result;
1083         ptr = g_stpcpy(ptr, pkg1);
1084         va_start(args, pkg1);
1085         s = va_arg(args, char *);
1086         while (s) {
1087                 ptr = g_stpcpy(ptr, s);
1088                 s = va_arg(args, char *);
1089         }
1090         va_end(args);
1091
1092         if (g_strstr_len(result, -1, caller_pkgname) == NULL) {
1093                 new_pkgs = g_strdup_printf("%s%s", caller_pkgname, result);
1094                 if (!new_pkgs) {
1095                         ERR("fail to alloc memory");
1096                         if (err)
1097                                 *err = BADGE_ERROR_OUT_OF_MEMORY;
1098
1099                         free(result);
1100                         free(caller_pkgname);
1101                         return NULL;
1102                 }
1103                 free(result);
1104                 result = new_pkgs;
1105         }
1106
1107         free(caller_pkgname);
1108
1109         return result;
1110 }
1111
1112 char *_badge_pkgs_new_valist(int *err, const char *pkg1, va_list args)
1113 {
1114         char *caller_pkgname = NULL;
1115         char *s = NULL;
1116         char *result = NULL;
1117         char *ptr = NULL;
1118         gsize length;
1119         va_list args2;
1120         char *new_pkgs = NULL;
1121
1122         if (err)
1123                 *err = BADGE_ERROR_NONE;
1124
1125         caller_pkgname = _badge_get_pkgname_by_pid();
1126         if (!caller_pkgname) {
1127                 ERR("fail to get caller pkgname");
1128                 if (err)
1129                         *err = BADGE_ERROR_PERMISSION_DENIED;
1130                 return NULL;
1131         }
1132
1133         if (!pkg1) {
1134                 WARN("pkg1 is NULL");
1135                 return caller_pkgname;
1136         }
1137
1138         G_VA_COPY(args2, args);
1139
1140         length = strlen(pkg1);
1141         s = va_arg(args, char *);
1142         while (s) {
1143                 length += strlen(s) ;
1144                 s = va_arg(args, char *);
1145         }
1146
1147         if (length <= 0) {
1148                 WARN("length is %d", length);
1149                 va_end(args2);
1150                 return caller_pkgname;
1151         }
1152
1153         result = g_new0(char, length + 1); /* 1 for null terminate */
1154         if (!result) {
1155                 ERR("fail to alloc memory");
1156                 if (err)
1157                         *err = BADGE_ERROR_OUT_OF_MEMORY;
1158                 free(caller_pkgname);
1159                 va_end(args2);
1160                 return NULL;
1161         }
1162
1163         ptr = result;
1164         ptr = g_stpcpy(ptr, pkg1);
1165         s = va_arg(args2, char *);
1166         while (s) {
1167                 ptr = g_stpcpy(ptr, s);
1168                 s = va_arg(args2, char *);
1169         }
1170         va_end(args2);
1171
1172         if (g_strstr_len(result, -1, caller_pkgname) == NULL) {
1173                 new_pkgs = g_strdup_printf("%s%s", caller_pkgname, result);
1174                 if (!new_pkgs) {
1175                         ERR("fail to alloc memory");
1176                         if (err)
1177                                 *err = BADGE_ERROR_OUT_OF_MEMORY;
1178
1179                         free(result);
1180                         free(caller_pkgname);
1181                         return NULL;
1182                 }
1183                 free(result);
1184                 result = new_pkgs;
1185         }
1186
1187         free(caller_pkgname);
1188
1189         return result;
1190 }
1191