Absorb: ask for the passphrase once the archive starts arriving
With gpg --decrypt x.tar.gpg | vault absorb, vault printed its prompt while gpg was still writing to the terminal, which buried it, so the command looked hung. Peek at standard input first: the upstream program has finished with the terminal by the time data arrives, and an empty pipe now fails without asking at all. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
1403be8b1c
commit
730877823e
@@ -581,7 +581,11 @@ vault absorb old < archive.tar.gz
|
||||
|
||||
Each file is encrypted straight from the stream, so nothing is unpacked to
|
||||
disk first. Directories need no entry of their own; links, devices and any
|
||||
name that tries to climb out with \file{..} are skipped with a note. If the
|
||||
name that tries to climb out with \file{..} are skipped with a note.
|
||||
vault asks for your passphrase only once the archive starts arriving, so
|
||||
when it comes out of something that asks first, like
|
||||
\cmd{gpg --decrypt secrets.tar.gpg | vault absorb}, gpg's prompt comes
|
||||
and goes before vault's appears. If the
|
||||
archive stops halfway through a file, that file isn't stored and vault
|
||||
stops; everything before it is already safely in.
|
||||
|
||||
|
||||
+6
-2
@@ -35,8 +35,12 @@ or
|
||||
is dropped.
|
||||
.PP
|
||||
The passphrase prompt reads from the terminal, not standard input, so
|
||||
it still works with an archive piped in. The vault is locked exclusively
|
||||
for the whole run.
|
||||
it still works with an archive piped in. It waits until the archive starts
|
||||
arriving, so a program feeding the pipe, such as
|
||||
.BR gpg (1)
|
||||
asking for its own passphrase, has finished with the terminal first.
|
||||
An empty pipe fails without asking at all.
|
||||
The vault is locked exclusively for the whole run.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI \-\-key " PATH"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
@@ -158,10 +159,17 @@ func main() {
|
||||
if len(pos) == 1 {
|
||||
dest = strings.Trim(pos[0], "/")
|
||||
}
|
||||
// Wait for the archive to start arriving before asking for the
|
||||
// passphrase, so a program feeding the pipe (gpg, ssh) has finished
|
||||
// with the terminal and cannot bury the prompt.
|
||||
in := bufio.NewReader(os.Stdin)
|
||||
if _, err := in.Peek(1); err != nil {
|
||||
fail("nothing to absorb on standard input")
|
||||
}
|
||||
s := open(*keyPath, *vaultDir, true)
|
||||
cat, err := s.catalogue()
|
||||
check(err)
|
||||
check(absorb(s, cat, os.Stdin, dest))
|
||||
check(absorb(s, cat, in, dest))
|
||||
case "list", "ls":
|
||||
want(0, 1)
|
||||
prefix := ""
|
||||
|
||||
Reference in New Issue
Block a user