From e7c0b4212d904a10523532fa0cb10e3d5fa58e56 Mon Sep 17 00:00:00 2001 From: Kichan Kwon Date: Mon, 15 Jun 2020 14:14:47 +0900 Subject: [PATCH] Read value from per-key file Change-Id: I0cb6e0607961fe7660b8234f5ae32f90e5294530 Signed-off-by: Kichan Kwon --- CMakeLists.txt | 2 +- packaging/capi-system-info.spec | 1 - src/init_db/CMakeLists.txt | 2 +- src/init_db/system_info_db_init.c | 145 ++++++++++++++++++------------------- src/system_info.c | 149 ++++++-------------------------------- 5 files changed, 96 insertions(+), 203 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 894d242..24f300c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,7 +43,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 diff --git a/packaging/capi-system-info.spec b/packaging/capi-system-info.spec index 0efe509..cb03b72 100644 --- a/packaging/capi-system-info.spec +++ b/packaging/capi-system-info.spec @@ -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 diff --git a/src/init_db/CMakeLists.txt b/src/init_db/CMakeLists.txt index d0e6804..21e0801 100755 --- a/src/init_db/CMakeLists.txt +++ b/src/init_db/CMakeLists.txt @@ -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) diff --git a/src/init_db/system_info_db_init.c b/src/init_db/system_info_db_init.c index 4efa0b0..6c8eb7e 100644 --- a/src/init_db/system_info_db_init.c +++ b/src/init_db/system_info_db_init.c @@ -15,13 +15,13 @@ */ +#include #include #include #include #include #include #include -#include #include #include #include @@ -52,87 +52,102 @@ 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); diff --git a/src/system_info.c b/src/system_info.c index 4cbf9f3..f340659 100644 --- a/src/system_info.c +++ b/src/system_info.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -36,15 +35,11 @@ #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, @@ -84,12 +79,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) @@ -107,9 +100,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) { @@ -128,41 +121,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) { - _D("Failed to find key in DB (%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; } @@ -180,101 +162,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) -- 2.7.4