From b9a4e573377eec26b4981deefc6b9a640fc229db Mon Sep 17 00:00:00 2001 From: Flavio Poletti Date: Sun, 31 Aug 2008 00:45:07 +0200 Subject: [PATCH] Added support for the mv command. --- s3 | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/s3 b/s3 index cd2ef0e..81bc3ad 100755 --- a/s3 +++ b/s3 @@ -334,8 +334,24 @@ sub get { return; } ## end sub get -sub cp { - my ($s3, $config, @list) = @_; +=begin comment + +Can perform both cp and mv, this is only the "framework" logic +that uses $callback_for in order to understand which operations +has to be applied exactly in the different situations. The +$callback_for is an hash reference with the following keys: + + l2l - local to local + l2r - local to remote (S3) + r2l - remote (S3) to local + r2r - remote (S3) to remote (S3) + +=end comment + +=cut + +sub _cp_or_mv { + my ($callback_for, $s3, $config, @list) = @_; LOGDIE "no parameters" unless @list; my $dst = pop @list; @@ -347,7 +363,7 @@ sub cp { for my $src (@list) { my $this_dst = main::resolve_dst($dst, $src); if (main::is_s3path($src)) { - copy($s3, $config, $src, $this_dst); + $callback_for->{r2r}->($s3, $config, $src, $this_dst); } else { my %config = %$config; @@ -363,7 +379,7 @@ sub cp { unshift @{$config{meta}}, 'stat:' . join ',', stat $src; - add($s3, \%config, $this_dst, $src); + $callback_for->{l2r}->($s3, \%config, $src, $this_dst); } ## end else [ if (main::is_s3path($src... } ## end for my $src (@list) } ## end if (main::is_s3path($dst... @@ -371,14 +387,58 @@ sub cp { LOGDIE "$dst should be a directory with more than one source" if (@list > 1) && !-d $dst; main::is_s3path($_) - ? get($s3, $config, $_, $dst) - : main::cp_local($_, $dst) + ? $callback_for->{r2l}->($s3, $config, $_, $dst) + : $callback_for->{l2l}->($_, $dst) for @list; } ## end else [ if (main::is_s3path($dst... return; } ## end sub cp +sub cp { + return _cp_or_mv({ + r2r => \©, + l2r => sub { + my ($s3, $config, $src, $dst) = @_; + add($s3, $config, $dst, $src); # swap dst and src for add! + }, + r2l => \&get, + l2l => \&main::cp_local, + }, @_); +} + +sub mv { + return _cp_or_mv({ + r2r => sub { + copy(@_); + _delete(@_); + }, + l2r => sub { + my ($s3, $config, $src, $dst) = @_; + add($s3, $config, $dst, $src); # swap dst and src for add! + unlink $src or LOGDIE "could not delete '$src': $OS_ERROR"; + return; + }, + r2l => sub { + get(@_); + _delete(@_); + }, + l2l => sub { + my ($src, $dst) = @_; + + # Try a simple rename, if possible + rename($src, $dst) and return; + + # Fall back to copy-and-delete + main::cp_local($src, $dst); + unlink $src or LOGDIE "could not delete '$src': $OS_ERROR"; + + return; + }, + }, @_); +} + + sub cat { my ($s3, $config, @paths) = @_; for my $path (@paths) { -- 2.11.4.GIT