Improve the "waiting for input on stdin" message.

- Require the caller to indicate what they are waiting for, and
    include that in the warning.

  - For instance, `sq decrypt` now says "Waiting for an encrypted
    message on stdin..."
This commit is contained in:
Neal H. Walfield 2024-11-19 13:36:54 +01:00
parent 5f84605a4b
commit fdc963cd59
No known key found for this signature in database
GPG Key ID: 6863C9AD5B4D22D3
12 changed files with 34 additions and 28 deletions

View File

@ -87,7 +87,8 @@ pub trait ClapData {
/// read within a certain amount of time.
pub struct StdinWarning {
do_warn: bool,
warning: &'static str,
/// The thing that is being waited for. See `StdinWarning::emit`.
thing: &'static str,
}
/// Print a warning if we don't get any input after this amount of
@ -96,28 +97,27 @@ const STDIN_TIMEOUT: Duration = std::time::Duration::new(2, 0);
impl StdinWarning {
/// Emit a custom warning if no input is received.
pub fn warn(warning: &'static str) -> Self {
pub fn new(thing: &'static str) -> Self {
Self {
do_warn: true,
warning,
thing,
}
}
/// Emit a standard warning if no input is received.
pub fn new() -> Self {
Self::warn("Waiting for input on stdin...")
}
/// Emit a warning that a certificate is expected if no input is
/// received.
pub fn openpgp() -> Self {
Self::warn("Waiting for OpenPGP data on stdin...")
Self::new("OpenPGP data")
}
/// Emit a warning that certificates are expected if no input is
/// received.
pub fn certs() -> Self {
Self::warn("Waiting for certificates on stdin...")
Self::new("OpenPGP certificates")
}
pub fn emit(&self) {
eprintln!("Waiting for {} on stdin...", self.thing);
}
}
@ -145,7 +145,7 @@ impl Read for StdinWarning {
if let Err(mpsc::RecvTimeoutError::Timeout)
= receiver.recv_timeout(STDIN_TIMEOUT)
{
eprintln!("{}", self.warning);
self.emit();
}
});
@ -215,14 +215,20 @@ impl FileOrStdin {
/// Get a boxed BufferedReader for the FileOrStdin
///
/// Opens a file if there is Some(PathBuf), else opens stdin.
pub fn open<'a>(&self) -> Result<Box<dyn BufferedReader<Cookie> + 'a>> {
///
/// `thing` is the thing that we expect to read, e.g., "OpenPGP
/// certificates" or "a signed message".
pub fn open<'a>(&self, thing: &'static str)
-> Result<Box<dyn BufferedReader<Cookie> + 'a>>
{
if let Some(path) = self.inner() {
Ok(Box::new(
File::with_cookie(path, Default::default())
.with_context(|| format!("Failed to open {}", self))?))
} else {
Ok(Box::new(
Generic::with_cookie(StdinWarning::new(), None, Default::default())))
Generic::with_cookie(
StdinWarning::new(thing), None, Default::default())))
}
}

View File

@ -42,7 +42,7 @@ where 'store: 'rstore
let inner = || -> Result<()> {
for input in inputs.into_iter() {
let input = FileOrStdin::from(input);
let mut input_reader = input.open()?;
let mut input_reader = input.open("OpenPGP certificates")?;
if input_reader.eof() {
// Empty file. Silently skip it.

View File

@ -39,7 +39,7 @@ use crate::{
pub fn dispatch(sq: Sq, command: cli::decrypt::Command) -> Result<()> {
tracer!(TRACE, "decrypt::dispatch");
let mut input = command.input.open()?;
let mut input = command.input.open("an encrypted message")?;
let mut output = command.output.create_safe(&sq)?;
let signers =

View File

@ -206,7 +206,7 @@ pub fn encrypt<'a, 'b: 'a>(
.context("Failed to create literal writer")?;
// Finally, copy stdin to our writer stack to encrypt the data.
io::copy(&mut input.open()?, &mut writer_stack)
io::copy(&mut input.open("data to encrypt")?, &mut writer_stack)
.context("Failed to encrypt")?;
writer_stack.finalize().context("Failed to encrypt")?;

View File

@ -71,7 +71,7 @@ pub fn dispatch(mut sq: Sq, c: inspect::Command)
}
}
inspect(&mut sq, input.open()?,
inspect(&mut sq, input.open("OpenPGP or autocrypt data")?,
Some(&input.to_string()), output,
print_certifications, dump_bad_signatures)?;
} else {

View File

@ -158,11 +158,11 @@ pub fn dispatch(sq: Sq, c: keyring::Command) -> Result<()> {
Merge(c) =>
merge(&sq, c.input, c.output, false),
List(c) => {
let mut input = c.input.open()?;
let mut input = c.input.open("OpenPGP certificates")?;
list(sq, &mut input, c.all_userids)
},
Split(c) => {
let mut input = c.input.open()?;
let mut input = c.input.open("OpenPGP certificates")?;
let prefix =
// The prefix is either specified explicitly...
c.prefix.unwrap_or(

View File

@ -64,7 +64,7 @@ pub fn dispatch(sq: Sq, command: Command)
}
}
Box::new(command.input.open()?)
Box::new(command.input.open("OpenPGP packets")?)
as Box<dyn io::Read + Send + Sync>
} else {
let cert = sq.resolve_cert(&command.cert, 0)?.0;
@ -92,7 +92,7 @@ pub fn dispatch(sq: Sq, command: Command)
},
Subcommands::Decrypt(command) => {
let mut input = command.input.open()?;
let mut input = command.input.open("an encrypted message")?;
let mut output = command.output.create_pgp_safe(
&sq,
command.binary,
@ -124,7 +124,7 @@ pub fn dispatch(sq: Sq, command: Command)
pub fn split(sq: Sq, c: SplitCommand) -> Result<()>
{
let input = c.input.open()?;
let input = c.input.open("OpenPGP packets")?;
// If --binary is given, the user has to provide a prefix.
assert!(! c.binary || c.prefix.is_some(),

View File

@ -50,7 +50,7 @@ pub fn dispatch(sq: Sq, command: cli::packet::armor::Command)
{
tracer!(TRACE, "armor::dispatch");
let mut input = command.input.open()?;
let mut input = command.input.open("the data to encode")?;
let mut want_kind: Option<armor::Kind>
= command.kind.into();

View File

@ -12,7 +12,7 @@ pub fn dispatch(sq: Sq, command: cli::packet::dearmor::Command)
{
tracer!(TRACE, "dearmor::dispatch");
let mut input = command.input.open()?;
let mut input = command.input.open("the OpenPGP data")?;
let mut output = command.output.create_safe(&sq)?;
let mut filter = armor::Reader::from_buffered_reader(&mut input, None)?;
io::copy(&mut filter, &mut output)?;

View File

@ -35,7 +35,7 @@ use merge_signatures::merge_signatures;
pub fn dispatch(sq: Sq, command: cli::sign::Command) -> Result<()> {
tracer!(TRACE, "sign::dispatch");
let mut input = command.input.open()?;
let mut input = command.input.open("the data to sign")?;
let output = &command.output;
let detached = command.detached;
let binary = command.binary;
@ -61,7 +61,7 @@ pub fn dispatch(sq: Sq, command: cli::sign::Command) -> Result<()> {
armor::Kind::Message,
)?;
let data: FileOrStdin = merge.into();
let mut input2 = data.open()?;
let mut input2 = data.open("OpenPGP signatures")?;
return merge_signatures(&mut input, &mut input2, output);
}

View File

@ -31,7 +31,7 @@ pub fn dispatch(sq: Sq, command: cli::verify::Command)
{
tracer!(TRACE, "verify::dispatch");
let mut input = command.input.open()?;
let mut input = command.input.open("a signed message")?;
let mut output = command.output.create_safe(&sq)?;
let signatures = command.signatures;

View File

@ -497,7 +497,7 @@ impl<'store: 'rstore, 'rstore> Sq<'store, 'rstore> {
for handle in handles {
let (kh, mut certs) = match handle.into() {
FileStdinOrKeyHandle::FileOrStdin(file) => {
let br = file.open()?;
let br = file.open("an OpenPGP certificate")?;
let cert = Cert::from_buffered_reader(br)?;
(cert.key_handle(), vec![ cert ])
}