Current ini_file backend built into Config::Model works pretty well, but not for all files. Config::Tiny module (used for reading INI files) makes assumption that a variable name cannot be repeated in one section. This statement is true only for about 99% of INI files. Look at the following fragment of valid Kismet config file:
# Sources are defined as:
# source=sourcetype,interface,name[,initialchannel]
source = ipw2100,eth1,intel
source = madwifi,ath0,atheros
As you can see, source variable is repeated – in this case, backend based on Config::Tiny will report only one occurrence of it.
New backend
I decided to write a new backend. Patching Config::Tiny is not a good idea in my humble opinion – modifying this module could break applications dependent on it. Dominique suggested that repeated variables should be handled as lists. I had some trouble with Config::Model docs, but with his help I managed to create a fully working backend today.
Reading file
my $data = {};
my $section;
foreach ($args{io_handle}->getlines) {
next if /^[;#]/ ;
chomp ;
next if/^\s*$/;
#Update section name
if(/\[(.*)\]/)
{
$section = $1;
next;
}
my ($name,$val) = split(/\s*=\s*/);
#Get the 'right' ref
my $r = $data;
if (defined $section)
{
$data->{$section} = {} if not defined $data->{$section};
$r = $data->{$section}
}
if (defined $r->{$name})
{
$r->{$name} = [$r->{$name}] if ref($r->{$name}) ne 'ARRAY';
push @{$r->{$name}}, $val;
}
else
{
$r->{$name} = $val;
}
}
$self->node->load_data($data);
This simple loop goes through all of the lines of a config file and builds a Perl data structure of it. All values are initially stored as strings. When a variable name appears for the second time, it’s converted to an array of values. Finally, data is loaded into a model using load_data method.
Problems
This approach solves only one problem of Config::Tiny – comments in the file are still lost. However, this can be easily solved – all I need to do is store comments separately (like in ShellVar backend). Some basic file validation would be good too.
Files
New backend
Modified Kismet model (source parameter as list)
P.S.
I promised to post some notes about Config::Model docs, but I’ll do it after some more investigation.
Comments extracted from the configuration file can be extracted by the read backend and stored in the new annotation feature provided by Config::Model 1.202. Then they can be written back by the write backend.
Hope this helps