tzplatform_mkpath(TZ_SYS_GLOBALUSER_DATA, \
"pkgmgr/fota/.all_preload_rw_list")
#define DBPATH tzplatform_mkpath(TZ_SYS_DB, "/.pkgmgr_parser.db")
-#define JOURNAL_DBPATH tzplatform_mkpath(TZ_SYS_DB, \
- "/.pkgmgr_parser.db-journal")
#define CERT_DBPATH tzplatform_mkpath(TZ_SYS_DB, "/.pkgmgr_cert.db")
-#define JOURNAL_CERT_DBPATH tzplatform_mkpath(TZ_SYS_DB, \
- "/.pkgmgr_cert.db-journal")
#define OPT_ZIP_FILE "/usr/system/RestoreDir/opt.zip"
#define ALL_PRELOAD_RW_PKG_LIST "/opt/usr/share/.all_preload_rw_list"
#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
static int __set_db_permission(const char *path)
{
int fd;
+ const char *files[2];
+ char journal_file[BUF_SIZE];
struct stat sb;
mode_t mode;
uid_t uid;
struct passwd *result;
char buf[BUF_SIZE];
int ret;
+ int i;
ret = getpwnam_r(APPFW_USER, &pwd, buf, sizeof(buf), &result);
if (result == NULL) {
}
uid = pwd.pw_uid;
+ snprintf(journal_file, sizeof(journal_file), "%s-journal", path);
+ files[0] = path;
+ files[1] = journal_file;
+
ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
if (result == NULL) {
if (ret == 0)
_LOGE("getpwuid_r failed: %d", errno);
return -1;
}
- fd = open(path, O_RDONLY);
- if (fd == -1) {
- _LOGE("open %s failed: %d", path, errno);
- return -1;
- }
- ret = fstat(fd, &sb);
- if (ret == -1) {
- _LOGE("stat %s failed: %d", path, errno);
- close(fd);
- return -1;
- }
- if (S_ISLNK(sb.st_mode)) {
- _LOGE("%s is symlink!", path);
- close(fd);
- return -1;
- }
- ret = fchown(fd, uid, pwd.pw_gid);
- if (ret == -1) {
- _LOGE("fchown %s failed: %d", path, errno);
- close(fd);
- return -1;
- }
- mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
- if (strstr(path, CERT_DBPATH))
- mode |= S_IWOTH;
- ret = fchmod(fd, mode);
- if (ret == -1) {
- _LOGE("fchmod %s failed: %d", path, errno);
+ for (i = 0; i < 2; i++) {
+ fd = open(files[i], O_RDONLY);
+ if (fd == -1) {
+ _LOGE("open %s failed: %d", files[i], errno);
+ return -1;
+ }
+ ret = fstat(fd, &sb);
+ if (ret == -1) {
+ _LOGE("stat %s failed: %d", files[i], errno);
+ close(fd);
+ return -1;
+ }
+ if (S_ISLNK(sb.st_mode)) {
+ _LOGE("%s is symlink!", files[i]);
+ close(fd);
+ return -1;
+ }
+ ret = fchown(fd, uid, pwd.pw_gid);
+ if (ret == -1) {
+ _LOGE("fchown %s failed: %d", files[i], errno);
+ close(fd);
+ return -1;
+ }
+
+ mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
+ if (strstr(files[i], CERT_DBPATH))
+ mode |= S_IWOTH;
+ ret = fchmod(fd, mode);
+ if (ret == -1) {
+ _LOGE("fchmod %s failed: %d", files[i], errno);
+ close(fd);
+ return -1;
+ }
+ fsync(fd);
close(fd);
- return -1;
+ SET_SMACK_LABEL(files[i]);
}
- fsync(fd);
- close(fd);
- SET_SMACK_LABEL(path);
return 0;
}
static int __check_and_restore_backup(const char *origin_path) {
char backup_path[BUF_SIZE];
+ char journal_path[BUF_SIZE];
+ char journal_backup_path[BUF_SIZE];
char buf[BUF_SIZE];
+
snprintf(backup_path, BUF_SIZE, "%s.bck", origin_path);
+ snprintf(journal_path, BUF_SIZE, "%s-journal", origin_path);
+ snprintf(journal_backup_path, BUF_SIZE, "%s.bck-journal", origin_path);
- // if backup flag exists, it means the previous backup process aborted.
- if (access(backup_path, F_OK) && __check_backup_flag(origin_path))
+ if (access(backup_path, F_OK))
return 0;
- if (access(origin_path, F_OK) == 0) {
- if (remove(origin_path)) {
- _LOG("cannot remove path(%s) : %s\n", origin_path,
+ if (access(journal_backup_path, F_OK) == 0) {
+ if (rename(journal_backup_path, journal_path)) {
+ _LOG("fail to rename %s to %s : %s\n",
+ journal_backup_path, journal_path,
strerror_r(errno, buf, sizeof(buf)));
return -1;
}
return 0;
}
-static int __check_and_restore_backup_dbs() {
- if (__check_and_restore_backup(DBPATH))
+static int __db_integrity_check(char *db_path)
+{
+ const char *query = "PRAGMA integrity_check";
+ const char *val;
+ sqlite3 *db;
+ sqlite3_stmt *stmt;
+ int ret;
+
+ if (access(db_path, F_OK))
+ return 0;
+
+ ret = sqlite3_open_v2(db_path, &db, SQLITE_OPEN_READONLY, NULL);
+ if (ret != SQLITE_OK) {
+ _LOGE("Fail to open (%s) db handle\n", db_path);
return -1;
+ }
- if (__check_and_restore_backup(JOURNAL_DBPATH))
+ ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ _LOGE("prepare failed: %s\n", sqlite3_errmsg(db));
+ sqlite3_close_v2(db);
return -1;
+ }
- if (__check_and_restore_backup(CERT_DBPATH))
+ if (sqlite3_step(stmt) != SQLITE_ROW) {
+ _LOGE("sqlite3_step fail\n");
+ sqlite3_finalize(stmt);
+ sqlite3_close_v2(db);
return -1;
+ }
- if (__check_and_restore_backup(JOURNAL_CERT_DBPATH))
+ val = (const char *)sqlite3_column_text(stmt, 0);
+ if (strcmp(val, "ok")) {
+ _LOGE("Fail to integrity check, db(%s), val(%s)\n",
+ db_path, val);
+ sqlite3_finalize(stmt);
+ sqlite3_close_v2(db);
return -1;
+ }
+
+ sqlite3_finalize(stmt);
+ sqlite3_close_v2(db);
return 0;
}
-static int __backup_file(const char *src_path, const char *dest_path)
+static int __integrity_check_backup_dbs(void)
{
- int ret = 0;
- int rc;
- FILE *src = NULL;
- FILE *dest = NULL;
- char temp_buf[8192] = {'\0', };
- size_t size_of_char = sizeof(char);
- size_t size_of_temp_buf = sizeof(temp_buf);
+ char parser_db_bck[BUF_SIZE];
+ char cert_db_bck[BUF_SIZE];
- retvm_if(src_path == NULL || dest_path == NULL,
- -1, "Invalid parameters");
+ snprintf(parser_db_bck, BUF_SIZE, "%s.bck", DBPATH);
+ snprintf(cert_db_bck, BUF_SIZE, "%s.bck", CERT_DBPATH);
+
+ retvm_if(__db_integrity_check(parser_db_bck) < 0,
+ -1, "Fail to integrity check db(%s)\n",
+ parser_db_bck);
+
+ retvm_if(__db_integrity_check(cert_db_bck) < 0,
+ -1, "Fail to integrity check db(%s)\n",
+ cert_db_bck);
- retvm_if(access(src_path, F_OK) != 0, -1,
- "File(%s) is not exist", src_path);
+ return 0;
+}
+static void __remove_backup_path(const char *origin_path)
+{
+ char backup_path[BUF_SIZE];
+ char journal_backup_path[BUF_SIZE];
+
+ snprintf(backup_path, BUF_SIZE, "%s.bck", origin_path);
+ snprintf(journal_backup_path, BUF_SIZE, "%s.bck-journal", origin_path);
+
+ if (access(backup_path, F_OK) == 0 && remove(backup_path))
+ _LOG("cannot remove backup file(%s): %d", backup_path, errno);
+
+ if (access(journal_backup_path, F_OK) == 0
+ && remove(journal_backup_path))
+ _LOG("cannot remove backup file(%s): %d",
+ journal_backup_path, errno);
+}
+
+static void __remove_backup_dbs(void)
+{
+ __remove_backup_path(DBPATH);
+ __remove_backup_path(CERT_DBPATH);
+}
+
+static int __check_and_restore_backup_dbs(void)
+{
// if backup flag exists, it means the previous backup process aborted.
- if (__check_backup_flag(src_path)) {
- if (access(dest_path, F_OK) == 0) {
- if (remove(dest_path))
- _LOG("Failed to remove uncompleted backup file "
- "%s: %d", dest_path, errno);
- return -1;
- }
- } else {
- if (__create_backup_flag(src_path)) {
- _LOG("failed to create backup flag");
- return -1;
- }
+ if (__check_backup_flag(DBPATH) == 0
+ || __check_backup_flag(CERT_DBPATH) == 0) {
+ __remove_backup_dbs();
+ __remove_backup_flag(DBPATH);
+ __remove_backup_flag(CERT_DBPATH);
+
+ return 0;
+ }
+
+ if (__integrity_check_backup_dbs() < 0) {
+ __remove_backup_dbs();
+ return 0;
}
- src = fopen(src_path, "r");
- tryvm_if(src == NULL, ret = -1, "Failed to open : %s\n", src_path);
+ if (__check_and_restore_backup(DBPATH))
+ return -1;
- dest = fopen(dest_path, "w");
- tryvm_if(dest == NULL, ret = -1, "Failed to open : %s\n", dest_path);
+ if (__check_and_restore_backup(CERT_DBPATH))
+ return -1;
- while (!feof(src)) {
- rc = fread(temp_buf, size_of_char, size_of_temp_buf, src);
- fwrite(temp_buf, size_of_char, rc, dest);
+ return 0;
+}
+
+static int __backup_file(const char *src_path, const char *dest_path)
+{
+ int ret = 0;
+ sqlite3 *src_db;
+ sqlite3 *dest_db;
+ sqlite3_backup *p_backup;
+
+ if (src_path == NULL || dest_path == NULL) {
+ _LOGE("Invalid parameters");
+ return -1;
}
- fsync(fileno(dest));
+ if (access(src_path, F_OK) != 0) {
+ _LOGE("File(%s) is not exist", src_path);
+ return -1;
+ }
-catch:
- if (src)
- fclose(src);
+ if (__create_backup_flag(src_path)) {
+ _LOG("failed to create backup flag");
+ return -1;
+ }
+
+ ret = sqlite3_open_v2(src_path, &src_db, SQLITE_OPEN_READONLY, NULL);
+ if (ret != SQLITE_OK) {
+ _LOGE("Fail to open (%s) db handle\n", src_path);
+ return -1;
+ }
+
+ ret = sqlite3_open_v2(dest_path, &dest_db,
+ SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
+ if (ret != SQLITE_OK) {
+ _LOGE("Fail to open (%s) db handle\n", dest_path);
+ sqlite3_close_v2(src_db);
+ return -1;
+ }
- if (dest)
- fclose(dest);
+ p_backup = sqlite3_backup_init(dest_db, "main", src_db, "main");
+ if (p_backup) {
+ do {
+ ret = sqlite3_backup_step(p_backup, -1);
+ if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED)
+ sqlite3_sleep(250);
+ } while (ret == SQLITE_OK || ret == SQLITE_BUSY
+ || ret == SQLITE_LOCKED);
+ sqlite3_backup_finish(p_backup);
+ }
+
+ ret = sqlite3_errcode(dest_db);
+ if (ret != SQLITE_OK) {
+ _LOGE("Fail to backup db err(%d)\n", ret);
+ sqlite3_close_v2(src_db);
+ sqlite3_close_v2(dest_db);
+ return -1;
+ }
+
+ sqlite3_close_v2(src_db);
+ sqlite3_close_v2(dest_db);
__remove_backup_flag(src_path);
- return ret;
+ return 0;
}
-static int __backup_db(const char *src_path, const char *dest_path) {
+static int __backup_db(const char *src_path, const char *dest_path)
+{
if (__backup_file(src_path, dest_path) != 0)
return -1;
return 0;
}
-static int __make_backup_dbs() {
- int ret = 0;
+static int __make_backup_dbs()
+{
char parser_db_bck[BUF_SIZE];
- char parser_db_journal_bck[BUF_SIZE];
char cert_db_bck[BUF_SIZE];
- char cert_db_journal_bck[BUF_SIZE];
snprintf(parser_db_bck, BUF_SIZE, "%s.bck", DBPATH);
- snprintf(parser_db_journal_bck, BUF_SIZE, "%s.bck", JOURNAL_DBPATH);
snprintf(cert_db_bck, BUF_SIZE, "%s.bck", CERT_DBPATH);
- snprintf(cert_db_journal_bck, BUF_SIZE, "%s.bck", JOURNAL_CERT_DBPATH);
-
- tryvm_if(__backup_db(DBPATH, parser_db_bck) == -1,
- ret = -1, "Fail to backup [%s] to [%s]\n",
- DBPATH, parser_db_bck);
- tryvm_if(__backup_db(JOURNAL_DBPATH, parser_db_journal_bck) == -1,
- ret = -1, "Fail to backup [%s] to [%s]\n",
- JOURNAL_DBPATH, parser_db_journal_bck);
-
- tryvm_if(__backup_db(CERT_DBPATH, cert_db_bck) == -1,
- ret = -1, "Fail to backup [%s] to [%s]\n",
- CERT_DBPATH, cert_db_bck);
+ if (__backup_db(DBPATH, parser_db_bck) < 0) {
+ _LOGE("Fail to backup [%s] to [%s]\n", DBPATH, parser_db_bck);
+ __remove_backup_dbs();
+ return -1;
+ }
- tryvm_if(__backup_db(JOURNAL_CERT_DBPATH, cert_db_journal_bck) == -1,
- ret = -1, "Fail to backup [%s] to [%s]\n",
- JOURNAL_CERT_DBPATH, cert_db_journal_bck);
+ if (__backup_db(CERT_DBPATH, cert_db_bck) < 0) {
+ _LOGE("Fail to backup [%s] to [%s]\n",
+ CERT_DBPATH, cert_db_bck);
+ __remove_backup_dbs();
+ return -1;
+ }
return 0;
-
-catch:
- remove(parser_db_bck);
- remove(parser_db_journal_bck);
- remove(cert_db_bck);
- remove(cert_db_journal_bck);
-
- return ret;
-}
-
-static void __remove_backup_path(const char *origin_path) {
- char backup_path[BUF_SIZE];
-
- snprintf(backup_path, BUF_SIZE, "%s.bck", origin_path);
-
- if (remove(backup_path))
- _LOG("cannot remove backup file(%s): %d", backup_path, errno);
-}
-
-static void __remove_backup_dbs() {
- __remove_backup_path(DBPATH);
- __remove_backup_path(JOURNAL_DBPATH);
- __remove_backup_path(CERT_DBPATH);
- __remove_backup_path(JOURNAL_CERT_DBPATH);
}
int main(int argc, char *argv[])
int ret = 0;
ret = __check_and_restore_backup_dbs();
- retvm_if(ret < 0, -1, "__check_and_restore_backup_dbs is failed.\n");
+ if (ret < 0) {
+ _LOGE("__check_and_restore_backup_dbs is failed.\n");
+ return -1;
+ }
ret = __make_backup_dbs();
- retvm_if(ret < 0, -1, "__make_backup_dbs is failed.\n");
+ if (ret < 0) {
+ _LOGE("__make_backup_dbs is failed.\n");
+ return -1;
+ }
/* check pkgmgr-fota dir, if it is not, then exit */
ret = __check_pkgmgr_fota_dir();
- retvm_if(ret < 0, -1, "__check_pkgmgr_fota_dir is failed.\n");
+ if (ret < 0) {
+ _LOGE("__check_pkgmgr_fota_dir is failed.\n");
+ __remove_backup_dbs();
+ return -1;
+ }
/* clean pkgid list file */
ret = __remove_pkgid_list();
/* get pkgid from orginal pkgmgr db */
ret = __get_pkgid_list_from_db_and_xml();
- retvm_if(ret < 0, -1, "__get_pkgid_list_from_db_and_xml is failed.\n");
+ if (ret < 0) {
+ _LOGE("__get_pkgid_list_from_db_and_xml is failed.\n");
+ __remove_backup_dbs();
+ return -1;
+ }
//__get_pkginfo_from_opt();
ret = __check_tmp_all_preload_rw_pkg_list();
- retvm_if(ret < 0, -1,
- "__check_tmp_all_preload_rw_pkg_list is failed.\n");
+ if (ret < 0) {
+ _LOGE("__check_tmp_all_preload_rw_pkg_list is failed.\n");
+ __remove_backup_dbs();
+ return -1;
+ }
preload_rw_table = g_hash_table_new_full(
g_str_hash, g_str_equal, free, __free_pkginfo);
if (__fill_preload_rw_table(preload_rw_table) < 0) {
ret = __find_preload_rw_pkgid_from_db(preload_rw_table);
- retvm_if(ret < 0, -1, "__find_preload_rw_pkgid_from_db is failed\n");
+ if (ret < 0) {
+ _LOGE("__find_preload_rw_pkgid_from_db is failed\n");
+ g_hash_table_destroy(preload_rw_table);
+ __remove_backup_dbs();
+ return -1;
+ }
}
if (argc == 1) {
ret = __process_ro_fota(preload_rw_table);
if (ret < 0) {
- g_hash_table_destroy(preload_rw_table);
_LOGE("__process_ro_fota is failed.\n");
- return EXIT_FAILURE;
+ g_hash_table_destroy(preload_rw_table);
+ __remove_backup_dbs();
+ return -1;
}
ret = __process_rw_fota(preload_rw_table);
if (ret < 0) {
- g_hash_table_destroy(preload_rw_table);
_LOGE("__process_rw_fota is failed.\n");
- return EXIT_FAILURE;
+ g_hash_table_destroy(preload_rw_table);
+ __remove_backup_dbs();
+ return -1;
}
} else {
if (strcmp(argv[1], "-rof") == 0) {
ret = __process_ro_fota(preload_rw_table);
if (ret < 0) {
- g_hash_table_destroy(preload_rw_table);
_LOGE("__process_ro_fota is failed.\n");
- return EXIT_FAILURE;
+ g_hash_table_destroy(preload_rw_table);
+ __remove_backup_dbs();
+ return -1;
}
} else if (strcmp(argv[1], "-rwf") == 0) {
ret = __process_rw_fota(preload_rw_table);
if (ret < 0) {
- g_hash_table_destroy(preload_rw_table);
_LOGE("__process_rw_fota is failed.\n");
- return EXIT_FAILURE;
+ g_hash_table_destroy(preload_rw_table);
+ __remove_backup_dbs();
+ return -1;
}
} else {
fprintf(stderr, "not supported operand\n");
+ g_hash_table_destroy(preload_rw_table);
+ __remove_backup_dbs();
+ return -1;
}
}
__make_preload_rw_list(preload_rw_table);
g_hash_table_destroy(preload_rw_table);
__remove_backup_dbs();
- return EXIT_SUCCESS;
+ return 0;
}