Perl script writing output twice; second time in reverse order -
i'm trying figure out why script writing output twice. first time in proper order, second time in reverse order. should writing once.
#!/usr/bin/perl use warnings; use strict; use fcntl ':mode'; use file::find; no warnings 'file::find'; no warnings 'uninitialized'; $dir = "/var/log/tivoli/"; $mtab = "/etc/mtab"; $permfile = "world_writable_files.txt"; $tmpfile = "world_writable_files.tmp"; $exclude = "/usr/local/etc/world_writable_excludes.txt"; $mask = s_iwusr | s_iwgrp | s_iwoth; (%excludes, %devnums); $errheader; # compile list of mountpoints need scanned @mounts; open mt, "<${mtab}" or die "cannot open ${mtab}, $!"; # want local mountpoints while (<mt>) { if ($_ =~ /ext[34]/) { chomp; @line = split; push(@mounts, $line[1]); @stats = stat($line[1]); $devnums{$stats[0]} = undef; } } close mt; # build hash /usr/local/etc/world_writables_excludes.txt if ((! -e $exclude) || (-z $exclude)) { $errheader = <<header; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! !! !! /usr/local/etc/world_writable_excludes.txt !! !! missing or empty. report includes !! !! every world-writable file including !! !! expected , should excluded. !! !! !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! header } else { open xcld, "<${exclude}" or die "cannot open ${exclude}, $!\n"; while (<xcld>) { chomp; $excludes{$_} = 1; } } sub wanted { @dirstats = stat($file::find::name); # excluded report... return if exists $excludes{$file::find::name}; # ...is tivoli installation directory or special directory... if ($file::find::name =~ m{^/sys|^/proc|^/dev|^/opt/ibm/itm}) { $file::find::prune = 1; return; } # ...a regular file, ... return unless -f; # ...local, ... return unless (exists $devnums{$dirstats[0]}); # ...and world writable? return unless ($dirstats[2] & $mask) == $mask; # if so, add file list of world writable files print(wwfile "$file::find::name\n"); } # create output file path if doesn't exist. mkdir($dir or die "cannot execute mkdir on ${dir}, $!") unless (-d $dir); # create our filehandle writing our findings open wwfile, ">${dir}${tmpfile}" or die "cannot open ${dir}${tmpfile}, $!"; print(wwfile "${errheader}") if ($errheader); find(\&wanted, @mounts); close wwfile; # if no world-writable files have been found ${tmpfile} should zero-size; # delete tivoli won't alert if (-z "${dir}${tmpfile}") { unlink "${dir}${tmpfile}"; } else { rename("${dir}${tmpfile}","${dir}${permfile}") or die "cannot rename file ${dir}${tmpfile}, $!"; } example output:
# cat world_writable_files.txt /var/opt/ds_agent/am/diagnostic_1.log /home/user1/report.pl.20130220 /home/user1/report.pl.20130220 /var/opt/ds_agent/am/diagnostic_1.log each file being written once in script wondering if filesystem being scanned twice. once in each direction. don't see happening, don't know.
excludes file:
# cat /usr/local/etc/world_writable_excludes.txt /var/opt/ds_agent/diagnostic.log /var/opt/ds_agent/am/diagnostic.log any thoughts on conundrum?
it's because @mounts has / in addition /home , /var. you're asking scan @ , below / (including /home , /var), scan @ , below /home, scan @ , below /var.
it's better identify places want avoid.
while (<mt>) { @fields = split; if ($field[2] !~ /^ext[34]\z/) { ++$excludes{ $fields[1] }; } } find(\&wanted, '/'); sub wanted { if ($excludes{$file::find::name}) { $file::find::prune = 1; return; } @dirstats = stat($file::find::name); return if !-f; return if $dirstats[2] & s_iwoth; print(wwfile "$file::find::name\n"); } you won't need if ($file::find::name =~ m{^/sys|^/proc|^/dev|^/opt/ibm/itm}) anymore because they're not ext3 or ext4. except maybe /opt/ibm/itm (since don't know is). if did have files or directories wanted skip, add them %excludes rather making relatively expensive regex match.
++$excludes{$_} qw( /foo /bar /opt/ibm/itm );
Comments
Post a Comment