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 <tzplatform_config.h>
35 #include "ail_private.h"
38 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
40 #define QUERY_ATTACH "attach database '%s' as Global"
41 #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)"
43 #define QUERY_CREATE_VIEW_LOCAL "CREATE temp VIEW localname as select distinct * from (select * from main.localname m union select * from Global.localname g)"
45 #define retv_with_dbmsg_if(expr, val) do { \
47 _E("db_info.dbUserro: %s", sqlite3_errmsg(db_info.dbUserro)); \
48 _E("db_info.dbGlobalro: %s", sqlite3_errmsg(db_info.dbGlobalro)); \
49 _E("db_info.dbUserrw: %s", sqlite3_errmsg(db_info.dbUserrw)); \
50 _E("db_info.dbGlobalrw: %s", sqlite3_errmsg(db_info.dbGlobalrw)); \
51 _E("db_info.dbUserro errcode: %d", sqlite3_extended_errcode(db_info.dbUserro)); \
52 _E("db_info.dbGlobalro errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalro)); \
53 _E("db_info.dbUserrw errcode: %d", sqlite3_extended_errcode(db_info.dbUserrw)); \
54 _E("db_info.dbGlobalrw errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalrw)); \
59 static __thread struct {
70 static __thread sqlite3 *dbInit = NULL;
72 static int ail_db_change_perm(const char *db_file)
75 char journal_file[BUFSIZE];
78 struct group *grpinfo = NULL;
79 const char *name = "users";
81 files[0] = (char *)db_file;
82 files[1] = journal_file;
85 retv_if(!db_file, AIL_ERROR_FAIL);
86 if(getuid()) //At this time we should be root to apply this
89 snprintf(journal_file, sizeof(journal_file), "%s%s", db_file, "-journal");
91 for (i = 0; files[i]; i++) {
92 grpinfo = getgrnam(name);
94 _E("getgrnam(users) returns NULL !");
96 // Compare git_t type and not group name
97 ret = chown(files[i], OWNER_ROOT, grpinfo->gr_gid);
99 strerror_r(errno, buf, sizeof(buf));
100 _E("FAIL : chown %s %d.%d, because %s", db_file, OWNER_ROOT, grpinfo->gr_gid, buf);
101 return AIL_ERROR_FAIL;
104 ret = chmod(files[i], S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
106 strerror_r(errno, buf, sizeof(buf));
107 _E("FAIL : chmod %s 0664, because %s", db_file, buf);
108 return AIL_ERROR_FAIL;
115 char* ail_get_icon_path(uid_t uid)
118 struct group *grpinfo = NULL;
120 struct passwd *userinfo = getpwuid(uid);
122 if (uid != GLOBAL_USER) {
124 if (userinfo == NULL) {
125 _E("getpwuid(%d) returns NULL !", uid);
128 grpinfo = getgrnam("users");
129 if (grpinfo == NULL) {
130 _E("getgrnam(users) returns NULL !");
133 // Compare git_t type and not group name
134 if (grpinfo->gr_gid != userinfo->pw_gid) {
135 _E("UID [%d] does not belong to 'users' group!", uid);
138 asprintf(&result, "%s/.applications/icons/", userinfo->pw_dir);
140 result = tzplatform_mkpath(TZ_SYS_RW_ICONS, "/");
143 mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
144 if (getuid() == OWNER_ROOT) {
145 ret = chown(result, uid, grpinfo->gr_gid);
148 strerror_r(errno, buf, sizeof(buf));
149 _E("FAIL : chown %s %d.%d, because %s", result, uid, grpinfo->gr_gid, buf);
155 static char* ail_get_app_DB(uid_t uid)
158 char *journal = NULL;
159 struct group *grpinfo = NULL;
161 struct passwd *userinfo = getpwuid(uid);
163 if (uid != GLOBAL_USER) {
165 if (userinfo == NULL) {
166 _E("getpwuid(%d) returns NULL !", uid);
169 grpinfo = getgrnam("users");
170 if (grpinfo == NULL) {
171 _E("getgrnam(users) returns NULL !");
174 // Compare git_t type and not group name
175 if (grpinfo->gr_gid != userinfo->pw_gid) {
176 _E("UID [%d] does not belong to 'users' group!", uid);
179 asprintf(&result, "%s/.applications/dbspace/.app_info.db", userinfo->pw_dir);
180 asprintf(&journal, "%s/.applications/dbspace/.app_info.db-journal", userinfo->pw_dir);
182 result = strdup(APP_INFO_DB_FILE);
183 journal = strdup(APP_INFO_DB_FILE_JOURNAL);
185 char *temp = strdup(result);
186 dir = strrchr(temp, '/');
193 if ((uid != GLOBAL_USER)||((uid == GLOBAL_USER)&& (geteuid() == 0 ))) {
195 mkdir(temp, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
196 if (getuid() == OWNER_ROOT) {
197 ret = chown(dir + 1, uid, grpinfo->gr_gid);
200 strerror_r(errno, buf, sizeof(buf));
201 _E("FAIL : chown %s %d.%d, because %s", dir + 1, uid, grpinfo->gr_gid, buf);
209 char* al_get_desktop_path(uid_t uid)
212 struct group *grpinfo = NULL;
214 struct passwd *userinfo = getpwuid(uid);
216 if (uid != GLOBAL_USER) {
218 if (userinfo == NULL) {
219 _E("getpwuid(%d) returns NULL !", uid);
222 grpinfo = getgrnam("users");
223 if (grpinfo == NULL) {
224 _E("getgrnam(users) returns NULL !");
227 // Compare git_t type and not group name
228 if (grpinfo->gr_gid != userinfo->pw_gid) {
229 _E("UID [%d] does not belong to 'users' group!", uid);
232 asprintf(&result, "%s/.applications/desktop/", userinfo->pw_dir);
234 result = tzplatform_mkpath(TZ_SYS_RW_DESKTOP_APP, "/");
236 if ((uid != GLOBAL_USER)||((uid == GLOBAL_USER)&& (geteuid() == 0 ))) {
238 mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
239 ret = chown(result, uid, grpinfo->gr_gid);
242 strerror_r(errno, buf, sizeof(buf));
243 _E("FAIL : chown %s %d.%d, because %s", result, uid, grpinfo->gr_gid, buf);
250 static ail_error_e db_do_prepare(sqlite3 *db, const char *query, sqlite3_stmt **stmt)
254 retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
255 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
256 retv_if(!db, AIL_ERROR_DB_FAILED);
258 ret = sqlite3_prepare_v2(db, query, strlen(query), stmt, NULL);
259 if (ret != SQLITE_OK) {
260 _E("%s\n", sqlite3_errmsg(db));
261 return AIL_ERROR_DB_FAILED;
266 ail_error_e db_open(db_open_mode mode, uid_t uid)
271 const char *tbls[3] = {
272 "CREATE TABLE app_info "
273 "(package TEXT PRIMARY KEY, "
274 "exec TEXT DEFAULT 'No Exec', "
275 "name TEXT DEFAULT 'No Name', "
276 "type TEXT DEFAULT 'Application', "
277 "icon TEXT DEFAULT 'No Icon', "
281 "x_slp_service TEXT, "
282 "x_slp_packagetype TEXT, "
283 "x_slp_packagecategories TEXT, "
284 "x_slp_packageid TEXT, "
287 "x_slp_exe_path TEXT, "
290 "x_slp_domain TEXT, "
291 "x_slp_submodemainid TEXT, "
292 "x_slp_installedstorage TEXT, "
293 "x_slp_baselayoutwidth INTEGER DEFAULT 0, "
294 "x_slp_installedtime INTEGER DEFAULT 0, "
295 "nodisplay INTEGER DEFAULT 0, "
296 "x_slp_taskmanage INTEGER DEFAULT 1, "
297 "x_slp_multiple INTEGER DEFAULT 0, "
298 "x_slp_removable INTEGER DEFAULT 1, "
299 "x_slp_ishorizontalscale INTEGER DEFAULT 0, "
300 "x_slp_enabled INTEGER DEFAULT 1, "
301 "x_slp_submode INTEGER DEFAULT 0, "
302 "desktop TEXT UNIQUE NOT NULL);",
303 "CREATE TABLE localname (package TEXT NOT NULL, "
304 "locale TEXT NOT NULL, "
305 "name TEXT NOT NULL, "
306 "x_slp_pkgid TEXT NOT NULL, PRIMARY KEY (package, locale));",
311 if (access(ail_get_app_DB(uid), F_OK)) {
312 if (AIL_ERROR_OK == db_util_open_with_options(ail_get_app_DB(uid), &dbInit, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL))
314 for (i = 0; tbls[i] != NULL; i++) {
315 ret = do_db_exec(tbls[i], dbInit);
316 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
318 if(AIL_ERROR_OK != ail_db_change_perm(ail_get_app_DB(uid))) {
319 _E("Failed to change permission\n");
323 _E("Failed to create table %s\n", ail_get_app_DB(uid));
327 ret = sqlite3_close(dbInit);
328 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
331 if(mode & DB_OPEN_RO) {
332 if(uid != GLOBAL_USER) {
333 if (!db_info.dbUserro) {
334 db_util_open_with_options(ail_get_app_DB(uid), &db_info.dbUserro, SQLITE_OPEN_READONLY, NULL);
335 char query_attach[AIL_SQL_QUERY_MAX_LEN];
336 char query_view_app[AIL_SQL_QUERY_MAX_LEN];
337 char query_view_local[AIL_SQL_QUERY_MAX_LEN];
338 snprintf(query_attach, AIL_SQL_QUERY_MAX_LEN, QUERY_ATTACH, ail_get_app_DB(GLOBAL_USER));
339 if (db_exec_usr_ro(query_attach) < 0) {
340 _D("executing query_attach : %s", query_attach );
341 return AIL_ERROR_DB_FAILED;
343 snprintf(query_view_app, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_APP);
344 if (db_exec_usr_ro(query_view_app) < 0) {
345 _D("executing query_attach : %s", query_view_app );
346 return AIL_ERROR_DB_FAILED;
349 snprintf(query_view_local, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_LOCAL);
350 if (db_exec_usr_ro(query_view_local) < 0) {
351 _D("executing query_attach : %s", query_view_local );
352 return AIL_ERROR_DB_FAILED;
356 if (!db_info.dbGlobalro) {
357 ret = db_util_open_with_options(ail_get_app_DB(GLOBAL_USER), &db_info.dbGlobalro, SQLITE_OPEN_READONLY, NULL);
358 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
362 if(mode & DB_OPEN_RW) {
363 if(uid != GLOBAL_USER) {
364 if(!db_info.dbUserrw){
365 ret = db_util_open(ail_get_app_DB(uid), &db_info.dbUserrw, 0);
368 if(!db_info.dbGlobalrw){
369 ret = db_util_open(ail_get_app_DB(GLOBAL_USER), &db_info.dbGlobalrw, 0);
372 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
379 ail_error_e db_prepare(const char *query, sqlite3_stmt **stmt)
381 return db_do_prepare(db_info.dbUserro, query, stmt);
384 ail_error_e db_prepare_globalro(const char *query, sqlite3_stmt **stmt)
386 return db_do_prepare(db_info.dbGlobalro, query, stmt);
389 ail_error_e db_prepare_rw(const char *query, sqlite3_stmt **stmt)
391 return db_do_prepare(db_info.dbUserrw, query, stmt);
395 ail_error_e db_prepare_globalrw(const char *query, sqlite3_stmt **stmt)
397 return db_do_prepare(db_info.dbGlobalrw, query, stmt);
401 ail_error_e db_bind_bool(sqlite3_stmt *stmt, int idx, bool value)
405 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
407 ret = sqlite3_bind_int(stmt, idx, (int) value);
408 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
415 ail_error_e db_bind_int(sqlite3_stmt *stmt, int idx, int value)
419 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
421 ret = sqlite3_bind_int(stmt, idx, value);
422 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
427 ail_error_e db_bind_text(sqlite3_stmt *stmt, int idx, char* value)
431 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
433 ret = sqlite3_bind_text(stmt, idx, value, strlen(value), 0);
434 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
440 ail_error_e db_step(sqlite3_stmt *stmt)
444 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
446 ret = sqlite3_step(stmt);
449 return AIL_ERROR_NO_DATA;
454 retv_with_dbmsg_if(1, AIL_ERROR_DB_FAILED);
459 ail_error_e db_column_bool(sqlite3_stmt *stmt, int index, bool *value)
463 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
464 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
466 out_val = sqlite3_column_int(stmt, index);
467 *value = (out_val == 1)? true:false;
474 ail_error_e db_column_int(sqlite3_stmt *stmt, int index, int *value)
476 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
477 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
479 *value = sqlite3_column_int(stmt, index);
486 ail_error_e db_column_str(sqlite3_stmt *stmt, int index, char **str)
488 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
489 retv_if(!str, AIL_ERROR_INVALID_PARAMETER);
491 *str = (char *)sqlite3_column_text(stmt, index);
498 ail_error_e db_reset(sqlite3_stmt *stmt)
502 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
504 sqlite3_clear_bindings(stmt);
506 ret = sqlite3_reset(stmt);
507 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
514 ail_error_e db_finalize(sqlite3_stmt *stmt)
518 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
520 ret = sqlite3_finalize(stmt);
521 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
528 ail_error_e do_db_exec(const char *query, sqlite3 * fileSQL)
533 retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
534 retv_if(!fileSQL, AIL_ERROR_DB_FAILED);
536 ret = sqlite3_exec(fileSQL, query, NULL, NULL, &errmsg);
537 if (ret != SQLITE_OK) {
538 _E("Cannot execute this query - %s. because %s",
539 query, errmsg? errmsg:"uncatched error");
540 sqlite3_free(errmsg);
541 return AIL_ERROR_DB_FAILED;
549 ail_error_e db_exec_usr_rw(const char *query)
551 return do_db_exec(query, db_info.dbUserrw);
555 ail_error_e db_exec_usr_ro(const char *query)
557 return do_db_exec(query, db_info.dbUserro);
560 ail_error_e db_exec_glo_ro(const char *query)
562 return do_db_exec(query, db_info.dbGlobalro);
565 ail_error_e db_exec_glo_rw(const char *query)
567 return do_db_exec(query, db_info.dbGlobalrw);
571 ail_error_e db_close(void)
575 if(db_info.dbUserro) {
576 ret = sqlite3_close(db_info.dbUserro);
577 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
579 db_info.dbUserro = NULL;
581 if(db_info.dbGlobalrw) {
582 ret = sqlite3_close(db_info.dbGlobalrw);
583 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
585 db_info.dbGlobalrw = NULL;
587 if(db_info.dbUserrw) {
588 ret = sqlite3_close(db_info.dbUserrw);
589 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
591 db_info.dbUserrw = NULL;
597 EXPORT_API ail_error_e ail_db_close(void)
602 int db_exec_sqlite_query(char *query, sqlite_query_callback callback, void *data)
604 char *error_message = NULL;
605 if(db_info.dbGlobalro) {
607 sqlite3_exec(db_info.dbGlobalro, query, callback, data, &error_message)) {
608 _E("Don't execute query = %s error message = %s\n", query,
610 sqlite3_free(error_message);
614 if(db_info.dbUserro) {
616 sqlite3_exec(db_info.dbUserro, query, callback, data, &error_message)) {
617 _E("Don't execute query = %s error message = %s\n", query,
619 sqlite3_free(error_message);
623 sqlite3_free(error_message);