commit 8ce01796c68dfe0e12b6a1869be69cf3b2cf2584 from: Omar Polo date: Wed Jan 11 21:22:35 2023 UTC add `edit' subcommand to interactively modify an entry It's more or less equivalent to $ cd /tmp $ umask 077 $ plass cat entry > tempfile $ $EDITOR tempfile $ plass tee entry < tempfile $ rm tempfile but way easier. It's also safer because it creates an unique randomly named file set up with correct permissions. Suggested by heph, thanks! commit - 91fcc6e3ddaac1838153b32e3d6d453b445309c0 commit + 8ce01796c68dfe0e12b6a1869be69cf3b2cf2584 blob - 2b6c011002aca0e9b82b904e8766b47729d49aca blob + 54d1d407f6d1a8d05b2acbf06a055e1d7c8c1a34 --- plass +++ plass @@ -23,6 +23,7 @@ use open ":std", ":encoding(UTF-8)"; use Getopt::Long qw(:config bundling require_order); use File::Basename; use File::Find; +use File::Temp qw(tempfile); my $store = $ENV{'PLASS_STORE'} // $ENV{'HOME'}.'/.password-store'; @@ -33,6 +34,7 @@ my @gpg_flags = qw(--quiet --compress-algo=none --no-e my %subcmd = ( cat => [\&cmd_cat, "entries..."], + edit => [\&cmd_edit, "entry"], find => [\&cmd_find, "[pattern]"], mv => [\&cmd_mv, "from to"], rm => [\&cmd_rm, "entries..."], @@ -180,6 +182,47 @@ sub cmd_cat { } } +sub cmd_edit { + GetOptions('h|?' => \&usage) or usage; + usage if @ARGV != 1; + + my $editor = $ENV{'VISUAL'} // $ENV{'EDITOR'} // 'ed'; + + my $entry = shift @ARGV; + my $epath = name2file $entry; + + my ($fh, $filename) = tempfile "/tmp/plass-XXXXXXXXXX"; + + open (my $stdout, ">&", STDOUT) or die "can't redirect stdout: $!"; + + open (STDOUT, ">&", $fh) or die "can't redirect stdout to $filename"; + system ($gpg, @gpg_flags, '-d', $epath); + die "$gpg exited with $?\n" if $? != 0; + + # restore stdout so the editor can access the TTY if needed. + open (STDOUT, ">&", $stdout) or die "can't restore stdout: $!"; + + my $oldtime = (stat($fh))[9]; + + system ($editor, $filename); + die "editor $editor failed\n" if $? != 0; + + my $newtime = (stat($filename))[9]; + + if ($oldtime == $newtime) { + say STDERR "no changes made."; + return + } + + open(STDIN, '<', $filename) or die "can't redirect stdin: $!"; + open(STDOUT, '>', $epath) or die "can't redirect stdout: $!"; + system ($gpg, @gpg_flags, '-e', '-r', recipient(), '-o', '-'); + die "gpg failed" if $? != 0; + + got_add $epath; + got_ci "update $entry"; +} + sub cmd_find { GetOptions('h|?' => \&usage) or usage; usage if @ARGV > 1; blob - 29c86a688e11715b0210252556fd70871e31e110 blob + 500adc028fb0c65e742643eae1ce47f61b0146c2 --- plass.1 +++ plass.1 @@ -60,6 +60,10 @@ The following commands are available: Decrypt and print the content of .Ar entries in the given order. +.It Cm edit Ar entry +Modify the content of the given +.Ar entry +using an editor. .It Cm find Op Ar pattern Print the entries of the store one per line, optionally filtered by the case-insensitive @@ -93,6 +97,14 @@ Path to the executable. .It Ev PLASS_STORE Alternative path to the password store directory tree. +.It Ev VISUAL , Ev EDITOR +The editor spawned by +.Nm +.Cm edit . +If not set, the +.Xr ed 1 +text editor will be used in order to given it the attention +it deserves. .El .Sh FILES .Bl -tag -width Ds @@ -141,7 +153,7 @@ Enable tab-completion of command names and entries in .Xr ksh 1 : .Bd -literal -offset indent -$ set -A complete_plass_1 -- cat find mv rm tee +$ set -A complete_plass_1 -- cat edit find mv rm tee $ set -A complete_plass -- $(plass find) .Ed .Sh SEE ALSO