Add preference_tool 28/174628/4
authorSemun Lee <semun.lee@samsung.com>
Tue, 3 Apr 2018 08:25:42 +0000 (17:25 +0900)
committerSemun Lee <semun.lee@samsung.com>
Tue, 3 Apr 2018 08:40:07 +0000 (17:40 +0900)
This tool is migrated from tizen_3.0 branch.

Change-Id: I48a7488def18819fce4253aeac61e9e069cf424b
Signed-off-by: Semun Lee <semun.lee@samsung.com>
packaging/capi-appfw-preference.spec
src/CMakeLists.txt
src/tool/CMakeLists.txt [new file with mode: 0644]
src/tool/pref_dump.sh [new file with mode: 0644]
src/tool/preference_tool.c [new file with mode: 0644]

index bf4cce5c9d3e8eb9a410f3f3b43d3ff62dbe58f3..520b7db1c2a14f0009e9165b60eb5b250b8fc924 100644 (file)
@@ -12,6 +12,7 @@ BuildRequires:  pkgconfig(sqlite3)
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(capi-appfw-app-common)
 BuildRequires:  pkgconfig(capi-base-common)
+BuildRequires:  pkgconfig(libtzplatform-config)
 
 %description
 An Application preference library in Tizen C API
@@ -43,6 +44,8 @@ rm -rf %{buildroot}
 %files
 %manifest %{name}.manifest
 %{_libdir}/libcapi-appfw-preference.so.*
+%attr(0700,root,root) %{_bindir}/preference_tool
+%attr(755,root,root) /opt/etc/dump.d/module.d/pref_dump.sh
 %license LICENSE
 
 %files devel
index e2b7ec9018216a2b9653fee135ef316c177cfa16..b3a18e8625f55da2c1ca715b495865dd0cd20333 100644 (file)
@@ -63,4 +63,4 @@ CONFIGURE_FILE(
 )
 INSTALL(FILES ${CMAKE_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
 
-
+ADD_SUBDIRECTORY(tool)
diff --git a/src/tool/CMakeLists.txt b/src/tool/CMakeLists.txt
new file mode 100644 (file)
index 0000000..144de57
--- /dev/null
@@ -0,0 +1,31 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(tool_name "preference_tool")
+
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+SET(INC_DIR ${CMAKE_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${INC_DIR})
+
+SET(requires "sqlite3 glib-2.0 capi-appfw-app-common libtzplatform-config")
+
+INCLUDE(FindPkgConfig)
+SET(EXTRA_CFLAGS "")
+pkg_check_modules(${tool_name} REQUIRED ${requires})
+FOREACH(flag ${${tool_name}_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE -Wall -Werror")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIB_INSTALL_DIR}")
+
+add_executable(${tool_name}
+               preference_tool.c
+               )
+
+TARGET_LINK_LIBRARIES(${tool_name} ${fw_name} ${${tool_name}_LDFLAGS} -pie)
+INSTALL(TARGETS ${tool_name} DESTINATION bin)
+INSTALL(FILES pref_dump.sh DESTINATION /opt/etc/dump.d/module.d)
+
diff --git a/src/tool/pref_dump.sh b/src/tool/pref_dump.sh
new file mode 100644 (file)
index 0000000..575ebc9
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+PREF_DUMP=$1/pref
+/bin/mkdir -p $PREF_DUMP
+
+for file in `/usr/bin/find /opt/usr/apps/ -name *.pref`
+do
+       chsmack $file >> $PREF_DUMP/pref_value
+       chsmack $file/* >> $PREF_DUMP/pref_value
+       ls -alZ $file >> $PREF_DUMP/pref_value
+       PKG_ID=`echo "$file" | awk -F'/' '{print $5}'`
+       /usr/bin/preference_tool get $PKG_ID >> $PREF_DUMP/pref_value
+       mkdir -p $PREF_DUMP/$PKG_ID
+       cp -rf --preserve=all $file/* $PREF_DUMP/$PKG_ID
+       echo "===============================================" >> $PREF_DUMP/pref_value
+done
diff --git a/src/tool/preference_tool.c b/src/tool/preference_tool.c
new file mode 100644 (file)
index 0000000..9791277
--- /dev/null
@@ -0,0 +1,1056 @@
+/*
+ * Copyright (c) 2011 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <grp.h>
+#include <linux/limits.h>
+#include <wordexp.h>
+#include <sqlite3.h>
+#include <glib.h>
+#include <locale.h>
+
+#include <app_common_internal.h>
+#include <app_preference.h>
+#include <app_preference_internal.h>
+#include <tzplatform_config.h>
+
+#define PREF_F_KEY_NAME "pref_key"
+#define PREF_F_TYPE_NAME "pref_type"
+#define PREF_F_DATA_NAME "pref_data"
+#define PREF_TBL_NAME "pref"
+
+#define DELIMITER 29
+#define HISTORY "/opt/var/kdb/.restore/.history/preference"
+
+typedef enum {
+       PREFERENCE_OLD_TYPE_INT = 1,
+       PREFERENCE_OLD_TYPE_BOOLEAN,
+       PREFERENCE_OLD_TYPE_DOUBLE,
+       PREFERENCE_OLD_TYPE_STRING
+} old_preference_type_e;
+
+typedef enum {
+       PREFERENCE_OP_RESTORE = 1,
+       PREFERENCE_OP_NEW_CREATE
+} preference_op_type;
+
+static sqlite3 *pref_db;
+
+static void _finish(void *data)
+{
+       if (pref_db != NULL) {
+               sqlite3_close(pref_db);
+               pref_db = NULL;
+       }
+}
+
+static int _busy_handler(void *pData, int count)
+{
+       if (count < 5) {
+               printf("Busy Handler Called!: PID(%d) / CNT(%d)\n",
+                               getpid(), count + 1);
+               usleep((count + 1) * 100000);
+               return 1;
+       }
+
+       return 0;
+}
+
+static int _initialize(const char *db_path)
+{
+       int ret;
+       char *path = strdup(db_path);
+
+       if (!path) {
+               printf("error, strdup(): Insufficient memory available\n");
+               return -1;
+       }
+
+       ret = sqlite3_open(path, &pref_db);
+       if (ret != SQLITE_OK) {
+               printf("error, fail to open db\n");
+               pref_db = NULL;
+               free(path);
+               return -1;
+       }
+
+       ret = sqlite3_busy_handler(pref_db, _busy_handler, NULL);
+       if (ret != SQLITE_OK)
+               printf("error, fail to resigter busy handler\n");
+       app_finalizer_add(_finish, NULL);
+       free(path);
+
+       return 0;
+}
+
+static int __system(const char *cmd)
+{
+       int status;
+       pid_t cpid;
+       wordexp_t p;
+       char **w;
+
+       cpid = fork();
+       if (cpid < 0) {
+               perror("fork");
+               return -1;
+       }
+
+       if (cpid == 0) {
+               /* child */
+               wordexp(cmd, &p, 0);
+               w = p.we_wordv;
+
+               execv(w[0], (char * const *)w);
+
+               wordfree(&p);
+
+               _exit(-1);
+       } else {
+               /* parent */
+               if (waitpid(cpid, &status, 0) == -1) {
+                       perror("waitpid failed\n");
+                       return -1;
+               }
+
+               if (WIFSIGNALED(status)) {
+                       printf("signal(%d)\n", WTERMSIG(status));
+                       perror("exit by signal\n");
+                       return -1;
+               }
+
+               if (!WIFEXITED(status)) {
+                       perror("exit abnormally\n");
+                       return -1;
+               }
+
+               if (WIFEXITED(status) && WEXITSTATUS(status)) {
+                       perror("child return error\n");
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+static const char *__get_package_path(const char *package_id)
+{
+       uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+       const char *path;
+
+       tzplatform_set_user(uid);
+       path = tzplatform_mkpath(TZ_USER_APP, package_id);
+       tzplatform_reset_user();
+
+       return path;
+}
+
+static int is_exist_package(const char *pkgid)
+{
+       const char *pkg_path;
+
+       pkg_path = __get_package_path(pkgid);
+       if (pkg_path == NULL) {
+               printf("Failed to get package path(%s)\n", pkgid);
+               return -1;
+       }
+
+       if (access(pkg_path, F_OK) == -1) {
+               printf("package(%s) is not exist.\n", pkgid);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int is_exist_data_dir_in_package(const char *pkgid)
+{
+       char pkg_data_path[PATH_MAX];
+       const char *pkg_path;
+
+       pkg_path = __get_package_path(pkgid);
+       if (pkg_path == NULL) {
+               printf("Failed to get package path(%s)\n", pkgid);
+               return -1;
+       }
+
+       snprintf(pkg_data_path, sizeof(pkg_data_path), "%s/data/", pkg_path);
+       if (access(pkg_data_path, F_OK) == -1) {
+               printf("Data directory is not exist in package(%s).\n", pkgid);
+               return -1;
+       }
+
+       return 0;
+}
+
+static gid_t __get_gid(const char *name)
+{
+       char buf[LINE_MAX];
+       struct group entry;
+       struct group *ge;
+       int ret;
+
+       ret = getgrnam_r(name, &entry, buf, sizeof(buf), &ge);
+       if (ret || ge == NULL) {
+               printf("Fail to get gid of %s\n", name);
+               return -1;
+       }
+
+       return entry.gr_gid;
+}
+
+static int _make_key_path(const char *pkgid, const char *keyname, char *path)
+{
+       const char *key;
+       gchar *convert_key;
+       char pref_dir[PATH_MAX];
+       char cmd[PATH_MAX];
+       mode_t dir_mode = 0664 | 0111;
+       const char *pkg_path;
+       uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+       gid_t gid = __get_gid("system_share");
+
+       pkg_path = __get_package_path(pkgid);
+       if (pkg_path == NULL) {
+               printf("Failed to get package path(%s)\n", pkgid);
+               return -1;
+       }
+
+       snprintf(pref_dir, sizeof(pref_dir), "%s/data/.pref", pkg_path);
+       if (access(pref_dir, F_OK) == -1) {
+               if (mkdir(pref_dir, dir_mode) < 0) {
+                       if (is_exist_package(pkgid) < 0)
+                               return -1;
+
+                       if (is_exist_data_dir_in_package(pkgid) < 0)
+                               return -1;
+
+                       printf("pref_dir making failed.(%d/%s)\n",
+                                       errno, strerror(errno));
+                       return -1;
+               }
+               if (chown(pref_dir, uid, gid) < 0) {
+                       printf("chown() failed(%d/%s)\n",
+                                       errno, strerror(errno));
+                       return -1;
+               }
+       }
+
+       snprintf(cmd, sizeof(cmd),
+                       "/usr/bin/chsmack -t -a User::Pkg::\"%s\" %s",
+                       pkgid, pref_dir);
+       if (__system(cmd)) {
+               printf("[pref] cmd error()\n");
+               return -1;
+       }
+
+       convert_key = g_compute_checksum_for_string(G_CHECKSUM_SHA1,
+                       keyname, strlen(keyname));
+       if (convert_key == NULL) {
+               LOGE("fail to convert");
+               return PREFERENCE_ERROR_IO_ERROR;
+       }
+
+       key = (const char *)convert_key;
+       snprintf(path, PATH_MAX, "%s/%s", pref_dir, key);
+       g_free(convert_key);
+
+       return 0;
+}
+
+static int _get_key_name(const char *keyfile, char **keyname)
+{
+       int read_size = 0;
+       size_t keyname_len = 0;
+       char *convert_key = NULL;
+       FILE *fp = NULL;
+
+       fp = fopen(keyfile, "r");
+       if (fp == NULL)
+               return PREFERENCE_ERROR_FILE_OPEN;
+
+       read_size = fread((void *)&keyname_len, sizeof(int), 1, fp);
+       if (read_size <= 0 || keyname_len > PREFERENCE_KEY_PATH_LEN) {
+               fclose(fp);
+               return PREFERENCE_ERROR_FILE_FREAD;
+       }
+
+       convert_key = (char *)calloc(1, keyname_len + 1);
+       if (convert_key == NULL) {
+               LOGE("memory alloc failed");
+               fclose(fp);
+               return PREFERENCE_ERROR_OUT_OF_MEMORY;
+       }
+
+       read_size = fread((void *)convert_key, keyname_len, 1, fp);
+       if (read_size <= 0) {
+               free(convert_key);
+               fclose(fp);
+               return PREFERENCE_ERROR_FILE_FREAD;
+       }
+
+       *keyname = convert_key;
+
+       fclose(fp);
+
+       return PREFERENCE_ERROR_NONE;
+}
+
+static int _create_key(const char *path, const char *pkgid)
+{
+       int fd;
+       char cmd[PATH_MAX];
+       uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+       gid_t gid = __get_gid("system_share");
+
+       fd = open(path, O_RDWR | O_CREAT,
+                       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+       if (fd == -1) {
+               printf("[error] %d(%s)\n", errno, strerror(errno));
+               return -1;
+       }
+       close(fd);
+
+       if (chown(path, uid, gid) < 0) {
+               printf("chown() failed(%d/%s)\n", errno, strerror(errno));
+               return -1;
+       }
+
+       snprintf(cmd, sizeof(cmd), "/usr/bin/chsmack -a User::Pkg::\"%s\" %s",
+                       pkgid, path);
+       if (__system(cmd)) {
+               printf("[pref] cmd error()\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+static int _create_new_preference_key(preference_op_type OP, const char *pkgid,
+                       const char *key, const char *type, const char *value)
+{
+       FILE *fp;
+       int ret;
+       char key_path[PATH_MAX] = {0,};
+       size_t keyname_len;
+       int type_i;
+       int temp_i;
+       double temp_d;
+       locale_t loc;
+
+       _make_key_path(pkgid, key, key_path);
+retry:
+       fp = fopen(key_path, "r+");
+       if (fp == NULL) {
+               if (_create_key(key_path, pkgid) == -1) {
+                       printf("preference key failed to create.(%d/%s)\n",
+                                       errno, strerror(errno));
+                       return -1;
+               }
+
+               goto retry;
+       }
+
+       /* write keyname and size */
+       keyname_len = strlen(key);
+       ret = fwrite((void *)&keyname_len, sizeof(int), 1, fp);
+       if (ret <= 0) {
+               printf("preference write key name length error(%d/%s)\n",
+                                               errno, strerror(errno));
+               fclose(fp);
+               return -1;
+       }
+
+       ret = fwrite((void *)key, keyname_len, 1, fp);
+       if (ret <= 0) {
+               printf("preference write key name length error(%d/%s)\n",
+                                               errno, strerror(errno));
+               fclose(fp);
+               return -1;
+       }
+
+       loc = newlocale(LC_NUMERIC_MASK, "C", NULL);
+       uselocale(loc);
+
+       if (OP == PREFERENCE_OP_RESTORE) {
+               type_i = atoi(type);
+               switch (type_i) {
+               case PREFERENCE_OLD_TYPE_INT:
+                       type_i = PREFERENCE_TYPE_INT;
+                       break;
+               case PREFERENCE_OLD_TYPE_DOUBLE:
+                       type_i = PREFERENCE_TYPE_DOUBLE;
+                       break;
+               case PREFERENCE_OLD_TYPE_BOOLEAN:
+                       type_i = PREFERENCE_TYPE_BOOLEAN;
+                       break;
+               case PREFERENCE_OLD_TYPE_STRING:
+                       type_i = PREFERENCE_TYPE_STRING;
+                       break;
+               default:
+                       break;
+               }
+       } else { /* OP is PREFERENCE_OP_NEW_CREATE.*/
+               if (strcmp(type, "int") == 0) {
+                       type_i = PREFERENCE_TYPE_INT;
+               } else if (strcmp(type, "double") == 0) {
+                       type_i = PREFERENCE_TYPE_DOUBLE;
+               } else if (strcmp(type, "bool") == 0) {
+                       type_i = PREFERENCE_TYPE_BOOLEAN;
+               } else if (strcmp(type, "string") == 0) {
+                       type_i = PREFERENCE_TYPE_STRING;
+               } else {
+                       printf("key type is invalid.int|double|bool|string\n");
+                       fclose(fp);
+                       return -1;
+               }
+       }
+
+       ret = fwrite((void *)&type_i, sizeof(int), 1, fp);
+       if (ret <= 0) {
+               if (!errno) {
+                       printf("number of written item is 0. try again\n");
+                       errno = EAGAIN;
+               }
+       }
+
+       switch (type_i) {
+       case PREFERENCE_TYPE_INT:
+               temp_i = atoi(value);
+               ret = fwrite((void *)&temp_i, sizeof(int), 1, fp);
+               if (ret <= 0) {
+                       printf("failed. fwrite() %d\n", ret);
+               } else {
+                       printf("[SET][key]:%s [type]int[value]:%d\n",
+                                       key, temp_i);
+               }
+               break;
+       case PREFERENCE_TYPE_DOUBLE:
+               temp_d = atof(value);
+               ret = fwrite((void *)&temp_d, sizeof(double), 1, fp);
+               if (ret <= 0) {
+                       printf("failed. fwrite() %d\n", ret);
+               } else {
+                       printf("[SET][key]:%s[type]double[value]:%f\n",
+                                       key, temp_d);
+               }
+               break;
+       case PREFERENCE_TYPE_BOOLEAN:
+               temp_i = atoi(value);
+               ret = fwrite((void *)&temp_i, sizeof(int), 1, fp);
+               if (ret <= 0) {
+                       printf("failed. fwrite() %d\n", ret);
+               } else {
+                       printf("[SET][key]:%s [type]bool[value]:%d\n",
+                                       key, temp_i);
+               }
+               break;
+       case PREFERENCE_TYPE_STRING:
+               printf("[SET][key]:%s [type] string [value] %s\n",
+                               key, value);
+               ret = fprintf(fp, "%s", value);
+               if (ftruncate(fileno(fp), ret) == -1) {
+                       printf("[error] ftruncate failed %s(%s)\n",
+                                       key_path, value);
+               }
+               break;
+       default:
+               break;
+       }
+
+       uselocale(LC_GLOBAL_LOCALE);
+       fflush(fp);
+       if (fp) {
+               ret = fdatasync(fileno(fp));
+               fclose(fp);
+       }
+
+       return 0;
+}
+
+static int _print_pref_value_from_file_path(const char *path,
+               const char *keyname)
+{
+       FILE *fp;
+       int type = 0;
+       int read_size;
+       size_t keyname_len = 0;
+       int ret;
+       int value_int = 0;
+       double value_dbl = 0;
+       char file_buf[BUF_LEN] = {0,};
+       char *value_str = NULL;
+       int value_size = 0;
+
+       fp = fopen(path, "r");
+       if (fp == NULL) {
+               printf("fopen() failed.(%d/%s).fp is null.\n",
+                               errno, strerror(errno));
+               return -1;
+       }
+
+       read_size = fread((void *)&keyname_len, sizeof(int), 1, fp);
+       if ((read_size <= 0) || (read_size > sizeof(int))) {
+               printf("key(%s) name length read error(%d)\n", keyname, errno);
+               fclose(fp);
+               return -1;
+       }
+
+       ret = fseek(fp, keyname_len, SEEK_CUR);
+       if (ret) {
+               printf("key(%s) name seek error(%d)\n", keyname, errno);
+               fclose(fp);
+               return -1;
+       }
+
+       /* read data type */
+       read_size = fread((void *)&type, sizeof(int), 1, fp);
+       if ((read_size <= 0) || (read_size > sizeof(int))) {
+               printf("key(%s) type read error(%d)\n", keyname, errno);
+               fclose(fp);
+               return -1;
+       }
+
+       /* read data value */
+       switch (type) {
+       case PREFERENCE_TYPE_INT:
+               read_size = fread((void *)&value_int, sizeof(int),
+                               1, fp);
+               if ((read_size <= 0) || (read_size > sizeof(int))) {
+                       if (!ferror(fp)) {
+                               printf("number of read items wrong.err: %d\n",
+                                               errno);
+                       }
+               } else {
+                       printf("[key] %s  [type] int  [value] %d\n",
+                                       keyname, value_int);
+               }
+               break;
+       case PREFERENCE_TYPE_DOUBLE:
+               read_size = fread((void *)&value_dbl, sizeof(double),
+                               1, fp);
+               if ((read_size <= 0) || (read_size > sizeof(double))) {
+                       if (!ferror(fp)) {
+                               printf("number of read items wrong.err:%d\n",
+                                               errno);
+                       }
+               } else {
+                       printf("[key] %s [type] double [value] %f\n",
+                                       keyname, value_dbl);
+               }
+               break;
+       case PREFERENCE_TYPE_BOOLEAN:
+               read_size = fread((void *)&value_int, sizeof(int),
+                               1, fp);
+               if ((read_size <= 0) || (read_size > sizeof(int))) {
+                       if (!ferror(fp)) {
+                               printf("number of read items wrong.err:%d\n",
+                                               errno);
+                       }
+               } else {
+                       printf("[key] %s [type] bool [value] %d\n",
+                                       keyname, value_int);
+               }
+               break;
+       case PREFERENCE_TYPE_STRING:
+               while (fgets(file_buf, sizeof(file_buf), fp)) {
+                       if (value_str) {
+                               value_size += strlen(file_buf);
+                               value_str = (char *)realloc(value_str,
+                                               value_size);
+                               if (value_str == NULL)
+                                       break;
+
+                               strncat(value_str, file_buf, strlen(file_buf));
+                       } else {
+                               value_size = strlen(file_buf) + 1;
+                               value_str = (char *)malloc(value_size);
+                               if (value_str == NULL)
+                                       break;
+
+                               memset(value_str, 0x00, value_size);
+                               strncpy(value_str, file_buf, strlen(file_buf));
+                       }
+               }
+
+               if (ferror(fp)) {
+                       printf("error, fgets() failed.\n");
+               } else {
+                       if (value_str) {
+                               printf("[key] %s [type] string [value] %s\n",
+                                               keyname, value_str);
+                       } else {
+                               printf("[key] %s [value] NULL\n", keyname);
+                       }
+               }
+               if (value_str)
+                       free(value_str);
+               break;
+       default:
+               break;
+       }
+       fclose(fp);
+
+       return 0;
+}
+
+static int _restore(const char *pkgid)
+{
+       int ret;
+       char *query;
+       sqlite3_stmt *stmt = NULL;
+       const char *tmp_key;
+       const char *tmp_type;
+       const char *tmp_value;
+
+       query = sqlite3_mprintf("SELECT * FROM %s;", PREF_TBL_NAME);
+       if (query == NULL) {
+               printf("error, query is null\n");
+               return -1;
+       }
+
+       /*prepare query*/
+       ret = sqlite3_prepare_v2(pref_db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               printf("error, sqlite3_prepare_v2 failed(%d)\n", ret);
+               return -1;
+       }
+
+       while (1) {
+               ret = sqlite3_step(stmt);
+               if (ret == SQLITE_ROW) {
+                       tmp_key = (const char *)sqlite3_column_text(stmt, 0);
+                       tmp_type = (const char *)sqlite3_column_text(stmt, 1);
+                       tmp_value = (const char *)sqlite3_column_text(stmt, 2);
+
+                       printf("col[key]:%s\ncol[type]:%s\ncol[value]:%s\n",
+                                       tmp_key, tmp_type, tmp_value);
+
+                       /*key create*/
+                       ret = _create_new_preference_key(PREFERENCE_OP_RESTORE,
+                                       pkgid, tmp_key, tmp_type, tmp_value);
+                       if (ret < 0) {
+                               printf("create new prefer key failed (%d)\n",
+                                               ret);
+                               return -1;
+                       }
+               } else {
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+
+static int _remove_old_db(const char *db_path)
+{
+       int ret;
+       char journal_path[PATH_MAX];
+       char *path = strdup(db_path);
+
+       if (!path) {
+               printf("error, strdup(): Insufficient memory available\n");
+               return -1;
+       }
+
+       ret = remove(path);
+       if (ret < 0) {
+               printf("error, remove(%d/%s)\n", errno, strerror(errno));
+               free(path);
+               return -1;
+       }
+
+       snprintf(journal_path, sizeof(journal_path), "%s-journal", path);
+
+       if (access(journal_path, F_OK) == 0) {
+               ret = remove(journal_path);
+               if (ret < 0) {
+                       printf("error, remove(%d/%s)\n", errno,
+                                               strerror(errno));
+                       free(path);
+                       return -1;
+               }
+       }
+       free(path);
+
+       return 0;
+}
+
+static void _print_help(void)
+{
+       printf("\n[Set preference value]\n");
+       printf("preference_tool set <pkgid> <key_name> <type> <value>\n");
+       printf("ex) preference_tool set ");
+       printf("org.tizen.preferencetest test_key string value\n\n");
+
+       printf("[Get preference value]\n");
+       printf("preference_tool get <pkgid>\n");
+       printf("ex) preference_tool get org.tizen.preferencetest\n\n");
+       printf("preference_tool get <pkgid> <key>\n");
+       printf("ex) preference_tool get ");
+       printf("org.tizen.preferencetest test_key\n\n");
+
+       printf("[Convert preference file name from plain text]\n");
+       printf("preference_tool convert_file_name <app_dir>\n");
+       printf("ex) preference_tool convert_file_name /opt/usr/apps\n\n");
+}
+
+static void _preference_set_key(const char *pkgid, const char *key,
+               const char *type, const char *value)
+{
+       _create_new_preference_key(PREFERENCE_OP_NEW_CREATE,
+                       pkgid, key, type, value);
+}
+
+static void _print_preference_key(const char *pkgid, const char *key)
+{
+       char key_path[PATH_MAX] = {0,};
+
+       _make_key_path(pkgid, key, key_path);
+       _print_pref_value_from_file_path(key_path, key);
+}
+
+static void _print_preference_in_package(const char *pkgid)
+{
+       char pref_dir[PATH_MAX];
+       DIR *dir;
+       int dfd;
+       struct stat st;
+       int res;
+       struct dirent *ent = NULL;
+       const char *name;
+       char *keyname = NULL;
+       char file_full_path[PATH_MAX];
+       const char *pkg_path;
+
+       pkg_path = __get_package_path(pkgid);
+       if (pkg_path == NULL)
+               return;
+
+       snprintf(pref_dir, sizeof(pref_dir), "%s/data/.pref", pkg_path);
+
+       dir = opendir(pref_dir);
+       if (dir == NULL) {
+               printf("Is not exist preference key in %s.\n", pkgid);
+               return;
+       }
+
+       dfd = dirfd(dir);
+       res = fstat(dfd, &st);
+       if (res < 0) {
+               printf("fstat() failed. path: %s, errno: %d(%s)\n",
+                               pref_dir, errno, strerror(errno));
+               closedir(dir);
+               return;
+       }
+
+       while ((ent = readdir(dir))) {
+               name = ent->d_name;
+               if (name[0] == '.') {
+                       if (name[1] == '\0')
+                               continue;
+                       if ((name[1] == '.') && (name[2] == '\0'))
+                               continue;
+               }
+
+               snprintf(file_full_path, sizeof(file_full_path), "%s/%s",
+                               pref_dir, name);
+               _get_key_name(file_full_path, &keyname);
+               _print_pref_value_from_file_path(file_full_path, keyname);
+               if (keyname) {
+                       free(keyname);
+                       keyname = NULL;
+               }
+       }
+       closedir(dir);
+}
+
+static void write_history(const char *str)
+{
+       FILE *fp = NULL;
+       int ret = 0;
+
+       fp = fopen(HISTORY, "a");
+       if (fp == NULL) {
+               printf("fopen() failed. FOTA history log (%d/%s)",
+                               errno, strerror(errno));
+               return;
+       }
+
+       ret = fwrite((void *)str, strlen(str) + 1, 1, fp);
+       if (ret <= 0) {
+               printf("fwrite() failed. FOTA history log (%d/%s)",
+                               errno, strerror(errno));
+       }
+       fclose(fp);
+}
+
+static int _add_key_info_to_file(const char *key_path, const char *key)
+{
+       FILE *fp = NULL;
+       size_t keyname_len;
+       char *buf = NULL;
+       int read_size;
+       int ret;
+       long file_size;
+
+       fp = fopen(key_path, "r+");
+       if (fp == NULL) {
+               printf("fopen() failed.(%d/%s).fp is null.\n",
+                               errno, strerror(errno));
+               return -1;
+       }
+
+       fseek(fp, 0, SEEK_END);
+       file_size = ftell(fp);
+       rewind(fp);
+
+       buf = (char *)calloc(1, file_size);
+       if (buf == NULL) {
+               printf("Out of memory\n");
+               ret = -1;
+               goto out;
+       }
+
+       /* write keyname and size */
+       read_size = fread(buf, 1, file_size, fp);
+       if ((read_size <= 0)) {
+               printf("preference read key-val data error(%d/%s)\n",
+                               errno, strerror(errno));
+               ret = -1;
+               goto out;
+       }
+
+       rewind(fp);
+
+       keyname_len = strlen(key);
+       ret = fwrite((void *)&keyname_len, sizeof(int), 1, fp);
+       if (ret <= 0) {
+               printf("preference write key name length error(%d/%s)\n",
+                                               errno, strerror(errno));
+               ret = -1;
+               goto out;
+       }
+
+       ret = fwrite((void *)key, keyname_len, 1, fp);
+       if (ret <= 0) {
+               printf("preference write key name error(%d/%s)\n",
+                                               errno, strerror(errno));
+               ret = -1;
+               goto out;
+       }
+       ret = fwrite((void *)buf, read_size, 1, fp);
+       if (ret <= 0) {
+               printf("preference write key-val data error(%d/%s)\n",
+                                               errno, strerror(errno));
+               ret = -1;
+               goto out;
+       }
+
+       ret = 0;
+
+out:
+       if (fp)
+               fclose(fp);
+       if (buf)
+               free(buf);
+
+       return ret;
+}
+
+static int _convert_pref_file(const char *pref_dir)
+{
+       DIR *dir;
+       struct dirent *ent;
+       char old_file[BUF_LEN];
+       char new_file[BUF_LEN];
+       gchar *convert_key;
+       char _key[PREFERENCE_KEY_PATH_LEN] = {0,};
+       char *chrptr = NULL;
+
+       dir = opendir(pref_dir);
+       if (!dir)
+               return -1;
+
+       while ((ent = readdir(dir))) {
+               if (ent->d_type != DT_REG)
+                       continue;
+
+               snprintf(old_file, sizeof(old_file), "%s/%s", pref_dir,
+                               ent->d_name);
+
+               strncpy(_key, ent->d_name, PREFERENCE_KEY_PATH_LEN - 1);
+
+               chrptr = strchr((const char*)_key, DELIMITER);
+               if (chrptr) {
+                       chrptr = strchr((const char*)_key, DELIMITER);
+                       while (chrptr) {
+                               _key[chrptr-_key] = '/';
+                               chrptr = strchr((const char*)chrptr + 1, DELIMITER);
+                       }
+               }
+
+               convert_key = g_compute_checksum_for_string(G_CHECKSUM_SHA1,
+                               _key, strlen(_key));
+               if (convert_key == NULL) {
+                       printf("fail to convert key\n");
+                       closedir(dir);
+                       return -1;
+               }
+
+               snprintf(new_file, sizeof(new_file), "%s/%s", pref_dir,
+                               convert_key);
+               g_free(convert_key);
+
+               if (rename(old_file, new_file) < 0) {
+                       printf("rename %s to %s failed.(%d/%s)\n",
+                                       old_file, new_file,
+                                       errno, strerror(errno));
+               }
+
+               if (_add_key_info_to_file(new_file, _key) < 0)
+                       printf("convert %s file failed\n", new_file);
+       }
+
+       closedir(dir);
+       return 0;
+}
+
+static int _convert_file_name(const char *app_dir)
+{
+       DIR *dir;
+       struct dirent *ent;
+       char buf[BUF_LEN];
+       int res;
+
+       dir = opendir(app_dir);
+       if (!dir) {
+               printf("failed to open app dir (%s)\n", app_dir);
+               return -1;
+       }
+
+       while ((ent = readdir(dir))) {
+               if (ent->d_type != DT_DIR)
+                       continue;
+
+               if (strcmp(ent->d_name, ".") == 0 ||
+                               strcmp(ent->d_name, "..") == 0)
+                       continue;
+
+               snprintf(buf, sizeof(buf), "%s/%s/data/.pref",
+                               app_dir, ent->d_name);
+               if (access(buf, F_OK) == -1)
+                       continue;
+
+               res = _convert_pref_file(buf);
+               if (res < 0) {
+                       printf("_convert_pref_file error (%s)\n", buf);
+                       closedir(dir);
+                       return -1;
+               }
+       }
+
+       closedir(dir);
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+       int res;
+
+       if (getuid() != 0) {
+               printf("[pref] Only root user can use.\n");
+               return -1;
+       }
+
+       if (argc < 3) {
+               _print_help();
+               return -1;
+       }
+
+       if (strcmp(argv[1], "restore") == 0 && argc == 4) {
+               printf("[ start ] ----------------------------------------\n");
+               printf("Db file path:%s\n\n", argv[2]);
+
+               res = _initialize(argv[2]);
+               if (res < 0) {
+                       printf("failed. _initialize(%d)\n", res);
+                       return -1;
+               }
+
+               res = _restore(argv[3]);
+               if (res < 0) {
+                       printf("failed. _restore(%d)\n", res);
+                       write_history("\t\t- restore failed.\n");
+                       printf("restore failed.\n");
+                       return -1;
+               }
+
+               res = _remove_old_db(argv[2]);
+               if (res < 0) {
+                       printf("failed. _remove_old_db(%d)\n", res);
+                       return -1;
+               }
+
+               printf("-------------------------------------------------\n");
+               printf("done\n\n");
+               write_history("\t\t+ restore success.\n");
+       } else if (strcmp(argv[1], "get") == 0 || strcmp(argv[1], "GET") == 0) {
+               if (is_exist_package(argv[2]) < 0)
+                       return -1;
+
+               if (is_exist_data_dir_in_package(argv[2]) < 0)
+                       return -1;
+
+               if (argv[3])
+                       _print_preference_key(argv[2], argv[3]);
+               else
+                       _print_preference_in_package(argv[2]);
+       } else if (strcmp(argv[1], "set") == 0 || strcmp(argv[1], "SET") == 0) {
+               if (is_exist_package(argv[2]) < 0)
+                       return -1;
+
+               if (is_exist_data_dir_in_package(argv[2]) < 0)
+                       return -1;
+
+               if (argv[2] && argv[3] && argv[4] && argv[5])
+                       _preference_set_key(argv[2], argv[3], argv[4], argv[5]);
+               else
+                       _print_help();
+       } else if (strcmp(argv[1], "convert_file_name") == 0) {
+               res = _convert_file_name(argv[2]);
+
+               if (res < 0) {
+                       printf("converting preference file name failed (%s)\n",
+                                       argv[2]);
+                       return -1;
+               }
+       } else {
+               _print_help();
+       }
+
+       return 0;
+}