regex and parsing config file directives..
7 answers - 2174 bytes -

Hi.
Sorry to bother but I can't get this script to work
It is supposed to parse the openvpn config,
1) any line starting with a ";" is to be ignored
2) all directives are written to a hash where the key is the directive and
the value is the value of the directive .
3) if the directive is present but no value is set then the key must be set
to the directive and the value must be set to "defined" or the same value as
the key
this is the script so far
#!/usr/bin/perl
#
use strict;
# vars
my @tmp_load_file;
my @tmp_directive;
my %directive;
#
sub get_config_file {
my $line; #used in while for outputing each line.
print "opening config file for processing\n\n";
open(IN, "< /etc/openvpn/client.conf");
while (<IN>){
if (( $_ =~ /^#/ ) || ( $_ =~ /^\ /) || ( $_ =~ /^\n/) ){
} else {
chomp; push(@tmp_directive , $_ );
}
}
close (IN);
}
get_config_file;
sub config_hash {
regex used in the function
## /.+\s(.+) used to find the option set for that directive. "dev
tun" will return "tun"
my $value ;
foreach (@tmp_directive) {
#print "$_"; if ( $_ != /^\;/) {
} else {
/^([\w|-]+)\s(.+)/ ;
print " $1 =$2 \n";
$directive{$1} = $2 ;
} if ( $_ != /^\;/) {
} else {
/^([\w|-]+)\n/ ;
#print ">$1 =$1 \n";
#$value = "1" unless $2;
$directive{$1} = $1 ;
} }
}
config_hash ;
my $key; my $value;#
print "\n\n";
for $key (keys %directive){
$value = $directive{$key};
print "$key =$value\n";
}
this it the output
[greg@greg openvpn]$ perl passconfig.pl
opening config file for processing
=>
dev =tun0
proto =tcp
remote =192.168.1.1 1194
resolv-retry =infinite
=>
=>
=>
ca =ca.crt
cert =greg.crt
key =greg.key
cipher =AES-128-CBC
=>
verb =3
=>
proto =tcp
cert =greg.crt
dev =tun0
ca =ca.crt
key =greg.key
remote =192.168.1.1 1194
verb =3
cipher =AES-128-CBC
resolv-retry =infinite
Many Thanks
Greg
No.1 | | 2406 bytes |
| 
Just to check my understanding and that i'm learning this rite . :-)
--
while(<HD>){
next if /^\s*#|^\s*;/; ignors any lines with # and ;
next if /^\s*$/; ignores lines that start with a
space
my @array = split/\s+/; puts each value seperated by a space
into an array
my $key = shift @array; gets the first value, of the array and
sets key to this value
$hash{$key} = \@array || 'nodefined'; sets the value of the hash
to the array ?
}
>
>
>From: "Gregory Machin" <gregory.machin (AT) gmail (DOT) com>
>To: "Jeff Peng" <peng (AT) dig-tech (DOT) com>
>CC: beginners (AT) perl (DOT) org
>Subject: Re: regex and parsing config file directives
>Date: Fri, 14 Jul 2006 12:36:55 +0200
>
>here is basic config
>All lines starting with ; or # are to be regarded as commented out as
>are ignored
>
>client some of the directives are set jst by
there
>pressence
>;dev tap
>dev tun0
>;dev-node MyTap
>proto tcp
>;proto udp
>remote 192.168.1.1 1194
>;remote my-server-2 1194
>;remote-random
>resolv-retry infinite
>nobind
>;user nobody
>;group nobody
>persist-key
>persist-tun
>;http-proxy-retry # retry on connection failures
>;http-proxy [proxy server] [proxy port #]
>;mute-replay-warnings
>ca ca.crt
>cert greg.crt
>key greg.key
>;ns-cert-type server
>;tls-auth ta.key 1
>cipher AES-128-CBC
>comp-lzo
>verb 3
>;mute 20
>
>
7/14/06, Jeff Peng <peng (AT) dig-tech (DOT) comwrote:
>>
>>
>>Could you paste your config file here?Then we could look at the
situation
>>more clearly.
>>
>>
>>looks good but my configs don't us "=" there is just a space so
>>could
>>one use my ($key,$value) = split/\ /; to split the kay and the value ?
>>
>>
>>
>
>
>Gregory Machin
>gregory.machin (AT) gmail (DOT) com
>www.linuxpro.co.za
>
>
>
No.2 | | 1082 bytes |
| 
here is basic config
All lines starting with ; or # are to be regarded as commented out as
are ignored
client some of the directives are set jst by there
pressence
;dev tap
dev tun0
;dev-node MyTap
proto tcp
;proto udp
remote 192.168.1.1 1194
;remote my-server-2 1194
;remote-random
resolv-retry infinite
nobind
;user nobody
;group nobody
persist-key
persist-tun
;http-proxy-retry # retry on connection failures
;http-proxy [proxy server] [proxy port #]
;mute-replay-warnings
ca ca.crt
cert greg.crt
key greg.key
;ns-cert-type server
;tls-auth ta.key 1
cipher AES-128-CBC
comp-lzo
verb 3
;mute 20
7/14/06, Jeff Peng <peng (AT) dig-tech (DOT) comwrote:
--
Could you paste your config file here?Then we could look at the situation
more clearly.
>
>
>looks good but my configs don't us "=" there is just a space so could
>one use my ($key,$value) = split/\ /; to split the kay and the value ?
>
>
>
No.3 | | 4412 bytes |
| 
looks good but my configs don't us "=" there is just a space so could
one use my ($key,$value) = split/\ /; to split the kay and the value ?
7/14/06, Jeff Peng <peng (AT) dig-tech (DOT) comwrote:
Hello,
Follow the conditions,the resolving way is not so complicated as yours.I
would give my sample way,hope it's useful to you.
here is the config file's content:
$ cat config.txt
;test file
# comment lines
IP = 1.2.3.4
PRT = 80
PREFRK_CHILDS = 5
MIN_SPARE_CHILDS
here is the sample script:
$ cat test.pl
use strict;
use Data::Dumper;
my %hash;
open HD,"config.txt" or die $!;
while(<HD>){
next if /^\s*#|^\s*;/;
next if /^\s*$/;
my ($key,$value) = split/=/;
$key =~ s/^\s+|\s+$//g;
$value =~ s/^\s+|\s+$//g;
$hash{$key} = $value || 'nodefined';
}
close HD;
print Dumper \%hash;
__END__
--
Run it and get the result output:
$ perl test.pl
$VAR1 = {
'PREFRK_CHILDS' ='5',
'IP' ='1.2.3.4',
'MIN_SPARE_CHILDS' ='nodefined',
'PRT' ='80'
};
>
>
>From: "Gregory Machin" <gregory.machin (AT) gmail (DOT) com>
>To: beginners (AT) perl (DOT) org
>Subject: regex and parsing config file directives
>Date: Fri, 14 Jul 2006 11:18:40 +0200
>
>Hi.
>Sorry to bother but I can't get this script to work
>It is supposed to parse the openvpn config,
>1) any line starting with a ";" is to be ignored
>2) all directives are written to a hash where the key is the directive
and
>the value is the value of the directive .
>3) if the directive is present but no value is set then the key must be
set
>to the directive and the value must be set to "defined" or the same value
>as
>the key
>
>this is the script so far
>
>
>#!/usr/bin/perl
>#
>
>use strict;
>
># vars
>my @tmp_load_file;
>my @tmp_directive;
>my %directive;
>#
>sub get_config_file {
>my $line; #used in while for outputing each line.
>print "opening config file for processing\n\n";
>open(IN, "< /etc/openvpn/client.conf");
>
>while (<IN>){
>
if (( $_ =~ /^#/ ) || ( $_ =~ /^\ /) || ( $_ =~ /^\n/) ){
} else {
chomp; push(@tmp_directive , $_ );
}
>}
>
>close (IN);
>}
>
>get_config_file;
>
>
>
>sub config_hash {
regex used in the function
## /.+\s(.+) used to find the option set for that directive. "dev
>tun" will return "tun"
my $value ;
>foreach (@tmp_directive) {
#print "$_"; if ( $_ != /^\;/) {
} else {
/^([\w|-]+)\s(.+)/ ;
print " $1 =$2 \n";
$directive{$1} = $2 ;
} if ( $_ != /^\;/) {
} else {
/^([\w|-]+)\n/ ;
#print ">$1 =$1 \n";
#$value = "1" unless $2;
$directive{$1} = $1 ;
} }
>}
>
>
>config_hash ;
>
>my $key; my $value;#
>
>print "\n\n";
>for $key (keys %directive){
$value = $directive{$key};
print "$key =$value\n";
>}
>
>this it the output
>[greg@greg openvpn]$ perl passconfig.pl
>opening config file for processing
>
>dev =tun0
>proto =tcp
>remote =192.168.1.1 1194
>resolv-retry =infinite
>ca =ca.crt
>cert =greg.crt
>key =greg.key
>cipher =AES-128-CBC
>verb =3
>proto =tcp
>cert =greg.crt
>dev =tun0
>ca =ca.crt
>key =greg.key
>remote =192.168.1.1 1194
>verb =3
>cipher =AES-128-CBC
>resolv-retry =infinite
>
>
>
>Many Thanks
>Greg
>
>
>
>Gregory Machin
>gregory.machin (AT) gmail (DOT) com
>www.linuxpro.co.za
>
>
>
No.4 | | 410 bytes |
| 
"Jeff Peng" schreef:
next if /^\s*#|^\s*;/;
next if /^[[:blank:]]*[#;]/ ;
next if /^\s*$/;
next if /^[[:blank:]]*$/ ;
my @array = split/\s+/;
my @array = split ;
Simpler would be to remove any blanks from the start end end of the line
first:
s/^[[:blank:]]+//, s/\s+$// ; # chomps as well
And please don't quote tails'n'sigs.
No.5 | | 1096 bytes |
| 
Gregory Machin wrote:
Hi.
Hello,
Sorry to bother
No bother. :-)
but I can't get this script to work
It is supposed to parse the openvpn config,
1) any line starting with a ";" is to be ignored
2) all directives are written to a hash where the key is the directive and
the value is the value of the directive .
3) if the directive is present but no value is set then the key must be set
to the directive and the value must be set to "defined" or the same
value as
the key
This may work for you (UNTESTED):
#!/usr/bin/perl
use warnings;
use strict;
print "opening config file for processing\n\n";
open IN, '<', '/etc/openvpn/client.conf'
or die "Cannot open '/etc/openvpn/client.conf' $!";
my %directive;
while ( <IN) {
next if /^[#;]/ or not /\S/;
my ( $key, $value ) = split;
$directive{ $key } = $value || 1;
}
print "\n\n";
for my $key ( keys %directive ) {
print "$key =$directive{$key}\n";
}
__END__
John
No.6 | | 320 bytes |
| 
Dr.Ruud wrote:
>
>next if /^\s*$/;
next if /^[[:blank:]]*$/ ;
Why do you prefer /[[:blank:]]/ over /\s/ Ruud? I can't see the point in
treating CR, LF and FF as valid data. Anyway, I would prefer:
next unless /\S/;
which says it all.
Rob
No.7 | | 699 bytes |
| 
Rob Dixon schreef:
Dr.Ruud:
next if /^\s*$/;
>>
>>
>next if /^[[:blank:]]*$/ ;
>
Why do you prefer /[[:blank:]]/ over /\s/ Ruud?
[[:blank:]] is TAB + SP only (for ASCII).
I can't see the point
in treating CR, LF and FF as valid data.
LF won't happen in this context ($ matches before LF).
If there would be CR of FF in the line, I wouldn't want to have them
been silently removed, because they shouldn't have been there in the
first place.
Anyway, I would prefer:
next unless /\S/;
The "double negation" might scare some people.