libcfg is the heart of the cfgd-project. It provides an API to create and manipulate configurations.

You can find the API-documentation here

An example configuration:


<?xml version="1.0" ?>

<config version="1.0">

<var>
        <name> port </name>
        <value> 333 </value>
        <predef>
                <value> 333 </value>
                <value> 334 </value>
                <value> 335 </value>
        </predef>
</var>

<var>
        <name> secret </name>
        <value> IamvErySecrEt </value>
</var>

<section>
        <name> servers </name>
        <description>
                all servers of nfod
        </description>
        <var>
                <name> server1.domain.tld </name>
        </var>
        <var>
                <name> server2.domain.tld </name>
        </var>
        <var>
                <name> server3.domain.tld </name>
        </var>
</section>

<section>
        <name> server1.domain.tld </name>
        <var>
                <name> port </name>
                <value> 333 </value>
        </var>
        <var>
                <name> secret </name>
                <value> secret1 </value>
        </var>
</section>

<section>
        <name> server2.domain.tld </name>
        <var>
                <name> port </name>
                <value> 334 </value>
        </var>
        <var>
                <name> secret </name>
                <value> secret2 </value>
        </var>
</section>

<section>
        <name> server3.domain.tld </name>
        <var>
                <name> port </name>
                <value> 335 </value>
        </var>
        <var>
                <name> secret </name>
                <value> secret3 </value>
        </var>
</section>

</config>


As you can see, config files are stored in XML-format. Now we have a look at how to read this configuration in our application:


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cconfig.h"

int
main ( int argc, char* argv[] )
{
        t_config* MyConfig;
        int Len;
        char* psz_Str;
        char* psz_Server;
        char  sz_Buffer [512];

        CfgReadConfig (&MyConfig, "example.conf");

        printf ("\n########## - 1 - ###########\n\n");
        CfgSetStart (MyConfig);
        /*
         *      the standard seperator is a '.' which conflicts
         *      with hostnames. so we explicitly choose another
         *      seperator here.
         */
        CfgSetSeperator (MyConfig, ';');
        /*
         * read our port
         */
        psz_Str = CfgGetVarValueOf (MyConfig, "port");
        if (psz_Str != 0)
        {
                printf ("port: %u\n", atoi (psz_Str));
        }
        else    printf ("no port!\n");
        /*
         * read our secret
         */
        psz_Str = CfgGetVarValueOf (MyConfig, "secret");
        if (psz_Str != 0)
        {
                printf ("secret: %s\n", psz_Str);
        }
        else    printf ("no secret!\n");
        /*
         * now go for our list of servers
         */
        if (CfgSetToSection (MyConfig, "servers") == 0)
        {
                printf ("no 'servers'-section in config!\n");
                return (1);
        }
        psz_Str = CfgGetVarName (MyConfig);
        while (psz_Str != 0)
        {
                printf ("got server '%s'\n", psz_Str);
                Len = strlen (psz_Str);
                psz_Server = (char*) malloc (Len+1);
                strncpy (psz_Server, psz_Str, Len+1);
                CfgStore (MyConfig);    /* store current position */
                /*
                 * now go for server config 
                 */
                if (CfgSetToSection(MyConfig, psz_Server) == 0)
                {
                        printf ("no config for '%s'\n", psz_Server);
                        return (1);
                }
                /* build the complete path to 'server'-port variable */
                sprintf (sz_Buffer, "%s;port", psz_Server);
                psz_Str = CfgGetVarValueOf (MyConfig, sz_Buffer);
                if (psz_Str != 0)
                {
                        printf ("port for server %s is %s\n",
                                psz_Server, psz_Str);
                }
                /* build the complete path to 'server'-secret variable */
                sprintf (sz_Buffer, "%s;secret", psz_Server);
                psz_Str = CfgGetVarValueOf (MyConfig, sz_Buffer);
                if (psz_Str != 0)
                {
                        printf ("secret for server %s is %s\n",
                                psz_Server, psz_Str);
                }
                CfgRestore (MyConfig); /* and back to server-section */
                psz_Str = CfgNextVariable (MyConfig);
        }
        CfgFreeConfig (MyConfig);
        return (0);
}

The output of this program is:

########## - 1 - ###########

port: 333
secret: IamvErySecrEt
got server 'server1.domain.tld'
port for server server1.domain.tld is 333
secret for server server1.domain.tld is secret1
got server 'server2.domain.tld'
port for server server2.domain.tld is 334
secret for server server2.domain.tld is secret2
got server 'server3.domain.tld'
port for server server3.domain.tld is 335
secret for server server3.domain.tld is secret3