First step for understanding a complex code with very deep structures: remove useless brackets, add temporary variables.
sub Dumpbbcs { my $css = $_[0]; print "Content-Type: text/plain\n\n"; foreach my $owner ( keys ( %{${${$CSSDUMP{CSSS}}{$css}}{OWNERS}} ) ) { foreach my $content ( keys ( %{${${${${$CSSDUMP{CSSS}}{$css}}{OWNERS}}{$owner}}{CONTENTS}} ) ) { my $enable = ${${${${${${$CSSDUMP{CSSS}}{$css}}{OWNERS}}{$owner}}{CONTENTS}}{$content}}{ENABLE} if ( exists(${${${${${${$CSSDUMP{CSSS}}{$css}}{OWNERS}}{$owner}}{CONTENTS}}{$content}}{ENABLE}) ); foreach my $service ( keys ( %{${${${${${${$CSSDUMP{CSSS}}{$css}}{OWNERS}}{$owner}}{CONTENTS}}{$content}}{SERVICES}} ) ) { my $ip = ${${${${${${${${$CSSDUMP{CSSS}}{$css}}{OWNERS}}{$owner}}{CONTENTS}}{$content}}{SERVICES}}{$service}}{apSvcIPAddress} if ( exists(${${${${${${${${$CSSDUMP{CSSS}}{$css}}{OWNERS}}{$owner}}{CONTENTS}}{$content}}{SERVICES}}{$service}}{apSvcIPAddress}) ); my $state = ${${${${${${${${$CSSDUMP{CSSS}}{$css}}{OWNERS}}{$owner}}{CONTENTS}}{$content}}{SERVICES}}{$service}}{apSvcState} if ( exists(${${${${${${${${$CSSDUMP{CSSS}}{$css}}{OWNERS}}{$owner}}{CONTENTS}}{$content}}{SERVICES}}{$service}}{apSvcState}) ); my $KALType = ${${${${${${${${$CSSDUMP{CSSS}}{$css}}{OWNERS}}{$owner}}{CONTENTS}}{$content}}{SERVICES}}{$service}}{apSvcKALType} if ( exists(${${${${${${${${$CSSDUMP{CSSS}}{$css}}{OWNERS}}{$owner}}{CONTENTS}}{$content}}{SERVICES}}{$service}}{apSvcKALType}) ); my $SvcKALUri = ${${${${${${${${$CSSDUMP{CSSS}}{$css}}{OWNERS}}{$owner}}{CONTENTS}}{$content}}{SERVICES}}{$service}}{apSvcKALUri} if ( exists(${${${${${${${${$CSSDUMP{CSSS}}{$css}}{OWNERS}}{$owner}}{CONTENTS}}{$content}}{SERVICES}}{$service}}{apSvcKALUri}) ); if ( defined($enable) && ($enable eq "enable") && defined($ip) && defined($state) && defined($KALType) && defined($SvcKALUri) ) { print "$owner $content $enable $service $ip DNS $state $KALType $SvcKALUri\n"; } } } } }becomes:
sub Dumpbbcs { my ($css) = @_; my $owners = $CSSDUMP{CSSS}{$css}{OWNERS}; print "Content-Type: text/plain\n\n"; foreach my $owner (keys %$owners) { foreach my $content (keys %{ $owners->{$owner}{CONTENTS} }) { my $cont_fields = $owners->{$owner}{CONTENTS}{$content}; my $enable = $cont_fields->{ENABLE} || ""; foreach my $service (keys %{ $cont_fields->{SERVICES} }) { my $serv_fields = $cont_fields->{SERVICES}{$service}; my $ip = $serv_fields->{apSvcIPAddress}; my $state = $serv_fields->{apSvcState}; my $KALType = $serv_fields->{apSvcKALType}; my $SvcKALUri = $serv_fields->{apSvcKALUri}; if ($enable eq "enable" and all {defined} $ip, $state, $KALType, $SvcKALUri) { print "$owner $content $enable $service $ip DNS $state $KALType $SvcKALUri\n"; } } } } }
(Ok, I cheated, I'm also using List::MoreUtils
's all
(this module rocks)).
Both functions should do exactly the same thing, except than the corrected form is actually readable and probably a lot faster given the number of opcodes such long dereference chains take (run perl -MO=Terse
on these).
OTOH, these ${..}
may be a technique obfuscators can use in the future ;-)