2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
29 #include <system_info.h>
30 #include <iniparser.h>
31 #include <libxml/xmlmemory.h>
32 #include <libxml/parser.h>
33 #include <libxml/tree.h>
35 #include "system_info_private.h"
41 #define LOG_TAG "SYSTEM_INFO"
42 #define _D(fmt, args...) SLOGD(fmt, ##args)
43 #define _E(fmt, args...) SLOGE(fmt, ##args)
44 #define _I(fmt, args...) SLOGI(fmt, ##args)
46 #define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
50 #define MODEL_CONFIG_TAG "model-config"
51 #define KEY_PREFIX "http://"
53 extern const struct runtime runtime[LANG_MAX];
55 static int db_set_value(GDBM_FILE *db, char *tag, char *name, char *type, char *value, int val_len)
62 if (!db || !*db || !tag || !name || !type || !value)
65 if (name == strstr(name, KEY_PREFIX))
66 snprintf(key, sizeof(key), "%s:%s:%s", name, type, tag);
68 snprintf(key, sizeof(key), "%s%s:%s:%s", KEY_PREFIX, name, type, tag);
71 d_key.dsize = strlen(key) + 1;
74 d_data.dsize = val_len + 1;
76 ret = gdbm_store(*db, d_key, d_data, GDBM_REPLACE);
78 _E("Failed to store key (%s, %s, %d)", key, type, gdbm_errno);
84 _I("DB: value (key:%s,value:%s) is stored", key, value);
89 static int db_get_value(GDBM_FILE *db, char *tag, char *name, char *type, char *value, int val_len)
95 if (!db || !*db || !tag || !name || !type || !value)
98 if (name == strstr(name, KEY_PREFIX))
99 snprintf(key, sizeof(key), "%s:%s:%s", name, type, tag);
101 snprintf(key, sizeof(key), "%s%s:%s:%s", KEY_PREFIX, name, type, tag);
104 d_key.dsize = strlen(key) + 1;
106 d_data = gdbm_fetch(*db, d_key);
108 _E("Failed to find key (%s, %s)", key, type);
112 snprintf(value, val_len, "%s", d_data.dptr);
115 _I("DB: value (key:%s,value:%s) is fetched", key, value);
120 static int db_set_value_specific_runtime(GDBM_FILE *db, char *tag, char *name, char *type, char *value, int lang)
122 char value_intg[LANG_MAX + 1] = {0};
125 ret = db_get_value(db, tag, name, type, value_intg, LANG_MAX);
129 value_intg[lang] = (value[0] == 't' ? 'T' : 'F');
130 ret = db_set_value(db, tag, name, type, value_intg, LANG_MAX);
135 static int db_set_value_foreach_runtime(GDBM_FILE *db, xmlNode *node,
136 char *tag, char *name, char *type, char *value)
140 char value_intg[LANG_MAX + 1] = {0};
143 memset(value_intg, strncmp(value, "true", 4) ? 'F' : 'T', LANG_MAX);
145 for (rt = 0; rt < LANG_MAX; rt++) {
146 if (!runtime[rt].xml_prop)
149 prop_val = xmlGetProp(node, (xmlChar *)(runtime[rt].xml_prop));
153 value_intg[runtime[rt].lang] = xmlStrcmp(prop_val, (xmlChar *)"on") ? 'F' : 'T';
158 ret = db_set_value(db, tag, name, type, value_intg, LANG_MAX);
163 static int system_info_get_values_config_xml(GDBM_FILE *db)
167 xmlNode *cur_node, *tag_node;
168 char *tag, *name, *type, *value;
174 doc = xmlParseFile(CONFIG_FILE_PATH);
176 _E("cannot file open %s file!!!", CONFIG_FILE_PATH);
177 return SYSTEM_INFO_ERROR_IO_ERROR;
180 cur = xmlDocGetRootElement(doc);
182 _E("empty document %s file!!!", CONFIG_FILE_PATH);
187 for (cur_node = cur; cur_node ; cur_node = cur_node->next) {
188 if (!xmlStrcmp(cur->name, (const xmlChar*)MODEL_CONFIG_TAG))
192 _E("cannot find %s root element file!!!", MODEL_CONFIG_TAG);
197 cur = cur_node->xmlChildrenNode;
198 for (tag_node = cur; tag_node; tag_node = tag_node->next) {
199 if (!xmlStrcmp(tag_node->name, (const xmlChar *)TAG_TYPE_PLATFORM_STR))
200 tag = TAG_TYPE_PLATFORM_STR;
201 else if (!xmlStrcmp(tag_node->name, (const xmlChar *)TAG_TYPE_CUSTOM_STR))
202 tag = TAG_TYPE_CUSTOM_STR;
206 cur = tag_node->xmlChildrenNode;
207 for (cur_node = cur; cur_node ; cur_node = cur_node->next) {
208 if (cur_node->type != XML_ELEMENT_NODE)
211 name = (char *)xmlGetProp(cur_node, (const xmlChar*)"name");
215 type = (char *)xmlGetProp(cur_node, (const xmlChar*)"type");
221 value = (char *)xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
228 if (!strncmp(type, "bool", 4))
229 ret = db_set_value_foreach_runtime(db, cur_node, tag, name, type, value);
231 ret = db_set_value(db, tag, name, type, value, strlen(value));
234 _E("Failed to set value (%d)", ret);
250 static struct build_ini_keys {
254 { "version:model", "http://tizen.org/system/build.model" },
255 { "version:build", "http://tizen.org/system/build.string" },
256 { "version:release", "http://tizen.org/system/build.release" },
257 { "build:type", "http://tizen.org/system/build.type" },
258 { "build:date", "http://tizen.org/system/build.date" },
259 { "build:time", "http://tizen.org/system/build.time" },
260 { "build:variant", "http://tizen.org/system/build.variant" },
261 { "build:id", "http://tizen.org/system/build.id" },
264 static int system_info_get_values_ini(GDBM_FILE *db)
273 ini = iniparser_load(INFO_FILE_PATH);
275 _E("cannot file open %s file!!!", INFO_FILE_PATH);
279 for (i = 0 ; i < ARRAY_SIZE(ini_keys) ; i++) {
280 value = iniparser_getstring(ini, ini_keys[i].info, NULL);
282 _E("NOT found %s", ini_keys[i].info);
286 ret = db_set_value(db, TAG_TYPE_PLATFORM_STR, ini_keys[i].key, STR_TYPE, value, strlen(value));
288 _E("Failed to set value (%d)", ret);
291 iniparser_freedict(ini);
296 static int system_info_create_db(void)
301 db = gdbm_open(SYSTEM_INFO_DB_PATH, 0, GDBM_WRCREAT, S_IRUSR | S_IRGRP | S_IROTH, NULL);
303 _E("Failed to open db (%d, %s)", gdbm_errno, gdbm_strerror(gdbm_errno));
307 ret = system_info_get_values_config_xml(&db);
309 _E("Failed to get keys and values from xml(%d)", ret);
311 ret = system_info_get_values_ini(&db);
313 _E("Failed to get keys and values from ini(%d)", ret);
320 static void show_help(void)
322 /* TODO : support -l (--lang) option */
323 printf("system_info_init_db [OPTIONS]\n");
324 printf(" -h --help Show this help\n");
325 printf(" -k --key=KEY System info key to update\n");
326 printf(" -t --type=TYPE System info type to update (int/bool/double/string)\n");
327 printf(" -l --lang=LANG System info specific language target (capi/webapi/csapi)\n");
328 printf(" -g --tag=TAG System info tag to update (platform/custom)\n");
329 printf(" -v --value=VALUE System info value to update\n");
332 static int system_info_update_db(int argc, char *argv[])
338 char key[KEY_MAX] = {0};
339 char type[KEY_MAX] = {0};
340 char tag[KEY_MAX] = {0};
341 char value[KEY_MAX] = {0};
342 char value_bool[LANG_MAX + 1] = {0};
343 enum language lang = LANG_MAX;
346 struct option long_options[] = {
347 { "key", required_argument, 0, 0 },
348 { "type", required_argument, 0, 0 },
349 { "tag", required_argument, 0, 0 },
350 { "value", required_argument, 0, 0 },
351 { "help", no_argument, 0, 0 },
356 opt = getopt_long(argc, argv, "k:t:g:v:l:h",
362 snprintf(key, sizeof(key), "%s", optarg);
365 snprintf(type, sizeof(type), "%s", optarg);
368 snprintf(tag, sizeof(tag), "%s", optarg);
371 snprintf(value, sizeof(value), "%s", optarg);
374 for (rt = 0; rt < LANG_MAX; rt++) {
375 if (!runtime[rt].xml_prop)
377 if (!strncmp(optarg, runtime[rt].xml_prop, RT_PREFIX)) {
378 lang = runtime[rt].lang;
382 if (!runtime[rt].xml_prop) {
383 printf("Invalid language (%s)\n", optarg);
395 if (key[0] == '\0') {
396 printf("Invalid Parameter: no key\n");
399 if (type[0] == '\0') {
400 printf("Invalid Parameter: no type\n");
403 if (tag[0] == '\0') {
404 printf("Invalid Parameter: no tag\n");
407 if (value[0] == '\0') {
408 printf("Invalid Parameter: no value\n");
411 if ((lang != LANG_MAX) && (strncmp(type, "bool", 4))) {
412 printf("Invalid Parameter: lang parameter supports for just bool type\n");
419 if (lang == LANG_MAX)
420 _I("Request to update: key(%s), type(%s), tag(%s), value(%s)",
421 key, type, tag, value);
423 _I("Request to update for specific lang(%s): key(%s), type(%s), tag(%s), value(%s)",
424 runtime[lang].xml_prop, key, type, tag, value);
426 /* http://www.gnu.org.ua/software/gdbm/manual/html_node/Open.html
427 * If flags is set to ‘GDBM_WRITER’,
428 * the user wants both read and write access to the database
429 * and requires exclusive access */
430 db = gdbm_open(SYSTEM_INFO_DB_PATH, 0, GDBM_WRITER, S_IRUSR | S_IRGRP | S_IROTH, NULL);
432 _E("Failed to open db (%d, %s)", gdbm_errno, gdbm_strerror(gdbm_errno));
436 if (!strncmp(type, "bool", 4)) {
437 if (lang == LANG_MAX) {
438 memset(value_bool, value[0] == 't' ? 'T' : 'F', LANG_MAX);
439 ret = db_set_value(&db, tag, key, type, value_bool, LANG_MAX);
441 ret = db_set_value_specific_runtime(&db, tag, key, type, value, lang);
443 ret = db_set_value(&db, tag, key, type, value, strlen(value));
446 _E("Failed to set value (%d)", ret);
452 int main(int argc, char *argv[])
455 return system_info_create_db();
457 return system_info_update_db(argc, argv);