tool: allow prefix "http://" for get/set/clear key
[platform/core/api/system-info.git] / tool / system-info-tool-get.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <string.h>
5
6 #include "system-info-tool.h"
7 #include "system-info-tool-get.h"
8
9 void system_info_tool_get_help(void)
10 {
11         printf("  -l|--list-all                  List all system-info database entries\n");
12         printf("  -g|--get KEY [-v|--verbose]    Get value of feature KEY\n");
13         printf("                                 If -v option is given, shows result in detail\n");
14         printf("                                 ex) system-info-tool -g tizen.org/feature/display\n");
15         printf("                                     system-info-tool -g tizen.org/system/manufacturer -v\n");
16 }
17
18 static void print_dbentry(struct dbentry *dbentry, bool found)
19 {
20         const struct db *db;
21
22         if (!dbentry || !dbentry->db)
23                 return;
24
25         db = dbentry->db;
26
27         if (found) {
28                 printf("%s Key (%c) found: ", db->name, db->ticker);
29         } else {
30                 printf("%s Key (%c) not found\n", db->name, db->ticker);
31                 return;
32         }
33
34         print_value(dbentry->value);
35 }
36
37 int system_info_tool_get_raw(const char *searchkey, system_info_type_e searchtype,
38         enum db_e searchdb, struct dbentry *dbentry)
39 {
40         char dbpath[BUFFER_MAX - 1];
41         char dbentry_format[BUFFER_MAX];
42         int retval;
43
44         if (!dbentry)
45                 return -EINVAL;
46
47         if (searchdb < DB_START || searchdb >= DB_END)
48                 return -EINVAL;
49
50         dbentry->db = &db[searchdb];
51
52         /* scanf format: "%127[^:]:%127[^:]:%127s %127s" */
53         snprintf(dbentry_format, sizeof(dbentry_format), "%%%d[^:]:%%%d[^:]:%%%ds %%%ds",
54                 BUFFER_MAX - 1, BUFFER_MAX - 1, BUFFER_MAX - 1, BUFFER_MAX - 1);
55
56         for (int i = 0; i < NUM_HASH_FILE; ++i) {
57                 __auto_fclose__ FILE *fp = NULL;
58                 char line[BUFFER_MAX * 8] = {0, };
59                 char tag[BUFFER_MAX - 1] = {0, };
60                 char key[BUFFER_MAX - 1] = {0, };
61                 char type[BUFFER_MAX - 1] = {0, };
62                 char value[BUFFER_MAX - 1] = {0, };
63                 const char *typestring;
64
65                 snprintf(dbpath, sizeof(dbpath), "%s/%d", db[searchdb].path, i);
66                 fp = fopen(dbpath, "r");
67                 if (!fp)
68                         continue;
69
70                 while ((fgets(line, sizeof(line), fp))) {
71                         retval = sscanf(line, dbentry_format, tag, key, type, value);
72                         if (retval != 4)
73                                 continue;
74
75                         if (strncmp(key, searchkey, strlen(key) + 1))
76                                 continue;
77
78                         typestring = type_to_string(searchtype);
79                         if (strncmp(type, typestring, strlen(type) + 1))
80                                 continue;
81
82                         strncpy(dbentry->key, key, sizeof(dbentry->key) - 1);
83                         strncpy(dbentry->tag, tag, sizeof(dbentry->tag) - 1);
84                         dbentry->value.type = searchtype;
85                         if (strncmp(type, "bool", sizeof("bool")) == 0)
86                                 dbentry->value.b = (value[runtime_env] == 'T');
87                         else if (strncmp(type, "int", sizeof("int")) == 0)
88                           dbentry->value.i = atoi(value);
89                         else if (strncmp(type, "double", sizeof("double")) == 0)
90                           dbentry->value.d = atof(value);
91                         else if (strncmp(type, "string", sizeof("string")) == 0)
92                           dbentry->value.s = strndup(value, sizeof(value));
93
94                         return 0;
95                 }
96         }
97
98         return -ENOENT;
99 }
100
101 static int system_info_tool_get_api(const char *key, struct value *value)
102 {
103         int retval;
104         int ret;
105         int match = 0;
106         int select;
107         int i;
108
109         struct cache {
110                 int match;
111                 struct value value;
112         } cache[SYSTEM_INFO_TYPE_MAX] = {
113                 { -1, { SYSTEM_INFO_BOOL,   } },
114                 { -1, { SYSTEM_INFO_INT,    } },
115                 { -1, { SYSTEM_INFO_DOUBLE, } },
116                 { -1, { SYSTEM_INFO_STRING, } },
117         };
118
119         retval = system_info_get_platform_bool(key, &cache[SYSTEM_INFO_BOOL].value.b);
120         if (retval == 0)
121                 cache[SYSTEM_INFO_BOOL].match = ++match;
122
123         retval = system_info_get_platform_int(key, &cache[SYSTEM_INFO_INT].value.i);
124         if (retval == 0)
125                 cache[SYSTEM_INFO_INT].match = ++match;
126
127         retval = system_info_get_platform_double(key, &cache[SYSTEM_INFO_DOUBLE].value.d);
128         if (retval == 0)
129                 cache[SYSTEM_INFO_DOUBLE].match = ++match;
130
131         retval = system_info_get_platform_string(key, &cache[SYSTEM_INFO_STRING].value.s);
132         if (retval == 0)
133                 cache[SYSTEM_INFO_STRING].match = ++match;
134
135         if (match == 1) {
136                 for (i = 0; i < SYSTEM_INFO_TYPE_MAX; ++i)
137                         if (cache[i].match == match)
138                                 memcpy(value, &cache[i].value, sizeof(struct value));
139                 return 0;
140         } else if (match > 1) {
141                 printf("There is multiple same keys with different type. Which type to search?\n");
142                 for (i = 0; i < SYSTEM_INFO_TYPE_MAX; ++i)
143                         if (cache[i].match > 0) {
144                                 printf(" [%d] ", cache[i].match);
145                                 print_value(cache[i].value);
146                         }
147
148                 printf("Select: ");
149                 retval = scanf("%d", &select);
150                 if (retval != 1) {
151                         printf("Invalid selection\n");
152                         ret = -EINVAL;
153                         goto out;
154                 }
155
156                 for (i = 0; i < SYSTEM_INFO_TYPE_MAX; ++i) {
157                         if (cache[i].match == select) {
158                                 memcpy(value, &cache[i].value, sizeof(struct value));
159                                 return 0;
160                         }
161                 }
162
163                 if (i == SYSTEM_INFO_TYPE_MAX) {
164                         printf("Invalid selection\n");
165                         ret =  -EINVAL;
166                         goto out;
167                 }
168         }
169
170         printf("key=%s is not found\n", key);
171         ret = -ENOENT;
172
173 out:
174         free(cache[SYSTEM_INFO_STRING].value.s);
175
176         return ret;
177 }
178
179 void system_info_tool_get(const char *rawkey, bool verbose)
180 {
181         struct value api;
182         char key[BUFFER_MAX];
183         int retval;
184
185         retval = convert_raw_key(rawkey, key, sizeof(key));
186         if (retval < 0)
187                 return;
188
189         retval = system_info_tool_get_api(key, &api);
190         if (retval < 0)
191                 return;
192
193         /* show each database if -v option is given */
194         if (verbose) {
195                 int retplt;
196                 int rethal;
197                 int retusr;
198
199                 /* set db to be searched */
200                 __auto_free_dbentry__ struct dbentry plt = { 0, }; /* scan platform ro db */
201                 __auto_free_dbentry__ struct dbentry hal = { 0, }; /* scan platform hal ro db */
202                 __auto_free_dbentry__ struct dbentry usr = { 0, }; /* scan platform rw db */
203
204                 retplt = system_info_tool_get_raw(key, api.type, DB_DEFAULT_RO, &plt);
205                 print_dbentry(&plt, retplt == 0);
206
207                 rethal = system_info_tool_get_raw(key, api.type, DB_HAL_RO, &hal);
208                 print_dbentry(&hal, rethal == 0);
209
210                 retusr = system_info_tool_get_raw(key, api.type, DB_DEFAULT_RW, &usr);
211                 print_dbentry(&usr, retusr == 0);
212
213                 /* print description how API have derived the result */
214                 if (retusr == 0) {
215                         printf("Result (=%c overrides %c,%c): ", usr.db->ticker, plt.db->ticker, hal.db->ticker);
216                 } else if (retplt == 0 && rethal == 0) {
217                         if (plt.value.type == SYSTEM_INFO_BOOL && hal.value.type == SYSTEM_INFO_BOOL)
218                                 printf("Result (=%c && %c): ", plt.db->ticker, hal.db->ticker);
219                         else
220                                 printf("Result (=%c overrides %c): ", hal.db->ticker, plt.db->ticker);
221                 } else if (retplt == 0) {
222                         printf("Result (=%c): ", plt.db->ticker);
223                 } else if (rethal == 0) {
224                         printf("Result (=%c): ", hal.db->ticker);
225                 } else {
226                         printf("Result (error occured): ");
227                 }
228         }
229
230         print_value(api);
231
232         return;
233 }
234
235 void system_info_tool_list_all(enum db_e dbtype)
236 {
237         char dbpath[BUFFER_MAX - 1];
238         char dbentry_format[BUFFER_MAX];
239         int retval;
240
241         if (access(db[dbtype].path, F_OK) != 0)
242                 return;
243
244         /* scanf format: "%127[^:]:%127[^:]:%127s %127s" */
245         snprintf(dbentry_format, sizeof(dbentry_format), "%%%d[^:]:%%%d[^:]:%%%ds %%%ds",
246                 BUFFER_MAX - 1, BUFFER_MAX - 1, BUFFER_MAX - 1, BUFFER_MAX - 1);
247
248         for (int i = 0; i < NUM_HASH_FILE; ++i) {
249                 __auto_fclose__ FILE *fp = NULL;
250                 char line[BUFFER_MAX * 8] = {0, };
251                 char tag[BUFFER_MAX - 1] = {0, };
252                 char key[BUFFER_MAX - 1] = {0, };
253                 char type[BUFFER_MAX - 1] = {0, };
254                 char value[BUFFER_MAX - 1] = {0, };
255
256                 snprintf(dbpath, sizeof(dbpath), "%s/%d", db[dbtype].path, i);
257                 fp = fopen(dbpath, "r");
258                 if (!fp)
259                         continue;
260
261                 while ((fgets(line, sizeof(line), fp))) {
262                         retval = sscanf(line, dbentry_format, tag, key, type, value);
263                         if (retval != 4)
264                                 continue;
265
266                         printf("%s: ", db[dbtype].name);
267                         printf("key=%s, ", key);
268                         printf("type=%s, ", type);
269                         if (strncmp(type, "bool", sizeof("bool")) == 0)
270                                 printf("value=%d, ", (value[runtime_env] == 'T'));
271                         else
272                                 printf("value=%s, ", value);
273                         printf("tag=%s\n", tag);
274                 }
275         }
276 }