Read value from per-key file 79/236679/1
authorKichan Kwon <k_c.kwon@samsung.com>
Mon, 15 Jun 2020 05:14:47 +0000 (14:14 +0900)
committerKichan Kwon <k_c.kwon@samsung.com>
Fri, 19 Jun 2020 07:46:32 +0000 (16:46 +0900)
Change-Id: I0cb6e0607961fe7660b8234f5ae32f90e5294530
Signed-off-by: Kichan Kwon <k_c.kwon@samsung.com>
CMakeLists.txt
packaging/capi-system-info.spec
src/init_db/CMakeLists.txt
src/init_db/system_info_db_init.c
src/system_info.c

index 2a74d58..a152039 100644 (file)
@@ -39,7 +39,7 @@ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib")
 aux_source_directory(src SOURCES)
 ADD_LIBRARY(${fw_name} SHARED ${SOURCES})
 
-TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS} "-ldl -lgdbm")
+TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS} "-ldl")
 
 SET_TARGET_PROPERTIES(${fw_name}
      PROPERTIES
index 220404f..0cdd46b 100644 (file)
@@ -14,7 +14,6 @@ BuildRequires:  pkgconfig(libxml-2.0)
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(libtzplatform-config)
 BuildRequires:  pkgconfig(uuid)
-BuildRequires:  gdbm-devel
 BuildRequires:  glibc-devel-static
 Requires: security-config
 
index d0e6804..21e0801 100755 (executable)
@@ -24,7 +24,7 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
 SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
 
 ADD_EXECUTABLE(${INIT_DB} ${SRCS})
-TARGET_LINK_LIBRARIES(${INIT_DB} ${init_db_pkgs_LDFLAGS} "-lgdbm")
+TARGET_LINK_LIBRARIES(${INIT_DB} ${init_db_pkgs_LDFLAGS})
 
 INSTALL(TARGETS ${INIT_DB} DESTINATION bin)
 #INSTALL(FILES ${CMAKE_SOURCE_DIR}/packaging/system_info_init_db.service DESTINATION lib/systemd/system)
index 911c997..2f14a3b 100644 (file)
  */
 
 
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <ctype.h>
 #include <getopt.h>
-#include <gdbm.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <dlog.h>
 
 extern const struct runtime runtime[LANG_MAX];
 
-static int db_set_value(GDBM_FILE *db, char *tag, char *name, char *type, char *value, int val_len)
+static int db_set_value(const char *db_path, char *tag, char *name, char *type, char *value, int val_len)
 {
-       char key[KEY_MAX];
-       datum d_key;
-       datum d_data;
        int ret;
+       char file_path[PATH_MAX];
+       char *ptr;
+       FILE *fp = NULL;
 
-       if (!db || !*db || !tag || !name || !type || !value)
+       if (!db_path || !tag || !name || !type || !value)
                return -EINVAL;
 
        if (name == strstr(name, KEY_PREFIX))
-               snprintf(key, sizeof(key), "%s:%s:%s", name, type, tag);
+               snprintf(file_path, sizeof(file_path), "%s/%s/%s:%s", db_path, tag, name + strlen(KEY_PREFIX), type);
        else
-               snprintf(key, sizeof(key), "%s%s:%s:%s", KEY_PREFIX, name, type, tag);
+               snprintf(file_path, sizeof(file_path), "%s/%s/%s:%s", db_path, tag, name, type);
+
+       // Make directory recursively
+       for (ptr = file_path + 1; *ptr != '\0'; ptr++) {
+               if (*ptr == '/') {
+                       *ptr = '\0';
+                       ret = mkdir(file_path, 0555);
+                       if (ret != 0 && errno != EEXIST) {
+                               _E("mkdir for %s failed (%d)", file_path, errno);
+                               return -errno;
+                       }
+                       *ptr = '/';
+               }
+       }
 
-       d_key.dptr = key;
-       d_key.dsize = strlen(key) + 1;
+       fp = fopen(file_path, "w");
+       if (!fp) {
+               _E("fopen for %s failed (%d)", file_path, errno);
+               return -errno;
+       }
 
-       d_data.dptr = value;
-       d_data.dsize = val_len + 1;
+       ret = fwrite(value, val_len, 1, fp);
+       fclose(fp);
 
-       ret = gdbm_store(*db, d_key, d_data, GDBM_REPLACE);
-       if (ret != 0) {
-               _E("Failed to store key (%s, %s, %d)", key, type, gdbm_errno);
-               return -gdbm_errno;
+       if (ret < 1) {
+               _E("fwrite for %s failed", file_path);
+               return -errno;
        }
 
-       gdbm_sync(*db);
-
-       _I("DB: value (key:%s,value:%s) is stored", key, value);
+       _I("DB: value (key:%s,value:%s) is stored", name, value);
 
        return 0;
 }
 
-static int db_get_value(GDBM_FILE *db, char *tag, char *name, char *type, char *value, int val_len)
+static int db_get_value(const char *db_path, char *tag, char *name, char *type, char *value, int val_len)
 {
-       datum d_key;
-       datum d_data;
-       char key[KEY_MAX];
+       int ret;
+       char file_path[PATH_MAX];
+       FILE *fp = NULL;
 
-       if (!db || !*db || !tag || !name || !type || !value)
+       if (!db_path || !tag || !name || !type || !value)
                return -EINVAL;
 
        if (name == strstr(name, KEY_PREFIX))
-               snprintf(key, sizeof(key), "%s:%s:%s", name, type, tag);
+               snprintf(file_path, sizeof(file_path), "%s/%s/%s:%s", db_path, tag, name + strlen(KEY_PREFIX), type);
        else
-               snprintf(key, sizeof(key), "%s%s:%s:%s", KEY_PREFIX, name, type, tag);
-
-       d_key.dptr = key;
-       d_key.dsize = strlen(key) + 1;
+               snprintf(file_path, sizeof(file_path), "%s/%s/%s:%s", db_path, tag, name, type);
 
-       d_data = gdbm_fetch(*db, d_key);
-       if (!d_data.dptr) {
-               _E("Failed to find key (%s, %s)", key, type);
-               return -gdbm_errno;
+       fp = fopen(file_path, "r");
+       if (!fp) {
+               _E("fopen for %s failed (%d)", file_path, errno);
+               return -errno;
        }
 
-       snprintf(value, val_len, "%s", d_data.dptr);
-       free(d_data.dptr);
+       ret = fread(value, val_len, 1, fp);
+       fclose(fp);
+
+       if (ret < 1) {
+               _E("fread for %s failed", file_path);
+               return -EIO;
+       }
 
-       _I("DB: value (key:%s,value:%s) is fetched", key, value);
+       _I("DB: value (key:%s,value:%s) is fetched", name, value);
 
        return 0;
 }
 
-static int db_set_value_specific_runtime(GDBM_FILE *db, char *tag, char *name, char *type, char *value, int lang)
+static int db_set_value_specific_runtime(const char *db_path, char *tag, char *name, char *type, char *value, int lang)
 {
        char value_intg[LANG_MAX + 1] = {0};
        int ret;
 
-       ret = db_get_value(db, tag, name, type, value_intg, LANG_MAX);
+       ret = db_get_value(db_path, tag, name, type, value_intg, LANG_MAX);
        if (ret != 0)
                return ret;
 
        value_intg[lang] = (value[0] == 't' ? 'T' : 'F');
-       ret = db_set_value(db, tag, name, type, value_intg, LANG_MAX);
+       ret = db_set_value(db_path, tag, name, type, value_intg, LANG_MAX);
 
        return ret;
 }
 
-static int db_set_value_foreach_runtime(GDBM_FILE *db, xmlNode *node,
+static int db_set_value_foreach_runtime(const char *db_path, xmlNode *node,
                                                char *tag, char *name, char *type, char *value)
 {
        int rt;
@@ -155,12 +170,12 @@ static int db_set_value_foreach_runtime(GDBM_FILE *db, xmlNode *node,
                xmlFree(prop_val);
        }
 
-       ret = db_set_value(db, tag, name, type, value_intg, LANG_MAX);
+       ret = db_set_value(db_path, tag, name, type, value_intg, LANG_MAX);
 
        return ret;
 }
 
-static int system_info_get_values_config_xml(GDBM_FILE *db, const char *path)
+static int system_info_get_values_config_xml(const char *db_path, const char *path)
 {
        xmlDocPtr doc;
        xmlNodePtr cur;
@@ -168,7 +183,7 @@ static int system_info_get_values_config_xml(GDBM_FILE *db, const char *path)
        char *tag, *name, *type, *value;
        int ret;
 
-       if (!db || !*db)
+       if (!db_path)
                return -EINVAL;
 
        doc = xmlParseFile(path);
@@ -226,9 +241,9 @@ static int system_info_get_values_config_xml(GDBM_FILE *db, const char *path)
                        }
 
                        if (!strncmp(type, "bool", 4))
-                               ret = db_set_value_foreach_runtime(db, cur_node, tag, name, type, value);
+                               ret = db_set_value_foreach_runtime(db_path, cur_node, tag, name, type, value);
                        else
-                               ret = db_set_value(db, tag, name, type, value, strlen(value));
+                               ret = db_set_value(db_path, tag, name, type, value, strlen(value));
 
                        if (ret < 0)
                                _E("Failed to set value (%d)", ret);
@@ -261,13 +276,13 @@ static struct build_ini_keys {
        { "build:id",        "http://tizen.org/system/build.id"      },
 };
 
-static int system_info_get_values_ini(GDBM_FILE *db)
+static int system_info_get_values_ini(const char *db_path)
 {
        dictionary *ini;
        int i, ret;
        char *value;
 
-       if (!db || !*db)
+       if (!db_path)
                return -EINVAL;
 
        ini = iniparser_load(INFO_FILE_PATH);
@@ -283,7 +298,7 @@ static int system_info_get_values_ini(GDBM_FILE *db)
                        continue;
                }
 
-               ret = db_set_value(db, TAG_TYPE_PLATFORM_STR, ini_keys[i].key, STR_TYPE, value, strlen(value));
+               ret = db_set_value(db_path, TAG_TYPE_PLATFORM_STR, ini_keys[i].key, STR_TYPE, value, strlen(value));
                if (ret < 0)
                        _E("Failed to set value (%d)", ret);
        }
@@ -296,7 +311,6 @@ static int system_info_get_values_ini(GDBM_FILE *db)
 static int system_info_create_db(const char *conf_path, char *db_path)
 {
        int ret;
-       GDBM_FILE db;
 
        if (conf_path == NULL)
                conf_path = MODEL_CONFIG_RO_PATH;
@@ -304,28 +318,19 @@ static int system_info_create_db(const char *conf_path, char *db_path)
        if (db_path == NULL)
                db_path = SYSTEM_INFO_DB_RO_PATH;
 
-       db = gdbm_open(db_path, 0, GDBM_WRCREAT, S_IRUSR | S_IRGRP | S_IROTH, NULL);
-       if (!db) {
-               _E("Failed to open db (%d, %s)", gdbm_errno, gdbm_strerror(gdbm_errno));
-               return -ENOENT;
-       }
-
-       ret = system_info_get_values_config_xml(&db, conf_path);
+       ret = system_info_get_values_config_xml(db_path, conf_path);
        if (ret < 0)
                _E("Failed to get keys and values from xml(%d)", ret);
 
-       ret = system_info_get_values_ini(&db);
+       ret = system_info_get_values_ini(db_path);
        if (ret < 0)
                _E("Failed to get keys and values from ini(%d)", ret);
 
-       gdbm_close(db);
-
        return 0;
 }
 
 static void show_help(void)
 {
-       /* TODO : support -l (--lang) option */
        printf("system_info_init_db [OPTIONS]\n");
        printf("  -h --help         Show this help\n");
        printf("  -k --key=KEY      System info key to update\n");
@@ -340,7 +345,6 @@ static void show_help(void)
 static int system_info_update_db(int argc, char *argv[])
 {
        int ret;
-       GDBM_FILE db;
        int opt;
        bool failed = false;
        char key[KEY_MAX] = {0};
@@ -446,34 +450,25 @@ static int system_info_update_db(int argc, char *argv[])
                _I("Request to update for specific lang(%s): key(%s), type(%s), tag(%s), value(%s)",
                                runtime[lang].xml_prop, key, type, tag, value);
 
-       /* http://www.gnu.org.ua/software/gdbm/manual/html_node/Open.html
-        *   If flags is set to ‘GDBM_WRITER’,
-        *   the user wants both read and write access to the database
-        *   and requires exclusive access */
-       db = gdbm_open(SYSTEM_INFO_DB_RO_PATH, 0, GDBM_WRITER, S_IRUSR | S_IRGRP | S_IROTH, NULL);
-       if (!db) {
-               _E("Failed to open db (%d, %s)", gdbm_errno, gdbm_strerror(gdbm_errno));
-               return -ENOENT;
-       }
-
        if (!strncmp(type, "bool", 4)) {
                if (lang == LANG_MAX) {
                        memset(value_bool, value[0] == 't' ? 'T' : 'F', LANG_MAX);
-                       ret = db_set_value(&db, tag, key, type, value_bool, LANG_MAX);
+                       ret = db_set_value(SYSTEM_INFO_DB_RO_PATH, tag, key, type, value_bool, LANG_MAX);
                } else
-                       ret = db_set_value_specific_runtime(&db, tag, key, type, value, lang);
+                       ret = db_set_value_specific_runtime(SYSTEM_INFO_DB_RO_PATH, tag, key, type, value, lang);
        } else
-               ret = db_set_value(&db, tag, key, type, value, strlen(value));
+               ret = db_set_value(SYSTEM_INFO_DB_RO_PATH, tag, key, type, value, strlen(value));
 
        if (ret != 0)
                _E("Failed to set value (%d)", ret);
 
-       gdbm_close(db);
        return ret;
 }
 
 int main(int argc, char *argv[])
 {
+       umask(0222);
+
        if (argc == 1)
                return system_info_create_db(NULL, NULL);
 
index 030a795..ea5c205 100644 (file)
@@ -20,7 +20,6 @@
 #include <string.h>
 #include <unistd.h>
 #include <ctype.h>
-#include <gdbm.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <glib.h>
 #define KEY_MAX 256
 #define STR_MAX 256
 
-#define GDBM_CACHE_SIZE 10 /* GDBM default == 100 */
-
 extern const struct runtime runtime[LANG_MAX];
 
 GHashTable *hashtable = NULL;
 static pthread_mutex_t fmutex = PTHREAD_MUTEX_INITIALIZER;
 
-static char *system_info_db_path;
-
 enum tag_type {
        TAG_TYPE_PLATFORM,
        TAG_TYPE_CUSTOM,
@@ -82,12 +77,10 @@ static int db_get_value(enum tag_type tag, const char *key,
 {
        char *db_path;
        char key_internal[KEY_MAX];
-       GDBM_FILE db = NULL;
-       datum d_key;
-       datum d_data;
+       char file_path[PATH_MAX];
+       FILE *fp = NULL;
        int ret;
        char *tag_s;
-       int cache_size = GDBM_CACHE_SIZE;
        char *temp;
 
        if (!key || !type || !value)
@@ -105,9 +98,9 @@ static int db_get_value(enum tag_type tag, const char *key,
        }
 
        if (strstr(key, KEY_PREFIX) == key)
-               snprintf(key_internal, sizeof(key_internal), "%s:%s:%s", key, type, tag_s);
+               snprintf(key_internal, sizeof(key_internal), "%s/%s:%s", tag_s, key + strlen(KEY_PREFIX), type);
        else
-               snprintf(key_internal, sizeof(key_internal), "%s%s:%s:%s", KEY_PREFIX, key, type, tag_s);
+               snprintf(key_internal, sizeof(key_internal), "%s/%s:%s", tag_s, key, type);
 
        pthread_mutex_lock(&fmutex);
        if (!hashtable) {
@@ -126,41 +119,30 @@ static int db_get_value(enum tag_type tag, const char *key,
        else
                db_path = SYSTEM_INFO_DB_RO_PATH;
 
-       db = gdbm_open(db_path, 0, GDBM_READER, S_IRUSR | S_IRGRP | S_IROTH, NULL);
-       if (!db) {
-               _E("Failed to open db (%d, %s)", gdbm_errno, gdbm_strerror(gdbm_errno)); //LCOV_EXCL_LINE
-               pthread_mutex_unlock(&fmutex);
-               return SYSTEM_INFO_ERROR_IO_ERROR; //LCOV_EXCL_LINE
-       }
-
-       ret = gdbm_setopt(db, GDBM_CACHESIZE, &cache_size, sizeof(cache_size));
-       if (ret < 0)
-               _E("Failed to set cache size to (%d) (ret:%d)", cache_size, gdbm_errno); //LCOV_EXCL_LINE
-
-       d_key.dptr = key_internal;
-       d_key.dsize = strlen(key_internal) + 1;
-
-       d_data = gdbm_fetch(db, d_key);
-       if (!d_data.dptr) {
-               _E("Failed to find key (%s, %s)", key, type);
-               ret = SYSTEM_INFO_ERROR_INVALID_PARAMETER;
+       snprintf(file_path, sizeof(file_path), "%s/%s", db_path, key_internal);
+       fp = fopen(file_path, "r");
+       if (!fp) {
+               if (errno == ENOENT)
+                       _D("Failed to find key in DB (%s, %s)", key, type);
+               else
+                       _E("fopen for %s failed (%d)", file_path, errno); //LCOV_EXCL_LINE
+               ret = SYSTEM_INFO_ERROR_IO_ERROR; //LCOV_EXCL_LINE
                goto out;
        }
 
-       if (len <= d_data.dsize) {
-               _E("Buffer size is smaller than DB value size. It can be cut");
-               d_data.dsize = len - 1;
+       temp = fgets(value, len, fp);
+       if (!temp) {
+               _E("fgets for %s failed", file_path);
+               ret = SYSTEM_INFO_ERROR_IO_ERROR;
+               goto out;
        }
 
-       memcpy(value, d_data.dptr, d_data.dsize);
-       value[d_data.dsize] = '\0';
-       free(d_data.dptr);
        ret = SYSTEM_INFO_ERROR_NONE;
 
        g_hash_table_insert(hashtable, strdup(key_internal), strdup(value));
 out:
-       if (db)
-               gdbm_close(db);
+       if (fp)
+               fclose(fp);
        pthread_mutex_unlock(&fmutex);
        return ret;
 }
@@ -178,101 +160,18 @@ struct sysinfo_type {
 static int system_info_get_type(enum tag_type tag, const char *key,
                system_info_type_e *type)
 {
-       char key_internal[KEY_MAX];
-       GDBM_FILE db = NULL;
-       datum d_key;
-       datum d_data;
+       char val[STR_MAX];
        int ret, i;
-       char *tag_s;
-       int cache_size = GDBM_CACHE_SIZE;
-       char *temp;
-
-       if (!key || !type)
-               return SYSTEM_INFO_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
-
-       switch (tag) {
-       case TAG_TYPE_PLATFORM:
-               tag_s = TAG_TYPE_PLATFORM_STR;
-               break;
-       case TAG_TYPE_CUSTOM:
-               tag_s = TAG_TYPE_CUSTOM_STR;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       pthread_mutex_lock(&fmutex);
-       if (!hashtable) {
-               hashtable = g_hash_table_new_full(g_str_hash, g_str_equal, destroy_key_value, destroy_key_value);
-       } else {
-               for (i = 0 ; i < ARRAY_SIZE(info_type); i++) {
-                       if (strstr(key, KEY_PREFIX) == key)
-                               snprintf(key_internal, sizeof(key_internal),
-                                               "%s:%s:%s", key, info_type[i].type_str, tag_s);
-                       else
-                               snprintf(key_internal, sizeof(key_internal),
-                                               "%s%s:%s:%s", KEY_PREFIX, key, info_type[i].type_str, tag_s);
-                       temp = g_hash_table_lookup(hashtable, key_internal);
-                       if (!temp)
-                               continue;
 
+       for (i = 0; i < ARRAY_SIZE(info_type); i++) {
+               ret = db_get_value(tag, key, info_type[i].type_str, val, STR_MAX);
+               if (ret == SYSTEM_INFO_ERROR_NONE) {
                        *type = info_type[i].type_e;
-                       pthread_mutex_unlock(&fmutex);
                        return SYSTEM_INFO_ERROR_NONE;
                }
        }
 
-       if (!system_info_db_path) {
-               if (access(SYSTEM_INFO_DB_RW_PATH, R_OK) == 0)
-                       system_info_db_path = SYSTEM_INFO_DB_RW_PATH;
-               else
-                       system_info_db_path = SYSTEM_INFO_DB_RO_PATH;
-       }
-
-       db = gdbm_open(system_info_db_path, 0, GDBM_READER, S_IRUSR | S_IRGRP | S_IROTH, NULL);
-       if (!db) {
-               _E("Failed to open db (%d, %s)", gdbm_errno, gdbm_strerror(gdbm_errno)); //LCOV_EXCL_LINE
-               pthread_mutex_unlock(&fmutex);
-               return SYSTEM_INFO_ERROR_IO_ERROR; //LCOV_EXCL_LINE
-       }
-
-       ret = gdbm_setopt(db, GDBM_CACHESIZE, &cache_size, sizeof(cache_size));
-       if (ret < 0)
-               _E("Failed to set cache size to (%d) (ret:%d)", cache_size, gdbm_errno); //LCOV_EXCL_LINE
-
-       for (i = 0 ; i < ARRAY_SIZE(info_type); i++) {
-               if (strstr(key, KEY_PREFIX) == key)
-                       snprintf(key_internal, sizeof(key_internal),
-                                       "%s:%s:%s", key, info_type[i].type_str, tag_s);
-               else
-                       snprintf(key_internal, sizeof(key_internal),
-                                       "%s%s:%s:%s", KEY_PREFIX, key, info_type[i].type_str, tag_s);
-
-               d_key.dptr = key_internal;
-               d_key.dsize = strlen(key_internal) + 1;
-
-               d_data = gdbm_fetch(db, d_key);
-               if (d_data.dptr) {
-                       *type = info_type[i].type_e;
-                       ret = SYSTEM_INFO_ERROR_NONE;
-
-                       g_hash_table_insert(hashtable, strndup(key_internal, d_key.dsize),
-                                       strndup(d_data.dptr, d_data.dsize));
-                       free(d_data.dptr);
-                       goto out;
-               }
-       }
-
-       if (tag == TAG_TYPE_PLATFORM)
-               ret = system_info_get_type_file(key, type);
-       else
-               ret = SYSTEM_INFO_ERROR_INVALID_PARAMETER;
-
-out:
-       if (db)
-               gdbm_close(db);
-       pthread_mutex_unlock(&fmutex);
-       return ret;
+       return SYSTEM_INFO_ERROR_INVALID_PARAMETER;
 }
 
 static int system_info_get_bool(enum tag_type tag, const char *key, bool *value)