aboutsummaryrefslogtreecommitdiff
path: root/contrib/ls-config/src/ls-config.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ls-config/src/ls-config.c')
-rw-r--r--contrib/ls-config/src/ls-config.c1345
1 files changed, 1345 insertions, 0 deletions
diff --git a/contrib/ls-config/src/ls-config.c b/contrib/ls-config/src/ls-config.c
new file mode 100644
index 0000000..4db8966
--- /dev/null
+++ b/contrib/ls-config/src/ls-config.c
@@ -0,0 +1,1345 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <locale.h>
+#include <libintl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <math.h>
+#include <libconfig.h>
+
+#define PACKAGE "LS bash config"
+#define VERSION "1.0.3"
+
+// global flags
+struct flags {
+ int quiet; //quiet output
+ int names; //set for printout config variables names
+ int types; //set for printout config variables types
+ int values; //set for printout config variables values
+ int indexes; //set for printout config variables indexes
+ int counter; //set for printout config varibales counting (for grout, list, array. in other cases it return 1)
+ int unset; //unset valriable
+ int boolstring; //set for output bool variable (0|1) as test (false|true)
+ int mode; //1 - for setting variable, 0 - for get hist data
+ int error; //error status handling
+};
+
+//take valur from input and comvert it to int
+//TODO: Read long too
+int getNumber() {
+ char buf[1000];
+ int test,val;
+ unsigned int inp;
+ fgets(buf, sizeof buf, stdin);
+ test = sscanf(buf, "%u", &inp);
+ val = (int) inp;
+ if(val < 0) val *= -1;
+ if(test > 0) return val;
+ return (int) 0;
+}
+
+//printout help messsage
+void printHelp() {
+ printf(gettext("Configuration file handling\n"));
+ printf("\n");
+ printf(gettext("Usage: ls-config [OPTION]\n"));
+ printf(gettext("Reading and writening data from configuration files\n"));
+ printf(gettext("in libconfig9 format.\n"));
+ printf("\n");
+ printf(gettext("CAUTION: using without given config file are cause error!\n"));
+ printf("\n");
+ printf(gettext("Available options:\n"));
+ printf(gettext(" -f, --file=FILE Configuration file to handle.\n"));
+ printf("\n");
+ printf(gettext(" -s, --set=PATH Set configuration variable of given path.\n"));
+ printf(gettext(" -d, --data=DATA Configuration variable value (only with -s)\n"));
+ printf(gettext(" -p, --type=TYPE Configuration value type\n"));
+ printf("\n");
+ printf(gettext(" -g, --get=PATH Get configuration variable of given path.\n"));
+ printf(gettext(" -n, --names Printout variables names.\n"));
+ printf(gettext(" -t, --types Printout variables types.\n"));
+ printf(gettext(" -v, --values Printout variables values.\n"));
+ printf(gettext(" -i, --indexes Printout variables indexes.\n"));
+ printf(gettext(" -c, --count Printout elements count (only: array, list, group).\n"));
+ printf(gettext(" -b, --bool-string Printout boolean variables as text.\n"));
+ printf("\n");
+ printf(gettext(" -q, --quiet Quiet output to use in scripts.\n"));
+ printf(gettext(" -h, --help Print this help message.\n"));
+ printf("\n");
+ printf(gettext("TYPE: Variable types:\n"));
+ printf(gettext(" group - variables group,\n"));
+ printf(gettext(" array - array of variables,\n"));
+ printf(gettext(" list - list of variables,\n"));
+ printf(gettext(" int - integer number,\n"));
+ printf(gettext(" int64 - 64bit integer number,\n"));
+ printf(gettext(" float - float point number,\n"));
+ printf(gettext(" bool - boolean value,\n"));
+ printf(gettext(" string - character string.\n"));
+ printf("\n");
+ printf("(c) 2013 by LucaS web sutio - http://www.lucas.net.pl\n");
+ printf("Author: Ɓukasz A. Grabowski\n");
+ printf(gettext("Licence: "));
+ printf("GPL v2.\n");
+ exit(0);
+};
+
+//set configuration int value
+int set_config_int(config_setting_t *setting, char *dataString, struct flags optflags) {
+ long bufl; //int (long) to get from input data string
+ int buf, scs; //config int, success status
+ char *erp; //error output
+
+ //convert input data to int
+ errno = 0;
+ bufl = strtol(dataString, &erp, 0);
+ if(((errno == ERANGE && (bufl == LONG_MAX || bufl == LONG_MIN)) || (errno != 0 && bufl == 0)) || (erp == dataString) || bufl > INT_MAX || bufl < INT_MIN) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Incorrect data format.\n"));
+ return 12;
+ };
+ buf = (int)bufl;
+
+ //set configuration variable
+ scs = config_setting_set_int(setting, buf);
+ if(scs == CONFIG_FALSE) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ return 0;
+};
+
+//set configuration int64 value
+int set_config_int64(config_setting_t *setting, char *dataString, struct flags optflags) {
+ long bufl; //long to get from input data string
+ int scs; //success status
+ char *erp; //error output
+
+ //convert input data to long
+ errno = 0;
+ bufl = strtol(dataString, &erp, 0);
+ if(((errno == ERANGE && (bufl == LONG_MAX || bufl == LONG_MIN)) || (errno != 0 && bufl == 0)) || (erp == dataString)) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Incorrect data format.\n"));
+ return 12;
+ };
+
+ //set configuration variable
+ scs = config_setting_set_int64(setting, bufl);
+ if(scs == CONFIG_FALSE) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ return 0;
+};
+
+//set configuration float value
+int set_config_float(config_setting_t *setting, char *dataString, struct flags optflags) {
+ double buff; //double (float) to get from input data string
+ int scs; //success status
+ char *erp; //error output
+
+ //convert input data to double
+ errno = 0;
+ buff = strtod(dataString, &erp);
+ if(((errno == ERANGE && (buff == HUGE_VALF || buff == HUGE_VALL)) || (errno != 0 && buff == 0)) || (erp == dataString)) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Incorrect data format.\n"));
+ return 12;
+ }
+
+ //set configuration variable
+ scs = config_setting_set_float(setting, buff);
+ if(scs == CONFIG_FALSE) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ return 0;
+};
+
+//set configuration boolean value
+int set_config_bool(config_setting_t *setting, char *dataString, struct flags optflags) {
+ int scs, buf; //success status, input convert burrer
+
+ //convert input data
+ //chceck both 1/0 and true/false string
+ buf = -1;
+ if(!strcmp(dataString, "1") || !strcmp(dataString, "true") || !strcmp(dataString, "TRUE")) buf = 1;
+ if(!strcmp(dataString, "0") || !strcmp(dataString, "false") || !strcmp(dataString, "FALSE")) buf = 0;
+ if(buf < 0) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Incorrect data format.\n"));
+ return 12;
+ }
+
+ //set configuration variable
+ scs = config_setting_set_bool(setting, buf);
+ if(scs == CONFIG_FALSE) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ return 0;
+};
+
+//configuratnion variable path look like: foo.bar.car
+//this fuction return string giving path to parent element (foo.bar)
+char* path_parent(char *dataPath) {
+ char *str_ptr, *last_ptr, *newpath, *dot="."; //tokenized buffer, last buffer, new parent path, separator
+ newpath = malloc(1);
+ memset(newpath, 0, 1);
+ last_ptr = malloc(1);
+ memset(last_ptr, 0, 1);
+
+ //tokenize string and save last token
+ str_ptr = strtok(dataPath, ".");
+ last_ptr = (char*)realloc(last_ptr, (strlen(str_ptr)+1)*sizeof(char));
+ strcpy(last_ptr, str_ptr);
+
+ //loop overt path to build new path without last element
+ while(str_ptr != NULL) {
+ str_ptr = strtok(NULL, ".");
+ if(str_ptr != NULL) {
+ if(strlen(last_ptr) > 0 ) {
+ newpath = (char*)realloc(newpath, (strlen(newpath)+strlen(last_ptr)+2)*sizeof(char));
+ strcat(newpath, dot);
+ strcat(newpath, last_ptr);
+ };
+ last_ptr = (char*)realloc(last_ptr, (strlen(str_ptr)+1)*sizeof(char));
+ strcpy(last_ptr, str_ptr);
+ } else {
+ last_ptr = (char*)realloc(last_ptr, (1)*sizeof(char));
+ memset(last_ptr, 0, 1);
+ };
+ };
+ free(dataPath);
+
+ //if new path empty thren return null
+ if(strlen(newpath) == 0) {
+ free(newpath);
+ newpath = NULL;
+ };
+ return newpath;
+};
+
+//get element name from configuration variable path
+//e.g.: from foo.bar return bar
+char* path_name(char *dataPath) {
+ char *str_ptr, *name, *tk; //tokenized buffer, element name, copy of dataPath
+ name = malloc(1);
+
+ //make copy of dataPath
+ tk = malloc((strlen(dataPath)+1)*sizeof(char));
+ memset(name, 0, 1);
+ strcpy(tk, dataPath);
+
+ //tokenize dataPath
+ str_ptr = strtok(tk, ".");
+
+ //loop over tokenize pathh to get last element
+ while(str_ptr != NULL) {
+ name = (char*)realloc(name, (strlen(str_ptr)+1)*sizeof(char));
+ strcpy(name, str_ptr);
+ str_ptr = strtok(NULL, ".");
+ };
+ free(tk);
+
+ //if no element name then return null
+ if(strlen(name) == 0) {
+ free(name);
+ name = NULL;
+ };
+ return name;
+};
+
+//set configuration path
+//@return int success
+//@param configFile - name (with path) of configuration fille
+//@param dataPath - path of configuration variable (in config file)
+//@param optflags - global options flags
+//@param dataString - data to store in configuration variable in string format
+//@param dataType - type of variable to save
+int set_config(char *configFile, char *dataPath, struct flags optflags, char *dataString, char *dataType) {
+ config_t cfg; //libcongig configuration handler
+ config_setting_t *setting, *ss; //libconfig element handrer: mant, and subset (uset for multielement types)
+ config_init(&cfg);
+ int scs, dt, dattyp; //sucess statu, data type
+ char *npath; // new variable configuration path path
+
+ //open and read configuration file
+ if(!config_read_file(&cfg, configFile)) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Can't read configuration file.\n"));
+ return 1;
+ };
+
+ //if no data path or data string then cause error
+ if(dataPath == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Conviguration variable path not given.\n"));
+ return 4;
+ };
+ if(dataString == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable value not given.\n"));
+ return 9;
+ };
+
+ //find configuration variable of given path
+ setting = config_lookup(&cfg, dataPath);
+ if(setting == NULL) {
+ //if variable of given path not found get element name and partent path,
+ //then try to create it
+ npath = path_name(dataPath);
+ dataPath = path_parent(dataPath);
+ if(dataPath == NULL) {
+ setting = config_root_setting(&cfg);
+ } else {
+ setting = config_lookup(&cfg, dataPath);
+ };
+ if(setting == NULL) {
+ //if parent not exists exit with error
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Inavlid configuration variable path.\n"));
+ return 16;
+ };
+ //chceck type of parent element (named alement can be added only to group element)
+ dt = config_setting_type(setting);
+ if(dt != CONFIG_TYPE_GROUP) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! New named configuration variable can be added only to group element.\n"));
+ return 17;
+ };
+ //check if new element type are given
+ if(dataType == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable type not given.\n"));
+ return 13;
+ };
+ //now get type based on his name
+ if(!strcmp(dataType, "int")) {
+ dattyp = CONFIG_TYPE_INT;
+ } else if(!strcmp(dataType, "int64")) {
+ dattyp = CONFIG_TYPE_INT64;
+ } else if(!strcmp(dataType, "float")) {
+ dattyp = CONFIG_TYPE_FLOAT;
+ } else if(!strcmp(dataType, "string")) {
+ dattyp = CONFIG_TYPE_STRING;
+ } else if(!strcmp(dataType, "bool")) {
+ dattyp = CONFIG_TYPE_BOOL;
+ } else if(!strcmp(dataType, "array")) {
+ dattyp = CONFIG_TYPE_ARRAY;
+ } else if(!strcmp(dataType, "list")) {
+ dattyp = CONFIG_TYPE_LIST;
+ } else if(!strcmp(dataType, "group")) {
+ dattyp = CONFIG_TYPE_GROUP;
+ } else {
+ //if given type no mutch eny then cause error and exit
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Inlegal data type.\n"));
+ return 14;
+ };
+ //add new element to configuration file
+ ss = config_setting_add(setting, npath, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ scs = 0;
+ //and based on new type set his value
+ switch(dattyp) {
+ case CONFIG_TYPE_INT:
+ scs = set_config_int(ss, dataString, optflags);
+ break;
+ case CONFIG_TYPE_INT64:
+ scs = set_config_int64(ss, dataString, optflags);
+ break;
+ case CONFIG_TYPE_FLOAT:
+ scs = set_config_float(ss, dataString, optflags);
+ break;
+ case CONFIG_TYPE_STRING:
+ scs = config_setting_set_string(ss, dataString);
+ if(scs == CONFIG_FALSE) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ scs = 11;
+ } else scs = 0;
+ break;
+ case CONFIG_TYPE_BOOL:
+ scs = set_config_bool(ss, dataString, optflags);
+ break;
+ };
+ if(scs > 0) {
+ //if occurs some error wihe setting variable value exit with error
+ config_destroy(&cfg);
+ return scs;
+ };
+ } else {
+ //but if we found element of given path, try to set his value
+ //first of all determinate type of value
+ dt = config_setting_type(setting);
+ switch(dt) {
+ case CONFIG_TYPE_INT:
+ if(dataType != NULL && strcmp(dataType, "int")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //then set value
+ scs = set_config_int(setting, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_INT64:
+ if(dataType != NULL && strcmp(dataType, "int64")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //then set value
+ scs = set_config_int64(setting, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_FLOAT:
+ if(dataType != NULL && strcmp(dataType, "float")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //then set value
+ scs = set_config_float(setting, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_STRING:
+ if(dataType != NULL && strcmp(dataType, "string")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //then set value
+ scs = config_setting_set_string(setting, dataString);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ break;
+ case CONFIG_TYPE_BOOL:
+ if(dataType != NULL && strcmp(dataType, "bool")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //then set value
+ scs = set_config_bool(setting, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_ARRAY:
+ //if array are empty we can set alement of any scalar type
+ if(config_setting_length(setting) == 0) {
+ //but we must have his type
+ if(dataType == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable type not given.\n"));
+ return 13;
+ };
+ if(!strcmp(dataType, "int")) {
+ dattyp = CONFIG_TYPE_INT;
+ } else if(!strcmp(dataType, "int64")) {
+ dattyp = CONFIG_TYPE_INT64;
+ } else if(!strcmp(dataType, "float")) {
+ dattyp = CONFIG_TYPE_FLOAT;
+ } else if(!strcmp(dataType, "string")) {
+ dattyp = CONFIG_TYPE_STRING;
+ } else if(!strcmp(dataType, "bool")) {
+ dattyp = CONFIG_TYPE_BOOL;
+ } else {
+ //only scalar type availabe
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Prohibited data type.\n"));
+ return 18;
+ };
+ //first of all we must add new element to array
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //then based on his type set value
+ switch(dattyp) {
+ case CONFIG_TYPE_INT:
+ scs = set_config_int(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_INT64:
+ scs = set_config_int64(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_FLOAT:
+ scs = set_config_float(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_STRING:
+ scs = config_setting_set_string(ss, dataString);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ break;
+ case CONFIG_TYPE_BOOL:
+ scs = set_config_bool(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ };
+ } else {
+ //but if we have some element in array, we can add only element of same type
+ //so, because all element in arry must be same type, we get type of first element
+ //and based on it set new element
+ dattyp = config_setting_type(config_setting_get_elem(setting, 0));
+ switch(dattyp) {
+ case CONFIG_TYPE_INT:
+ if(dataType != NULL && strcmp(dataType, "int")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //add new element
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //then set his value
+ scs = set_config_int(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_INT64:
+ if(dataType != NULL && strcmp(dataType, "int64")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //add new element
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //then set his value
+ scs = set_config_int64(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_FLOAT:
+ if(dataType != NULL && strcmp(dataType, "float")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //add new element
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //then set his value
+ scs = set_config_float(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_STRING:
+ if(dataType != NULL && strcmp(dataType, "string")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //add new element
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //then set his value
+ scs = config_setting_set_string(ss, dataString);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ break;
+ case CONFIG_TYPE_BOOL:
+ if(dataType != NULL && strcmp(dataType, "bool")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //add new element
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //then set his value
+ scs = set_config_bool(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ };
+ };
+ break;
+ case CONFIG_TYPE_LIST:
+ //in case adding element to list, we can add any type of element
+ if(dataType == NULL) {
+ //but we must konwn his type
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable type not given.\n"));
+ return 13;
+ };
+ if(!strcmp(dataType, "int")) {
+ dattyp = CONFIG_TYPE_INT;
+ } else if(!strcmp(dataType, "int64")) {
+ dattyp = CONFIG_TYPE_INT64;
+ } else if(!strcmp(dataType, "float")) {
+ dattyp = CONFIG_TYPE_FLOAT;
+ } else if(!strcmp(dataType, "string")) {
+ dattyp = CONFIG_TYPE_STRING;
+ } else if(!strcmp(dataType, "bool")) {
+ dattyp = CONFIG_TYPE_BOOL;
+ } else if(!strcmp(dataType, "array")) {
+ dattyp = CONFIG_TYPE_ARRAY;
+ } else if(!strcmp(dataType, "list")) {
+ dattyp = CONFIG_TYPE_LIST;
+ } else if(!strcmp(dataType, "group")) {
+ dattyp = CONFIG_TYPE_GROUP;
+ } else {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Inlegal data type.\n"));
+ return 14;
+ };
+ //add new element of given type
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //now, based on type, set element value
+ scs = 0;
+ switch(dattyp) {
+ case CONFIG_TYPE_INT:
+ scs = set_config_int(ss, dataString, optflags);
+ break;
+ case CONFIG_TYPE_INT64:
+ scs = set_config_int64(ss, dataString, optflags);
+ break;
+ case CONFIG_TYPE_FLOAT:
+ scs = set_config_int64(ss, dataString, optflags);
+ break;
+ case CONFIG_TYPE_STRING:
+ scs = config_setting_set_string(ss, dataString);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ scs = 0;
+ break;
+ case CONFIG_TYPE_BOOL:
+ scs = set_config_int64(ss, dataString, optflags);
+ break;
+ };
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ //finaly outpt index of new added element
+ if(optflags.quiet == 0) {
+ printf(gettext("Added element index: %d\n"), config_setting_index(ss));
+ } else {
+ printf("%d", config_setting_index(ss));
+ };
+ break;
+ case CONFIG_TYPE_GROUP:
+ //to group we can add any type of element, but we must have his name
+ if(dataType == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable type not given.\n"));
+ return 13;
+ };
+ if(strlen(dataString) < 1) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Bad name of configuration variable.\n"));
+ return 15;
+ };
+ //determinate type of new variable
+ if(!strcmp(dataType, "int")) {
+ dattyp = CONFIG_TYPE_INT;
+ } else if(!strcmp(dataType, "int64")) {
+ dattyp = CONFIG_TYPE_INT64;
+ } else if(!strcmp(dataType, "float")) {
+ dattyp = CONFIG_TYPE_FLOAT;
+ } else if(!strcmp(dataType, "string")) {
+ dattyp = CONFIG_TYPE_STRING;
+ } else if(!strcmp(dataType, "bool")) {
+ dattyp = CONFIG_TYPE_BOOL;
+ } else if(!strcmp(dataType, "array")) {
+ dattyp = CONFIG_TYPE_ARRAY;
+ } else if(!strcmp(dataType, "list")) {
+ dattyp = CONFIG_TYPE_LIST;
+ } else if(!strcmp(dataType, "group")) {
+ dattyp = CONFIG_TYPE_GROUP;
+ } else {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Inlegal data type.\n"));
+ return 14;
+ };
+ //then add new alement
+ ss = config_setting_add(setting, dataString, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //in case of adding new element to group we not set his value
+ //(value field of input are used to get variable name)
+ //We only output index of new added element
+ if(optflags.quiet == 0) {
+ printf(gettext("Added element index: %d\n"), config_setting_index(ss));
+ } else {
+ printf("%d", config_setting_index(ss));
+ };
+ break;
+ };
+ }
+
+ //Finaly write configuration file
+ scs = config_write_file(&cfg, configFile);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration file write failed.\n"));
+ return 8;
+ };
+ config_destroy(&cfg);
+ return 0;
+};
+
+//unset configuration path
+//(remove variable from configuration file)
+//@return int success
+//@param char* configFile - the name (with path) of configuration file
+//@param char* configPath - path to configuration valriable to remove (unset)
+//@param struct flags optflags - global flags
+int unset_config(char *configFile, char *dataPath, struct flags optflags) {
+ config_t cfg; //configuration file handler
+ config_setting_t *setting, *par; //configuration valriale handler, and paren variable handler
+ int idx, scs; //index of variable, sucess status
+ //open configuration file
+ config_init(&cfg);
+ if(!config_read_file(&cfg, configFile)) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Can't read configuration file.\n"));
+ return 1;
+ };
+ //chceck if data path given
+ if(dataPath == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Conviguration variable path not given.\n"));
+ return 4;
+ };
+ //now find variable of given path
+ setting = config_lookup(&cfg, dataPath);
+ if(setting == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Given variable path not found.\n"));
+ return 3;
+ };
+ //get element index
+ idx = config_setting_index(setting);
+ if(idx < 0) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Can't remove root element.\n"));
+ return 5;
+ };
+ //now find parent element
+ par = config_setting_parent(setting);
+ if(par == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Can't find parent element.\n"));
+ return 6;
+ };
+ //then remove element
+ scs = config_setting_remove_elem(par, idx);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable unset failed.\n"));
+ return 7;
+ };
+ //Finaly write configuration file
+ scs = config_write_file(&cfg, configFile);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration file write failed.\n"));
+ return 8;
+ };
+ config_destroy(&cfg);
+ return 0;
+};
+
+//get configuratioin variable
+//(read it from configuration file)
+//@return char* variable value
+//@param char* configFile - configuration file name (with path)
+//@param cher* dataPath - configuration variable path (in file)
+//@param struct flags optflags - global flags
+int read_config(char *configFile, char *dataPath, struct flags optflags) {
+ config_t cfg; //configuration file handler
+ config_setting_t *setting, *ss; //configuration element handler, and helper handler (config element too)
+ int comaset, varindex, varcounter; //helper flat for buid output strings, varibale index, counter
+ unsigned int maxel, i; //max elements, and loop index
+ char buffer[256]; //reading buffer
+ const char *cbuffer;
+ const char *coma=";"; //output string variable separator
+ int ibuffer, ssize; //value int buffer
+ char *dataName, *dataTypeName, *dataValueString; //name of variable, type of variable, value of variable
+ int dataType, st; //internale variable type
+ //initialize values
+ dataValueString = malloc(1);
+ dataTypeName = malloc(1);
+ memset(dataValueString, 0, 1);
+ memset(dataTypeName, 0, 1);
+ varindex = 0;
+ varcounter = 0;
+ //open and read configuration file
+ config_init(&cfg);
+ if(!config_read_file(&cfg, configFile)) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Can't read configuration file.\n"));
+ return 1;
+ };
+ //now find variable element of given path
+ if(dataPath == NULL) {
+ //if path not givne load root element (default)
+ setting = config_root_setting(&cfg);
+ } else {
+ setting = config_lookup(&cfg, dataPath);
+ };
+ if(setting == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Given variable path not found.\n"));
+ return 3;
+ };
+ //read variable name
+ dataName = config_setting_name(setting);
+ if(dataName == NULL) dataName = "NULL"; //in case variable have no name convert to string representation
+ //read variable type
+ dataType = config_setting_type(setting);
+ //next conver type to human readable and read variable value based on his type
+ //and in cases in type not scalar read index and coutn variables
+ switch(dataType) {
+ case CONFIG_TYPE_INT:
+ dataTypeName = (char*)realloc(dataTypeName, 4*sizeof(char));
+ strcpy(dataTypeName, "int");
+ sprintf(buffer, "%d", config_setting_get_int(setting));
+ dataValueString = (char*)realloc(dataValueString, (strlen(buffer)+1)*sizeof(char));
+ strcpy(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_INT64:
+ dataTypeName = (char*)realloc(dataTypeName, 6*sizeof(char));
+ strcpy(dataTypeName, "int64");
+ sprintf(buffer, "%lld", config_setting_get_int64(setting));
+ dataValueString = (char*)realloc(dataValueString, (strlen(buffer)+1)*sizeof(char));
+ strcpy(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_FLOAT:
+ dataTypeName = (char*)realloc(dataTypeName, 9*sizeof(char));
+ strcpy(dataTypeName, "float");
+ sprintf(buffer, "%f", config_setting_get_float(setting));
+ dataValueString = (char*)realloc(dataValueString, (strlen(buffer)+1)*sizeof(char));
+ strcpy(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_STRING:
+ dataTypeName = (char*)realloc(dataTypeName, 7*sizeof(char));
+ strcpy(dataTypeName, "string");
+ cbuffer = config_setting_get_string(setting);
+ dataValueString = (char*)realloc(dataValueString, (strlen(cbuffer)+1)*sizeof(char));
+ strcpy(dataValueString, cbuffer);
+ break;
+ case CONFIG_TYPE_BOOL:
+ dataTypeName = (char*)realloc(dataTypeName, 5*sizeof(char));
+ strcpy(dataTypeName, "bool");
+ if(optflags.boolstring == 1) {
+ //if expect bool as string, convert it to human readable
+ ibuffer = config_setting_get_bool(setting);
+ if(ibuffer == CONFIG_TRUE) {
+ dataValueString = (char*)realloc(dataValueString, 5*sizeof(char));
+ strcpy(dataValueString, "true");
+ } else {
+ dataValueString = (char*)realloc(dataValueString, 6*sizeof(char));
+ strcpy(dataValueString, "false");
+ }
+ } else {
+ //else output as digit
+ sprintf(buffer, "%d", config_setting_get_bool(setting));
+ dataValueString = (char*)realloc(dataValueString, (strlen(buffer)+1)*sizeof(char));
+ strcpy(dataValueString, buffer);
+ };
+ break;
+ case CONFIG_TYPE_ARRAY:
+ dataTypeName = (char*)realloc(dataTypeName, 6*sizeof(char));
+ strcpy(dataTypeName, "array");
+ //get element count
+ maxel = (unsigned int)config_setting_length(setting);
+ comaset = 0;
+ //and loop over all elements
+ for(i = 0; i < maxel; i++) {
+ //get element
+ ss = config_setting_get_elem(setting, i);
+ if(ss != NULL) {
+ st = config_setting_type(ss);
+ switch(st) {
+ case CONFIG_TYPE_INT:
+ sprintf(buffer, "%d", config_setting_get_int(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_INT64:
+ sprintf(buffer, "%lld", config_setting_get_int64(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_FLOAT:
+ sprintf(buffer, "%f", config_setting_get_float(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_STRING:
+ ssize = (int)strlen(config_setting_get_string(ss));
+
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+ssize+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, config_setting_get_string(ss));
+ break;
+ case CONFIG_TYPE_BOOL:
+ if(optflags.boolstring == 1) {
+ ibuffer = config_setting_get_bool(ss);
+ if(ibuffer == CONFIG_TRUE) {
+ //if bool must be outputed as humen readable - convert it
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+4+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "true");
+ } else {
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+5+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "false");
+ }
+ } else {
+ //else output as digit
+ sprintf(buffer, "%d", config_setting_get_bool(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ };
+ break;
+ case CONFIG_TYPE_ARRAY:
+ //if array contains array output as kwyword ARRAY
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+7)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "ARRAY");
+ break;
+ case CONFIG_TYPE_LIST:
+ //if array contains list output as keyword LIST
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+6)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "LIST");
+ break;
+ case CONFIG_TYPE_GROUP:
+ //if array contains group output as keywort GROUP
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+7)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "GROUP");
+ break;
+ };
+ comaset = 1;
+ };
+ };
+ break;
+ case CONFIG_TYPE_LIST:
+ dataTypeName = (char*)realloc(dataTypeName, 5*sizeof(char));
+ strcpy(dataTypeName, "list");
+ //get element count
+ maxel = (unsigned int)config_setting_length(setting);
+ //end loop over all elements
+ comaset = 0;
+ for(i = 0; i < maxel; i++) {
+ ss = config_setting_get_elem(setting, i);
+ if(ss != NULL) {
+ st = config_setting_type(ss);
+ switch(st) {
+ case CONFIG_TYPE_INT:
+ sprintf(buffer, "%d", config_setting_get_int(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_INT64:
+ sprintf(buffer, "%lld", config_setting_get_int64(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_FLOAT:
+ sprintf(buffer, "%f", config_setting_get_float(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_STRING:
+ ssize = (int)strlen(config_setting_get_string(ss));
+
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+ssize+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, config_setting_get_string(ss));
+ break;
+ case CONFIG_TYPE_BOOL:
+ if(optflags.boolstring == 1) {
+ ibuffer = config_setting_get_bool(ss);
+ if(ibuffer == CONFIG_TRUE) {
+ //if bool must be printout as humanreadable - convert it
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+4+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "true");
+ } else {
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+5+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "false");
+ }
+ } else {
+ //else output as int
+ sprintf(buffer, "%d", config_setting_get_bool(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ };
+ break;
+ case CONFIG_TYPE_ARRAY:
+ //if list contain array output as keyword ARRAY
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+7)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "ARRAY");
+ break;
+ case CONFIG_TYPE_LIST:
+ //if list contain list output as keyword LIST
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+6)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "LIST");
+ break;
+ case CONFIG_TYPE_GROUP:
+ //if list contain group output as keyword GROUP
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+7)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "GROUP");
+ break;
+ };
+ comaset = 1;
+ };
+ };
+ break;
+ case CONFIG_TYPE_GROUP:
+ dataTypeName = (char*)realloc(dataTypeName, 6*sizeof(char));
+ strcpy(dataTypeName, "group");
+ //get elementc count
+ maxel = (unsigned int)config_setting_length(setting);
+ //and loop over all elements
+ //but in group case, we return inside variables names
+ comaset = 0;
+ for(i = 0; i < maxel; i++) {
+ ss = config_setting_get_elem(setting, i);
+ if(ss != NULL) {
+ ssize = (int)strlen(config_setting_name(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+ssize+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, config_setting_name(ss));
+ comaset = 1;
+ };
+ };
+ break;
+ };
+
+ //last we get readed variable index, and element count
+ varindex = config_setting_index(setting);
+ varcounter = config_setting_length(setting);
+
+ //and finaly output data
+ if(optflags.names == 1 && optflags.quiet == 0) printf(gettext("Variable name: %s\n"), dataName);
+ if(optflags.names == 1 && optflags.quiet == 1) printf("%s", dataName);
+ if((optflags.types == 1 && optflags.quiet == 1) && optflags.names == 1) printf(":");
+ if(optflags.types == 1 && optflags.quiet == 0) printf(gettext("Variable type: %s\n"), dataTypeName);
+ if(optflags.types == 1 && optflags.quiet == 1) printf("%s", dataTypeName);
+ if((optflags.values == 1 && optflags.quiet == 1) && (optflags.names == 1 || optflags.types == 1)) printf(":");
+ if(optflags.values == 1 && optflags.quiet == 0) printf(gettext("Variable value: %s\n"), dataValueString);
+ if(optflags.values == 1 && optflags.quiet == 1) printf("%s", dataValueString);
+ if((optflags.indexes == 1 && optflags.quiet == 1) && (optflags.names == 1 || optflags.types == 1 || optflags.values == 1)) printf(":");
+ if(optflags.indexes == 1 && optflags.quiet == 0) printf(gettext("Variable index: %d\n"), varindex);
+ if(optflags.indexes == 1 && optflags.quiet == 1) printf("%d", varindex);
+ if((optflags.counter == 1 && optflags.quiet == 1) && (optflags.names == 1 || optflags.types == 1 || optflags.values == 1 || optflags.indexes == 1)) printf(":");
+ if(optflags.counter == 1 && optflags.quiet == 0) printf(gettext("Variable elements count: %d\n"), varcounter);
+ if(optflags.counter == 1 && optflags.quiet == 1) printf("%d", varcounter);
+ if(optflags.quiet == 1) printf("\n");
+
+ config_destroy(&cfg);
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ //firs set locale and domain to work with internationalization
+ setlocale(LC_ALL, "");
+ bindtextdomain("ls-config", "/usr/share/locale");
+ textdomain("ls-config");
+
+ //then declare and init values
+ int opt,test; //used for read innput: option, and testing
+ int fd; //file descriptor
+ char *sinp, *dataPath=NULL, *dataString=NULL, *dataType=NULL; //string input, configuration variable path, input data, variable type
+ char *configFile=NULL; //config file name (with path)
+ struct flags optflags = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //global flags initialize
+ int excode; //program exit code
+ excode = 0;
+
+ sinp = malloc(sizeof(char) * 256);
+
+ //long options reading
+ struct option long_options[] = {
+ /* These options set a flag. */
+ {"quiet", no_argument, &optflags.quiet, 1},
+ {"names", no_argument, &optflags.names, 1},
+ {"types", no_argument, &optflags.types, 1},
+ {"values", no_argument, &optflags.values, 1},
+ {"indexes", no_argument, &optflags.indexes, 1},
+ {"count", no_argument, &optflags.counter, 1},
+ {"unset", no_argument, &optflags.unset, 1},
+ {"bool-string", no_argument, &optflags.boolstring, 1},
+ /* These options don't set a flag.
+ We distinguish them by their indices. */
+ {"help", no_argument, 0, 'h'},
+ {"set", required_argument, 0, 's'},
+ {"get", optional_argument, 0, 'g'},
+ {"data", required_argument, 0, 'd'},
+ {"type", required_argument, 0, 'p'},
+ {"file", required_argument, 0, 'f'},
+ {0, 0, 0, 0}
+ };
+
+ //next collect all input (given as options to program)
+ while(1) {
+ int option_index = 0;
+ opt = getopt_long (argc, argv, "qntvicubs:g:d:p:hf:", long_options, &option_index);
+
+ if(opt == -1) break;
+
+ switch (opt) {
+ case 0:
+ /* If this option set a flag, do nothing else now. */
+ if(long_options[option_index].flag != 0) break;
+ if(strcmp(long_options[option_index].name, "set") == 0 && optarg) {
+ test = sscanf(optarg, "%s", sinp);
+ if(test > 0) {
+ dataPath = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataPath, sinp);
+ };
+ optflags.mode = 1;
+ };
+ if(strcmp(long_options[option_index].name, "get") == 0 && optarg) {
+ test = sscanf(optarg, "%s", sinp);
+ if(test > 0) {
+ dataPath = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataPath, sinp);
+ };
+ optflags.mode = 0;
+ };
+ if(strcmp(long_options[option_index].name, "data") == 0 && optarg) {
+ test = sscanf(optarg, "%[^\n]s", sinp);
+ if(test > 0) {
+ dataString = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataString, sinp);
+ };
+ };
+ if(strcmp(long_options[option_index].name, "type") == 0 && optarg) {
+ test = sscanf(optarg, "%s", sinp);
+ if(test > 0) {
+ dataType = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataType, sinp);
+ };
+ };
+ if(strcmp(long_options[option_index].name, "file") == 0 && optarg) {
+ test = sscanf(optarg, "%[^\n]s", sinp);
+ if(test > 0) {
+ configFile = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(configFile, sinp);
+ };
+ };
+ break;
+ case 'q':
+ optflags.quiet = 1;
+ break;
+ case 'n':
+ optflags.names = 1;
+ break;
+ case 't':
+ optflags.types = 1;
+ break;
+ case 'v':
+ optflags.values = 1;
+ break;
+ case 'i':
+ optflags.indexes = 1;
+ break;
+ case 'c':
+ optflags.counter = 1;
+ break;
+ case 'u':
+ optflags.unset = 1;
+ break;
+ case 'b':
+ optflags.boolstring = 1;
+ break;
+ case 's':
+ if(optarg) {
+ test = sscanf(optarg, "%s", sinp);
+ if(test > 0) {
+ dataPath = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataPath, sinp);
+ };
+ optflags.mode = 1;
+ };
+ break;
+ case 'g':
+ if(optarg) {
+ test = sscanf(optarg, "%s", sinp);
+ if(test > 0) {
+ dataPath = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataPath, sinp);
+ };
+ };
+ optflags.mode = 0;
+ break;
+ case 'd':
+ if(optarg) {
+ test = sscanf(optarg, "%[^\n]s", sinp);
+ if(test > 0) {
+ dataString = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataString, sinp);
+ };
+ };
+ break;
+ case 'p':
+ if(optarg) {
+ test = sscanf(optarg, "%s", sinp);
+ if(test > 0) {
+ dataType = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataType, sinp);
+ };
+ };
+ break;
+ case 'h':
+ //free input buffer and printout help message
+ free(sinp);
+ printHelp(); //this function contain exit from program
+ break;
+ case 'f':
+ test = sscanf(optarg, "%[^\n]s", sinp);
+ if(test > 0) {
+ configFile = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(configFile, sinp);
+ };
+ break;
+ case '?':
+ break;
+ default:
+ break;
+ }
+ };
+
+ //first of all we must ensure, then configuration file are available with right access mode
+ if(optflags.mode == 0 && access(configFile, R_OK) < 0) optflags.error = 1;
+ if(optflags.mode == 1) {
+ fd = open(configFile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+ if(fd < 0) {
+ optflags.error = 1;
+ };
+ close(fd);
+ };
+ if(optflags.error > 0) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Can't read configuration file.\n"));
+ free(sinp);
+ free(configFile);
+ exit(1);
+ };
+
+ //now if we want to set variable, we must have his path
+ if(optflags.mode == 1 && dataPath == NULL) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Conviguration variable path not given.\n"));
+ free(sinp);
+ free(configFile);
+ exit(4);
+ };
+
+ //if no output data requested, set to default output
+ if(optflags.names == 0 && optflags.types == 0 && optflags.values == 0 && optflags.indexes == 0 && optflags.counter == 0) {
+ optflags.names = 1;
+ optflags.types = 1;
+ optflags.values = 1;
+ };
+
+ //now we invode main work of this software based on request type (set, unset of get)
+ if(optflags.mode == 0) excode = read_config(configFile, dataPath, optflags);
+ if(optflags.mode == 1 && optflags.unset == 1) excode = unset_config(configFile, dataPath, optflags);
+ if(optflags.mode == 1 && optflags.unset == 0) excode = set_config(configFile, dataPath, optflags, dataString, dataType);
+
+ //then finalize free resources and exit returnig excode
+ free(sinp);
+ free(configFile);
+ exit(excode);
+}
+