#!/usr/bin/perl $version=' $Id: sfvdir.pl,v 1.8 2003/07/24 11:55:02 torh Exp $ '; ## ## recursively scans a directory for .sfv files and checks the validity ## of the content. makes an OK file if dir passes sfv, FAILED if not. ## also renames files that do not pass the test. ## ## currently only tested with pdsfv. you'll need pdsfv (or something that ## takes similar command line options) in order to make use of sfvdir. ## ## sfvdir is (c) 2003 th+sfvdir@bogus.net ## ## updates can be found here: ## ## http://www.bogus.net/torh/files/sfvdir.pl ## ## this has a BSD license. you can sell this script if you want to, and ## make changes too. but make sure all my comments and copyright notices ## herein remain intact. ## ## version 1.4 is the first release version. ## $|=1; ## use Getopt::Long; GetOptions("h","x","v","t","l","p", "d=s" => \$dir, "b=s" => \$binary, "e=s" => \$efile); $DEBUG=1 if($opt_x); $PWD=$ENV{'PWD'}; $ENV{'PATH'}="/bin:/usr/bin:/usr/local/bin"; $tfail=0; if(!$binary) { $binary=`which pdsfv`; chop($binary); } if($opt_v) { print "version:$version\n"; exit(0); } if($opt_h) { print <] [-b ] -d -v : version number -h : this stuff -d : directory to start from (mandatory) -t : turn off ".ALL_OK/.BAD" file touching (optional) -b : ".svf" binary to use (defaults to $binary) -e : create a file containing a list of bad files (optional) -x : debug info -l : only show files missing from .sfv lists -p : strip path given to -d in -l output EOM exit(0); } if(-f $efile) { die "ERROR: $efile exists.\n"; } if(!$dir) { die "ERROR: need a directory to start with!\n"; } $dir=~s/\/$//g; $TOPDIR=$dir; print "DEBUG: using $binary\n" if($DEBUG); if(!-x $binary) { die "ERROR: cannot find .sfv binary (e.g. pdsfv): $!\n"; } if($efile) { open(EFILE,">$efile"); } RecurseDir($dir); if($efile) { close(EFILE); } if($tfail) { if($opt_l) { print "There seems to be $tfail missing file(s) in total.\n"; } else { print "Found $tfail file(s) that failed the SFV test\n"; } exit(1); } else { print "All OK.\n"; exit(0); } sub RecurseDir($) { my($dir)=$_[0]; my(@files,@dirs); print "DEBUG: $dir\n" if($DEBUG); if(!-R $dir) { print "DEBUG: no read access to $dir\n" if($DEBUG); return(); } opendir(DIR,$dir) || die "ERROR: failed to open $dir: $!"; @files = grep { -r "$dir/$_" && -s "$dir/$_" } readdir(DIR); closedir(DIR); opendir(DIR,$dir); @dirs = grep { -d "$dir/$_" && -s "$dir/$_" } readdir(DIR); closedir(DIR); foreach $subdir (sort @dirs) { next if(($subdir eq ".")|($subdir eq "..")); RecurseDir("$dir/$subdir"); }; foreach $file (sort @files) { if($file=~/\.sfv$/) { if(!$opt_l) { my($line,@result,$failed,$rename); print "Checking $dir/$file...\n"; @result=`cd $dir; $binary -T $file`; foreach $line (@result) { if($line =~ /Testing (\S+) .* BAD/) { my($bad)=$1; $rename=`mv $dir/$bad $dir/$bad.FAILED`; print "BAD file: $dir/$bad (renamed to $dir/$bad.FAILED)\n"; $failed=1; $tfail++; print EFILE "BAD: $dir/$bad.FAILED\n" if($efile); } } if($failed) { print "DEBUG: SFV failed on $dir (.FAILED)\n" if($DEBUG); $touch=`touch $dir/.FAILED` if(!$opt_t); } else { print "DEBUG: SFV ok on $dir (.ALL_OK)\n" if($DEBUG); $touch=`touch $dir/.ALL_OK` if(!$opt_t); } } else { ## open the .sfv file, find out what files SHOULD be in this directory ## then spit out some information if any seem to be missing ## open(SFVLIST,"$dir/$file") || die "Cannot open SFV file: $dir/$file"; while() { next if(/^\;|^\#/); if(/(\S+)\s+([0-9A-Z]+)/i) { my($f)=$1; if(!-e "$dir/$f") { my($foo)=$dir."/".$f; $foo=~s/$TOPDIR//g if($opt_p); ## some jackass wanted this $foo=~s/^\///g; ## but who am i to argue.. print "Missing: $foo\n"; $failed=1; $tfail++; } else { if(-z "$dir/$f") { print "File $dir/$f exists, but has zero size.\n"; $failed=1; $tfail++; } } } } close(SFVLIST); } } } }