1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//! Terminal input for the CLI commands (no TUI): the hidden backup-password
//! prompt, and discarding whatever was typed while a long command was running.
//!
//! The prompt is used by the CLI `restore` path (docs/history/backup-password.md
//! §4 F6): restoring a foreign archive on a fresh machine is exactly the case
//! where there is no stored password, and the only alternative would be
//! `--password` on the command line — which lands in the shell history and the
//! process list.
//!
//! No new dependency: `crossterm` is already used by the TUI, and raw mode is
//! what suppresses the echo. Both functions are **skipped when stdin is not a
//! terminal** (a pipe, a CI job, a service): prompting there would hang forever
//! instead of failing with a message, and discarding would eat piped input.
use ;
use Duration;
use ;
use terminal;
/// Whether an interactive prompt is possible at all (stdin is a terminal).
/// Prompts for a password with the input hidden.
///
/// `Ok(None)` — the user cancelled (`Esc`/`Ctrl+C`) or submitted an empty line.
/// `Err` — the terminal could not be switched into raw mode.
///
/// Deliberately hand-rolled rather than pulling in `rpassword`: the surface is a
/// dozen lines, and the project's precedent is its own micro-solution when the
/// alternative is a crate for one function (ADR 0003, `features/cli.rs`).
/// A backstop against an unresponsive terminal: a drain can't outlive this many
/// events. Real type-ahead is a handful of keystrokes.
const MAX_DISCARDED_EVENTS: usize = 4096;
/// Discards keystrokes typed while a long command was running.
///
/// Packing or unpacking a real data root takes seconds, and keys pressed in the
/// meantime — an impatient `Enter` after the password prompt, most of all — sit
/// in the console input buffer untouched. They were typed at *us*, but nothing
/// here reads them, so on exit the shell inherits them and replays them as its
/// own command line. Discarding is the standard fix, and it is safe because
/// there is no other consumer: the CLI is done reading by the time this runs.
///
/// Deliberately silent about failures — a terminal we can't poll is exactly the
/// case where there is nothing to discard.
/// Reads characters until Enter, in raw mode (nothing is echoed).