Bio-GMOD
view release on metacpan or search on metacpan
GMOD/Util/Mirror.pm view on Meta::CPAN
# return shift->{path};}
my $p = $_[0]->{path};
$_[0]->{path} = $_[1] if defined $_[1];
$p;
}
sub ftp {
# return shift->{ftp}; }
my $p = $_[0]->{ftp};
$_[0]->{ftp} = $_[1] if defined $_[1];
$p;
}
sub verbose {
# return shift->{verbose}; }
my $p = $_[0]->{verbose};
$_[0]->{verbose} = $_[1] if defined $_[1];
$p;
}
# top-level entry point for mirroring.
sub mirror {
my $self = shift;
$self->path(shift) if @_;
my $path = $self->path;
my $cd;
if ($self->{localpath}) {
chomp($cd = `pwd`);
chdir($self->{localpath}) or croak "can't chdir to $self->{localpath}: $!";
}
my $type = $self->find_type($self->path) or croak "top level file/directory not found";
my ($prefix,$leaf) = $path =~ m!^(.*?)([^/]+)/?$!;
$self->ftp->cwd($prefix) if $prefix;
my $ok;
if ($type eq '-') { # ordinary file
$ok = $self->get_file($leaf);
} elsif ($type eq 'd') { # directory
$ok = $self->get_dir($leaf);
} else {
carp "Can't parse file type for $leaf\n";
return;
}
chdir $cd if $cd;
$ok;
}
# mirror a file
sub get_file {
my $self = shift;
my ($path,$mode) = @_;
my $ftp = $self->ftp;
my $rtime = $ftp->mdtm($path);
my $rsize = $ftp->size($path);
$mode = ($self->parse_listing($ftp->dir($path)))[2] unless defined $mode;
my ($lsize,$ltime) = stat($path) ? (stat(_))[7,9] : (0,0);
if ( defined($rtime) and defined($rsize)
and ($ltime >= $rtime)
and ($lsize == $rsize) ) {
$self->warning(-msg => "Getting file $path: not newer than local copy.") if $self->verbose;
return 1;
}
$self->logit(-msg => "Downloading file $path");
$ftp->get($path) or ($self->warning(-msg=>$ftp->message) and return);
chmod $mode,$path if $mode;
}
# mirror a directory, recursively
sub get_dir {
my $self = shift;
my ($path,$mode) = @_;
my $localpath = $path;
-d $localpath or mkpath $localpath or carp "mkpath failed: $!" && return;
chdir $localpath or carp "can't chdir to $localpath: $!" && return;
$mode = 0755 if ($mode == 365); # Kludge-can't mirror non-writable directories
chmod $mode,'.' if $mode;
my $ftp = $self->ftp;
my $cwd = $ftp->pwd or carp("can't pwd: ",$ftp->message) && return;
$ftp->cwd($path) or carp("can't cwd: ",$ftp->message) && return;
$self->logit(-msg => "Downloading directory $path") if $self->verbose;
foreach ($ftp->dir) {
next unless my ($type,$name,$mode) = $self->parse_listing($_);
next if $name =~ /^(\.|\.\.)$/; # skip . and ..
$self->get_dir ($name,$mode) if $type eq 'd';
$self->get_file($name,$mode) if $type eq '-';
$self->make_link($name) if $type eq 'l';
}
$ftp->cwd($cwd) or carp("can't cwd: ",$ftp->message) && return;
chdir '..';
}
# subroutine to determine whether a path is a directory or a file
sub find_type {
my $self = shift;
my $path = shift;
my $ftp = $self->ftp;
my $pwd = $ftp->pwd;
my $type = '-'; # assume plain file
if ($ftp->cwd($path)) {
$ftp->cwd($pwd);
$type = 'd';
}
return $type;
}
# Attempt to mirror a link. Only works on relative targets.
sub make_link {
my $self = shift;
( run in 1.956 second using v1.01-cache-2.11-cpan-97f6503c9c8 )