mirror of https://github.com/sipwise/ngcpcfg.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.2 KiB
118 lines
3.2 KiB
#!/usr/bin/perl -wCSD
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Safe;
|
|
use YAML::XS;
|
|
use Scalar::Util qw(looks_like_number);
|
|
|
|
my ($file, @data) = @ARGV;
|
|
|
|
unless (defined($file)) {
|
|
print {*STDERR} ("1st parameter 'file' is not defined\n");
|
|
exit (1);
|
|
}
|
|
|
|
unless (@data) {
|
|
print {*STDERR} ("2nd parameter 'data' is not defined\n");
|
|
exit (1);
|
|
}
|
|
|
|
my $yaml = YAML::XS::LoadFile($file);
|
|
my $compartment = Safe->new();
|
|
|
|
foreach my $option_data (@data) {
|
|
my ($option, $value) = $option_data =~ m/^([\w\.\[\]]+)=(.+)$/;
|
|
if (!(defined($option)) || !(defined($value))) {
|
|
print {*STDERR} ("Error: can't parse '$option_data'\n");
|
|
exit (1);
|
|
}
|
|
else {
|
|
set_value($option, $value);
|
|
}
|
|
}
|
|
|
|
YAML::XS::DumpFile($file, $yaml);
|
|
|
|
sub log_debug {
|
|
my $message = shift;
|
|
if (defined($ENV{DEBUG})) {
|
|
print "$message\n";
|
|
}
|
|
}
|
|
|
|
sub set_value {
|
|
my $option = shift;
|
|
my $value = shift;
|
|
|
|
my $valref = \$yaml;
|
|
|
|
if ($value =~ /^['"]+.*['"]+$/) {
|
|
log_debug ('$value is already quoted.');
|
|
}
|
|
elsif (looks_like_number($value)) {
|
|
log_debug ('Not quoting $value for integers.');
|
|
}
|
|
elsif ($value =~ /^\[.*\]$/) {
|
|
log_debug ('Not quoting $value for arrays.');
|
|
if ($value =~ /^\[\]$/) {
|
|
log_debug ('Empty array, do not check quoting');
|
|
}
|
|
elsif ($value !~ /^\[['"].+['"]\]$/) {
|
|
print {*STDERR} ("Error: Elements in array '$value' should be quoted\n");
|
|
exit (1);
|
|
}
|
|
}
|
|
elsif ($value =~ /^\{.*\}$/) {
|
|
log_debug ('Not quoting $value for hashes.');
|
|
}
|
|
else {
|
|
$value = "\"$value\"";
|
|
}
|
|
|
|
# If the value is a float number like N.0 - reval turns it into int N
|
|
# even if it's quoted.
|
|
if ($value =~ /^['"]*(\d+\.\d+)['"]*$/ ) {
|
|
$value = $1;
|
|
log_debug ('$value is a float number so no need to reval() it');
|
|
}
|
|
else {
|
|
$value = $compartment->reval($value);
|
|
}
|
|
|
|
for my $component (split(/\./, $option)) {
|
|
if (ref($valref) eq 'SCALAR' && defined(${$valref})) {
|
|
print {*STDERR} ("Key resolved to a SCALAR at '$component'; cannot continue.\n");
|
|
exit (1);
|
|
}
|
|
elsif (looks_like_number($component) && (! defined(${$valref}) || ref(${$valref}) eq 'ARRAY')) {
|
|
$valref = \${$valref}->[$component];
|
|
}
|
|
elsif ($component eq 'APPEND' && ref($$valref) eq 'ARRAY') {
|
|
$valref = \${$valref}->[$#{$$valref}+1];
|
|
}
|
|
elsif (! defined(${$valref}) || ref(${$valref}) eq 'HASH') {
|
|
$valref = \${$valref}->{$component};
|
|
}
|
|
else {
|
|
print {*STDERR} ("Key resolved to a " . ref(${$valref}) . " reference; refusing to overwrite.\n");
|
|
exit (1);
|
|
}
|
|
}
|
|
|
|
if (! defined(${$valref}) || ref($valref) eq 'SCALAR') {
|
|
${$valref} = $value;
|
|
}
|
|
elsif (ref(${$valref}) eq 'ARRAY' && ref($value) eq 'ARRAY') {
|
|
${$valref} = $value;
|
|
}
|
|
elsif (ref(${$valref}) eq 'HASH' && ref($value) eq 'HASH') {
|
|
${$valref} = $value;
|
|
}
|
|
else {
|
|
print {*STDERR} ("Key resolved to a " . ref(${$valref}) . " reference; refusing to overwrite.\n");
|
|
exit (1);
|
|
}
|
|
}
|