From e27f064917ced2a96199c738435ea5fe96c0ea8e Mon Sep 17 00:00:00 2001 From: venaas Date: Thu, 4 Dec 2008 13:56:08 +0000 Subject: adding gconfig doc git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@436 e88ac4ed-0b26-0410-9574-a7f39faa03bf --- gconfig.txt | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 gconfig.txt diff --git a/gconfig.txt b/gconfig.txt new file mode 100644 index 0000000..ec77545 --- /dev/null +++ b/gconfig.txt @@ -0,0 +1,160 @@ +Documentation for gconfig + +gconfig is a configuration file parser. It is generic in the sense that it can +be used for different applications that need different configuration keywords +and value. There is however a fixed syntax. + +The basic syntax is + +option-name value +or +option-name = value + +where white space is used as delimiters, where you can have any amount of +whitespace (spaces and tabs) where there is a space above. option-name cannot +contain spaces. A value can contain spaces if the value is quoted. E.g. + +option-name = "option value" + +There is a special keyword "include" used for including config files. +Anywhere in a config file one can write "include filespec". At that +point the entire content of a file pointed to by filespec will be +inserted. When the end of the file is read, the config parser will +continue with whatever is after include. "filespec" can use UNIX +shell type globbing, so you may do e.g. "include /etc/gconf.d/*" to +include everything in that directory. This will behave exactly like +including each of the files separately (in alphabetic order). + +In addition to this, one may also group options together into +blocks, where blocks also have names. + +A block has the syntax + +type name { + option-name value + option-name value + ... +} + +The application specifies which block types are valid, and which +option-names and syntaxes can be used for each of the types. + +The available option syntaxes (or types) are String, Integer and +Boolean. + +Usually the same option-name cannot be repeated (unless in different +blocks). For Strings one can specify whether it is allowed or not. +Also, for strings one can use hex notation for bytes. This works +similar to URL hex escaping. E.g. a space can be written as "%20". + +radsecproxy uses gconfig and shows what is possible. Here is an +example extracted from getmainconfig() from radsecproxy. + +struct gconffile *cfs; +cfs = openconfigfile(configfile); + if (!getgenericconfig(&cfs, NULL, + "ListenUDP", CONF_MSTR, &listenudp, + "LogDestination", CONF_STR, &logdestination, + "LogLevel", CONF_LINT, &loglevel, + "LoopPrevention", CONF_BLN, &loopprevention, + "Client", CONF_CBK, confclient_cb, NULL, + NULL + )) + debugx(1, DBG_ERR, "configuration error"); /* exit */ + /* parsing successful, continue normal operations */ + +The arguments to getgenericconfig are as follows. First there is a +gconffile struct, this is normally a single file, but as we discuss later, +it can also be a list of files (or data). The second parameter should be +NULL when not in a block, or the block name if inside one. This is only +used for logging. + +After this one lists all the legal option and block names that are allowed. +For each option one specifies a name followed by a syntax type and a pointer to +the variable that will hold the value. The syntax types are CONF_STR for a +string, CONF_MSTR for string when the option can be used multiple times, +CONF_LINT for Integer (long int), CONF_BLN for Boolean ("on" or "off"). For +blocks one uses CONF_CBK followed by a callback function for handling the +block, and a pointer to userdata that can be passed to the callback. Normally +this would just be set to NULL. + +We will now discuss each of the syntax types and blocks in more detail. + +CONF_STR: +This is used for strings. The value argument must be of type "char **". If +the option is found in the config, it will allocate memory for a null-terminated +copy of the string and return a pointer to this. The value argument is not +modified if the option is not used. In the example above, one might do +"char *logdestination = NULL". One then uses &logdestination for the +argument, and can check for NULL to see whether the option was present. + +CONF_MSTR: +This is used for strings when the option can be used multiple times. It +will return an array of strings in the order they are found in the config. +The value argument must be of type "char ***". One might do +"char **listenudp = NULL", and use &listenudp for the argument. Memory will +be allocated for the array and the strings if the option is used. If no +options are found, the value is unchanged. If there is at least one value, +one will get an array of strings, and the last element of the array will be +set to NULL. + +CONF_LINT: +The option value argument must be of type "long int *". If the option is +present, the value will be set, else it will not be modified. + +CONF_BLN: +The option value argument must be of type "uint8_t *". It is set to 0 or 1 +for "off" or "on" resp. It is only modified if the option is found. + +CONF_CBK: +This is a block where one uses a call back. Here is an example callback: + +int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char + *val) { + char *type = NULL, *host = NULL; + debug(DBG_DBG, "confclient_cb called for %s", block); + if (!getgenericconfig(cf, block, + "type", CONF_STR, &type, + "host", CONF_STR, &host, + NULL + )) + debugx(1, DBG_ERR, "configuration error"); /* exit */ + /* parsing successful, continue normal operations */ + +Here cf is the list of config files we're using, arg is a pointer to +userdata (the parameter after the name of the callback function, often +this is just set to NULL). opt is the type of block, in this case it will +be set to "client". val is the value of the block. E.g. if the config said + +client example { + type udp + host 1.2.3.4 +} + +then val will be set to "example". The string block is set to +"client example" (opt val) and is normally just used for logging. +Note that the opt, val and optval parameters to the callback will all be +freed when the callback function exits. + +The gconffile struct can hold a list of config files. Typically one would +just use cfs = openconfigfile(configfile) as above. But one can use any of +the ones below. It can be used to create a new struct (a pointer to NULL), +or a pointer to an existing struct where new files are pushed (as a stack). +The latest pushed is used first, when that is used it continues reading +from the next. + +int pushgconfdata(struct gconffile **cf, const char *data); +This can be used to read config stored in memory + +FILE *pushgconfpath(struct gconffile **cf, const char *path); +Here one specifies a file path (no globbing) + +FILE *pushgconfpaths(struct gconffile **cf, const char *path); +Here one specifies a filespec with globbing. In case of multiple files, +they are pushed in reverse alphabetical order so that the alphabetically +first file is read first. + +FILE *pushgconffile(struct gconffile **cf, FILE *file, const char *description); +This can be used for reading config from an already open file descriptor. + +For a complete example, see radsecproxy. -- cgit v1.1