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 SMACK_LABEL "_"
46 #define retv_with_dbmsg_if(expr, val) do { \
48 _E("db_info.dbUserro: %s", sqlite3_errmsg(db_info.dbUserro)); \
49 _E("db_info.dbGlobalro: %s", sqlite3_errmsg(db_info.dbGlobalro)); \
50 _E("db_info.dbUserrw: %s", sqlite3_errmsg(db_info.dbUserrw)); \
51 _E("db_info.dbGlobalrw: %s", sqlite3_errmsg(db_info.dbGlobalrw)); \
52 _E("db_info.dbUserro errcode: %d", sqlite3_extended_errcode(db_info.dbUserro)); \
53 _E("db_info.dbGlobalro errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalro)); \
54 _E("db_info.dbUserrw errcode: %d", sqlite3_extended_errcode(db_info.dbUserrw)); \
55 _E("db_info.dbGlobalrw errcode: %d", sqlite3_extended_errcode(db_info.dbGlobalrw)); \
60 static __thread struct {
71 static __thread sqlite3 *dbInit = NULL;
73 static int ail_db_change_perm(const char *db_file)
76 char journal_file[BUFSIZE];
79 struct group *grpinfo = NULL;
80 const char *name = "users";
82 files[0] = (char *)db_file;
83 files[1] = journal_file;
86 retv_if(!db_file, AIL_ERROR_FAIL);
87 if(getuid()) //At this time we should be root to apply this
90 snprintf(journal_file, sizeof(journal_file), "%s%s", db_file, "-journal");
92 for (i = 0; files[i]; i++) {
93 grpinfo = getgrnam(name);
95 _E("getgrnam(users) returns NULL !");
97 // Compare git_t type and not group name
98 ret = chown(files[i], OWNER_ROOT, grpinfo->gr_gid);
100 strerror_r(errno, buf, sizeof(buf));
101 _E("FAIL : chown %s %d.%d, because %s", db_file, OWNER_ROOT, grpinfo->gr_gid, buf);
102 return AIL_ERROR_FAIL;
105 ret = chmod(files[i], S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
107 strerror_r(errno, buf, sizeof(buf));
108 _E("FAIL : chmod %s 0664, because %s", db_file, buf);
109 return AIL_ERROR_FAIL;
116 char* ail_get_icon_path(uid_t uid)
119 struct group *grpinfo = NULL;
121 struct passwd *userinfo = getpwuid(uid);
123 if (uid != GLOBAL_USER) {
125 if (userinfo == NULL) {
126 _E("getpwuid(%d) returns NULL !", uid);
129 grpinfo = getgrnam("users");
130 if (grpinfo == NULL) {
131 _E("getgrnam(users) returns NULL !");
134 // Compare git_t type and not group name
135 if (grpinfo->gr_gid != userinfo->pw_gid) {
136 _E("UID [%d] does not belong to 'users' group!", uid);
139 asprintf(&result, "%s/.applications/icons/", userinfo->pw_dir);
141 result = tzplatform_mkpath(TZ_SYS_RW_ICONS, "/");
142 grpinfo = getgrnam("root");
143 if (grpinfo == NULL) {
144 _E("getgrnam(root) returns NULL !");
147 if (grpinfo->gr_gid != userinfo->pw_gid) {
148 _E("UID [%d] does not belong to 'root' group!", uid);
152 if (smack_setlabel(result, SMACK_LABEL, SMACK_LABEL_ACCESS)) {
153 _E("failed chsmack -a \"%s\" %s", SMACK_LABEL, result);
155 _D("chsmack -a \"%s\" %s", SMACK_LABEL, result);
159 mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
160 ret = chown(result, uid, grpinfo->gr_gid);
163 strerror_r(errno, buf, sizeof(buf));
164 _E("FAIL : chown %s %d.%d, because %s", result, uid, grpinfo->gr_gid, buf);
169 static char* ail_get_app_DB(uid_t uid)
172 char *journal = NULL;
173 struct group *grpinfo = NULL;
175 struct passwd *userinfo = getpwuid(uid);
177 if (uid != GLOBAL_USER) {
179 if (userinfo == NULL) {
180 _E("getpwuid(%d) returns NULL !", uid);
183 grpinfo = getgrnam("users");
184 if (grpinfo == NULL) {
185 _E("getgrnam(users) returns NULL !");
188 // Compare git_t type and not group name
189 if (grpinfo->gr_gid != userinfo->pw_gid) {
190 _E("UID [%d] does not belong to 'users' group!", uid);
193 asprintf(&result, "%s/.applications/dbspace/.app_info.db", userinfo->pw_dir);
194 asprintf(&journal, "%s/.applications/dbspace/.app_info.db-journal", userinfo->pw_dir);
196 grpinfo = getgrnam("root");
197 if (grpinfo == NULL) {
198 _E("getgrnam(root) returns NULL !");
201 if (grpinfo->gr_gid != userinfo->pw_gid) {
202 _E("UID [%d] does not belong to 'root' group!", uid);
205 result = strdup(APP_INFO_DB_FILE);
206 journal = strdup(APP_INFO_DB_FILE_JOURNAL);
208 if (smack_setlabel(result, SMACK_LABEL, SMACK_LABEL_ACCESS)) {
209 _E("failed chsmack -a \"%s\" %s", SMACK_LABEL, result);
211 _D("chsmack -a \"%s\" %s", SMACK_LABEL, result);
213 if (smack_setlabel(journal, SMACK_LABEL, SMACK_LABEL_ACCESS)) {
214 _E("failed chsmack -a \"%s\" %s", SMACK_LABEL, journal);
216 _D("chsmack -a \"%s\" %s", SMACK_LABEL, journal);
219 dir = strrchr(result, '/');
224 mkdir(dir + 1, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
225 ret = chown(dir + 1, uid, grpinfo->gr_gid);
228 strerror_r(errno, buf, sizeof(buf));
229 _E("FAIL : chown %s %d.%d, because %s", dir + 1, uid, grpinfo->gr_gid, buf);
235 char* al_get_desktop_path(uid_t uid)
238 struct group *grpinfo = NULL;
240 struct passwd *userinfo = getpwuid(uid);
242 if (uid != GLOBAL_USER) {
244 if (userinfo == NULL) {
245 _E("getpwuid(%d) returns NULL !", uid);
248 grpinfo = getgrnam("users");
249 if (grpinfo == NULL) {
250 _E("getgrnam(users) returns NULL !");
253 // Compare git_t type and not group name
254 if (grpinfo->gr_gid != userinfo->pw_gid) {
255 _E("UID [%d] does not belong to 'users' group!", uid);
258 asprintf(&result, "%s/.applications/desktop/", userinfo->pw_dir);
260 grpinfo = getgrnam("root");
261 if (grpinfo == NULL) {
262 _E("getgrnam(root) returns NULL !");
265 if (grpinfo->gr_gid != userinfo->pw_gid) {
266 _E("UID [%d] does not belong to 'root' group!", uid);
269 result = tzplatform_mkpath(TZ_SYS_RW_DESKTOP_APP, "/");
271 if (smack_setlabel(result, SMACK_LABEL, SMACK_LABEL_ACCESS)) {
272 _E("failed chsmack -a \"%s\" %s", SMACK_LABEL, result);
274 _D("chsmack -a \"%s\" %s", SMACK_LABEL, result);
279 mkdir(result, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH);
280 ret = chown(result, uid, grpinfo->gr_gid);
283 strerror_r(errno, buf, sizeof(buf));
284 _E("FAIL : chown %s %d.%d, because %s", result, uid, grpinfo->gr_gid, buf);
290 static ail_error_e db_do_prepare(sqlite3 *db, const char *query, sqlite3_stmt **stmt)
294 retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
295 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
296 retv_if(!db, AIL_ERROR_DB_FAILED);
298 ret = sqlite3_prepare_v2(db, query, strlen(query), stmt, NULL);
299 if (ret != SQLITE_OK) {
300 _E("%s\n", sqlite3_errmsg(db));
301 return AIL_ERROR_DB_FAILED;
306 ail_error_e db_open(db_open_mode mode, uid_t uid)
311 const char *tbls[3] = {
312 "CREATE TABLE app_info "
313 "(package TEXT PRIMARY KEY, "
314 "exec TEXT DEFAULT 'No Exec', "
315 "name TEXT DEFAULT 'No Name', "
316 "type TEXT DEFAULT 'Application', "
317 "icon TEXT DEFAULT 'No Icon', "
321 "x_slp_service TEXT, "
322 "x_slp_packagetype TEXT, "
323 "x_slp_packagecategories TEXT, "
324 "x_slp_packageid TEXT, "
327 "x_slp_exe_path TEXT, "
330 "x_slp_domain TEXT, "
331 "x_slp_submodemainid TEXT, "
332 "x_slp_installedstorage TEXT, "
333 "x_slp_baselayoutwidth INTEGER DEFAULT 0, "
334 "x_slp_installedtime INTEGER DEFAULT 0, "
335 "nodisplay INTEGER DEFAULT 0, "
336 "x_slp_taskmanage INTEGER DEFAULT 1, "
337 "x_slp_multiple INTEGER DEFAULT 0, "
338 "x_slp_removable INTEGER DEFAULT 1, "
339 "x_slp_ishorizontalscale INTEGER DEFAULT 0, "
340 "x_slp_enabled INTEGER DEFAULT 1, "
341 "x_slp_submode INTEGER DEFAULT 0, "
342 "desktop TEXT UNIQUE NOT NULL);",
343 "CREATE TABLE localname (package TEXT NOT NULL, "
344 "locale TEXT NOT NULL, "
345 "name TEXT NOT NULL, "
346 "x_slp_pkgid TEXT NOT NULL, PRIMARY KEY (package, locale));",
351 if (access(ail_get_app_DB(uid), F_OK)) {
352 if (AIL_ERROR_OK == db_util_open_with_options(ail_get_app_DB(uid), &dbInit, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL))
354 for (i = 0; tbls[i] != NULL; i++) {
355 ret = do_db_exec(tbls[i], dbInit);
356 retv_if(ret != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
358 if(AIL_ERROR_OK != ail_db_change_perm(ail_get_app_DB(uid))) {
359 _E("Failed to change permission\n");
363 _E("Failed to create table %s\n", ail_get_app_DB(uid));
367 ret = sqlite3_close(dbInit);
368 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
371 if(mode & DB_OPEN_RO) {
372 if(uid != GLOBAL_USER) {
373 if (!db_info.dbUserro) {
374 db_util_open_with_options(ail_get_app_DB(uid), &db_info.dbUserro, SQLITE_OPEN_READONLY, NULL);
375 char query_attach[AIL_SQL_QUERY_MAX_LEN];
376 char query_view_app[AIL_SQL_QUERY_MAX_LEN];
377 char query_view_local[AIL_SQL_QUERY_MAX_LEN];
378 snprintf(query_attach, AIL_SQL_QUERY_MAX_LEN, QUERY_ATTACH, ail_get_app_DB(GLOBAL_USER));
379 _E("info : execute query_attach : %s", query_attach );
380 if (db_exec_usr_ro(query_attach) < 0) {
381 return AIL_ERROR_DB_FAILED;
383 snprintf(query_view_app, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_APP);
384 _E("info : execute query_attach : %s", query_view_app );
385 if (db_exec_usr_ro(query_view_app) < 0) {
386 return AIL_ERROR_DB_FAILED;
389 snprintf(query_view_local, AIL_SQL_QUERY_MAX_LEN, QUERY_CREATE_VIEW_LOCAL);
390 _E("info : execute query_attach : %s", query_view_local );
391 if (db_exec_usr_ro(query_view_local) < 0) {
392 return AIL_ERROR_DB_FAILED;
396 if (!db_info.dbGlobalro) {
397 ret = db_util_open_with_options(ail_get_app_DB(GLOBAL_USER), &db_info.dbGlobalro, SQLITE_OPEN_READONLY, NULL);
398 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
402 if(mode & DB_OPEN_RW) {
403 if(uid != GLOBAL_USER) {
404 if(!db_info.dbUserrw){
405 ret = db_util_open(ail_get_app_DB(uid), &db_info.dbUserrw, 0);
408 if(!db_info.dbGlobalrw){
409 ret = db_util_open(ail_get_app_DB(GLOBAL_USER), &db_info.dbGlobalrw, 0);
412 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
419 ail_error_e db_prepare(const char *query, sqlite3_stmt **stmt)
421 return db_do_prepare(db_info.dbUserro, query, stmt);
424 ail_error_e db_prepare_globalro(const char *query, sqlite3_stmt **stmt)
426 return db_do_prepare(db_info.dbGlobalro, query, stmt);
429 ail_error_e db_prepare_rw(const char *query, sqlite3_stmt **stmt)
431 return db_do_prepare(db_info.dbUserrw, query, stmt);
435 ail_error_e db_prepare_globalrw(const char *query, sqlite3_stmt **stmt)
437 return db_do_prepare(db_info.dbGlobalrw, query, stmt);
441 ail_error_e db_bind_bool(sqlite3_stmt *stmt, int idx, bool value)
445 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
447 ret = sqlite3_bind_int(stmt, idx, (int) value);
448 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
455 ail_error_e db_bind_int(sqlite3_stmt *stmt, int idx, int value)
459 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
461 ret = sqlite3_bind_int(stmt, idx, value);
462 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
467 ail_error_e db_bind_text(sqlite3_stmt *stmt, int idx, char* value)
471 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
473 ret = sqlite3_bind_text(stmt, idx, value, strlen(value), 0);
474 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
480 ail_error_e db_step(sqlite3_stmt *stmt)
484 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
486 ret = sqlite3_step(stmt);
489 return AIL_ERROR_NO_DATA;
494 retv_with_dbmsg_if(1, AIL_ERROR_DB_FAILED);
499 ail_error_e db_column_bool(sqlite3_stmt *stmt, int index, bool *value)
503 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
504 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
506 out_val = sqlite3_column_int(stmt, index);
507 *value = (out_val == 1)? true:false;
514 ail_error_e db_column_int(sqlite3_stmt *stmt, int index, int *value)
516 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
517 retv_if(!value, AIL_ERROR_INVALID_PARAMETER);
519 *value = sqlite3_column_int(stmt, index);
526 ail_error_e db_column_str(sqlite3_stmt *stmt, int index, char **str)
528 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
529 retv_if(!str, AIL_ERROR_INVALID_PARAMETER);
531 *str = (char *)sqlite3_column_text(stmt, index);
538 ail_error_e db_reset(sqlite3_stmt *stmt)
542 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
544 sqlite3_clear_bindings(stmt);
546 ret = sqlite3_reset(stmt);
547 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
554 ail_error_e db_finalize(sqlite3_stmt *stmt)
558 retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
560 ret = sqlite3_finalize(stmt);
561 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
568 ail_error_e do_db_exec(const char *query, sqlite3 * fileSQL)
573 retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
574 retv_if(!fileSQL, AIL_ERROR_DB_FAILED);
576 ret = sqlite3_exec(fileSQL, query, NULL, NULL, &errmsg);
577 if (ret != SQLITE_OK) {
578 _E("Cannot execute this query - %s. because %s",
579 query, errmsg? errmsg:"uncatched error");
580 sqlite3_free(errmsg);
581 return AIL_ERROR_DB_FAILED;
589 ail_error_e db_exec_usr_rw(const char *query)
591 return do_db_exec(query, db_info.dbUserrw);
595 ail_error_e db_exec_usr_ro(const char *query)
597 return do_db_exec(query, db_info.dbUserro);
600 ail_error_e db_exec_glo_ro(const char *query)
602 return do_db_exec(query, db_info.dbGlobalro);
605 ail_error_e db_exec_glo_rw(const char *query)
607 return do_db_exec(query, db_info.dbGlobalrw);
611 ail_error_e db_close(void)
615 if(db_info.dbUserro) {
616 ret = sqlite3_close(db_info.dbUserro);
617 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
619 db_info.dbUserro = NULL;
621 if(db_info.dbGlobalrw) {
622 ret = sqlite3_close(db_info.dbGlobalrw);
623 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
625 db_info.dbGlobalrw = NULL;
627 if(db_info.dbUserrw) {
628 ret = sqlite3_close(db_info.dbUserrw);
629 retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
631 db_info.dbUserrw = NULL;
637 EXPORT_API ail_error_e ail_db_close(void)
642 int db_exec_sqlite_query(char *query, sqlite_query_callback callback, void *data)
644 char *error_message = NULL;
645 if(db_info.dbGlobalro) {
647 sqlite3_exec(db_info.dbGlobalro, query, callback, data, &error_message)) {
648 _E("Don't execute query = %s error message = %s\n", query,
650 sqlite3_free(error_message);
654 if(db_info.dbUserro) {
656 sqlite3_exec(db_info.dbUserro, query, callback, data, &error_message)) {
657 _E("Don't execute query = %s error message = %s\n", query,
659 sqlite3_free(error_message);
663 sqlite3_free(error_message);