9
9
#include "config.h"
10
10
#include "utils/logger_helper.h"
11
11
#include "utils/macros.h"
12
+ #include "yaml.h"
12
13
13
14
#define CONFIG_LOGGER "TA"
14
15
15
16
static logger_id_t config_logger_id ;
16
17
18
+ int get_conf_key (char const * const key ) {
19
+ for (int i = 0 ; i < cli_cmd_num ; ++ i ) {
20
+ if (!strcmp (ta_cli_arguments_g [i ].name , key )) {
21
+ return ta_cli_arguments_g [i ].val ;
22
+ }
23
+ }
24
+
25
+ return 0 ;
26
+ }
27
+
17
28
struct option * cli_build_options () {
18
29
struct option * long_options = (struct option * )malloc (cli_cmd_num * sizeof (struct option ));
19
30
for (int i = 0 ; i < cli_cmd_num ; ++ i ) {
@@ -25,12 +36,13 @@ struct option* cli_build_options() {
25
36
return long_options ;
26
37
}
27
38
28
- status_t cli_config_set (ta_config_t * const info , iota_config_t * const iconf , ta_cache_t * const cache ,
39
+ status_t cli_config_set (char * conf_file , ta_config_t * const info , iota_config_t * const iconf , ta_cache_t * const cache ,
29
40
iota_client_service_t * const service , int key , char * const value ) {
30
41
if (value == NULL || info == NULL || iconf == NULL || cache == NULL || service == NULL ) {
31
42
log_error (config_logger_id , "[%s:%d:%s]\n" , __func__ , __LINE__ , "SC_CONF_NULL" );
32
43
return SC_CONF_NULL ;
33
44
}
45
+
34
46
switch (key ) {
35
47
// TA configuration
36
48
case TA_HOST_CLI :
@@ -70,7 +82,21 @@ status_t cli_config_set(ta_config_t* const info, iota_config_t* const iconf, ta_
70
82
iconf -> seed = value ;
71
83
break ;
72
84
case CACHE :
73
- cache -> cache_state = !(strncmp (value , "T" , 1 ));
85
+ cache -> cache_state = (toupper (value [0 ]) == 'T' );
86
+ break ;
87
+
88
+ // Verbose configuration
89
+ case VERBOSE :
90
+ verbose_mode = (toupper (value [0 ]) == 'T' );
91
+ break ;
92
+
93
+ // File configuration
94
+ case CONF_CLI : {
95
+ size_t arg_len = strlen (value );
96
+ strncpy (conf_file , value , arg_len );
97
+ conf_file [arg_len ] = '\0' ;
98
+ break ;
99
+ }
74
100
}
75
101
return SC_OK ;
76
102
}
@@ -122,6 +148,108 @@ status_t ta_config_default_init(ta_config_t* const info, iota_config_t* const ic
122
148
return ret ;
123
149
}
124
150
151
+ status_t ta_config_file_init (ta_core_t * const conf , int argc , char * * argv ) {
152
+ int key = 0 ;
153
+ status_t ret = SC_OK ;
154
+ struct option * long_options = cli_build_options ();
155
+ yaml_parser_t parser ;
156
+ yaml_token_t token ;
157
+ FILE * file = NULL ;
158
+ char * arg = NULL ;
159
+ int state = 0 ;
160
+
161
+ // Initialize default configuration file path with '\0'
162
+ conf -> conf_file [0 ] = '\0' ;
163
+
164
+ if (!yaml_parser_initialize (& parser )) {
165
+ ret = SC_CONF_PARSER_ERROR ;
166
+ log_error (config_logger_id , "[%s:%d:%s]\n" , __func__ , __LINE__ , "SC_CONF_PARSER_ERROR" );
167
+ goto done ;
168
+ }
169
+
170
+ // Loop through the CLI arguments for first time to find the configuration file path
171
+ while ((key = getopt_long (argc , argv , "hv" , long_options , NULL )) != -1 ) {
172
+ switch (key ) {
173
+ case ':' :
174
+ ret = SC_CONF_MISSING_ARGUMENT ;
175
+ log_error (config_logger_id , "[%s:%d:%s]\n" , __func__ , __LINE__ , "SC_CONF_MISSING_ARGUMENT" );
176
+ break ;
177
+ case '?' :
178
+ ret = SC_CONF_UNKNOWN_OPTION ;
179
+ log_error (config_logger_id , "[%s:%d:%s]\n" , __func__ , __LINE__ , "SC_CONF_UNKNOWN_OPTION" );
180
+ break ;
181
+ case CONF_CLI :
182
+ ret = cli_config_set (conf -> conf_file , & conf -> info , & conf -> iconf , & conf -> cache , & conf -> service , key , optarg );
183
+ break ;
184
+ default :
185
+ break ;
186
+ }
187
+ if (ret != SC_OK ) {
188
+ break ;
189
+ }
190
+ }
191
+
192
+ // Reset the CLI option index for the second loop where they are actually analyzed
193
+ optind = 1 ;
194
+
195
+ if (strlen (conf -> conf_file ) == 0 ) {
196
+ /* No configuration file specified */
197
+ ret = SC_OK ;
198
+ goto done ;
199
+ }
200
+
201
+ if ((file = fopen (conf -> conf_file , "r" )) == NULL ) {
202
+ /* The specified configuration file does not exist */
203
+ ret = SC_CONF_FOPEN_ERROR ;
204
+ log_error (config_logger_id , "[%s:%d:%s]\n" , __func__ , __LINE__ , "SC_CONF_FOPEN_ERROR" );
205
+ goto done ;
206
+ }
207
+
208
+ yaml_parser_set_input_file (& parser , file );
209
+
210
+ do { /* start reading tokens */
211
+ if (!yaml_parser_scan (& parser , & token )) {
212
+ ret = SC_CONF_PARSER_ERROR ;
213
+ log_error (config_logger_id , "[%s:%d:%s]\n" , __func__ , __LINE__ , "SC_CONF_PARSER_ERROR" );
214
+ goto done ;
215
+ }
216
+ switch (token .type ) {
217
+ case YAML_KEY_TOKEN :
218
+ state = 0 ;
219
+ break ;
220
+ case YAML_VALUE_TOKEN :
221
+ state = 1 ;
222
+ break ;
223
+ case YAML_SCALAR_TOKEN :
224
+ arg = (char * )token .data .scalar .value ;
225
+ if (state == 0 ) { // Key
226
+ key = get_conf_key (arg );
227
+ } else { // Value
228
+ if ((ret = cli_config_set (conf -> conf_file , & conf -> info , & conf -> iconf , & conf -> cache , & conf -> service , key ,
229
+ strdup (arg ))) != SC_OK ) {
230
+ goto done ;
231
+ }
232
+ }
233
+ break ;
234
+ default :
235
+ break ;
236
+ }
237
+ if (token .type != YAML_STREAM_END_TOKEN ) {
238
+ yaml_token_delete (& token );
239
+ }
240
+ } while (token .type != YAML_STREAM_END_TOKEN );
241
+
242
+ done :
243
+ yaml_token_delete (& token );
244
+ yaml_parser_delete (& parser );
245
+ if (file ) {
246
+ fclose (file );
247
+ }
248
+ free (long_options );
249
+
250
+ return ret ;
251
+ }
252
+
125
253
status_t ta_config_cli_init (ta_core_t * const conf , int argc , char * * argv ) {
126
254
int key = 0 ;
127
255
status_t ret = SC_OK ;
@@ -131,9 +259,11 @@ status_t ta_config_cli_init(ta_core_t* const conf, int argc, char** argv) {
131
259
switch (key ) {
132
260
case ':' :
133
261
ret = SC_CONF_MISSING_ARGUMENT ;
262
+ log_error (config_logger_id , "[%s:%d:%s]\n" , __func__ , __LINE__ , "SC_CONF_MISSING_ARGUMENT" );
134
263
break ;
135
264
case '?' :
136
265
ret = SC_CONF_UNKNOWN_OPTION ;
266
+ log_error (config_logger_id , "[%s:%d:%s]\n" , __func__ , __LINE__ , "SC_CONF_UNKNOWN_OPTION" );
137
267
break ;
138
268
case 'h' :
139
269
ta_usage ();
@@ -148,8 +278,11 @@ status_t ta_config_cli_init(ta_core_t* const conf, int argc, char** argv) {
148
278
// Enable backend_redis logger
149
279
br_logger_init ();
150
280
break ;
281
+ case CONF_CLI :
282
+ /* Already processed in ta_config_file_init() */
283
+ break ;
151
284
default :
152
- ret = cli_config_set (& conf -> info , & conf -> iconf , & conf -> cache , & conf -> service , key , optarg );
285
+ ret = cli_config_set (conf -> conf_file , & conf -> info , & conf -> iconf , & conf -> cache , & conf -> service , key , optarg );
153
286
break ;
154
287
}
155
288
if (ret != SC_OK ) {
0 commit comments