diff options
-rwxr-xr-x | cli/icevault | 29 | ||||
-rw-r--r-- | cli/icevault.1 | 14 |
2 files changed, 43 insertions, 0 deletions
diff --git a/cli/icevault b/cli/icevault index 5ad8ff2..fdc1b74 100755 --- a/cli/icevault +++ b/cli/icevault @@ -713,11 +713,13 @@ unless (@ARGV) { my @USAGE = ( fill => "[-f, --force] [-p, --show-passwords] [-s, --socket=PATH] scheme://hostname/identity", clip => "scheme://hostname/identity", + cp => "[-f, --force] scheme://hostname/identity1 scheme://hostname/identity2", dump => "[-p, --show-passwords] scheme://hostname/identity", edit => "scheme://hostname/identity", git => "GIT-COMMAND [GIT-ARG ...]", insert => "[-f, --force] [-s, --socket=PATH] [identity]", ls => "[-0, --zero] [-r, --recursive] [scheme://[hostname/[identity]] ...]", + mv => "[-f, --force] scheme://hostname/identity1 scheme://hostname/identity2", reencrypt => "[scheme://[hostname/[identity]] ...]", ); @@ -1187,6 +1189,33 @@ elsif ($COMMAND eq 'reencrypt') { , map {$_->{filename}} @filenames ); } +elsif ($COMMAND eq 'cp' or $COMMAND eq 'mv') { + getopts('force|f' => "-f, --force\tOverwrite preexisting destination"); + usage() if $#ARGV != 1; + my $source = shift; + my $target = shift; + + my $sourceFilename = identity2File($source); + $sourceFilename =~ /\A(\/\p{Print}+)\z/ or error "Insecure C<%s>", $sourceFilename; + $sourceFilename = $1; # untaint $sourceFilename + + my $targetFilename = identity2File($target); + $targetFilename =~ /\A(\/\p{Print}+)\z/ or error "Insecure C<%s>", $targetFilename; + $targetFilename = $1; # untaint $target + + error "Source and destination are the same identity C<%s>", $source if $source eq $target; + error "No such identity C<%s>", $source unless -f $sourceFilename; + exit 1 if -f $targetFilename and !$CONFIG{force} and !promptYN "Overwrite C<%s>?", 0, $target; + + copyIdentityFile $sourceFilename, $targetFilename; + my @filenames = $targetFilename; + if ($COMMAND eq 'mv') { + unlink $sourceFilename or error "Can't unlink C<%s>: %s", $sourceFilename, $!; + push @filenames, $sourceFilename; + } + commit(($COMMAND eq 'cp' ? 'copy' : 'move')." $source to $target", @filenames); +} + else { print STDERR "Usage: $NAME [COMMAND] [OPTION ...] [ARG ...]\n"; error "Unknown command C<%s>. Try C<%s> for more information.", $COMMAND, "$NAME --help"; diff --git a/cli/icevault.1 b/cli/icevault.1 index d49601f..2e40af3 100644 --- a/cli/icevault.1 +++ b/cli/icevault.1 @@ -64,6 +64,13 @@ Decrypt the \fIidentity\fR file and copy its first password to the clipboard using \fIxclip\fR(1), with a maximum number of pastes of 1. .TP +.B cp\fR [\fB-f\fR, \fB--force\fR] \fIscheme\fR://\fIhostname\fR/\fIidentity1\fR \fIscheme\fR://\fIhostname\fR/\fIidentity2\fR +Copy \fIscheme\fR://\fIhostname\fR/\fIidentity1\fR to +\fIscheme\fR://\fIhostname\fR/\fIidentity2\fR. The destination is +reencrypted on the fly. If \fB-f\fR is set, don't ask before overriding +an existing destination identity. + +.TP .B dump\fR [\fB-p\fR, \fB--show-passwords\fR] \fIscheme\fR://\fIhostname\fR/\fIidentity\fR Decrypt the \fIidentity\fR file and dump its content on the standard output. Note that while the output is a valid YAML document, original @@ -131,6 +138,13 @@ recursively all identities under \fIscheme\fR://\fIhostname\fR/ (resp. \fIscheme\fR://). .TP +.B mv\fR [\fB-f\fR, \fB--force\fR] \fIscheme\fR://\fIhostname\fR/\fIidentity1\fR \fIscheme\fR://\fIhostname\fR/\fIidentity2\fR +Rename \fIscheme\fR://\fIhostname\fR/\fIidentity1\fR as +\fIscheme\fR://\fIhostname\fR/\fIidentity2\fR. The destination is +reencrypted on the fly. If \fB-f\fR is set, don't ask before overriding +an existing destination identity. + +.TP .B reencrypt\fR [\fIscheme\fR://[\fIhostname\fR/[\fIidentity\fR]] ...] Reencrypt each given identity prefix(es) with the \fIkeyid\fR(s) found in the configuration file as recpient(s). If no argument is given, |