9 #include "system-info-tool.h"
10 #include "system-info-tool-get.h"
11 #include "system-info-tool-set.h"
13 void system_info_tool_set_help(void)
15 printf(" -s|--set KEY TYPE VALUE Add or update user-defined KEY\n");
16 printf(" Available TYPE: bool, int, double, string\n");
17 printf(" ex) system-info-tool -s tizen.org/feature/display bool true\n");
18 printf(" system-info-tool -s tizen.org/system/manufacturer string Tizen\n");
19 printf(" -c|--clear KEY Clear user-defined KEY. This cannot clear read-only system key\n");
20 printf(" -C|--clear-all Clear all user-defined keys\n");
23 static int convert_raw_value(const char *rawtype, const char *rawvalue, struct value *out)
25 system_info_type_e type = string_to_type(rawtype);
27 if (type == SYSTEM_INFO_TYPE_MAX) {
28 printf("Invalid type \"%s\"\n", rawtype);
34 if (type == SYSTEM_INFO_BOOL) {
36 if (sscanf(rawvalue, "%d", &tmpbool) == 1) {
39 } else if (strncasecmp(rawvalue, "true", sizeof("true")) == 0) {
42 } else if (strncasecmp(rawvalue, "false", sizeof("false")) == 0) {
46 printf("Invalid bool value \"%s\"\n", rawvalue);
47 } else if (type == SYSTEM_INFO_INT) {
48 if (sscanf(rawvalue, "%d", &out->i) == 1)
50 printf("Invalid int value \"%s\"\n", rawvalue);
51 } else if (type == SYSTEM_INFO_DOUBLE) {
52 if (sscanf(rawvalue, "%lf", &out->d) == 1)
54 printf("Invalid double value \"%s\"\n", rawvalue);
55 } else if (type == SYSTEM_INFO_STRING) {
56 out->s = strndup(rawvalue, BUFFER_MAX);
63 static int try_flock(FILE *fp, bool blocking)
76 if (blocking == false)
79 retval = flock(fd, flags);
81 if (errno == EWOULDBLOCK)
82 printf("User-defined database is now being accessed by someone. Try again\n");
84 printf("Failed to acquire exclusive flock, %m\n");
91 static int add_new_entry(const char *key, struct value value)
93 char dbpath[BUFFER_MAX];
94 char internal_key[BUFFER_MAX] = {0, };
95 char internal_value[BUFFER_MAX] = {0, };
97 __auto_fclose__ FILE *fp = NULL;
102 /* make internal_key */
103 snprintf(internal_key, sizeof(internal_key), "platform:%s:%s", key, type_to_string(value.type));
105 /* make internal_value */
106 if (value.type == SYSTEM_INFO_BOOL) {
108 snprintf(internal_value, sizeof(internal_value), "TTTTTTTT");
110 snprintf(internal_value, sizeof(internal_value), "FFFFFFFF");
111 } else if (value.type == SYSTEM_INFO_INT) {
112 snprintf(internal_value, sizeof(internal_value), "%d", value.i);
113 } else if (value.type == SYSTEM_INFO_DOUBLE) {
114 snprintf(internal_value, sizeof(internal_value), "%lf", value.d);
115 } else if (value.type == SYSTEM_INFO_STRING) {
116 snprintf(internal_value, sizeof(internal_value), "%s", value.s);
121 snprintf(dbpath, sizeof(dbpath), "%s/%lu", SYSTEM_INFO_DB_RW_PATH, simple_hash(internal_key));
122 fp = fopen(dbpath, "a");
126 retval = try_flock(fp, false);
130 retval = fprintf(fp, "%s %s\n", internal_key, internal_value);
137 static int remove_entry(const char *key, system_info_type_e type)
139 char dbpath[BUFFER_MAX];
140 char backup[BUFFER_MAX];
141 char internal_key[BUFFER_MAX];
142 char line[BUFFER_MAX * 8];
143 char readkey[BUFFER_MAX];
144 char readtype[BUFFER_MAX];
145 __auto_fclose__ FILE *fp1 = NULL;
146 __auto_fclose__ FILE *fp2 = NULL;
152 if (type < SYSTEM_INFO_TYPE_MIN || type >= SYSTEM_INFO_TYPE_MAX)
155 /* make internal_key */
156 snprintf(internal_key, sizeof(internal_key), "platform:%s:%s", key, type_to_string(type));
158 snprintf(dbpath, sizeof(dbpath), "%s/%lu", SYSTEM_INFO_DB_RW_PATH, simple_hash(internal_key));
159 fp1 = fopen(dbpath, "r+");
163 retval = try_flock(fp1, false);
167 snprintf(backup, sizeof(backup), "%s/.backup.%lu", SYSTEM_INFO_DB_RW_PATH, simple_hash(internal_key));
168 fp2 = fopen(backup, "w+");
172 while ((fgets(line, sizeof(line), fp1))) {
173 retval = sscanf(line, "platform:%127s:%127s", readkey, readtype);
177 if (strncmp(readkey, key, sizeof(readkey)) == 0
178 && string_to_type(readtype) == type)
181 fprintf(fp2, "%s", line);
184 if (truncate(dbpath, 0) < 0)
185 printf("Failed to reset database, %m\n");
190 while ((fgets(line, sizeof(line), fp2)))
191 fprintf(fp1, "%s", line);
198 static int modify_entry(const char *key, struct value value)
202 ret = remove_entry(key, value.type);
206 return add_new_entry(key, value);
209 static int system_info_tool_set_entry(const char *key, struct value value)
211 __auto_free_dbentry__ struct dbentry dbentry = {0, };
217 retval = system_info_tool_get_raw(key, value.type, DB_DEFAULT_RW, &dbentry);
219 return modify_entry(key, value);
221 return add_new_entry(key, value);
224 static int system_info_tool_init_rw_database(void)
226 return system("/usr/bin/mkdir -p "SYSTEM_INFO_DB_RW_PATH);
229 int system_info_tool_set(int argc, char *argv[])
232 char key[BUFFER_MAX];
235 /* argv[optind] : key
236 * argv[optind + 1]: type
237 * argv[optind + 2]: value
238 * check if there is at least 3 arguments */
239 if (argc - optind < 3) {
240 printf("Need key, type, value\n");
244 if (access(SYSTEM_INFO_DB_RW_PATH, F_OK) != 0) {
245 ret = system_info_tool_init_rw_database();
250 ret = convert_raw_key(argv[optind], key, sizeof(key));
254 ret = convert_raw_value(argv[optind + 1], argv[optind + 2], &value);
258 return system_info_tool_set_entry(key, value);
261 int system_info_tool_clear_key(const char *rawkey)
268 char key[BUFFER_MAX];
272 struct dbentry dbentry;
273 } cache[SYSTEM_INFO_TYPE_MAX] = {
280 ret = convert_raw_key(rawkey, key, sizeof(key));
284 for (i = 0; i < SYSTEM_INFO_TYPE_MAX; ++i) {
285 retval = system_info_tool_get_raw(key, i, DB_DEFAULT_RW, &cache[i].dbentry);
287 cache[i].match = ++match;
291 for (i = 0; i < SYSTEM_INFO_TYPE_MAX; ++i) {
292 if (cache[i].match == match) {
293 ret = remove_entry(cache[i].dbentry.key, cache[i].dbentry.value.type);
297 } else if (match > 1) {
298 printf("There is multiple same keys with different type. Which type to clear?\n");
299 for (i = 0; i < SYSTEM_INFO_TYPE_MAX; ++i)
300 if (cache[i].match > 0) {
301 printf(" [%d] ", cache[i].match);
302 print_value(cache[i].dbentry.value);
306 retval = scanf("%d", &select);
308 printf("Invalid selection\n");
313 for (i = 0; i < SYSTEM_INFO_TYPE_MAX; ++i) {
314 if (cache[i].match == select) {
315 ret = remove_entry(cache[i].dbentry.key, cache[i].dbentry.value.type);
321 printf("user-defined key=%s is not found\n", key);
325 if (cache[SYSTEM_INFO_STRING].match > 0)
326 free(cache[SYSTEM_INFO_STRING].dbentry.value.s);
331 void system_info_tool_clear_all(void)
333 char dbpath[BUFFER_MAX];
336 for (int i = 0; i < NUM_HASH_FILE; ++i) {
337 __auto_fclose__ FILE *fp = NULL;
338 snprintf(dbpath, sizeof(dbpath), "%s/%d", SYSTEM_INFO_DB_RW_PATH, i);
339 fp = fopen(dbpath, "r");
343 retval = try_flock(fp, true);
347 if (truncate(dbpath, 0) < 0)
348 printf("Failed to reset database, %m\n");