4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
32 #include <sys/smack.h>
34 #include "ail_private.h"
37 #define GLOBAL_USER 0 //#define tzplatform_getenv(TZ_GLOBAL) //TODO
39 #define QUERY_ATTACH "attach database '%s' as Global"
40 #define QUERY_CREATE_VIEW_APP "CREATE temp VIEW app_info as select distinct * from (select * from main.app_info m union select * from Global.app_info g)"
42 #define QUERY_CREATE_VIEW_LOCAL "CREATE temp VIEW localname as select distinct * from (select * from main.localname m union select * from Global.localname g)"
44 #define retv_with_dbmsg_if(expr, val) do { \
46 _E("db_info.dbUserro: %s", sqlite3_errmsg(db_info.dbUserro)); \
47 _E("db_info.dbGlobalro: %s", sqlite3_errmsg(db_info.dbGlobalro)); \
48 _E("db_info.dbUserrw: %s", sqlite3_errmsg(db_info.dbUserrw)); \
49 _E("db_info.dbGlobalrw: %s", sqlite3_errmsg(db_info.dbGlobalrw)); \
50 _E("db_info.dbUserro errcode: %d", sqlite3_extended_errcode(db_info.dbUserro)); \
51 _E("db_info.dbGlobalro errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalro)); \
52 _E("db_info.dbUserrw errcode: %d", sqlite3_extended_errcode(db_info.dbUserrw)); \
53 _E("db_info.dbGlobalrw errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalrw)); \
58 static __thread struct {
69 static __thread sqlite3 *dbInit = NULL;
71 static int ail_db_change_perm(const char *db_file)
74 char journal_file[BUFSIZE];
77 struct group *grpinfo = NULL;
78 const char *name = "users";
80 files[0] = (char *)db_file;
81 files[1] = journal_file;
84 retv_if(!db_file, AIL_ERROR_FAIL);
85 if(getuid()) //At this time we should be root to apply this
88 snprintf(journal_file, sizeof(journal_file), "%s%s", db_file, "-journal");
90 for (i = 0; files[i]; i++) {
91 grpinfo = getgrnam(name);
93 _E("getgrnam(users) returns NULL !");
95 // Compare git_t type and not group name
96 ret = chown(files[i], OWNER_ROOT, grpinfo->gr_gid);
98 strerror_r(errno, buf, sizeof(buf));
99 _E("FAIL : chown %s %d.%d, because %s", db_file, OWNER_ROOT, grpinfo->gr_gid, buf);
100 return AIL_ERROR_FAIL;
103 ret = chmod(files[i], S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
105 strerror_r(errno, buf, sizeof(buf));
106 _E("FAIL : chmod %s 0664, because %s", db_file, buf);
107 return AIL_ERROR_FAIL;
114 char* ail_get_icon_path(uid_t uid)
117 struct group *grpinfo = NULL;
119 struct passwd *userinfo = getpwuid(uid);
121 if (uid != GLOBAL_USER) {
123 if (userinfo == NULL) {
124 _E("getpwuid(%d) returns NULL !", uid);
127 grpinfo = getgrnam("users");
128 if (grpinfo == NULL) {
129 _E("getgrnam(users) returns NULL !");
132 // Compare git_t type and not group name
133 if (grpinfo->gr_gid != userinfo->pw_gid) {
134 _E("UID [%d] does not belong to 'users' group!", uid);
137 asprintf(&result, "%s/.applications/icons/", userinfo->pw_dir);
139 result = tzplatform_mkpath(TZ_SYS_RW_ICONS, "/");
140 grpinfo = getgrnam("root");
141 if (grpinfo == NULL) {
142 _E("getgrnam(root) returns NULL !");
145 if (grpinfo->gr_gid != userinfo->pw_gid) {
146 _E("UID [%d] does not belong to 'root' group!", uid);
151 mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
152 ret = chown(result, uid, grpinfo->gr_gid);
155 strerror_r(errno, buf, sizeof(buf));
156 _E("FAIL : chown %s %d.%d, because %s", result, uid, grpinfo->gr_gid, buf);
161 static char* ail_get_app_DB(uid_t uid)
164 char *journal = NULL;
165 struct group *grpinfo = NULL;
167 struct passwd *userinfo = getpwuid(uid);
169 if (uid != GLOBAL_USER) {
171 if (userinfo == NULL) {
172 _E("getpwuid(%d) returns NULL !", uid);
175 grpinfo = getgrnam("users");
176 if (grpinfo == NULL) {
177 _E("getgrnam(users) returns NULL !");
180 // Compare git_t type and not group name
181 if (grpinfo->gr_gid != userinfo->pw_gid) {
182 _E("UID [%d] does not belong to 'users' group!", uid);
185 asprintf(&result, "%s/.applications/dbspace/.app_info.db", userinfo->pw_dir);
186 asprintf(&journal, "%s/.applications/dbspace/.app_info.db-journal", userinfo->pw_dir);
188 grpinfo = getgrnam("root");
189 if (grpinfo == NULL) {
190 _E("getgrnam(root) returns NULL !");
193 if (grpinfo->gr_gid != userinfo->pw_gid) {
194 _E("UID [%d] does not belong to 'root' group!", uid);
197 result = strdup(APP_INFO_DB_FILE);
198 journal = strdup(APP_INFO_DB_FILE_JOURNAL);
200 char *temp = strdup(result);
201 dir = strrchr(temp, '/');
208 if ((uid != GLOBAL_USER)||((uid == GLOBAL_USER)&& (geteuid() == 0 ))) {
210 mkdir(temp, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
211 ret = chown(dir + 1, uid, grpinfo->gr_gid);
214 strerror_r(errno, buf, sizeof(buf));
215 _E("FAIL : chown %s %d.%d, because %s", dir + 1, uid, grpinfo->gr_gid, buf);
222 char* al_get_desktop_path(uid_t uid)
225 struct group *grpinfo = NULL;
227 struct passwd *userinfo = getpwuid(uid);
229 if (uid != GLOBAL_USER) {
231 if (userinfo == NULL) {
232 _E("getpwuid(%d) returns NULL !", uid);
235 grpinfo = getgrnam("users");
236 if (grpinfo == NULL) {
237 _E("getgrnam(users) returns NULL !");
240 // Compare git_t type and not group name
241 if (grpinfo->gr_gid != userinfo->pw_gid) {
242 _E("UID [%d] does not belong to 'users' group!", uid);
245 asprintf(&result, "%s/.applications/desktop/", userinfo->pw_dir);
247 grpinfo = getgrnam("root");
248 if (grpinfo == NULL) {
249 _E("getgrnam(root) returns NULL !");
252 if (grpinfo->gr_gid != userinfo->pw_gid) {
253 _E("UID [%d] does not belong to 'root' group!", uid);
256 result = tzplatform_mkpath(TZ_SYS_RW_DESKTOP_APP, "/");
258 if ((uid != GLOBAL_USER)||((uid == GLOBAL_USER)&& (geteuid() == 0 ))) {
260 mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
261 ret = chown(result, uid, grpinfo->gr_gid);
264 strerror_r(errno, buf, sizeof(buf));
265 _E("FAIL : chown %s %d.%d, because %s", result, uid, grpinfo->gr_gid, buf);
272 static ail_error_e db_do_prepare(sqlite3 *db, const char *query, sqlite3_stmt **stmt)
276 retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
277 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
278 retv_if(!db, AIL_ERROR_DB_FAILED);
280 ret = sqlite3_prepare_v2(db, query, strlen(query), stmt, NULL);
281 if (ret != SQLITE_OK) {
282 _E("%s\n", sqlite3_errmsg(db));
283 return AIL_ERROR_DB_FAILED;
288 ail_error_e db_open(db_open_mode mode, uid_t uid)
293 const char *tbls[3] = {
294 "CREATE TABLE app_info "
295 "(package TEXT PRIMARY KEY, "
296 "exec TEXT DEFAULT 'No Exec', "
297 "name TEXT DEFAULT 'No Name', "
298 "type TEXT DEFAULT 'Application', "
299 "icon TEXT DEFAULT 'No Icon', "
303 "x_slp_service TEXT, "
304 "x_slp_packagetype TEXT, "
305 "x_slp_packagecategories TEXT, "
306 "x_slp_packageid TEXT, "
309 "x_slp_exe_path TEXT, "
312 "x_slp_domain TEXT, "
313 "x_slp_submodemainid TEXT, "
314 "x_slp_installedstorage TEXT, "
315 "x_slp_baselayoutwidth INTEGER DEFAULT 0, "
316 "x_slp_installedtime INTEGER DEFAULT 0, "
317 "nodisplay INTEGER DEFAULT 0, "
318 "x_slp_taskmanage INTEGER DEFAULT 1, "
319 "x_slp_multiple INTEGER DEFAULT 0, "
320 "x_slp_removable INTEGER DEFAULT 1, "
321 "x_slp_ishorizontalscale INTEGER DEFAULT 0, "
322 "x_slp_enabled INTEGER DEFAULT 1, "
323 "x_slp_submode INTEGER DEFAULT 0, "
324 "desktop TEXT UNIQUE NOT NULL);",
325 "CREATE TABLE localname (package TEXT NOT NULL, "
326 "locale TEXT NOT NULL, "
327 "name TEXT NOT NULL, "
328 "x_slp_pkgid TEXT NOT NULL, PRIMARY KEY (package, locale));",
333 if (access(ail_get_app_DB(uid), F_OK)) {
334 if (AIL_ERROR_OK == db_util_open_with_options(ail_get_app_DB(uid), &dbInit, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL))
336 for (i = 0; tbls[i] != NULL; i++) {
337 ret = do_db_exec(tbls[i], dbInit);
338 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
340 if(AIL_ERROR_OK != ail_db_change_perm(ail_get_app_DB(uid))) {
341 _E("Failed to change permission\n");
345 _E("Failed to create table %s\n", ail_get_app_DB(uid));
349 ret = sqlite3_close(dbInit);
350 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
353 if(mode & DB_OPEN_RO) {
354 if(uid != GLOBAL_USER) {
355 if (!db_info.dbUserro) {
356 db_util_open_with_options(ail_get_app_DB(uid), &db_info.dbUserro, SQLITE_OPEN_READONLY, NULL);
357 char query_attach[AIL_SQL_QUERY_MAX_LEN];
358 char query_view_app[AIL_SQL_QUERY_MAX_LEN];
359 char query_view_local[AIL_SQL_QUERY_MAX_LEN];
360 snprintf(query_attach, AIL_SQL_QUERY_MAX_LEN, QUERY_ATTACH, ail_get_app_DB(GLOBAL_USER));
361 if (db_exec_usr_ro(query_attach) < 0) {
362 _D("executing query_attach : %s", query_attach );
363 return AIL_ERROR_DB_FAILED;
365 snprintf(query_view_app, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_APP);
366 if (db_exec_usr_ro(query_view_app) < 0) {
367 _D("executing query_attach : %s", query_view_app );
368 return AIL_ERROR_DB_FAILED;
371 snprintf(query_view_local, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_LOCAL);
372 if (db_exec_usr_ro(query_view_local) < 0) {
373 _D("executing query_attach : %s", query_view_local );
374 return AIL_ERROR_DB_FAILED;
378 if (!db_info.dbGlobalro) {
379 ret = db_util_open_with_options(ail_get_app_DB(GLOBAL_USER), &db_info.dbGlobalro, SQLITE_OPEN_READONLY, NULL);
380 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
384 if(mode & DB_OPEN_RW) {
385 if(uid != GLOBAL_USER) {
386 if(!db_info.dbUserrw){
387 ret = db_util_open(ail_get_app_DB(uid), &db_info.dbUserrw, 0);
390 if(!db_info.dbGlobalrw){
391 ret = db_util_open(ail_get_app_DB(GLOBAL_USER), &db_info.dbGlobalrw, 0);
394 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
401 ail_error_e db_prepare(const char *query, sqlite3_stmt **stmt)
403 return db_do_prepare(db_info.dbUserro, query, stmt);
406 ail_error_e db_prepare_globalro(const char *query, sqlite3_stmt **stmt)
408 return db_do_prepare(db_info.dbGlobalro, query, stmt);
411 ail_error_e db_prepare_rw(const char *query, sqlite3_stmt **stmt)
413 return db_do_prepare(db_info.dbUserrw, query, stmt);
417 ail_error_e db_prepare_globalrw(const char *query, sqlite3_stmt **stmt)
419 return db_do_prepare(db_info.dbGlobalrw, query, stmt);
423 ail_error_e db_bind_bool(sqlite3_stmt *stmt, int idx, bool value)
427 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
429 ret = sqlite3_bind_int(stmt, idx, (int) value);
430 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
437 ail_error_e db_bind_int(sqlite3_stmt *stmt, int idx, int value)
441 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
443 ret = sqlite3_bind_int(stmt, idx, value);
444 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
449 ail_error_e db_bind_text(sqlite3_stmt *stmt, int idx, char* value)
453 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
455 ret = sqlite3_bind_text(stmt, idx, value, strlen(value), 0);
456 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
462 ail_error_e db_step(sqlite3_stmt *stmt)
466 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
468 ret = sqlite3_step(stmt);
471 return AIL_ERROR_NO_DATA;
476 retv_with_dbmsg_if(1, AIL_ERROR_DB_FAILED);
481 ail_error_e db_column_bool(sqlite3_stmt *stmt, int index, bool *value)
485 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
486 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
488 out_val = sqlite3_column_int(stmt, index);
489 *value = (out_val == 1)? true:false;
496 ail_error_e db_column_int(sqlite3_stmt *stmt, int index, int *value)
498 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
499 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
501 *value = sqlite3_column_int(stmt, index);
508 ail_error_e db_column_str(sqlite3_stmt *stmt, int index, char **str)
510 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
511 retv_if(!str, AIL_ERROR_INVALID_PARAMETER);
513 *str = (char *)sqlite3_column_text(stmt, index);
520 ail_error_e db_reset(sqlite3_stmt *stmt)
524 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
526 sqlite3_clear_bindings(stmt);
528 ret = sqlite3_reset(stmt);
529 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
536 ail_error_e db_finalize(sqlite3_stmt *stmt)
540 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
542 ret = sqlite3_finalize(stmt);
543 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
550 ail_error_e do_db_exec(const char *query, sqlite3 * fileSQL)
555 retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
556 retv_if(!fileSQL, AIL_ERROR_DB_FAILED);
558 ret = sqlite3_exec(fileSQL, query, NULL, NULL, &errmsg);
559 if (ret != SQLITE_OK) {
560 _E("Cannot execute this query - %s. because %s",
561 query, errmsg? errmsg:"uncatched error");
562 sqlite3_free(errmsg);
563 return AIL_ERROR_DB_FAILED;
571 ail_error_e db_exec_usr_rw(const char *query)
573 return do_db_exec(query, db_info.dbUserrw);
577 ail_error_e db_exec_usr_ro(const char *query)
579 return do_db_exec(query, db_info.dbUserro);
582 ail_error_e db_exec_glo_ro(const char *query)
584 return do_db_exec(query, db_info.dbGlobalro);
587 ail_error_e db_exec_glo_rw(const char *query)
589 return do_db_exec(query, db_info.dbGlobalrw);
593 ail_error_e db_close(void)
597 if(db_info.dbUserro) {
598 ret = sqlite3_close(db_info.dbUserro);
599 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
601 db_info.dbUserro = NULL;
603 if(db_info.dbGlobalrw) {
604 ret = sqlite3_close(db_info.dbGlobalrw);
605 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
607 db_info.dbGlobalrw = NULL;
609 if(db_info.dbUserrw) {
610 ret = sqlite3_close(db_info.dbUserrw);
611 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
613 db_info.dbUserrw = NULL;
619 EXPORT_API ail_error_e ail_db_close(void)
624 int db_exec_sqlite_query(char *query, sqlite_query_callback callback, void *data)
626 char *error_message = NULL;
627 if(db_info.dbGlobalro) {
629 sqlite3_exec(db_info.dbGlobalro, query, callback, data, &error_message)) {
630 _E("Don't execute query = %s error message = %s\n", query,
632 sqlite3_free(error_message);
636 if(db_info.dbUserro) {
638 sqlite3_exec(db_info.dbUserro, query, callback, data, &error_message)) {
639 _E("Don't execute query = %s error message = %s\n", query,
641 sqlite3_free(error_message);
645 sqlite3_free(error_message);