1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <limits.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <getopt.h>
7 #include <locale.h>
8 #include <libintl.h>
9 #include <errno.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <math.h>
14 #include <libconfig.h>
15
16 #define PACKAGE "LS bash config"
17 #define VERSION "1.0.3"
18
19 // global flags
20 struct flags {
21 int quiet; //quiet output
22 int names; //set for printout config variables names
23 int types; //set for printout config variables types
24 int values; //set for printout config variables values
25 int indexes; //set for printout config variables indexes
26 int counter; //set for printout config varibales counting (for grout, list, array. in other cases it return 1)
27 int unset; //unset valriable
28 int boolstring; //set for output bool variable (0|1) as test (false|true)
29 int mode; //1 - for setting variable, 0 - for get hist data
30 int error; //error status handling
31 };
32
33 //take valur from input and comvert it to int
34 //TODO: Read long too
getNumber()35 int getNumber() {
36 char buf[1000];
37 int test,val;
38 unsigned int inp;
39 fgets(buf, sizeof buf, stdin);
40 test = sscanf(buf, "%u", &inp);
41 val = (int) inp;
42 if(val < 0) val *= -1;
43 if(test > 0) return val;
44 return (int) 0;
45 }
46
47 //printout help messsage
printHelp()48 void printHelp() {
49 printf(gettext("Configuration file handling\n"));
50 printf("\n");
51 printf(gettext("Usage: ls-config [OPTION]\n"));
52 printf(gettext("Reading and writening data from configuration files\n"));
53 printf(gettext("in libconfig9 format.\n"));
54 printf("\n");
55 printf(gettext("CAUTION: using without given config file are cause error!\n"));
56 printf("\n");
57 printf(gettext("Available options:\n"));
58 printf(gettext(" -f, --file=FILE Configuration file to handle.\n"));
59 printf("\n");
60 printf(gettext(" -s, --set=PATH Set configuration variable of given path.\n"));
61 printf(gettext(" -d, --data=DATA Configuration variable value (only with -s)\n"));
62 printf(gettext(" -p, --type=TYPE Configuration value type\n"));
63 printf("\n");
64 printf(gettext(" -g, --get=PATH Get configuration variable of given path.\n"));
65 printf(gettext(" -n, --names Printout variables names.\n"));
66 printf(gettext(" -t, --types Printout variables types.\n"));
67 printf(gettext(" -v, --values Printout variables values.\n"));
68 printf(gettext(" -i, --indexes Printout variables indexes.\n"));
69 printf(gettext(" -c, --count Printout elements count (only: array, list, group).\n"));
70 printf(gettext(" -b, --bool-string Printout boolean variables as text.\n"));
71 printf("\n");
72 printf(gettext(" -q, --quiet Quiet output to use in scripts.\n"));
73 printf(gettext(" -h, --help Print this help message.\n"));
74 printf("\n");
75 printf(gettext("TYPE: Variable types:\n"));
76 printf(gettext(" group - variables group,\n"));
77 printf(gettext(" array - array of variables,\n"));
78 printf(gettext(" list - list of variables,\n"));
79 printf(gettext(" int - integer number,\n"));
80 printf(gettext(" int64 - 64bit integer number,\n"));
81 printf(gettext(" float - float point number,\n"));
82 printf(gettext(" bool - boolean value,\n"));
83 printf(gettext(" string - character string.\n"));
84 printf("\n");
85 printf("(c) 2013 by LucaS web sutio - http://www.lucas.net.pl\n");
86 printf("Author: Łukasz A. Grabowski\n");
87 printf(gettext("Licence: "));
88 printf("GPL v2.\n");
89 exit(0);
90 };
91
92 //set configuration int value
set_config_int(config_setting_t * setting,char * dataString,struct flags optflags)93 int set_config_int(config_setting_t *setting, char *dataString, struct flags optflags) {
94 long bufl; //int (long) to get from input data string
95 int buf, scs; //config int, success status
96 char *erp; //error output
97
98 //convert input data to int
99 errno = 0;
100 bufl = strtol(dataString, &erp, 0);
101 if(((errno == ERANGE && (bufl == LONG_MAX || bufl == LONG_MIN)) || (errno != 0 && bufl == 0)) || (erp == dataString) || bufl > INT_MAX || bufl < INT_MIN) {
102 if(optflags.quiet == 0) printf(gettext("ERROR! Incorrect data format.\n"));
103 return 12;
104 };
105 buf = (int)bufl;
106
107 //set configuration variable
108 scs = config_setting_set_int(setting, buf);
109 if(scs == CONFIG_FALSE) {
110 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
111 return 11;
112 };
113 return 0;
114 };
115
116 //set configuration int64 value
set_config_int64(config_setting_t * setting,char * dataString,struct flags optflags)117 int set_config_int64(config_setting_t *setting, char *dataString, struct flags optflags) {
118 long bufl; //long to get from input data string
119 int scs; //success status
120 char *erp; //error output
121
122 //convert input data to long
123 errno = 0;
124 bufl = strtol(dataString, &erp, 0);
125 if(((errno == ERANGE && (bufl == LONG_MAX || bufl == LONG_MIN)) || (errno != 0 && bufl == 0)) || (erp == dataString)) {
126 if(optflags.quiet == 0) printf(gettext("ERROR! Incorrect data format.\n"));
127 return 12;
128 };
129
130 //set configuration variable
131 scs = config_setting_set_int64(setting, bufl);
132 if(scs == CONFIG_FALSE) {
133 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
134 return 11;
135 };
136 return 0;
137 };
138
139 //set configuration float value
set_config_float(config_setting_t * setting,char * dataString,struct flags optflags)140 int set_config_float(config_setting_t *setting, char *dataString, struct flags optflags) {
141 double buff; //double (float) to get from input data string
142 int scs; //success status
143 char *erp; //error output
144
145 //convert input data to double
146 errno = 0;
147 buff = strtod(dataString, &erp);
148 if(((errno == ERANGE && (buff == HUGE_VALF || buff == HUGE_VALL)) || (errno != 0 && buff == 0)) || (erp == dataString)) {
149 if(optflags.quiet == 0) printf(gettext("ERROR! Incorrect data format.\n"));
150 return 12;
151 }
152
153 //set configuration variable
154 scs = config_setting_set_float(setting, buff);
155 if(scs == CONFIG_FALSE) {
156 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
157 return 11;
158 };
159 return 0;
160 };
161
162 //set configuration boolean value
set_config_bool(config_setting_t * setting,char * dataString,struct flags optflags)163 int set_config_bool(config_setting_t *setting, char *dataString, struct flags optflags) {
164 int scs, buf; //success status, input convert burrer
165
166 //convert input data
167 //chceck both 1/0 and true/false string
168 buf = -1;
169 if(!strcmp(dataString, "1") || !strcmp(dataString, "true") || !strcmp(dataString, "TRUE")) buf = 1;
170 if(!strcmp(dataString, "0") || !strcmp(dataString, "false") || !strcmp(dataString, "FALSE")) buf = 0;
171 if(buf < 0) {
172 if(optflags.quiet == 0) printf(gettext("ERROR! Incorrect data format.\n"));
173 return 12;
174 }
175
176 //set configuration variable
177 scs = config_setting_set_bool(setting, buf);
178 if(scs == CONFIG_FALSE) {
179 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
180 return 11;
181 };
182 return 0;
183 };
184
185 //configuratnion variable path look like: foo.bar.car
186 //this fuction return string giving path to parent element (foo.bar)
path_parent(char * dataPath)187 char* path_parent(char *dataPath) {
188 char *str_ptr, *last_ptr, *newpath, *dot="."; //tokenized buffer, last buffer, new parent path, separator
189 newpath = malloc(1);
190 memset(newpath, 0, 1);
191 last_ptr = malloc(1);
192 memset(last_ptr, 0, 1);
193
194 //tokenize string and save last token
195 str_ptr = strtok(dataPath, ".");
196 last_ptr = (char*)realloc(last_ptr, (strlen(str_ptr)+1)*sizeof(char));
197 strcpy(last_ptr, str_ptr);
198
199 //loop overt path to build new path without last element
200 while(str_ptr != NULL) {
201 str_ptr = strtok(NULL, ".");
202 if(str_ptr != NULL) {
203 if(strlen(last_ptr) > 0 ) {
204 newpath = (char*)realloc(newpath, (strlen(newpath)+strlen(last_ptr)+2)*sizeof(char));
205 strcat(newpath, dot);
206 strcat(newpath, last_ptr);
207 };
208 last_ptr = (char*)realloc(last_ptr, (strlen(str_ptr)+1)*sizeof(char));
209 strcpy(last_ptr, str_ptr);
210 } else {
211 last_ptr = (char*)realloc(last_ptr, (1)*sizeof(char));
212 memset(last_ptr, 0, 1);
213 };
214 };
215 free(dataPath);
216
217 //if new path empty thren return null
218 if(strlen(newpath) == 0) {
219 free(newpath);
220 newpath = NULL;
221 };
222 return newpath;
223 };
224
225 //get element name from configuration variable path
226 //e.g.: from foo.bar return bar
path_name(char * dataPath)227 char* path_name(char *dataPath) {
228 char *str_ptr, *name, *tk; //tokenized buffer, element name, copy of dataPath
229 name = malloc(1);
230
231 //make copy of dataPath
232 tk = malloc((strlen(dataPath)+1)*sizeof(char));
233 memset(name, 0, 1);
234 strcpy(tk, dataPath);
235
236 //tokenize dataPath
237 str_ptr = strtok(tk, ".");
238
239 //loop over tokenize pathh to get last element
240 while(str_ptr != NULL) {
241 name = (char*)realloc(name, (strlen(str_ptr)+1)*sizeof(char));
242 strcpy(name, str_ptr);
243 str_ptr = strtok(NULL, ".");
244 };
245 free(tk);
246
247 //if no element name then return null
248 if(strlen(name) == 0) {
249 free(name);
250 name = NULL;
251 };
252 return name;
253 };
254
255 //set configuration path
256 //@return int success
257 //@param configFile - name (with path) of configuration fille
258 //@param dataPath - path of configuration variable (in config file)
259 //@param optflags - global options flags
260 //@param dataString - data to store in configuration variable in string format
261 //@param dataType - type of variable to save
set_config(char * configFile,char * dataPath,struct flags optflags,char * dataString,char * dataType)262 int set_config(char *configFile, char *dataPath, struct flags optflags, char *dataString, char *dataType) {
263 config_t cfg; //libcongig configuration handler
264 config_setting_t *setting, *ss; //libconfig element handrer: mant, and subset (uset for multielement types)
265 config_init(&cfg);
266 int scs, dt, dattyp; //sucess statu, data type
267 char *npath; // new variable configuration path path
268
269 //open and read configuration file
270 if(!config_read_file(&cfg, configFile)) {
271 config_destroy(&cfg);
272 if(optflags.quiet == 0) printf(gettext("ERROR! Can't read configuration file.\n"));
273 return 1;
274 };
275
276 //if no data path or data string then cause error
277 if(dataPath == NULL) {
278 config_destroy(&cfg);
279 if(optflags.quiet == 0) printf(gettext("ERROR! Conviguration variable path not given.\n"));
280 return 4;
281 };
282 if(dataString == NULL) {
283 config_destroy(&cfg);
284 if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable value not given.\n"));
285 return 9;
286 };
287
288 //find configuration variable of given path
289 setting = config_lookup(&cfg, dataPath);
290 if(setting == NULL) {
291 //if variable of given path not found get element name and partent path,
292 //then try to create it
293 npath = path_name(dataPath);
294 dataPath = path_parent(dataPath);
295 if(dataPath == NULL) {
296 setting = config_root_setting(&cfg);
297 } else {
298 setting = config_lookup(&cfg, dataPath);
299 };
300 if(setting == NULL) {
301 //if parent not exists exit with error
302 config_destroy(&cfg);
303 if(optflags.quiet == 0) printf(gettext("ERROR! Inavlid configuration variable path.\n"));
304 return 16;
305 };
306 //chceck type of parent element (named alement can be added only to group element)
307 dt = config_setting_type(setting);
308 if(dt != CONFIG_TYPE_GROUP) {
309 config_destroy(&cfg);
310 if(optflags.quiet == 0) printf(gettext("ERROR! New named configuration variable can be added only to group element.\n"));
311 return 17;
312 };
313 //check if new element type are given
314 if(dataType == NULL) {
315 config_destroy(&cfg);
316 if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable type not given.\n"));
317 return 13;
318 };
319 //now get type based on his name
320 if(!strcmp(dataType, "int")) {
321 dattyp = CONFIG_TYPE_INT;
322 } else if(!strcmp(dataType, "int64")) {
323 dattyp = CONFIG_TYPE_INT64;
324 } else if(!strcmp(dataType, "float")) {
325 dattyp = CONFIG_TYPE_FLOAT;
326 } else if(!strcmp(dataType, "string")) {
327 dattyp = CONFIG_TYPE_STRING;
328 } else if(!strcmp(dataType, "bool")) {
329 dattyp = CONFIG_TYPE_BOOL;
330 } else if(!strcmp(dataType, "array")) {
331 dattyp = CONFIG_TYPE_ARRAY;
332 } else if(!strcmp(dataType, "list")) {
333 dattyp = CONFIG_TYPE_LIST;
334 } else if(!strcmp(dataType, "group")) {
335 dattyp = CONFIG_TYPE_GROUP;
336 } else {
337 //if given type no mutch eny then cause error and exit
338 config_destroy(&cfg);
339 if(optflags.quiet == 0) printf(gettext("ERROR! Inlegal data type.\n"));
340 return 14;
341 };
342 //add new element to configuration file
343 ss = config_setting_add(setting, npath, dattyp);
344 if(ss == NULL) {
345 config_destroy(&cfg);
346 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
347 return 11;
348 };
349 scs = 0;
350 //and based on new type set his value
351 switch(dattyp) {
352 case CONFIG_TYPE_INT:
353 scs = set_config_int(ss, dataString, optflags);
354 break;
355 case CONFIG_TYPE_INT64:
356 scs = set_config_int64(ss, dataString, optflags);
357 break;
358 case CONFIG_TYPE_FLOAT:
359 scs = set_config_float(ss, dataString, optflags);
360 break;
361 case CONFIG_TYPE_STRING:
362 scs = config_setting_set_string(ss, dataString);
363 if(scs == CONFIG_FALSE) {
364 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
365 scs = 11;
366 } else scs = 0;
367 break;
368 case CONFIG_TYPE_BOOL:
369 scs = set_config_bool(ss, dataString, optflags);
370 break;
371 };
372 if(scs > 0) {
373 //if occurs some error wihe setting variable value exit with error
374 config_destroy(&cfg);
375 return scs;
376 };
377 } else {
378 //but if we found element of given path, try to set his value
379 //first of all determinate type of value
380 dt = config_setting_type(setting);
381 switch(dt) {
382 case CONFIG_TYPE_INT:
383 if(dataType != NULL && strcmp(dataType, "int")) {
384 config_destroy(&cfg);
385 if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
386 return 10;
387 };
388 //then set value
389 scs = set_config_int(setting, dataString, optflags);
390 if(scs > 0) {
391 config_destroy(&cfg);
392 return scs;
393 };
394 break;
395 case CONFIG_TYPE_INT64:
396 if(dataType != NULL && strcmp(dataType, "int64")) {
397 config_destroy(&cfg);
398 if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
399 return 10;
400 };
401 //then set value
402 scs = set_config_int64(setting, dataString, optflags);
403 if(scs > 0) {
404 config_destroy(&cfg);
405 return scs;
406 };
407 break;
408 case CONFIG_TYPE_FLOAT:
409 if(dataType != NULL && strcmp(dataType, "float")) {
410 config_destroy(&cfg);
411 if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
412 return 10;
413 };
414 //then set value
415 scs = set_config_float(setting, dataString, optflags);
416 if(scs > 0) {
417 config_destroy(&cfg);
418 return scs;
419 };
420 break;
421 case CONFIG_TYPE_STRING:
422 if(dataType != NULL && strcmp(dataType, "string")) {
423 config_destroy(&cfg);
424 if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
425 return 10;
426 };
427 //then set value
428 scs = config_setting_set_string(setting, dataString);
429 if(scs == CONFIG_FALSE) {
430 config_destroy(&cfg);
431 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
432 return 11;
433 };
434 break;
435 case CONFIG_TYPE_BOOL:
436 if(dataType != NULL && strcmp(dataType, "bool")) {
437 config_destroy(&cfg);
438 if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
439 return 10;
440 };
441 //then set value
442 scs = set_config_bool(setting, dataString, optflags);
443 if(scs > 0) {
444 config_destroy(&cfg);
445 return scs;
446 };
447 break;
448 case CONFIG_TYPE_ARRAY:
449 //if array are empty we can set alement of any scalar type
450 if(config_setting_length(setting) == 0) {
451 //but we must have his type
452 if(dataType == NULL) {
453 config_destroy(&cfg);
454 if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable type not given.\n"));
455 return 13;
456 };
457 if(!strcmp(dataType, "int")) {
458 dattyp = CONFIG_TYPE_INT;
459 } else if(!strcmp(dataType, "int64")) {
460 dattyp = CONFIG_TYPE_INT64;
461 } else if(!strcmp(dataType, "float")) {
462 dattyp = CONFIG_TYPE_FLOAT;
463 } else if(!strcmp(dataType, "string")) {
464 dattyp = CONFIG_TYPE_STRING;
465 } else if(!strcmp(dataType, "bool")) {
466 dattyp = CONFIG_TYPE_BOOL;
467 } else {
468 //only scalar type availabe
469 config_destroy(&cfg);
470 if(optflags.quiet == 0) printf(gettext("ERROR! Prohibited data type.\n"));
471 return 18;
472 };
473 //first of all we must add new element to array
474 ss = config_setting_add(setting, NULL, dattyp);
475 if(ss == NULL) {
476 config_destroy(&cfg);
477 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
478 return 11;
479 };
480 //then based on his type set value
481 switch(dattyp) {
482 case CONFIG_TYPE_INT:
483 scs = set_config_int(ss, dataString, optflags);
484 if(scs > 0) {
485 config_destroy(&cfg);
486 return scs;
487 };
488 break;
489 case CONFIG_TYPE_INT64:
490 scs = set_config_int64(ss, dataString, optflags);
491 if(scs > 0) {
492 config_destroy(&cfg);
493 return scs;
494 };
495 break;
496 case CONFIG_TYPE_FLOAT:
497 scs = set_config_float(ss, dataString, optflags);
498 if(scs > 0) {
499 config_destroy(&cfg);
500 return scs;
501 };
502 break;
503 case CONFIG_TYPE_STRING:
504 scs = config_setting_set_string(ss, dataString);
505 if(scs == CONFIG_FALSE) {
506 config_destroy(&cfg);
507 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
508 return 11;
509 };
510 break;
511 case CONFIG_TYPE_BOOL:
512 scs = set_config_bool(ss, dataString, optflags);
513 if(scs > 0) {
514 config_destroy(&cfg);
515 return scs;
516 };
517 break;
518 };
519 } else {
520 //but if we have some element in array, we can add only element of same type
521 //so, because all element in arry must be same type, we get type of first element
522 //and based on it set new element
523 dattyp = config_setting_type(config_setting_get_elem(setting, 0));
524 switch(dattyp) {
525 case CONFIG_TYPE_INT:
526 if(dataType != NULL && strcmp(dataType, "int")) {
527 config_destroy(&cfg);
528 if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
529 return 10;
530 };
531 //add new element
532 ss = config_setting_add(setting, NULL, dattyp);
533 if(ss == NULL) {
534 config_destroy(&cfg);
535 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
536 return 11;
537 };
538 //then set his value
539 scs = set_config_int(ss, dataString, optflags);
540 if(scs > 0) {
541 config_destroy(&cfg);
542 return scs;
543 };
544 break;
545 case CONFIG_TYPE_INT64:
546 if(dataType != NULL && strcmp(dataType, "int64")) {
547 config_destroy(&cfg);
548 if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
549 return 10;
550 };
551 //add new element
552 ss = config_setting_add(setting, NULL, dattyp);
553 if(ss == NULL) {
554 config_destroy(&cfg);
555 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
556 return 11;
557 };
558 //then set his value
559 scs = set_config_int64(ss, dataString, optflags);
560 if(scs > 0) {
561 config_destroy(&cfg);
562 return scs;
563 };
564 break;
565 case CONFIG_TYPE_FLOAT:
566 if(dataType != NULL && strcmp(dataType, "float")) {
567 config_destroy(&cfg);
568 if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
569 return 10;
570 };
571 //add new element
572 ss = config_setting_add(setting, NULL, dattyp);
573 if(ss == NULL) {
574 config_destroy(&cfg);
575 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
576 return 11;
577 };
578 //then set his value
579 scs = set_config_float(ss, dataString, optflags);
580 if(scs > 0) {
581 config_destroy(&cfg);
582 return scs;
583 };
584 break;
585 case CONFIG_TYPE_STRING:
586 if(dataType != NULL && strcmp(dataType, "string")) {
587 config_destroy(&cfg);
588 if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
589 return 10;
590 };
591 //add new element
592 ss = config_setting_add(setting, NULL, dattyp);
593 if(ss == NULL) {
594 config_destroy(&cfg);
595 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
596 return 11;
597 };
598 //then set his value
599 scs = config_setting_set_string(ss, dataString);
600 if(scs == CONFIG_FALSE) {
601 config_destroy(&cfg);
602 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
603 return 11;
604 };
605 break;
606 case CONFIG_TYPE_BOOL:
607 if(dataType != NULL && strcmp(dataType, "bool")) {
608 config_destroy(&cfg);
609 if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
610 return 10;
611 };
612 //add new element
613 ss = config_setting_add(setting, NULL, dattyp);
614 if(ss == NULL) {
615 config_destroy(&cfg);
616 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
617 return 11;
618 };
619 //then set his value
620 scs = set_config_bool(ss, dataString, optflags);
621 if(scs > 0) {
622 config_destroy(&cfg);
623 return scs;
624 };
625 break;
626 };
627 };
628 break;
629 case CONFIG_TYPE_LIST:
630 //in case adding element to list, we can add any type of element
631 if(dataType == NULL) {
632 //but we must konwn his type
633 config_destroy(&cfg);
634 if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable type not given.\n"));
635 return 13;
636 };
637 if(!strcmp(dataType, "int")) {
638 dattyp = CONFIG_TYPE_INT;
639 } else if(!strcmp(dataType, "int64")) {
640 dattyp = CONFIG_TYPE_INT64;
641 } else if(!strcmp(dataType, "float")) {
642 dattyp = CONFIG_TYPE_FLOAT;
643 } else if(!strcmp(dataType, "string")) {
644 dattyp = CONFIG_TYPE_STRING;
645 } else if(!strcmp(dataType, "bool")) {
646 dattyp = CONFIG_TYPE_BOOL;
647 } else if(!strcmp(dataType, "array")) {
648 dattyp = CONFIG_TYPE_ARRAY;
649 } else if(!strcmp(dataType, "list")) {
650 dattyp = CONFIG_TYPE_LIST;
651 } else if(!strcmp(dataType, "group")) {
652 dattyp = CONFIG_TYPE_GROUP;
653 } else {
654 config_destroy(&cfg);
655 if(optflags.quiet == 0) printf(gettext("ERROR! Inlegal data type.\n"));
656 return 14;
657 };
658 //add new element of given type
659 ss = config_setting_add(setting, NULL, dattyp);
660 if(ss == NULL) {
661 config_destroy(&cfg);
662 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
663 return 11;
664 };
665 //now, based on type, set element value
666 scs = 0;
667 switch(dattyp) {
668 case CONFIG_TYPE_INT:
669 scs = set_config_int(ss, dataString, optflags);
670 break;
671 case CONFIG_TYPE_INT64:
672 scs = set_config_int64(ss, dataString, optflags);
673 break;
674 case CONFIG_TYPE_FLOAT:
675 scs = set_config_int64(ss, dataString, optflags);
676 break;
677 case CONFIG_TYPE_STRING:
678 scs = config_setting_set_string(ss, dataString);
679 if(scs == CONFIG_FALSE) {
680 config_destroy(&cfg);
681 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
682 return 11;
683 };
684 scs = 0;
685 break;
686 case CONFIG_TYPE_BOOL:
687 scs = set_config_int64(ss, dataString, optflags);
688 break;
689 };
690 if(scs > 0) {
691 config_destroy(&cfg);
692 return scs;
693 };
694 //finaly outpt index of new added element
695 if(optflags.quiet == 0) {
696 printf(gettext("Added element index: %d\n"), config_setting_index(ss));
697 } else {
698 printf("%d", config_setting_index(ss));
699 };
700 break;
701 case CONFIG_TYPE_GROUP:
702 //to group we can add any type of element, but we must have his name
703 if(dataType == NULL) {
704 config_destroy(&cfg);
705 if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable type not given.\n"));
706 return 13;
707 };
708 if(strlen(dataString) < 1) {
709 config_destroy(&cfg);
710 if(optflags.quiet == 0) printf(gettext("ERROR! Bad name of configuration variable.\n"));
711 return 15;
712 };
713 //determinate type of new variable
714 if(!strcmp(dataType, "int")) {
715 dattyp = CONFIG_TYPE_INT;
716 } else if(!strcmp(dataType, "int64")) {
717 dattyp = CONFIG_TYPE_INT64;
718 } else if(!strcmp(dataType, "float")) {
719 dattyp = CONFIG_TYPE_FLOAT;
720 } else if(!strcmp(dataType, "string")) {
721 dattyp = CONFIG_TYPE_STRING;
722 } else if(!strcmp(dataType, "bool")) {
723 dattyp = CONFIG_TYPE_BOOL;
724 } else if(!strcmp(dataType, "array")) {
725 dattyp = CONFIG_TYPE_ARRAY;
726 } else if(!strcmp(dataType, "list")) {
727 dattyp = CONFIG_TYPE_LIST;
728 } else if(!strcmp(dataType, "group")) {
729 dattyp = CONFIG_TYPE_GROUP;
730 } else {
731 config_destroy(&cfg);
732 if(optflags.quiet == 0) printf(gettext("ERROR! Inlegal data type.\n"));
733 return 14;
734 };
735 //then add new alement
736 ss = config_setting_add(setting, dataString, dattyp);
737 if(ss == NULL) {
738 config_destroy(&cfg);
739 if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
740 return 11;
741 };
742 //in case of adding new element to group we not set his value
743 //(value field of input are used to get variable name)
744 //We only output index of new added element
745 if(optflags.quiet == 0) {
746 printf(gettext("Added element index: %d\n"), config_setting_index(ss));
747 } else {
748 printf("%d", config_setting_index(ss));
749 };
750 break;
751 };
752 }
753
754 //Finaly write configuration file
755 scs = config_write_file(&cfg, configFile);
756 if(scs == CONFIG_FALSE) {
757 config_destroy(&cfg);
758 if(optflags.quiet == 0) printf(gettext("ERROR! Configuration file write failed.\n"));
759 return 8;
760 };
761 config_destroy(&cfg);
762 return 0;
763 };
764
765 //unset configuration path
766 //(remove variable from configuration file)
767 //@return int success
768 //@param char* configFile - the name (with path) of configuration file
769 //@param char* configPath - path to configuration valriable to remove (unset)
770 //@param struct flags optflags - global flags
unset_config(char * configFile,char * dataPath,struct flags optflags)771 int unset_config(char *configFile, char *dataPath, struct flags optflags) {
772 config_t cfg; //configuration file handler
773 config_setting_t *setting, *par; //configuration valriale handler, and paren variable handler
774 int idx, scs; //index of variable, sucess status
775 //open configuration file
776 config_init(&cfg);
777 if(!config_read_file(&cfg, configFile)) {
778 config_destroy(&cfg);
779 if(optflags.quiet == 0) printf(gettext("ERROR! Can't read configuration file.\n"));
780 return 1;
781 };
782 //chceck if data path given
783 if(dataPath == NULL) {
784 config_destroy(&cfg);
785 if(optflags.quiet == 0) printf(gettext("ERROR! Conviguration variable path not given.\n"));
786 return 4;
787 };
788 //now find variable of given path
789 setting = config_lookup(&cfg, dataPath);
790 if(setting == NULL) {
791 config_destroy(&cfg);
792 if(optflags.quiet == 0) printf(gettext("ERROR! Given variable path not found.\n"));
793 return 3;
794 };
795 //get element index
796 idx = config_setting_index(setting);
797 if(idx < 0) {
798 config_destroy(&cfg);
799 if(optflags.quiet == 0) printf(gettext("ERROR! Can't remove root element.\n"));
800 return 5;
801 };
802 //now find parent element
803 par = config_setting_parent(setting);
804 if(par == NULL) {
805 config_destroy(&cfg);
806 if(optflags.quiet == 0) printf(gettext("ERROR! Can't find parent element.\n"));
807 return 6;
808 };
809 //then remove element
810 scs = config_setting_remove_elem(par, idx);
811 if(scs == CONFIG_FALSE) {
812 config_destroy(&cfg);
813 if(optflags.quiet == 0) printf(gettext("ERROR! Variable unset failed.\n"));
814 return 7;
815 };
816 //Finaly write configuration file
817 scs = config_write_file(&cfg, configFile);
818 if(scs == CONFIG_FALSE) {
819 config_destroy(&cfg);
820 if(optflags.quiet == 0) printf(gettext("ERROR! Configuration file write failed.\n"));
821 return 8;
822 };
823 config_destroy(&cfg);
824 return 0;
825 };
826
827 //get configuratioin variable
828 //(read it from configuration file)
829 //@return char* variable value
830 //@param char* configFile - configuration file name (with path)
831 //@param cher* dataPath - configuration variable path (in file)
832 //@param struct flags optflags - global flags
read_config(char * configFile,char * dataPath,struct flags optflags)833 int read_config(char *configFile, char *dataPath, struct flags optflags) {
834 config_t cfg; //configuration file handler
835 config_setting_t *setting, *ss; //configuration element handler, and helper handler (config element too)
836 int comaset, varindex, varcounter; //helper flat for buid output strings, varibale index, counter
837 unsigned int maxel, i; //max elements, and loop index
838 char buffer[256]; //reading buffer
839 const char *cbuffer;
840 const char *coma=";"; //output string variable separator
841 int ibuffer, ssize; //value int buffer
842 char *dataName, *dataTypeName, *dataValueString; //name of variable, type of variable, value of variable
843 int dataType, st; //internale variable type
844 //initialize values
845 dataValueString = malloc(1);
846 dataTypeName = malloc(1);
847 memset(dataValueString, 0, 1);
848 memset(dataTypeName, 0, 1);
849 varindex = 0;
850 varcounter = 0;
851 //open and read configuration file
852 config_init(&cfg);
853 if(!config_read_file(&cfg, configFile)) {
854 config_destroy(&cfg);
855 if(optflags.quiet == 0) printf(gettext("ERROR! Can't read configuration file.\n"));
856 return 1;
857 };
858 //now find variable element of given path
859 if(dataPath == NULL) {
860 //if path not givne load root element (default)
861 setting = config_root_setting(&cfg);
862 } else {
863 setting = config_lookup(&cfg, dataPath);
864 };
865 if(setting == NULL) {
866 config_destroy(&cfg);
867 if(optflags.quiet == 0) printf(gettext("ERROR! Given variable path not found.\n"));
868 return 3;
869 };
870 //read variable name
871 dataName = config_setting_name(setting);
872 if(dataName == NULL) dataName = "NULL"; //in case variable have no name convert to string representation
873 //read variable type
874 dataType = config_setting_type(setting);
875 //next conver type to human readable and read variable value based on his type
876 //and in cases in type not scalar read index and coutn variables
877 switch(dataType) {
878 case CONFIG_TYPE_INT:
879 dataTypeName = (char*)realloc(dataTypeName, 4*sizeof(char));
880 strcpy(dataTypeName, "int");
881 sprintf(buffer, "%d", config_setting_get_int(setting));
882 dataValueString = (char*)realloc(dataValueString, (strlen(buffer)+1)*sizeof(char));
883 strcpy(dataValueString, buffer);
884 break;
885 case CONFIG_TYPE_INT64:
886 dataTypeName = (char*)realloc(dataTypeName, 6*sizeof(char));
887 strcpy(dataTypeName, "int64");
888 sprintf(buffer, "%lld", config_setting_get_int64(setting));
889 dataValueString = (char*)realloc(dataValueString, (strlen(buffer)+1)*sizeof(char));
890 strcpy(dataValueString, buffer);
891 break;
892 case CONFIG_TYPE_FLOAT:
893 dataTypeName = (char*)realloc(dataTypeName, 9*sizeof(char));
894 strcpy(dataTypeName, "float");
895 sprintf(buffer, "%f", config_setting_get_float(setting));
896 dataValueString = (char*)realloc(dataValueString, (strlen(buffer)+1)*sizeof(char));
897 strcpy(dataValueString, buffer);
898 break;
899 case CONFIG_TYPE_STRING:
900 dataTypeName = (char*)realloc(dataTypeName, 7*sizeof(char));
901 strcpy(dataTypeName, "string");
902 cbuffer = config_setting_get_string(setting);
903 dataValueString = (char*)realloc(dataValueString, (strlen(cbuffer)+1)*sizeof(char));
904 strcpy(dataValueString, cbuffer);
905 break;
906 case CONFIG_TYPE_BOOL:
907 dataTypeName = (char*)realloc(dataTypeName, 5*sizeof(char));
908 strcpy(dataTypeName, "bool");
909 if(optflags.boolstring == 1) {
910 //if expect bool as string, convert it to human readable
911 ibuffer = config_setting_get_bool(setting);
912 if(ibuffer == CONFIG_TRUE) {
913 dataValueString = (char*)realloc(dataValueString, 5*sizeof(char));
914 strcpy(dataValueString, "true");
915 } else {
916 dataValueString = (char*)realloc(dataValueString, 6*sizeof(char));
917 strcpy(dataValueString, "false");
918 }
919 } else {
920 //else output as digit
921 sprintf(buffer, "%d", config_setting_get_bool(setting));
922 dataValueString = (char*)realloc(dataValueString, (strlen(buffer)+1)*sizeof(char));
923 strcpy(dataValueString, buffer);
924 };
925 break;
926 case CONFIG_TYPE_ARRAY:
927 dataTypeName = (char*)realloc(dataTypeName, 6*sizeof(char));
928 strcpy(dataTypeName, "array");
929 //get element count
930 maxel = (unsigned int)config_setting_length(setting);
931 comaset = 0;
932 //and loop over all elements
933 for(i = 0; i < maxel; i++) {
934 //get element
935 ss = config_setting_get_elem(setting, i);
936 if(ss != NULL) {
937 st = config_setting_type(ss);
938 switch(st) {
939 case CONFIG_TYPE_INT:
940 sprintf(buffer, "%d", config_setting_get_int(ss));
941 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
942 if(comaset == 1) strcat(dataValueString, coma);
943 strcat(dataValueString, buffer);
944 break;
945 case CONFIG_TYPE_INT64:
946 sprintf(buffer, "%lld", config_setting_get_int64(ss));
947 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
948 if(comaset == 1) strcat(dataValueString, coma);
949 strcat(dataValueString, buffer);
950 break;
951 case CONFIG_TYPE_FLOAT:
952 sprintf(buffer, "%f", config_setting_get_float(ss));
953 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
954 if(comaset == 1) strcat(dataValueString, coma);
955 strcat(dataValueString, buffer);
956 break;
957 case CONFIG_TYPE_STRING:
958 ssize = (int)strlen(config_setting_get_string(ss));
959
960 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+ssize+2)*sizeof(char));
961 if(comaset == 1) strcat(dataValueString, coma);
962 strcat(dataValueString, config_setting_get_string(ss));
963 break;
964 case CONFIG_TYPE_BOOL:
965 if(optflags.boolstring == 1) {
966 ibuffer = config_setting_get_bool(ss);
967 if(ibuffer == CONFIG_TRUE) {
968 //if bool must be outputed as humen readable - convert it
969 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+4+2)*sizeof(char));
970 if(comaset == 1) strcat(dataValueString, coma);
971 strcat(dataValueString, "true");
972 } else {
973 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+5+2)*sizeof(char));
974 if(comaset == 1) strcat(dataValueString, coma);
975 strcat(dataValueString, "false");
976 }
977 } else {
978 //else output as digit
979 sprintf(buffer, "%d", config_setting_get_bool(ss));
980 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
981 if(comaset == 1) strcat(dataValueString, coma);
982 strcat(dataValueString, buffer);
983 };
984 break;
985 case CONFIG_TYPE_ARRAY:
986 //if array contains array output as kwyword ARRAY
987 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+7)*sizeof(char));
988 if(comaset == 1) strcat(dataValueString, coma);
989 strcat(dataValueString, "ARRAY");
990 break;
991 case CONFIG_TYPE_LIST:
992 //if array contains list output as keyword LIST
993 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+6)*sizeof(char));
994 if(comaset == 1) strcat(dataValueString, coma);
995 strcat(dataValueString, "LIST");
996 break;
997 case CONFIG_TYPE_GROUP:
998 //if array contains group output as keywort GROUP
999 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+7)*sizeof(char));
1000 if(comaset == 1) strcat(dataValueString, coma);
1001 strcat(dataValueString, "GROUP");
1002 break;
1003 };
1004 comaset = 1;
1005 };
1006 };
1007 break;
1008 case CONFIG_TYPE_LIST:
1009 dataTypeName = (char*)realloc(dataTypeName, 5*sizeof(char));
1010 strcpy(dataTypeName, "list");
1011 //get element count
1012 maxel = (unsigned int)config_setting_length(setting);
1013 //end loop over all elements
1014 comaset = 0;
1015 for(i = 0; i < maxel; i++) {
1016 ss = config_setting_get_elem(setting, i);
1017 if(ss != NULL) {
1018 st = config_setting_type(ss);
1019 switch(st) {
1020 case CONFIG_TYPE_INT:
1021 sprintf(buffer, "%d", config_setting_get_int(ss));
1022 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
1023 if(comaset == 1) strcat(dataValueString, coma);
1024 strcat(dataValueString, buffer);
1025 break;
1026 case CONFIG_TYPE_INT64:
1027 sprintf(buffer, "%lld", config_setting_get_int64(ss));
1028 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
1029 if(comaset == 1) strcat(dataValueString, coma);
1030 strcat(dataValueString, buffer);
1031 break;
1032 case CONFIG_TYPE_FLOAT:
1033 sprintf(buffer, "%f", config_setting_get_float(ss));
1034 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
1035 if(comaset == 1) strcat(dataValueString, coma);
1036 strcat(dataValueString, buffer);
1037 break;
1038 case CONFIG_TYPE_STRING:
1039 ssize = (int)strlen(config_setting_get_string(ss));
1040
1041 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+ssize+2)*sizeof(char));
1042 if(comaset == 1) strcat(dataValueString, coma);
1043 strcat(dataValueString, config_setting_get_string(ss));
1044 break;
1045 case CONFIG_TYPE_BOOL:
1046 if(optflags.boolstring == 1) {
1047 ibuffer = config_setting_get_bool(ss);
1048 if(ibuffer == CONFIG_TRUE) {
1049 //if bool must be printout as humanreadable - convert it
1050 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+4+2)*sizeof(char));
1051 if(comaset == 1) strcat(dataValueString, coma);
1052 strcat(dataValueString, "true");
1053 } else {
1054 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+5+2)*sizeof(char));
1055 if(comaset == 1) strcat(dataValueString, coma);
1056 strcat(dataValueString, "false");
1057 }
1058 } else {
1059 //else output as int
1060 sprintf(buffer, "%d", config_setting_get_bool(ss));
1061 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
1062 if(comaset == 1) strcat(dataValueString, coma);
1063 strcat(dataValueString, buffer);
1064 };
1065 break;
1066 case CONFIG_TYPE_ARRAY:
1067 //if list contain array output as keyword ARRAY
1068 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+7)*sizeof(char));
1069 if(comaset == 1) strcat(dataValueString, coma);
1070 strcat(dataValueString, "ARRAY");
1071 break;
1072 case CONFIG_TYPE_LIST:
1073 //if list contain list output as keyword LIST
1074 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+6)*sizeof(char));
1075 if(comaset == 1) strcat(dataValueString, coma);
1076 strcat(dataValueString, "LIST");
1077 break;
1078 case CONFIG_TYPE_GROUP:
1079 //if list contain group output as keyword GROUP
1080 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+7)*sizeof(char));
1081 if(comaset == 1) strcat(dataValueString, coma);
1082 strcat(dataValueString, "GROUP");
1083 break;
1084 };
1085 comaset = 1;
1086 };
1087 };
1088 break;
1089 case CONFIG_TYPE_GROUP:
1090 dataTypeName = (char*)realloc(dataTypeName, 6*sizeof(char));
1091 strcpy(dataTypeName, "group");
1092 //get elementc count
1093 maxel = (unsigned int)config_setting_length(setting);
1094 //and loop over all elements
1095 //but in group case, we return inside variables names
1096 comaset = 0;
1097 for(i = 0; i < maxel; i++) {
1098 ss = config_setting_get_elem(setting, i);
1099 if(ss != NULL) {
1100 ssize = (int)strlen(config_setting_name(ss));
1101 dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+ssize+2)*sizeof(char));
1102 if(comaset == 1) strcat(dataValueString, coma);
1103 strcat(dataValueString, config_setting_name(ss));
1104 comaset = 1;
1105 };
1106 };
1107 break;
1108 };
1109
1110 //last we get readed variable index, and element count
1111 varindex = config_setting_index(setting);
1112 varcounter = config_setting_length(setting);
1113
1114 //and finaly output data
1115 if(optflags.names == 1 && optflags.quiet == 0) printf(gettext("Variable name: %s\n"), dataName);
1116 if(optflags.names == 1 && optflags.quiet == 1) printf("%s", dataName);
1117 if((optflags.types == 1 && optflags.quiet == 1) && optflags.names == 1) printf(":");
1118 if(optflags.types == 1 && optflags.quiet == 0) printf(gettext("Variable type: %s\n"), dataTypeName);
1119 if(optflags.types == 1 && optflags.quiet == 1) printf("%s", dataTypeName);
1120 if((optflags.values == 1 && optflags.quiet == 1) && (optflags.names == 1 || optflags.types == 1)) printf(":");
1121 if(optflags.values == 1 && optflags.quiet == 0) printf(gettext("Variable value: %s\n"), dataValueString);
1122 if(optflags.values == 1 && optflags.quiet == 1) printf("%s", dataValueString);
1123 if((optflags.indexes == 1 && optflags.quiet == 1) && (optflags.names == 1 || optflags.types == 1 || optflags.values == 1)) printf(":");
1124 if(optflags.indexes == 1 && optflags.quiet == 0) printf(gettext("Variable index: %d\n"), varindex);
1125 if(optflags.indexes == 1 && optflags.quiet == 1) printf("%d", varindex);
1126 if((optflags.counter == 1 && optflags.quiet == 1) && (optflags.names == 1 || optflags.types == 1 || optflags.values == 1 || optflags.indexes == 1)) printf(":");
1127 if(optflags.counter == 1 && optflags.quiet == 0) printf(gettext("Variable elements count: %d\n"), varcounter);
1128 if(optflags.counter == 1 && optflags.quiet == 1) printf("%d", varcounter);
1129 if(optflags.quiet == 1) printf("\n");
1130
1131 config_destroy(&cfg);
1132 return 0;
1133 }
1134
main(int argc,char ** argv)1135 int main(int argc, char **argv) {
1136 //firs set locale and domain to work with internationalization
1137 setlocale(LC_ALL, "");
1138 bindtextdomain("ls-config", "/usr/share/locale");
1139 textdomain("ls-config");
1140
1141 //then declare and init values
1142 int opt,test; //used for read innput: option, and testing
1143 int fd; //file descriptor
1144 char *sinp, *dataPath=NULL, *dataString=NULL, *dataType=NULL; //string input, configuration variable path, input data, variable type
1145 char *configFile=NULL; //config file name (with path)
1146 struct flags optflags = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //global flags initialize
1147 int excode; //program exit code
1148 excode = 0;
1149
1150 sinp = malloc(sizeof(char) * 256);
1151
1152 //long options reading
1153 struct option long_options[] = {
1154 /* These options set a flag. */
1155 {"quiet", no_argument, &optflags.quiet, 1},
1156 {"names", no_argument, &optflags.names, 1},
1157 {"types", no_argument, &optflags.types, 1},
1158 {"values", no_argument, &optflags.values, 1},
1159 {"indexes", no_argument, &optflags.indexes, 1},
1160 {"count", no_argument, &optflags.counter, 1},
1161 {"unset", no_argument, &optflags.unset, 1},
1162 {"bool-string", no_argument, &optflags.boolstring, 1},
1163 /* These options don't set a flag.
1164 We distinguish them by their indices. */
1165 {"help", no_argument, 0, 'h'},
1166 {"set", required_argument, 0, 's'},
1167 {"get", optional_argument, 0, 'g'},
1168 {"data", required_argument, 0, 'd'},
1169 {"type", required_argument, 0, 'p'},
1170 {"file", required_argument, 0, 'f'},
1171 {0, 0, 0, 0}
1172 };
1173
1174 //next collect all input (given as options to program)
1175 while(1) {
1176 int option_index = 0;
1177 opt = getopt_long (argc, argv, "qntvicubs:g:d:p:hf:", long_options, &option_index);
1178
1179 if(opt == -1) break;
1180
1181 switch (opt) {
1182 case 0:
1183 /* If this option set a flag, do nothing else now. */
1184 if(long_options[option_index].flag != 0) break;
1185 if(strcmp(long_options[option_index].name, "set") == 0 && optarg) {
1186 test = sscanf(optarg, "%s", sinp);
1187 if(test > 0) {
1188 dataPath = (char*)malloc((strlen(sinp)+1)*sizeof(char));
1189 strcpy(dataPath, sinp);
1190 };
1191 optflags.mode = 1;
1192 };
1193 if(strcmp(long_options[option_index].name, "get") == 0 && optarg) {
1194 test = sscanf(optarg, "%s", sinp);
1195 if(test > 0) {
1196 dataPath = (char*)malloc((strlen(sinp)+1)*sizeof(char));
1197 strcpy(dataPath, sinp);
1198 };
1199 optflags.mode = 0;
1200 };
1201 if(strcmp(long_options[option_index].name, "data") == 0 && optarg) {
1202 test = sscanf(optarg, "%[^\n]s", sinp);
1203 if(test > 0) {
1204 dataString = (char*)malloc((strlen(sinp)+1)*sizeof(char));
1205 strcpy(dataString, sinp);
1206 };
1207 };
1208 if(strcmp(long_options[option_index].name, "type") == 0 && optarg) {
1209 test = sscanf(optarg, "%s", sinp);
1210 if(test > 0) {
1211 dataType = (char*)malloc((strlen(sinp)+1)*sizeof(char));
1212 strcpy(dataType, sinp);
1213 };
1214 };
1215 if(strcmp(long_options[option_index].name, "file") == 0 && optarg) {
1216 test = sscanf(optarg, "%[^\n]s", sinp);
1217 if(test > 0) {
1218 configFile = (char*)malloc((strlen(sinp)+1)*sizeof(char));
1219 strcpy(configFile, sinp);
1220 };
1221 };
1222 break;
1223 case 'q':
1224 optflags.quiet = 1;
1225 break;
1226 case 'n':
1227 optflags.names = 1;
1228 break;
1229 case 't':
1230 optflags.types = 1;
1231 break;
1232 case 'v':
1233 optflags.values = 1;
1234 break;
1235 case 'i':
1236 optflags.indexes = 1;
1237 break;
1238 case 'c':
1239 optflags.counter = 1;
1240 break;
1241 case 'u':
1242 optflags.unset = 1;
1243 break;
1244 case 'b':
1245 optflags.boolstring = 1;
1246 break;
1247 case 's':
1248 if(optarg) {
1249 test = sscanf(optarg, "%s", sinp);
1250 if(test > 0) {
1251 dataPath = (char*)malloc((strlen(sinp)+1)*sizeof(char));
1252 strcpy(dataPath, sinp);
1253 };
1254 optflags.mode = 1;
1255 };
1256 break;
1257 case 'g':
1258 if(optarg) {
1259 test = sscanf(optarg, "%s", sinp);
1260 if(test > 0) {
1261 dataPath = (char*)malloc((strlen(sinp)+1)*sizeof(char));
1262 strcpy(dataPath, sinp);
1263 };
1264 };
1265 optflags.mode = 0;
1266 break;
1267 case 'd':
1268 if(optarg) {
1269 test = sscanf(optarg, "%[^\n]s", sinp);
1270 if(test > 0) {
1271 dataString = (char*)malloc((strlen(sinp)+1)*sizeof(char));
1272 strcpy(dataString, sinp);
1273 };
1274 };
1275 break;
1276 case 'p':
1277 if(optarg) {
1278 test = sscanf(optarg, "%s", sinp);
1279 if(test > 0) {
1280 dataType = (char*)malloc((strlen(sinp)+1)*sizeof(char));
1281 strcpy(dataType, sinp);
1282 };
1283 };
1284 break;
1285 case 'h':
1286 //free input buffer and printout help message
1287 free(sinp);
1288 printHelp(); //this function contain exit from program
1289 break;
1290 case 'f':
1291 test = sscanf(optarg, "%[^\n]s", sinp);
1292 if(test > 0) {
1293 configFile = (char*)malloc((strlen(sinp)+1)*sizeof(char));
1294 strcpy(configFile, sinp);
1295 };
1296 break;
1297 case '?':
1298 break;
1299 default:
1300 break;
1301 }
1302 };
1303
1304 //first of all we must ensure, then configuration file are available with right access mode
1305 if(optflags.mode == 0 && access(configFile, R_OK) < 0) optflags.error = 1;
1306 if(optflags.mode == 1) {
1307 fd = open(configFile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
1308 if(fd < 0) {
1309 optflags.error = 1;
1310 };
1311 close(fd);
1312 };
1313 if(optflags.error > 0) {
1314 if(optflags.quiet == 0) printf(gettext("ERROR! Can't read configuration file.\n"));
1315 free(sinp);
1316 free(configFile);
1317 exit(1);
1318 };
1319
1320 //now if we want to set variable, we must have his path
1321 if(optflags.mode == 1 && dataPath == NULL) {
1322 if(optflags.quiet == 0) printf(gettext("ERROR! Conviguration variable path not given.\n"));
1323 free(sinp);
1324 free(configFile);
1325 exit(4);
1326 };
1327
1328 //if no output data requested, set to default output
1329 if(optflags.names == 0 && optflags.types == 0 && optflags.values == 0 && optflags.indexes == 0 && optflags.counter == 0) {
1330 optflags.names = 1;
1331 optflags.types = 1;
1332 optflags.values = 1;
1333 };
1334
1335 //now we invode main work of this software based on request type (set, unset of get)
1336 if(optflags.mode == 0) excode = read_config(configFile, dataPath, optflags);
1337 if(optflags.mode == 1 && optflags.unset == 1) excode = unset_config(configFile, dataPath, optflags);
1338 if(optflags.mode == 1 && optflags.unset == 0) excode = set_config(configFile, dataPath, optflags, dataString, dataType);
1339
1340 //then finalize free resources and exit returnig excode
1341 free(sinp);
1342 free(configFile);
1343 exit(excode);
1344 }
1345
1346