#define _GNU_SOURCE
+#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
+#include <sys/smack.h>
#include <sys/stat.h>
#include <errno.h>
#include <iniparser.h>
#include <sys/time.h>
#include <libxml/xmlreader.h>
#include <sqlite3.h>
+#include <pwd.h>
#include <package-manager-types.h>
#include <package-manager.h>
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)
+#define APPFW_USER "app_fw"
struct pkginfo {
char *pkgid;
return 0;
}
+#define DB_LABEL "User::Home"
+#define SET_SMACK_LABEL(x) \
+do { \
+ if (smack_setlabel((x), DB_LABEL, SMACK_LABEL_ACCESS)) \
+ _LOGE("failed chsmack -a %s %s", DB_LABEL, x); \
+ else \
+ _LOG("chsmack -a %s %s", DB_LABEL, x); \
+} while (0)
+
+static int __set_db_permission(const char *path)
+{
+ int fd;
+ struct stat sb;
+ mode_t mode;
+ uid_t uid;
+ struct passwd pwd;
+ struct passwd *result;
+ char buf[BUF_SIZE];
+ int ret;
+
+ ret = getpwnam_r(APPFW_USER, &pwd, buf, sizeof(buf), &result);
+ if (result == NULL) {
+ if (ret == 0)
+ _LOGE("no such user: %s", APPFW_USER);
+ else
+ _LOGE("getpwnam_r failed: %d", errno);
+ return -1;
+ }
+ uid = pwd.pw_uid;
+
+ ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
+ if (result == NULL) {
+ if (ret == 0)
+ _LOGE("no such user: %d", uid);
+ else
+ _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);
+ close(fd);
+ return -1;
+ }
+ 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 buf[BUF_SIZE];
+ snprintf(backup_path, BUF_SIZE, "%s.bck", 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,
+ strerror_r(errno, buf, sizeof(buf)));
+ return -1;
+ }
+ }
+
+ if (rename(backup_path, origin_path)) {
+ _LOG("fail to rename %s to %s : %s\n", backup_path, origin_path,
+ strerror_r(errno, buf, sizeof(buf)));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __check_and_restore_backup_dbs() {
+ if (__check_and_restore_backup(DBPATH))
+ return -1;
+
+ if (__check_and_restore_backup(JOURNAL_DBPATH))
+ return -1;
+
+ if (__check_and_restore_backup(CERT_DBPATH))
+ return -1;
+
+ if (__check_and_restore_backup(JOURNAL_CERT_DBPATH))
+ return -1;
+
+ return 0;
+}
+
+static int __backup_file(const char *src_path, const char *dest_path)
+{
+ 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);
+
+ retvm_if(src_path == NULL || dest_path == NULL,
+ -1, "Invalid parameters");
+
+ retvm_if(access(src_path, F_OK) != 0, -1,
+ "File(%s) is not exist", src_path);
+
+ retvm_if(access(dest_path, F_OK) == 0, -1,
+ "File(%s) is already exist", dest_path);
+
+ retvm_if(rename(src_path, dest_path) != 0, -1,
+ "Fail to move file %s to %s", src_path, dest_path);
+
+ src = fopen(dest_path, "r");
+ tryvm_if(src == NULL, ret = -1, "Failed to open : %s\n", dest_path);
+
+ dest = fopen(src_path, "w");
+ tryvm_if(dest == NULL, ret = -1, "Failed to open : %s\n", src_path);
+
+ while (!feof(src)) {
+ rc = fread(temp_buf, size_of_char, size_of_temp_buf, src);
+ fwrite(temp_buf, size_of_char, rc, dest);
+ }
+
+ fsync(fileno(dest));
+
+catch:
+ if (src)
+ fclose(src);
+
+ if (dest)
+ fclose(dest);
+
+ return ret;
+}
+
+static int __make_backup_dbs() {
+ int ret = 0;
+ 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_file(DBPATH, parser_db_bck) == -1,
+ ret = -1, "Fail to backup [%s] to [%s]\n",
+ DBPATH, parser_db_bck);
+ tryvm_if(__set_db_permission(DBPATH) == -1,
+ ret = -1, "Fail to set db permission\n");
+
+ tryvm_if(__backup_file(JOURNAL_DBPATH, parser_db_journal_bck) == -1,
+ ret = -1, "Fail to backup [%s] to [%s]\n",
+ JOURNAL_DBPATH, parser_db_journal_bck);
+ tryvm_if(__set_db_permission(JOURNAL_DBPATH) == -1,
+ ret = -1, "Fail to set db permission\n");
+
+ tryvm_if(__backup_file(CERT_DBPATH, cert_db_bck) == -1,
+ ret = -1, "Fail to backup [%s] to [%s]\n",
+ CERT_DBPATH, cert_db_bck);
+ tryvm_if(__set_db_permission(CERT_DBPATH) == -1,
+ ret = -1, "Fail to set db permission\n");
+
+ tryvm_if(__backup_file(JOURNAL_CERT_DBPATH, cert_db_journal_bck) == -1,
+ ret = -1, "Fail to backup [%s] to [%s]\n",
+ JOURNAL_CERT_DBPATH, cert_db_journal_bck);
+ tryvm_if(__set_db_permission(JOURNAL_CERT_DBPATH) == -1,
+ ret = -1, "Fail to set db permission\n");
+
+ 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[])
{
GHashTable *preload_rw_table;
int ret = 0;
+ ret = __check_and_restore_backup_dbs();
+ retvm_if(ret < 0, -1, "__check_and_restore_backup_dbs is failed.\n");
+
+ ret = __make_backup_dbs();
+ retvm_if(ret < 0, -1, "__make_backup_dbs is failed.\n");
+
/* 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");
}
__make_preload_rw_list(preload_rw_table);
g_hash_table_destroy(preload_rw_table);
+ __remove_backup_dbs();
return EXIT_SUCCESS;
}