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