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.