package Util::ShortTermRepository; ############################################################################## # # DESCRIPTION: # # HISTORY # HISTORY: $Log: ShortTermRepository.pm,v $ # HISTORY: Revision 1.6 2007/11/30 16:34:22 apsop # HISTORY: Check for existence of fetched repository file before using it. # HISTORY: # HISTORY: Revision 1.5 2007/06/29 15:25:21 apsop # HISTORY: Set SEARCH_RANGE to 2. Only wait if checksum is wrong, not if no file is found. # HISTORY: # HISTORY: Revision 1.4 2006/12/20 14:20:19 apsop # HISTORY: Bug fix the previous changes. # HISTORY: # HISTORY: Revision 1.3 2006/12/19 15:23:37 apsop # HISTORY: Use time indexed directories for storing repository files. # HISTORY: # HISTORY: Revision 1.2 2006/08/01 20:35:34 apsop # HISTORY: Add in CVS history indicator. # HISTORY: # HISTORY: # # VERSION: 0.0 # ############################################################################## use strict; ######################### # constructor ######################### sub new { #(directory) my $proto = shift; my $class = ref($proto) || $proto; ##################################### # initialize some variables ##################################### my $self={}; $self->{DIR}=shift; $self->{FILENAME}=shift; $self->{FILES}={}; $self->{WAIT}=60; $self->{SEARCH_RANGE}=2; $self->{MAX_COUNT}=5; bless($self,$class); return $self; } # end of constructor ######################### # accessors ######################### ############################################################################## # ############################################################################## sub log { my $self = shift; return $self->{FILENAME}->log(); } ######################### # methods ######################### ############################################################################## # ############################################################################## sub export { my $self = shift; my $type = shift; my $log = $self->log(); my @files = @_; unless(@files) { ######################################### # export all the files of the given type ######################################### @files = $self->{FILENAME}->any($type); } ######################################## # copy all the files to the repository ######################################## my $file; foreach $file (@files) { $file =~ /_(\d+)\./; my $index = int($1/1000000)*1000000; my $dir = "$self->{DIR}/$type/$index"; mkdir $dir; my $checksum = "$dir/.$file.sha1"; unlink $checksum; system("sha1sum $file > $checksum"); system("cp $file $dir"); } } # end of export method ############################################################################## # ############################################################################## sub fetch { my $self = shift; my $type = shift; my @args = @_; my $log = $self->log(); my $filename = $self->{FILENAME}; my $dir; my $file; my $okaysum = 0; my $count = 0; until($okaysum){ ############################################## # locate the file in the repository directory ############################################## my $subdir = int($args[2]/1000000)*1000000; for(my $idir = 0; $idir < $self->{SEARCH_RANGE}; $idir++){ $dir = "$self->{DIR}/$type/" . ($subdir - 1000000*$idir); $filename->glob_dir($dir); $file = $filename->get($type, @args); ################################################################ # if we located the file, copy it into the working directory ################################################################ if($file && $self->{FILENAME}->fetch($file, $dir) && -f $file) { my $checksum = "$dir/.$file.sha1"; if( -f $checksum){ open SUM, $checksum; my $sum = (split ' ', <SUM>)[0]; close SUM; open SUM, "sha1sum $file |"; my $check = (split ' ', <SUM>)[0]; close SUM; $okaysum = 1 if $sum eq $check; last; } } } if($okaysum){ ########################################################### # we got a file, so remember its name for cataloging later ########################################################### $self->remember($type, $file); }elsif(!$file){ ###################### # no file, so give up ###################### return $file; }else{ ###################################################### # Got a file, but bad checksum, so wait and try again ###################################################### unlink $file; unless($count){ $log->entry("Waiting for repository while fetching $file."); } last if $count++ > $self->{MAX_COUNT}; sleep $self->{WAIT}; } } unless($okaysum){ $log->error(1, "Repository timeout while file fetching $file."); } return $file; } # end of fetch method ############################################################################## # store a file name and type internally so that it can be included in a catalog # of all fetched files later. ############################################################################## sub remember { my $self = shift; my $type = shift; my $file = shift; unless($self->{FILES}->{$type}) { $self->{FILES}->{$type} = {}; } $self->{FILES}->{$type}->{$file} =1; } # end of remember method 1;