1 # Girocco::Dumper.pm -- Installation Utility Dumper Functions
2 # Copyright (C) 2020,2021 Kyle J. McKay. All rights reserved.
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 {package _Girocco
::Dumper
::HashLog
;
24 use base
qw(Tie::ExtraHash);
29 ref($hr) eq 'HASH' or $hr = {};
30 my $self = bless([$hr, {}], $class);
36 ${$$self[1]}{$_[0]} = [$_[1]];
37 $self->SUPER::STORE
(@_);
42 ${$$self[1]}{$_[0]} = [];
43 $self->SUPER::DELETE
(@_);
48 package Girocco
::Dumper
;
53 use base
qw(Exporter);
54 our ($VERSION, @EXPORT, @EXPORT_OK);
58 @EXPORT_OK = qw(RequireENV Dump DumpENV Boilerplate Scalars FreezeConfig GetConfPath);
66 BEGIN {$_sortkeys = sub {
67 package _Girocco::Dumper;
68 sort({uc($a) cmp uc($b) || $a cmp $b} keys(%{$_[0]}));
72 BEGIN {$_dumpit = sub {
73 my $d = Data::Dumper->new([$_[0]],[$_[1]]);
74 $d->Purity(1)->Indent(1)->Useqq(1)->Quotekeys(0)->Sortkeys(1)->Deparse($_[2]||0);
79 BEGIN {$_dumpstr = sub {
80 my $d = Data::Dumper->new([$_[0]]);
81 $d->Purity(1)->Indent(0)->Useqq(1)->Quotekeys($_[1]||0)->Sortkeys(1)->Terse(1);
86 BEGIN {$_dumpenv = sub {
88 return 'delete $ENV{'.&$_dumpstr($k)."};\n" unless @$v;
89 return '$ENV{'.&$_dumpstr($k).'} = '.&$_dumpstr($$v[0],1).";\n";
93 BEGIN {$_scalarexists = sub {
94 # *foo{SCALAR} returns a reference to an anonymous scalar if $foo
95 # has not been used yet thereby creating the scalar and "using" it.
96 # Later perls (5.9+) assign a special value that can be detected.
97 B::svref_2object($_[0])->SV->isa("B::SV") # isa will be false if it's
"special"
98 # additionally ...SV->can("object_2svref") will be undef if it's "special"
102 return 'umask(umask() & ~0770);'."\n";
107 my $hr = eval '\%'.$ns.'::';
109 foreach (&$_sortkeys($hr)) {
110 my $gr = eval '\$'.$ns.'::{$_}';
111 push(@result, $_) if &$_scalarexists($gr) && !ref($$$gr);
118 my $hr = eval '\%'.$ns.'::';
120 foreach (&$_sortkeys($hr)) {
121 my $gr = eval '\$'.$ns.'::{$_}';
122 if (&$_scalarexists($gr)) {
123 $result .= "our ".&$_dumpit($$$gr, $_, ref($$$gr) eq 'CODE');
125 if (defined(*$$gr{ARRAY
})) {
126 $result .= "our ".&$_dumpit(\@
$$gr, '*'.$_);
128 if (defined(*$$gr{HASH
})) {
129 $result .= "our ".&$_dumpit(\
%$$gr, '*'.$_);
131 #if (defined(*$$gr{CODE})) {
132 # $result .= &$_dumpit(\&$$gr, '*'.$_, 1);
140 !ref($inmod) and $inmod = [ $inmod ];
141 ref($inmod) eq 'ARRAY' or die "invalid argument to RequireENV - must be scalar or ARRAY ref";
144 /^(\w+(?:::\w+)*)$/ or die "invalid module name: '$_'";
149 my $modkey = $modname;
150 $modkey =~ s{::}{/}gs;
152 !exists($INC{$modkey}) or die "RequireENV('$modname') called but '$modname' already in \%INC!\n";
157 my $logobj = tie
(%ENV, '_Girocco::Dumper::HashLog', \
%env);
158 eval 'require '.$_.';1' or die $@
foreach @mod;
159 $envlog = $$logobj[1];
169 $result .= &$_dumpenv($_, $envlog->{$_}) foreach &$_sortkeys($envlog);
174 my ($usemod, $conf, $sub) = @_;
175 defined($conf) && $conf ne "" or $conf = 'Girocco::Config';
176 defined($usemod) && $usemod ne "" or $usemod = [$conf, 'Girocco::Validator'];
177 my $env = RequireENV
($usemod);
178 # To avoid problems with taint mode, these four are always removed
182 $env->{BASH_ENV
} = [];
183 # Always make sure PATH gets set explicitly to something
184 exists($env->{PATH
}) && @
{$env->{PATH
}} or $env->{PATH
} = [GetConfPath
()];
185 if (exists($env->{PATH
}) && @
{$env->{PATH
}}) {
186 # special handling for $ENV{PATH}
187 my $pval = ${$env->{PATH
}}[0];
188 eval '$'.$conf.'::path = $pval;1' or die $@
;
190 &$sub($conf) if ref($sub) eq 'CODE';
191 return "package $conf;\n" . Dump
($conf) . DumpENV
($env) .
192 Boilerplate
() . "1;\n";
196 local ($ENV{IFS
}, $ENV{CDPATH
}, $ENV{ENV
}, $ENV{BASH_ENV
});
197 local $ENV{PATH
} = "/usr/bin:/bin";
198 my $cs_path = qx(getconf PATH
2>/dev/null
);
199 defined($cs_path) or $cs_path = "";
200 chomp $cs_path; $cs_path =~ s/^\s+//; $cs_path =~ s/\s+$//;
201 $cs_path = join(":", grep(!m{/[.]}, grep(m{^/.},
202 split(/\s*:+\s*/, $cs_path))));
203 $cs_path =~ m{^(/.+)$} and $cs_path = $1;
204 $cs_path ne "" or $cs_path = $ENV{PATH
};