Not sure how to properly word this question, or if it has already been asked using better wording...
I am parsing a file that is similar to a Windows registry file and building a hash from the key structure in the file.
The issue I am running into is the way the file is structured (pretty much identical to the Windows registry). I would like the resulting hash to mimic the file content structure, but I don't think it is possible to assign a value to a key that has subkeys under it (hash of hashes), in this case isn't the hash of the subkeys the value?
The only way I could think of that works is to create an array under the key (if it has a scalar value and subkeys) and make the "default value" the first element then any subkeys would become hashes in the other elements.
Not sure if their is a CPAN module that can tackle this task or if it is just not possible.
Here is a sample of the contents of the registry-ish file I am parsing (file.reg):
HKEY_LOCAL_MACHINE\SOFTWARE\VENDOR\PRODUCT\CurrentVersion\Reports\Name
+spaceProviders=25137
ODBC:= reportsodbclog; REG_SZ
SQLBulkInsertFlushInterval= 0x3c; REG_DWORD
SQLBulkInsertFlushRowCount= 0x3e8; REG_DWORD
SYSLOG:= reportssyslog; REG_SZ
TEXT:= reportstextlog; REG_SZ
HKEY_LOCAL_MACHINE\SOFTWARE\VENDOR\PRODUCT\CurrentVersion\SessionServe
+r=12060
MaintenancePeriod= 0x3c; REG_DWORD
MaintenanceQueryTimeout= 0x3c; REG_DWORD
HKEY_LOCAL_MACHINE\SOFTWARE\VENDOR\PRODUCT\CurrentVersion\SessionServe
+r\NamespaceProviders=32225
LDAP:= ssprovider_ldap; REG_SZ
ODBC:= ssprovider_db; REG_SZ
#Currently I am creating a key named 'DEF_VAL' and assigning the paren
+t key's value to that. Any suggestions?
use warnings;
use strict;
use Data::Dumper;
print Dumper loadreg('file.reg');
sub loadreg{
my $registry;
open(REGISTRY,'<',shift) or die("Error loading registry: $!\n");
my @reg = <REGISTRY>;
close REGISTRY;
my $head = 0;
my $section = "";
for my $line ( @reg ) {
#if ( $line =~ /^\s?(HKEY.*)\n/ ) {
if ( $line =~ /^\s?HKEY.*?CurrentVersion\\(.*)\n/ ) {
# found start of section
$head = 1;
my ( $key , $def_val ) = split /=/ , $1;
$key =~ s/\\/\//g;
$registry->{$key}{"DEF_VAL"} = $def_val;
$section = $key;
} elsif ( $head == 1 and $line =~ /^\n$/ ) {
$head = 0;
$section = "";
} elsif ( $head == 1 and $line =~ /^[a-z]/i ) {
# this is a key/value line for the current section
# MaxReferralHops= 0xa; REG_DWORD
# LDAP:= dsldap; REG_SZ
$line =~ /^([^=:]+)[:=]+\s+([^;]+);\s+([^ ]+)\n$/;
my $value = $2;
$value = hex($value) if $value =~ /^0x/;
$registry->{$section}{$1}{"VALUE"} = $value if $1;
$registry->{$section}{$1}{"TYPE"} = $3 if $1;
}
}
return($registry);
}
Here is the output from the above example:
$VAR1 = {
'SessionServer/NamespaceProviders' => {
'ODBC' => {
'VALUE'
+=> 'ssprovider_db',
'TYPE' =
+> 'REG_SZ'
},
'LDAP' => {
'VALUE'
+=> 'ssprovider_ldap',
'TYPE' =
+> 'REG_SZ'
},
'DEF_VAL' => '32225'
},
'SessionServer' => {
'DEF_VAL' => '12060'
},
'Reports/NamespaceProviders' => {
'TEXT' => {
'VALUE' => 're
+portstextlog',
'TYPE' => 'REG
+_SZ'
},
'ODBC' => {
'VALUE' => 're
+portsodbclog',
'TYPE' => 'REG
+_SZ'
},
'SYSLOG' => {
'VALUE' => '
+reportssyslog',
'TYPE' => 'R
+EG_SZ'
},
'DEF_VAL' => '25137'
}
};