Initialize Tizen 2.3
[framework/appfw/aul-1.git] / src / mida.c
1 /*
2  *  aul
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include "mida.h"
27 #include "menu_db_util.h"
28 #include "simple_util.h"
29
30 #define MIDA_DB_PATH    "/opt/dbspace/.mida.db"
31 #define QUERY_MAXLEN    4096
32 #define BUF_MAX_LEN             1024
33
34 #define MIDA_TBL_NAME   "mida"
35 #define MIDA_F_PKGNAME  "pkg_name"
36 #define MIDA_F_MIMETYPE "mime_type"
37
38 #define SVC_TBL_NAME    "svc"
39 #define SVC_F_PKGNAME   "pkg_name"
40 #define SVC_F_SVCNAME   "svc_name"
41
42 #define SYSSVC_TBL_NAME "system_svc"
43 #define SYSSVC_F_SVCNAME "svc_name"
44
45 static sqlite3 *mida_db = NULL;
46
47
48 static int _exec(sqlite3 *db, char *query);
49 static int _init(void);
50 static int __fini(void);
51 static int __delete_all(const char *tbl_name);
52 static int __delete_with_field(const char *tbl_name, const char *f_name,
53                                 const char *val, int equal);
54 static int __count_with_field(const char *tbl_name, const char *f_name,
55                                 const char *val, int equal);
56 static char *__get_with_field(const char *tbl_name, const char *get_f_name, 
57                                 const char *f_name, const char *val, int equal);
58 static int __doubt_sql_injection(const char *str);
59
60
61
62 /**
63  * exec  
64  * param[in] db handler
65  * param[in] query query
66  * return This method returns 0 (SUCCESS) or -1 (FAIL)
67  */
68 static int _exec(sqlite3 *db, char *query)
69 {
70         int rc = 0;
71         char *errmsg = NULL;
72
73         retvm_if(db == NULL, -1, "DB handler is null");
74
75         rc = sqlite3_exec(db, query, NULL, 0, &errmsg);
76
77         if (rc != SQLITE_OK) {
78                 _D("Query: [%s]", query);
79                 _E("SQL error: %s\n", errmsg);
80                 sqlite3_free(errmsg);
81                 return (-1);
82         }
83
84         return 0;
85 }
86
87 /**
88  * db initialize
89  */
90 static int _init(void)
91 {
92         int rc;
93
94         if (mida_db) {
95                 _D("Already initialized\n");
96                 return 0;
97         }
98
99         rc = sqlite3_open(MIDA_DB_PATH, &mida_db);
100         if (rc) {
101                 _E("Can't open database: %s", sqlite3_errmsg(mida_db));
102                 goto err;
103         }
104         /* Enable persist journal mode */
105         rc = sqlite3_exec(mida_db, "PRAGMA journal_mode = PERSIST", NULL, NULL,
106                           NULL);
107         if (SQLITE_OK != rc) {
108                 _D("Fail to change journal mode\n");
109                 goto err;
110         }
111
112         return 0;
113 err:
114         sqlite3_close(mida_db);
115         return -1;
116 }
117
118 static int __fini(void)
119 {
120         if (mida_db) {
121                 sqlite3_close(mida_db);
122                 mida_db = NULL;
123         }
124         return 0;
125 }
126
127 static int __delete_all(const char *tbl_name)
128 {
129         char *_sqlbuf;
130         int rc;
131
132         _sqlbuf = sqlite3_mprintf("DELETE FROM %s;", tbl_name);
133         rc = _exec(mida_db, _sqlbuf);
134         sqlite3_free(_sqlbuf);
135
136         return rc;
137 }
138
139 static int __delete_with_field(const char *tbl_name, const char *f_name,
140                               const char *val, int equal)
141 {
142         char tmp_val[BUF_MAX_LEN];
143         char *_sqlbuf;
144         int rc;
145
146         if (equal) {
147                 _sqlbuf = sqlite3_mprintf("DELETE FROM %s WHERE %s = '%s';",
148                                           tbl_name, f_name, val);
149         } else {
150                 snprintf(tmp_val, BUF_MAX_LEN, "%%%s%%", val);
151                 _sqlbuf = sqlite3_mprintf("DELETE FROM %s WHERE %s like '%s';",
152                                           tbl_name, f_name, tmp_val);
153         }
154
155         rc = _exec(mida_db, _sqlbuf);
156         sqlite3_free(_sqlbuf);
157
158         return rc;
159 }
160
161 static int __count_with_field(const char *tbl_name, const char *f_name,
162                              const char *val, int equal)
163 {
164         char tmp_val[BUF_MAX_LEN];
165         char *_sqlbuf;
166         int rc;
167         char **db_result = NULL;
168         char *db_err = NULL;
169         int nrows = 0;
170         int ncols = 0;
171         int cnt;
172
173         if (equal) {
174                 _sqlbuf = sqlite3_mprintf(
175                                 "SELECT COUNT(*) FROM %s WHERE %s = '%s';",
176                                 tbl_name, f_name, val);
177         } else {
178                 snprintf(tmp_val, BUF_MAX_LEN, "%%%s%%", val);
179                 _sqlbuf = sqlite3_mprintf(
180                 "SELECT COUNT(*) FROM %s WHERE %s like '%s';", tbl_name,
181                 f_name, tmp_val);
182         }
183
184         rc = sqlite3_get_table(mida_db, _sqlbuf, &db_result, &nrows, &ncols,
185                                &db_err);
186         if (rc == -1 || nrows == 0) {
187                 _D("get count = 0 or fail");
188                 sqlite3_free_table(db_result);
189                 sqlite3_free(_sqlbuf);
190                 return 0;
191         } else {
192                 cnt = atoi(db_result[1]);
193                 sqlite3_free_table(db_result);
194                 sqlite3_free(_sqlbuf);
195         }
196
197         return cnt;
198 }
199
200 static char *__get_with_field(const char *tbl_name, const char *get_f_name, 
201                         const char *f_name, const char *val, int equal)
202 {
203         char tmp_val[BUF_MAX_LEN];
204         char *_sqlbuf;
205         sqlite3_stmt *stmt;
206         int ret;
207         char *res = NULL;
208
209         if (equal) {
210                 _sqlbuf = sqlite3_mprintf("SELECT %s FROM %s WHERE %s = ?;",
211                                           get_f_name, tbl_name, f_name);
212
213         } else {
214                 _sqlbuf = sqlite3_mprintf("SELECT %s FROM %s WHERE %s like ?;",
215                                           get_f_name, tbl_name, f_name);
216         }
217         if (_sqlbuf == NULL) {
218                 _D("Failed to print the SQL query\n");
219                 return res;
220         }
221
222         if (sqlite3_prepare_v2(mida_db, _sqlbuf, 
223                                 -1, &stmt, NULL) != SQLITE_OK) {
224                 _D("Failed to prepare the SQL stmt\n");
225                 sqlite3_free(_sqlbuf);
226                 return res;
227         }
228
229         if (equal) {
230                 ret = sqlite3_bind_text(stmt, 1, val, -1, SQLITE_STATIC);
231         } else {
232                 snprintf(tmp_val, BUF_MAX_LEN, "%%%s%%", val);
233                 ret = sqlite3_bind_text(stmt, 1, tmp_val, -1, SQLITE_STATIC);
234         }
235         if (ret != SQLITE_OK) {
236                 _D("Failed to bind %s with SQL stmt\n", val);
237                 goto end;
238         }
239
240         if (sqlite3_step(stmt) == SQLITE_ROW) {
241                 if (sqlite3_column_text(stmt, 0)) {
242                         res = strdup((char *)sqlite3_column_text(stmt, 0));
243                 }
244         }
245
246 end:
247         sqlite3_finalize(stmt);
248         sqlite3_free(_sqlbuf);
249         return res;
250 }
251
252 static int __doubt_sql_injection(const char *str)
253 {
254         char *tmp;
255         char *token;
256         char *saveptr;
257
258         if (str == NULL)
259                 return 1;
260
261         /* check " , ' , ; */
262         tmp = strdup(str);
263         token = strtok_r(tmp, "\"';", &saveptr);
264
265         if (token == NULL)
266                 return 1;
267
268         if (strcmp(str, token) != 0)
269                 return 1;
270
271         free(tmp);
272
273         return 0;
274 }
275
276 int mida_clear(void)
277 {
278         int rc = 0;
279
280         if (_init() < 0)
281                 return -1;
282         rc = __delete_all(MIDA_TBL_NAME);
283         __fini();
284
285         return rc;
286 }
287
288 int mida_delete_with_pkgname(const char *pkg_name)
289 {
290         int rc = 0;
291
292         retvm_if(pkg_name == NULL, -1,
293                  "Invalid argument: data to delete is NULL\n");
294
295         if (_init() < 0)
296                 return -1;
297         rc = __delete_with_field(MIDA_TBL_NAME, MIDA_F_PKGNAME, pkg_name, 1);
298         __fini();
299
300         return rc;
301 }
302
303 int mida_delete_with_mimetype(const char *mime_type)
304 {
305         int rc = 0;
306
307         retvm_if(mime_type == NULL, -1,
308                  "Invalid argument: data to delete is NULL\n");
309
310         if (_init() < 0)
311                 return -1;
312         rc = __delete_with_field(MIDA_TBL_NAME, MIDA_F_MIMETYPE, mime_type, 0);
313         __fini();
314
315         return rc;
316 }
317
318 int mida_add_app(const char *mime_type, const char *pkg_name)
319 {
320         int rc = -1;
321         int cnt = 0;
322         char *_sqlbuf;
323
324         retvm_if(mime_type == NULL, -1, "Mime type is null\n");
325         retvm_if(pkg_name == NULL, -1, "Package name is null\n");
326
327         if (__doubt_sql_injection(mime_type))
328                 return -1;
329
330         if (_init() < 0)
331                 return -1;
332
333         cnt = __count_with_field(MIDA_TBL_NAME, MIDA_F_MIMETYPE, mime_type, 0);
334
335         if (cnt == 0) {
336                 SECURE_LOGD("Inserting (%s, %s)", pkg_name, mime_type);
337                 /* insert */
338                 _sqlbuf = sqlite3_mprintf(
339                             "INSERT INTO %s (%s,%s) values (\"%s\", \"%s\");",
340                             MIDA_TBL_NAME, MIDA_F_PKGNAME, MIDA_F_MIMETYPE, 
341                             pkg_name, mime_type);
342
343                 rc = _exec(mida_db, _sqlbuf);
344                 sqlite3_free(_sqlbuf);
345         } else {
346                 SECURE_LOGD("Setting %s for %s", pkg_name, mime_type);
347                 /* update */
348                 _sqlbuf = sqlite3_mprintf(
349                                     "UPDATE %s SET %s = '%s' where %s = '%s';",
350                                     MIDA_TBL_NAME, MIDA_F_PKGNAME, pkg_name,
351                                     MIDA_F_MIMETYPE, mime_type);
352
353                 rc = _exec(mida_db, _sqlbuf);
354                 sqlite3_free(_sqlbuf);
355         }
356
357         if (rc < 0)
358                 _E("fail to insert or update\n");
359
360         __fini();
361         return rc;
362 }
363
364 char *mida_get_app(const char *mime_type)
365 {
366         char *res = NULL;
367
368         if (mime_type == NULL)
369                 return NULL;
370
371         if (__doubt_sql_injection(mime_type))
372                 return NULL;
373
374         if (_init() < 0)
375                 return NULL;
376         res =
377             __get_with_field(MIDA_TBL_NAME, MIDA_F_PKGNAME, MIDA_F_MIMETYPE,
378                             mime_type, 0);
379         __fini();
380
381         return res;
382 }
383
384 int svc_clear(void)
385 {
386         int rc = 0;
387
388         if (_init() < 0)
389                 return -1;
390         rc = __delete_all(SVC_TBL_NAME);
391         __fini();
392
393         return rc;
394 }
395
396 int svc_delete_with_pkgname(const char *pkg_name)
397 {
398         int rc = 0;
399
400         retvm_if(pkg_name == NULL, -1,
401                  "Invalid argument: data to delete is NULL\n");
402
403         if (_init() < 0)
404                 return -1;
405         rc = __delete_with_field(SVC_TBL_NAME, SVC_F_PKGNAME, pkg_name, 1);
406         __fini();
407
408         return rc;
409 }
410
411 int svc_delete_with_svcname(const char *svc_name)
412 {
413         int rc = 0;
414
415         retvm_if(svc_name == NULL, -1,
416                  "Invalid argument: data to delete is NULL\n");
417
418         if (_init() < 0)
419                 return -1;
420         rc = __delete_with_field(SVC_TBL_NAME, SVC_F_SVCNAME, svc_name, 0);
421         __fini();
422
423         return rc;
424 }
425
426 int svc_add_app(const char *svc_name, const char *pkg_name)
427 {
428         int rc = -1;
429         int cnt = 0;
430         char *_sqlbuf;
431
432         retvm_if(svc_name == NULL, -1, "Service name is null\n");
433         retvm_if(pkg_name == NULL, -1, "Package name is null\n");
434
435         if (__doubt_sql_injection(svc_name))
436                 return -1;
437
438         if (_init() < 0)
439                 return -1;
440
441         cnt = __count_with_field(SVC_TBL_NAME, SVC_F_SVCNAME, svc_name, 0);
442
443         if (cnt == 0) {
444                 /* insert */
445                 SECURE_LOGD("Inserting (%s, %s)", pkg_name, svc_name);
446                 _sqlbuf = sqlite3_mprintf(
447                      "INSERT INTO %s (%s,%s) values (\"%s\", \"%s\");",
448                      SVC_TBL_NAME, SVC_F_PKGNAME, SVC_F_SVCNAME, pkg_name,
449                      svc_name);
450
451                 rc = _exec(mida_db, _sqlbuf);
452                 sqlite3_free(_sqlbuf);
453         } else {
454                 /* update */
455                 SECURE_LOGD("Setting %s for %s", pkg_name, svc_name);
456                 _sqlbuf = sqlite3_mprintf(
457                                     "UPDATE %s SET %s = '%s' where %s = '%s';",
458                                     SVC_TBL_NAME, SVC_F_PKGNAME, pkg_name,
459                                     SVC_F_SVCNAME, svc_name);
460
461                 rc = _exec(mida_db, _sqlbuf);
462                 sqlite3_free(_sqlbuf);
463         }
464
465         if (rc < 0)
466                 _E("fail to insert or update\n");
467
468         __fini();
469         return rc;
470 }
471
472 char *svc_get_app(const char *svc_name)
473 {
474         char *res = NULL;
475
476         if (svc_name == NULL)
477                 return NULL;
478
479         if (__doubt_sql_injection(svc_name))
480                 return NULL;
481
482         if (_init() < 0)
483                 return NULL;
484         res =
485             __get_with_field(SVC_TBL_NAME, SVC_F_PKGNAME, SVC_F_SVCNAME,
486                             svc_name, 0);
487         __fini();
488
489         return res;
490 }
491
492 int is_supported_svc(const char *svc_name)
493 {
494         int rc = 0;
495         int cnt = 0;
496
497         retvm_if(svc_name == NULL, 0, "Service name is null\n");
498
499         if (__doubt_sql_injection(svc_name))
500                 return 0;
501
502         if (_init() < 0)
503                 return 0;
504
505         cnt = __count_with_field(SYSSVC_TBL_NAME, 
506                         SYSSVC_F_SVCNAME, svc_name, 0);
507
508         if (cnt > 0)
509                 rc = 1;
510         else
511                 SECURE_LOGD("%s is not supported.", svc_name);
512
513         __fini();
514         return rc;
515 }
516