Word-wrap lines in human-readable messages.

- Replace every eprintln by wprintln, which prints to stderr as
    well, but word-wraps the messages.
This commit is contained in:
Justus Winter 2023-11-29 16:13:37 +01:00
parent 0400ae88eb
commit 2ab3bd5efd
No known key found for this signature in database
GPG Key ID: 686F55B4AB2B3386
21 changed files with 187 additions and 146 deletions

1
Cargo.lock generated
View File

@ -3231,6 +3231,7 @@ dependencies = [
"tempfile", "tempfile",
"termcolor", "termcolor",
"terminal_size", "terminal_size",
"textwrap",
"tokio", "tokio",
] ]

View File

@ -53,6 +53,7 @@ roff = "0.2.1"
terminal_size = ">=0.2.6, <0.4" terminal_size = ">=0.2.6, <0.4"
is-terminal = "0.4.7" is-terminal = "0.4.7"
termcolor = "1.2.0" termcolor = "1.2.0"
textwrap = "0.15"
[build-dependencies] [build-dependencies]
anyhow = "1.0.18" anyhow = "1.0.18"

View File

@ -171,7 +171,7 @@ fn get_keys<C>(certs: &[C], p: &dyn Policy,
keys.push((signer, Some(input_password.clone()))); keys.push((signer, Some(input_password.clone())));
continue 'next_cert; continue 'next_cert;
}, },
Err(error) => eprintln!("Could not unlock key: {:?}", error), Err(error) => wprintln!("Could not unlock key: {:?}", error),
} }
} }
} }
@ -474,7 +474,7 @@ impl<'a, 'store> VHelper<'a, 'store> {
p(&mut status, "bad checksum", self.bad_checksums); p(&mut status, "bad checksum", self.bad_checksums);
p(&mut status, "broken signatures", self.broken_signatures); p(&mut status, "broken signatures", self.broken_signatures);
if ! status.is_empty() { if ! status.is_empty() {
eprintln!("{}.", status); wprintln!("{}.", status);
} }
} }
@ -489,7 +489,7 @@ impl<'a, 'store> VHelper<'a, 'store> {
let (sig, ka) = match result { let (sig, ka) = match result {
Ok(GoodChecksum { sig, ka, .. }) => (sig, ka), Ok(GoodChecksum { sig, ka, .. }) => (sig, ka),
Err(MalformedSignature { error, .. }) => { Err(MalformedSignature { error, .. }) => {
eprintln!("Malformed signature:"); wprintln!("Malformed signature:");
print_error_chain(error); print_error_chain(error);
self.broken_signatures += 1; self.broken_signatures += 1;
continue; continue;
@ -502,19 +502,19 @@ impl<'a, 'store> VHelper<'a, 'store> {
0 => "checksum".into(), 0 => "checksum".into(),
n => format!("level {} notarizing checksum", n), n => format!("level {} notarizing checksum", n),
}; };
eprintln!("No key to check {} from {}", what, issuer); wprintln!("No key to check {} from {}", what, issuer);
self.unknown_checksums += 1; self.unknown_checksums += 1;
continue; continue;
}, },
Err(UnboundKey { cert, error, .. }) => { Err(UnboundKey { cert, error, .. }) => {
eprintln!("Signing key on {} is not bound:", wprintln!("Signing key on {} is not bound:",
cert.fingerprint()); cert.fingerprint());
print_error_chain(error); print_error_chain(error);
self.bad_checksums += 1; self.bad_checksums += 1;
continue; continue;
}, },
Err(BadKey { ka, error, .. }) => { Err(BadKey { ka, error, .. }) => {
eprintln!("Signing key on {} is bad:", wprintln!("Signing key on {} is bad:",
ka.cert().fingerprint()); ka.cert().fingerprint());
print_error_chain(error); print_error_chain(error);
self.bad_checksums += 1; self.bad_checksums += 1;
@ -526,7 +526,7 @@ impl<'a, 'store> VHelper<'a, 'store> {
0 => "checksum".into(), 0 => "checksum".into(),
n => format!("level {} notarizing checksum", n), n => format!("level {} notarizing checksum", n),
}; };
eprintln!("Error verifying {} from {}:", wprintln!("Error verifying {} from {}:",
what, issuer); what, issuer);
print_error_chain(error); print_error_chain(error);
self.bad_checksums += 1; self.bad_checksums += 1;
@ -549,7 +549,7 @@ impl<'a, 'store> VHelper<'a, 'store> {
prefix = " "; prefix = " ";
// Web of trust. // Web of trust.
eprintln!("Authenticating {} ({:?}) using the web of trust:", wprintln!("Authenticating {} ({:?}) using the web of trust:",
cert_fpr, signer_userid); cert_fpr, signer_userid);
if let Ok(Some(cert_store)) = self.config.cert_store() { if let Ok(Some(cert_store)) = self.config.cert_store() {
@ -559,7 +559,7 @@ impl<'a, 'store> VHelper<'a, 'store> {
let userids = if let Some(userid) = sig.signers_user_id() { let userids = if let Some(userid) = sig.signers_user_id() {
let userid = UserID::from(userid); let userid = UserID::from(userid);
eprintln!("{}Signature was made by {}", wprintln!("{}Signature was made by {}",
prefix, prefix,
String::from_utf8_lossy(userid.value())); String::from_utf8_lossy(userid.value()));
vec![ userid ] vec![ userid ]
@ -568,7 +568,7 @@ impl<'a, 'store> VHelper<'a, 'store> {
}; };
if userids.is_empty() { if userids.is_empty() {
eprintln!("{}{} cannot be authenticated. \ wprintln!("{}{} cannot be authenticated. \
It has no User IDs", It has no User IDs",
prefix, cert_fpr); prefix, cert_fpr);
} else if let Ok(n) = sequoia_wot::Network::new(&cert_store) { } else if let Ok(n) = sequoia_wot::Network::new(&cert_store) {
@ -588,7 +588,7 @@ impl<'a, 'store> VHelper<'a, 'store> {
let amount = paths.amount(); let amount = paths.amount();
let authenticated = if amount >= sequoia_wot::FULLY_TRUSTED { let authenticated = if amount >= sequoia_wot::FULLY_TRUSTED {
eprintln!("{}Fully authenticated \ wprintln!("{}Fully authenticated \
({} of {}) {}, {}", ({} of {}) {}, {}",
prefix, prefix,
amount, amount,
@ -597,7 +597,7 @@ impl<'a, 'store> VHelper<'a, 'store> {
userid_str); userid_str);
true true
} else if amount > 0 { } else if amount > 0 {
eprintln!("{}Partially authenticated \ wprintln!("{}Partially authenticated \
({} of {}) {}, {:?} ", ({} of {}) {}, {:?} ",
prefix, prefix,
amount, amount,
@ -606,7 +606,7 @@ impl<'a, 'store> VHelper<'a, 'store> {
userid_str); userid_str);
false false
} else { } else {
eprintln!("{}{}: {:?} is unauthenticated \ wprintln!("{}{}: {:?} is unauthenticated \
and may be an impersonation!", and may be an impersonation!",
prefix, prefix,
cert_fpr, cert_fpr,
@ -616,7 +616,7 @@ impl<'a, 'store> VHelper<'a, 'store> {
for (i, (path, amount)) in paths.iter().enumerate() { for (i, (path, amount)) in paths.iter().enumerate() {
let prefix = if paths.len() > 1 { let prefix = if paths.len() > 1 {
eprintln!("{} Path #{} of {}, \ wprintln!("{} Path #{} of {}, \
trust amount {}:", trust amount {}:",
prefix, prefix,
i + 1, paths.len(), amount); i + 1, paths.len(), amount);
@ -640,10 +640,10 @@ impl<'a, 'store> VHelper<'a, 'store> {
authenticated_userids[0].value()).to_string(); authenticated_userids[0].value()).to_string();
} }
} else { } else {
eprintln!("Failed to build web of trust network."); wprintln!("Failed to build web of trust network.");
} }
} else { } else {
eprintln!("Skipping, certificate store has been disabled"); wprintln!("Skipping, certificate store has been disabled");
} }
} }
@ -653,27 +653,27 @@ impl<'a, 'store> VHelper<'a, 'store> {
let level = sig.level(); let level = sig.level();
match (level == 0, trusted) { match (level == 0, trusted) {
(true, true) => { (true, true) => {
eprintln!("{}Good signature from {} ({:?})", wprintln!("{}Good signature from {} ({:?})",
prefix, label, signer_userid); prefix, label, signer_userid);
} }
(false, true) => { (false, true) => {
eprintln!("{}Good level {} notarization from {} ({:?})", wprintln!("{}Good level {} notarization from {} ({:?})",
prefix, level, label, signer_userid); prefix, level, label, signer_userid);
} }
(true, false) => { (true, false) => {
eprintln!("{}Unauthenticated checksum from {} ({:?})", wprintln!("{}Unauthenticated checksum from {} ({:?})",
prefix, label, signer_userid); prefix, label, signer_userid);
eprintln!("{} After checking that {} belongs to {:?}, \ wprintln!("{} After checking that {} belongs to {:?}, \
you can authenticate the binding using \ you can authenticate the binding using \
'sq link add {} {:?}'.", 'sq link add {} {:?}'.",
prefix, issuer_str, signer_userid, prefix, issuer_str, signer_userid,
issuer_str, signer_userid); issuer_str, signer_userid);
} }
(false, false) => { (false, false) => {
eprintln!("{}Unauthenticated level {} notarizing \ wprintln!("{}Unauthenticated level {} notarizing \
checksum from {} ({:?})", checksum from {} ({:?})",
prefix, level, label, signer_userid); prefix, level, label, signer_userid);
eprintln!("{} After checking that {} belongs to {:?}, \ wprintln!("{} After checking that {} belongs to {:?}, \
you can authenticate the binding using \ you can authenticate the binding using \
'sq link add {} {:?}'.", 'sq link add {} {:?}'.",
prefix, issuer_str, signer_userid, prefix, issuer_str, signer_userid,
@ -687,7 +687,7 @@ impl<'a, 'store> VHelper<'a, 'store> {
self.good_checksums += 1; self.good_checksums += 1;
} }
eprintln!(""); wprintln!("");
} }
} }
} }
@ -726,13 +726,13 @@ impl<'a, 'store> VerificationHelper for VHelper<'a, 'store> {
for layer in structure { for layer in structure {
match layer { match layer {
MessageLayer::Compression { algo } => MessageLayer::Compression { algo } =>
eprintln!("Compressed using {}", algo), wprintln!("Compressed using {}", algo),
MessageLayer::Encryption { sym_algo, aead_algo } => MessageLayer::Encryption { sym_algo, aead_algo } =>
if let Some(aead_algo) = aead_algo { if let Some(aead_algo) = aead_algo {
eprintln!("Encrypted and protected using {}/{}", wprintln!("Encrypted and protected using {}/{}",
sym_algo, aead_algo); sym_algo, aead_algo);
} else { } else {
eprintln!("Encrypted using {}", sym_algo); wprintln!("Encrypted using {}", sym_algo);
}, },
MessageLayer::SignatureGroup { ref results } => MessageLayer::SignatureGroup { ref results } =>
self.print_sigs(results), self.print_sigs(results),

View File

@ -65,16 +65,16 @@ pub fn certify(config: Config, c: certify::Command)
let userid = if let Some(userid) = u { let userid = if let Some(userid) = u {
userid userid
} else { } else {
eprintln!("User ID: '{}' not found.\nValid User IDs:", userid); wprintln!("User ID: '{}' not found.\nValid User IDs:", userid);
let mut have_valid = false; let mut have_valid = false;
for ua in vc.userids() { for ua in vc.userids() {
if let Ok(u) = std::str::from_utf8(ua.userid().value()) { if let Ok(u) = std::str::from_utf8(ua.userid().value()) {
have_valid = true; have_valid = true;
eprintln!(" - {}", u); wprintln!(" - {}", u);
} }
} }
if ! have_valid { if ! have_valid {
eprintln!(" - Certificate has no valid User IDs."); wprintln!(" - Certificate has no valid User IDs.");
} }
return Err(anyhow::format_err!("No matching User ID found")); return Err(anyhow::format_err!("No matching User ID found"));
}; };

View File

@ -215,7 +215,7 @@ impl<'a, 'certdb> Helper<'a, 'certdb> {
{ {
Some(sk) => { Some(sk) => {
if self.dump_session_key { if self.dump_session_key {
eprintln!("Session key: {}", hex::encode(&sk)); wprintln!("Session key: {}", hex::encode(&sk));
} }
Some(self.key_identities.get(&keyid).cloned()) Some(self.key_identities.get(&keyid).cloned())
}, },
@ -261,7 +261,7 @@ impl<'a, 'certdb> DecryptionHelper for Helper<'a, 'certdb> {
.any(|sa| decrypt(sa, &sk.session_key)) .any(|sa| decrypt(sa, &sk.session_key))
}; };
if decrypted { if decrypted {
eprintln!("Encrypted with Session Key {}", sk.display_sensitive()); wprintln!("Encrypted with Session Key {}", sk.display_sensitive());
return Ok(None); return Ok(None);
} }
} }
@ -303,7 +303,7 @@ impl<'a, 'certdb> DecryptionHelper for Helper<'a, 'certdb> {
match key.unlock(&p) { match key.unlock(&p) {
Ok(decryptor) => break decryptor, Ok(decryptor) => break decryptor,
Err(error) => eprintln!("Could not unlock key: {:?}", error), Err(error) => wprintln!("Could not unlock key: {:?}", error),
} }
}; };
@ -359,7 +359,7 @@ impl<'a, 'certdb> DecryptionHelper for Helper<'a, 'certdb> {
if let Ok(decryptor) = key.unlock(&p) { if let Ok(decryptor) = key.unlock(&p) {
break decryptor; break decryptor;
} else { } else {
eprintln!("Bad password."); wprintln!("Bad password.");
} }
}; };
@ -389,13 +389,13 @@ impl<'a, 'certdb> DecryptionHelper for Helper<'a, 'certdb> {
.and_then(|(algo, sk)| { if decrypt(algo, &sk) { Some(sk) } else { None }}) .and_then(|(algo, sk)| { if decrypt(algo, &sk) { Some(sk) } else { None }})
{ {
if self.dump_session_key { if self.dump_session_key {
eprintln!("Session key: {}", hex::encode(&sk)); wprintln!("Session key: {}", hex::encode(&sk));
} }
return Ok(None); return Ok(None);
} }
} }
eprintln!("Bad password."); wprintln!("Bad password.");
} }
} }
} }

View File

@ -45,7 +45,7 @@ pub fn dispatch<'store>(mut config: Config<'store>, cmd: import::Command)
let cert = match raw_cert { let cert = match raw_cert {
Ok(raw_cert) => LazyCert::from(raw_cert), Ok(raw_cert) => LazyCert::from(raw_cert),
Err(err) => { Err(err) => {
eprintln!("Error parsing input: {}", err); wprintln!("Error parsing input: {}", err);
stats.errors += 1; stats.errors += 1;
continue; continue;
} }
@ -55,12 +55,12 @@ pub fn dispatch<'store>(mut config: Config<'store>, cmd: import::Command)
let userid = best_effort_primary_uid( let userid = best_effort_primary_uid(
cert.to_cert()?, &policy, time).clone(); cert.to_cert()?, &policy, time).clone();
if let Err(err) = cert_store.update_by(Cow::Owned(cert), &mut stats) { if let Err(err) = cert_store.update_by(Cow::Owned(cert), &mut stats) {
eprintln!("Error importing {}, {:?}: {}", wprintln!("Error importing {}, {:?}: {}",
fingerprint, userid, err); fingerprint, userid, err);
stats.errors += 1; stats.errors += 1;
continue; continue;
} else { } else {
eprintln!("Imported {}, {}", fingerprint, Safe(&userid)); wprintln!("Imported {}, {}", fingerprint, Safe(&userid));
} }
} }
} }
@ -70,7 +70,7 @@ pub fn dispatch<'store>(mut config: Config<'store>, cmd: import::Command)
let result = inner(); let result = inner();
eprintln!("Imported {} new certificates, updated {} certificates, \ wprintln!("Imported {} new certificates, updated {} certificates, \
{} certificates unchanged, {} errors.", {} certificates unchanged, {} errors.",
stats.new, stats.updated, stats.unchanged, stats.errors); stats.new, stats.updated, stats.unchanged, stats.errors);

View File

@ -56,7 +56,7 @@ pub fn dispatch(config: Config, c: inspect::Command)
if let Some(path) = input.inner() { if let Some(path) = input.inner() {
if ! path.exists() && if ! path.exists() &&
format!("{}", input).parse::<KeyHandle>().is_ok() { format!("{}", input).parse::<KeyHandle>().is_ok() {
eprintln!("The file {} does not exist, \ wprintln!("The file {} does not exist, \
did you mean \"sq inspect --cert {}\"?", did you mean \"sq inspect --cert {}\"?",
input, input); input, input);
} }

View File

@ -55,7 +55,7 @@ pub fn adopt(config: Config, command: cli::key::AdoptCommand) -> Result<()>
let vc = match cert.with_policy(adoptee_policy, None) { let vc = match cert.with_policy(adoptee_policy, None) {
Ok(vc) => vc, Ok(vc) => vc,
Err(err) => { Err(err) => {
eprintln!( wprintln!(
"Ignoring {} from '{}': {}", "Ignoring {} from '{}': {}",
cert.keyid().to_hex(), cert.keyid().to_hex(),
keyring.display(), keyring.display(),

View File

@ -25,7 +25,7 @@ pub fn generate(
// User ID // User ID
if command.userid.is_empty() { if command.userid.is_empty() {
eprintln!("No user ID given, using direct key signature"); wprintln!("No user ID given, using direct key signature");
} else { } else {
for uid in command.userid { for uid in command.userid {
builder = builder.add_userid(uid); builder = builder.add_userid(uid);

View File

@ -109,14 +109,14 @@ impl<'a> SubkeyRevocation<'a> {
let rev = rev.build(&mut signer, &cert, subkey.key(), None)?; let rev = rev.build(&mut signer, &cert, subkey.key(), None)?;
Packet::Signature(rev) Packet::Signature(rev)
} else { } else {
eprintln!( wprintln!(
"Subkey {} not found.\nValid subkeys:", "Subkey {} not found.\nValid subkeys:",
keyhandle.to_spaced_hex() keyhandle.to_spaced_hex()
); );
let mut have_valid = false; let mut have_valid = false;
for k in valid_cert.keys().subkeys() { for k in valid_cert.keys().subkeys() {
have_valid = true; have_valid = true;
eprintln!( wprintln!(
" - {} {} [{:?}]", " - {} {} [{:?}]",
k.fingerprint().to_hex(), k.fingerprint().to_hex(),
DateTime::<Utc>::from(k.creation_time()).date_naive(), DateTime::<Utc>::from(k.creation_time()).date_naive(),
@ -124,7 +124,7 @@ impl<'a> SubkeyRevocation<'a> {
); );
} }
if !have_valid { if !have_valid {
eprintln!(" - Certificate has no subkeys."); wprintln!(" - Certificate has no subkeys.");
} }
return Err(anyhow!( return Err(anyhow!(
"The certificate does not contain the specified subkey." "The certificate does not contain the specified subkey."

View File

@ -89,7 +89,7 @@ impl<'a> UserIDRevocation<'a> {
.any(|u| u.value() == userid.as_bytes()); .any(|u| u.value() == userid.as_bytes());
if !present { if !present {
eprintln!( wprintln!(
"User ID, cert: Cert, secret: Option<Cert>: '{}' not found.\nValid User IDs:", "User ID, cert: Cert, secret: Option<Cert>: '{}' not found.\nValid User IDs:",
userid userid
); );
@ -97,11 +97,11 @@ impl<'a> UserIDRevocation<'a> {
for ua in valid_cert.userids() { for ua in valid_cert.userids() {
if let Ok(u) = from_utf8(ua.userid().value()) { if let Ok(u) = from_utf8(ua.userid().value()) {
have_valid = true; have_valid = true;
eprintln!(" - {}", u); wprintln!(" - {}", u);
} }
} }
if !have_valid { if !have_valid {
eprintln!(" - Certificate has no valid User IDs."); wprintln!(" - Certificate has no valid User IDs.");
} }
return Err(anyhow!( return Err(anyhow!(
"The certificate does not contain the specified User \ "The certificate does not contain the specified User \
@ -437,7 +437,7 @@ fn userid_strip(
if orig_cert_valid { if orig_cert_valid {
if let Err(err) = cert.with_policy(&config.policy, None) { if let Err(err) = cert.with_policy(&config.policy, None) {
eprintln!( wprintln!(
"Removing the User ID(s) has resulted in a invalid key: "Removing the User ID(s) has resulted in a invalid key:
{} {}

View File

@ -266,10 +266,10 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
Err(err) => { Err(err) => {
if ! args.quiet { if ! args.quiet {
if certi == 0 { if certi == 0 {
eprintln!("{:?} does not appear to be a keyring: {}", wprintln!("{:?} does not appear to be a keyring: {}",
filename, err); filename, err);
} else { } else {
eprintln!("Encountered an error parsing {:?}: {}", wprintln!("Encountered an error parsing {:?}: {}",
filename, err); filename, err);
} }
} }
@ -296,7 +296,7 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
} }
} }
if ! args.quiet { if ! args.quiet {
eprintln!($($arg)*); wprintln!($($arg)*);
} }
} }
}}; }};
@ -425,7 +425,7 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
} }
Err(err) => { Err(err) => {
unfixed_issue += 1; unfixed_issue += 1;
eprintln!("Certificate {}: \ wprintln!("Certificate {}: \
Failed to update \ Failed to update \
revocation certificate \ revocation certificate \
{:02X}{:02X}: {}", {:02X}{:02X}: {}",
@ -548,7 +548,7 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
} }
Err(err) => { Err(err) => {
unfixed_issue += 1; unfixed_issue += 1;
eprintln!("Certificate {}: User ID {}: \ wprintln!("Certificate {}: User ID {}: \
Failed to update \ Failed to update \
binding signature: {}", binding signature: {}",
cert.keyid().to_hex(), cert.keyid().to_hex(),
@ -600,7 +600,7 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
Ok(sig) => updates.push(sig), Ok(sig) => updates.push(sig),
Err(err) => { Err(err) => {
unfixed_issue += 1; unfixed_issue += 1;
eprintln!("Certificate {}, key {}: \ wprintln!("Certificate {}, key {}: \
Failed to update \ Failed to update \
binding signature: {}", binding signature: {}",
cert.keyid().to_hex(), cert.keyid().to_hex(),
@ -649,7 +649,7 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
backsigs.dedup(); backsigs.dedup();
if backsigs.len() > 1 { if backsigs.len() > 1 {
eprintln!("Warning: multiple cryptographically \ wprintln!("Warning: multiple cryptographically \
valid backsigs."); valid backsigs.");
} }
@ -688,7 +688,7 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
Ok(sig) => updates.push(sig), Ok(sig) => updates.push(sig),
Err(err) => { Err(err) => {
unfixed_issue += 1; unfixed_issue += 1;
eprintln!("Certificate {}, key: {}: \ wprintln!("Certificate {}, key: {}: \
Failed to update \ Failed to update \
binding signature: {}", binding signature: {}",
cert.keyid().to_hex(), cert.keyid().to_hex(),
@ -751,12 +751,12 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
eprint!("GOOD"); eprint!("GOOD");
} }
} }
eprintln!(")"); wprintln!(")");
}}; }};
} }
if certs_with_issues > 0 { if certs_with_issues > 0 {
eprintln!("Examined {} {}.", wprintln!("Examined {} {}.",
certs_valid + certs_invalid, certs_valid + certs_invalid,
pl(certs_valid + certs_invalid, pl(certs_valid + certs_invalid,
"certificate", "certificates")); "certificate", "certificates"));
@ -768,7 +768,7 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
pl(certs_invalid, "certificate is", "certificates are"), pl(certs_invalid, "certificate is", "certificates are"),
pl(certs_invalid, "was", "were")); pl(certs_invalid, "was", "were"));
if certs_valid > 0 { if certs_valid > 0 {
eprintln!(" {} {} linted.", wprintln!(" {} {} linted.",
certs_valid, certs_valid,
pl(certs_valid, pl(certs_valid,
"certificate was", "certificates were")); "certificate was", "certificates were"));
@ -779,7 +779,7 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
certs_valid + certs_invalid, certs_valid + certs_invalid,
certs_with_issues * 100 / (certs_valid + certs_invalid), certs_with_issues * 100 / (certs_valid + certs_invalid),
pl(certs_with_issues, "has", "have")); pl(certs_with_issues, "has", "have"));
eprintln!("{} of the linted certificates {} revoked.", wprintln!("{} of the linted certificates {} revoked.",
certs_revoked, certs_revoked,
pl(certs_revoked, "was", "were")); pl(certs_revoked, "was", "were"));
err!(certs_with_inadequota_revocations, err!(certs_with_inadequota_revocations,
@ -788,10 +788,10 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
recreated.", recreated.",
certs_with_inadequota_revocations, certs_with_inadequota_revocations,
certs_revoked); certs_revoked);
eprintln!("{} of the linted certificates {} expired.", wprintln!("{} of the linted certificates {} expired.",
certs_expired, certs_expired,
pl(certs_expired, "was", "were")); pl(certs_expired, "was", "were"));
eprintln!("{} of the non-revoked linted {} at least one non-revoked User ID:", wprintln!("{} of the non-revoked linted {} at least one non-revoked User ID:",
certs_sp_sha1_userids, certs_sp_sha1_userids,
pl(certs_sp_sha1_userids, pl(certs_sp_sha1_userids,
"certificate has", "certificates have")); "certificate has", "certificates have"));
@ -804,7 +804,7 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
certs_with_only_sha1_protected_userids, certs_with_only_sha1_protected_userids,
pl(certs_with_only_sha1_protected_userids, pl(certs_with_only_sha1_protected_userids,
"has", "have")); "has", "have"));
eprintln!("{} of the non-revoked linted certificates {} at least one \ wprintln!("{} of the non-revoked linted certificates {} at least one \
non-revoked, live subkey:", non-revoked, live subkey:",
certs_with_subkeys, certs_with_subkeys,
pl(certs_with_subkeys, pl(certs_with_subkeys,
@ -815,7 +815,7 @@ pub fn lint(config: Config, mut args: LintCommand) -> Result<()> {
certs_with_a_sha1_protected_binding_sig, certs_with_a_sha1_protected_binding_sig,
pl(certs_with_a_sha1_protected_binding_sig, pl(certs_with_a_sha1_protected_binding_sig,
"has", "have")); "has", "have"));
eprintln!("{} of the non-revoked linted certificates {} at least one non-revoked, live, \ wprintln!("{} of the non-revoked linted certificates {} at least one non-revoked, live, \
signing-capable subkey:", signing-capable subkey:",
certs_with_signing_subkeys, certs_with_signing_subkeys,
pl(certs_with_signing_subkeys, pl(certs_with_signing_subkeys,

View File

@ -157,18 +157,18 @@ pub fn check_userids(config: &Config, cert: &Cert, self_signed: bool,
if known_userids.is_empty() { if known_userids.is_empty() {
if self_signed { if self_signed {
eprintln!("{} has no self-signed User IDs.", wprintln!("{} has no self-signed User IDs.",
cert.fingerprint()); cert.fingerprint());
} else { } else {
eprintln!("{} has no known User IDs.", wprintln!("{} has no known User IDs.",
cert.fingerprint()); cert.fingerprint());
} }
} else { } else {
if self_signed { if self_signed {
eprintln!("{} has the following self-signed User IDs:", wprintln!("{} has the following self-signed User IDs:",
cert.fingerprint()); cert.fingerprint());
} else { } else {
eprintln!("{} has the following known User IDs:", wprintln!("{} has the following known User IDs:",
cert.fingerprint()); cert.fingerprint());
} }
@ -182,7 +182,7 @@ pub fn check_userids(config: &Config, cert: &Cert, self_signed: bool,
}; };
for (i, userid) in known_userids.iter().enumerate() { for (i, userid) in known_userids.iter().enumerate() {
eprintln!( wprintln!(
" {}. {:?}{}", " {}. {:?}{}",
i + 1, String::from_utf8_lossy(userid.value()), i + 1, String::from_utf8_lossy(userid.value()),
if self_signed_userids.contains(userid) { if self_signed_userids.contains(userid) {
@ -219,7 +219,7 @@ fn diff_link(old: &Signature, new: &SignatureBuilder, new_ct: SystemTime)
}; };
if a_expiration != b_expiration { if a_expiration != b_expiration {
changed = true; changed = true;
eprintln!( wprintln!(
" Updating expiration time: {} -> {}.", " Updating expiration time: {} -> {}.",
if let Some(a_expiration) = a_expiration { if let Some(a_expiration) = a_expiration {
chrono::DateTime::<chrono::offset::Utc>::from( chrono::DateTime::<chrono::offset::Utc>::from(
@ -240,12 +240,12 @@ fn diff_link(old: &Signature, new: &SignatureBuilder, new_ct: SystemTime)
if a_amount != b_amount { if a_amount != b_amount {
changed = true; changed = true;
eprintln!(" Updating trust amount: {} -> {}.", wprintln!(" Updating trust amount: {} -> {}.",
a_amount, b_amount); a_amount, b_amount);
} }
if a_depth != b_depth { if a_depth != b_depth {
changed = true; changed = true;
eprintln!(" Update trust depth: {} -> {}.", wprintln!(" Update trust depth: {} -> {}.",
a_depth, b_depth); a_depth, b_depth);
} }
@ -258,7 +258,7 @@ fn diff_link(old: &Signature, new: &SignatureBuilder, new_ct: SystemTime)
if a_regex != b_regex { if a_regex != b_regex {
changed = true; changed = true;
eprintln!(" Updating regular expressions:"); wprintln!(" Updating regular expressions:");
let a_regex: Vec<String> = a_regex.into_iter() let a_regex: Vec<String> = a_regex.into_iter()
.enumerate() .enumerate()
.map(|(i, r)| { .map(|(i, r)| {
@ -266,7 +266,7 @@ fn diff_link(old: &Signature, new: &SignatureBuilder, new_ct: SystemTime)
i + 1, String::from_utf8_lossy(r)) i + 1, String::from_utf8_lossy(r))
}) })
.collect(); .collect();
eprintln!(" Current link:\n {}", wprintln!(" Current link:\n {}",
a_regex.join("\n ")); a_regex.join("\n "));
let b_regex: Vec<String> = b_regex.into_iter() let b_regex: Vec<String> = b_regex.into_iter()
@ -276,7 +276,7 @@ fn diff_link(old: &Signature, new: &SignatureBuilder, new_ct: SystemTime)
i + 1, String::from_utf8_lossy(r)) i + 1, String::from_utf8_lossy(r))
}) })
.collect(); .collect();
eprintln!(" Updated link:\n {}", wprintln!(" Updated link:\n {}",
b_regex.join("\n ")); b_regex.join("\n "));
} }
@ -288,14 +288,14 @@ fn diff_link(old: &Signature, new: &SignatureBuilder, new_ct: SystemTime)
.collect(); .collect();
if a_notations != b_notations { if a_notations != b_notations {
changed = true; changed = true;
eprintln!(" Updating notations."); wprintln!(" Updating notations.");
let a_notations: Vec<String> = a_notations.into_iter() let a_notations: Vec<String> = a_notations.into_iter()
.enumerate() .enumerate()
.map(|(i, n)| { .map(|(i, n)| {
format!("{}. {:?}", i + 1, n) format!("{}. {:?}", i + 1, n)
}) })
.collect(); .collect();
eprintln!(" Current link:\n {}", wprintln!(" Current link:\n {}",
a_notations.join("\n ")); a_notations.join("\n "));
let b_notations: Vec<String> = b_notations.into_iter() let b_notations: Vec<String> = b_notations.into_iter()
@ -304,7 +304,7 @@ fn diff_link(old: &Signature, new: &SignatureBuilder, new_ct: SystemTime)
format!("{}. {:?}", i + 1, n) format!("{}. {:?}", i + 1, n)
}) })
.collect(); .collect();
eprintln!(" Updated link:\n {}", wprintln!(" Updated link:\n {}",
b_notations.join("\n ")); b_notations.join("\n "));
} }
@ -312,7 +312,7 @@ fn diff_link(old: &Signature, new: &SignatureBuilder, new_ct: SystemTime)
let b_exportable = new.exportable_certification().unwrap_or(true); let b_exportable = new.exportable_certification().unwrap_or(true);
if a_exportable != b_exportable { if a_exportable != b_exportable {
changed = true; changed = true;
eprintln!(" Updating exportable flag: {} -> {}.", wprintln!(" Updating exportable flag: {} -> {}.",
a_exportable, b_exportable); a_exportable, b_exportable);
} }
@ -354,12 +354,12 @@ pub fn add(mut config: Config, c: link::AddCommand)
if c.all { if c.all {
userids = vc.userids().map(|ua| ua.userid().clone()).collect(); userids = vc.userids().map(|ua| ua.userid().clone()).collect();
} else { } else {
eprintln!("No User IDs specified. \ wprintln!("No User IDs specified. \
Pass \"--all\" or one or more User IDs. \ Pass \"--all\" or one or more User IDs. \
{}'s self-signed User IDs are:", {}'s self-signed User IDs are:",
cert.fingerprint()); cert.fingerprint());
for (i, userid) in vc.userids().enumerate() { for (i, userid) in vc.userids().enumerate() {
eprintln!(" {}. {:?}", wprintln!(" {}. {:?}",
i + 1, i + 1,
String::from_utf8_lossy(userid.value())); String::from_utf8_lossy(userid.value()));
} }
@ -510,7 +510,7 @@ pub fn add(mut config: Config, c: link::AddCommand)
} }
} }
} else { } else {
eprintln!("Note: {:?} is NOT a self signed User ID. \ wprintln!("Note: {:?} is NOT a self signed User ID. \
If this was a mistake, use \ If this was a mistake, use \
`sq link retract {} \"{}\"` to undo it.", `sq link retract {} \"{}\"` to undo it.",
userid_str(), cert.fingerprint(), userid); userid_str(), cert.fingerprint(), userid);
@ -524,12 +524,12 @@ pub fn add(mut config: Config, c: link::AddCommand)
let retracted = matches!(active_certification.trust_signature(), let retracted = matches!(active_certification.trust_signature(),
Some((_depth, 0))); Some((_depth, 0)));
if retracted { if retracted {
eprintln!("{}, {} was retracted at {}.", wprintln!("{}, {} was retracted at {}.",
cert.fingerprint(), userid_str(), cert.fingerprint(), userid_str(),
chrono::DateTime::<chrono::offset::Utc>::from( chrono::DateTime::<chrono::offset::Utc>::from(
active_certification_ct)); active_certification_ct));
} else { } else {
eprintln!("{}, {} was already linked at {}.", wprintln!("{}, {} was already linked at {}.",
cert.fingerprint(), userid_str(), cert.fingerprint(), userid_str(),
chrono::DateTime::<chrono::offset::Utc>::from( chrono::DateTime::<chrono::offset::Utc>::from(
active_certification_ct)); active_certification_ct));
@ -540,13 +540,13 @@ pub fn add(mut config: Config, c: link::AddCommand)
&builders[0], config.time); &builders[0], config.time);
if ! changed && config.force { if ! changed && config.force {
eprintln!(" Link parameters are unchanged, but \ wprintln!(" Link parameters are unchanged, but \
updating anyway as \"--force\" was specified."); updating anyway as \"--force\" was specified.");
} else if c.temporary { } else if c.temporary {
eprintln!(" Creating a temporary link, \ wprintln!(" Creating a temporary link, \
which expires in a week."); which expires in a week.");
} else if ! changed { } else if ! changed {
eprintln!(" Link parameters are unchanged, no update \ wprintln!(" Link parameters are unchanged, no update \
needed (specify \"--force\" to update anyway)."); needed (specify \"--force\" to update anyway).");
// Return a signature packet to indicate that we // Return a signature packet to indicate that we
@ -554,11 +554,11 @@ pub fn add(mut config: Config, c: link::AddCommand)
// signature. // signature.
return Ok(vec![ Packet::from(userid.clone()) ]); return Ok(vec![ Packet::from(userid.clone()) ]);
} else { } else {
eprintln!(" Link parameters changed, updating link."); wprintln!(" Link parameters changed, updating link.");
} }
} }
eprintln!("Linking {} and {:?}.", wprintln!("Linking {} and {:?}.",
cert.fingerprint(), userid_str()); cert.fingerprint(), userid_str());
let mut sigs = builders.iter() let mut sigs = builders.iter()
@ -575,7 +575,7 @@ pub fn add(mut config: Config, c: link::AddCommand)
}) })
.collect::<Result<Vec<Packet>>>()?; .collect::<Result<Vec<Packet>>>()?;
eprintln!(); wprintln!();
let mut packets = vec![ Packet::from(userid.clone()) ]; let mut packets = vec![ Packet::from(userid.clone()) ];
packets.append(&mut sigs); packets.append(&mut sigs);
@ -666,7 +666,7 @@ pub fn retract(mut config: Config, c: link::RetractCommand)
.any(|issuer| issuer.aliases(&trust_root_kh)) .any(|issuer| issuer.aliases(&trust_root_kh))
}) })
{ {
eprintln!("You never linked {:?} to {}, \ wprintln!("You never linked {:?} to {}, \
no need to retract it.", no need to retract it.",
userid_str(), cert.fingerprint()); userid_str(), cert.fingerprint());
return Ok(vec![]); return Ok(vec![]);
@ -681,12 +681,12 @@ pub fn retract(mut config: Config, c: link::RetractCommand)
let retracted = matches!(active_certification.trust_signature(), let retracted = matches!(active_certification.trust_signature(),
Some((_depth, 0))); Some((_depth, 0)));
if retracted { if retracted {
eprintln!("{}, {} was already retracted at {}.", wprintln!("{}, {} was already retracted at {}.",
cert.fingerprint(), userid_str(), cert.fingerprint(), userid_str(),
chrono::DateTime::<chrono::offset::Utc>::from( chrono::DateTime::<chrono::offset::Utc>::from(
active_certification_ct)); active_certification_ct));
} else { } else {
eprintln!("{}, {} was linked at {}.", wprintln!("{}, {} was linked at {}.",
cert.fingerprint(), userid_str(), cert.fingerprint(), userid_str(),
chrono::DateTime::<chrono::offset::Utc>::from( chrono::DateTime::<chrono::offset::Utc>::from(
active_certification_ct)); active_certification_ct));
@ -697,10 +697,10 @@ pub fn retract(mut config: Config, c: link::RetractCommand)
&builder, config.time); &builder, config.time);
if ! changed && config.force { if ! changed && config.force {
eprintln!(" Link parameters are unchanged, but \ wprintln!(" Link parameters are unchanged, but \
updating anyway as \"--force\" was specified."); updating anyway as \"--force\" was specified.");
} else if ! changed { } else if ! changed {
eprintln!(" Link parameters are unchanged, no update \ wprintln!(" Link parameters are unchanged, no update \
needed (specify \"--force\" to update anyway)."); needed (specify \"--force\" to update anyway).");
// Return a signature packet to indicate that we // Return a signature packet to indicate that we
@ -708,14 +708,14 @@ pub fn retract(mut config: Config, c: link::RetractCommand)
// signature. // signature.
return Ok(vec![ Packet::from(userid.clone()) ]); return Ok(vec![ Packet::from(userid.clone()) ]);
} else { } else {
eprintln!(" Link parameters changed, updating link."); wprintln!(" Link parameters changed, updating link.");
} }
} else if config.force { } else if config.force {
eprintln!("There is no link to retract between {} and {:?}, \ wprintln!("There is no link to retract between {} and {:?}, \
retracting anyways as \"--force\" was specified.", retracting anyways as \"--force\" was specified.",
cert.fingerprint(), userid_str()); cert.fingerprint(), userid_str());
} else { } else {
eprintln!("There is no link to retract between {} and {:?} \ wprintln!("There is no link to retract between {} and {:?} \
(specify \"--force\" to mark as retracted anyways).", (specify \"--force\" to mark as retracted anyways).",
cert.fingerprint(), userid_str()); cert.fingerprint(), userid_str());
@ -725,7 +725,7 @@ pub fn retract(mut config: Config, c: link::RetractCommand)
return Ok(vec![ Packet::from(userid.clone()) ]); return Ok(vec![ Packet::from(userid.clone()) ]);
} }
eprintln!("Breaking link between {} and {:?}.", wprintln!("Breaking link between {} and {:?}.",
cert.fingerprint(), userid_str()); cert.fingerprint(), userid_str());
// XXX: If we already have exactly this signature (modulo // XXX: If we already have exactly this signature (modulo
@ -749,7 +749,7 @@ pub fn retract(mut config: Config, c: link::RetractCommand)
.collect::<Vec<Packet>>(); .collect::<Vec<Packet>>();
if certifications.is_empty() { if certifications.is_empty() {
eprintln!("Nothing to retract."); wprintln!("Nothing to retract.");
return Ok(()); return Ok(());
} }
@ -793,7 +793,7 @@ pub fn list(mut config: Config, c: link::ListCommand)
} }
if amount == 0 { if amount == 0 {
eprintln!("{}, {:?}'s link was retracted.", wprintln!("{}, {:?}'s link was retracted.",
cert.fingerprint(), cert.fingerprint(),
String::from_utf8_lossy(userid.value())); String::from_utf8_lossy(userid.value()));
} else { } else {
@ -844,9 +844,9 @@ pub fn list(mut config: Config, c: link::ListCommand)
} }
if ! params.is_empty() { if ! params.is_empty() {
eprintln!(": {}.", params.join(", ")); wprintln!(": {}.", params.join(", "));
} else { } else {
eprintln!("."); wprintln!(".");
} }
} }
} }

View File

@ -82,22 +82,22 @@ pub fn import_certs(config: &mut Config, certs: Vec<Cert>) -> Result<()> {
let mut stats let mut stats
= cert_store::store::MergePublicCollectStats::new(); = cert_store::store::MergePublicCollectStats::new();
eprintln!("\nImporting {} certificates into the certificate store:\n", wprintln!("\nImporting {} certificates into the certificate store:\n",
certs.len()); certs.len());
for (i, (fpr, userid, cert)) in certs.into_iter().enumerate() { for (i, (fpr, userid, cert)) in certs.into_iter().enumerate() {
cert_store.update_by(Cow::Owned(cert.into()), &mut stats) cert_store.update_by(Cow::Owned(cert.into()), &mut stats)
.with_context(|| format!("Inserting {}, {}", fpr, Safe(&userid)))?; .with_context(|| format!("Inserting {}, {}", fpr, Safe(&userid)))?;
eprintln!(" {}. {} {}", i + 1, fpr, Safe(&userid)); wprintln!(" {}. {} {}", i + 1, fpr, Safe(&userid));
} }
eprintln!("\nImported {} new certificates, \ wprintln!("\nImported {} new certificates, \
updated {} certificates, \ updated {} certificates, \
{} certificates unchanged, \ {} certificates unchanged, \
{} errors.", {} errors.",
stats.new, stats.updated, stats.unchanged, stats.new, stats.updated, stats.unchanged,
stats.errors); stats.errors);
eprintln!("\nAfter checking that a certificate really belongs to the \ wprintln!("\nAfter checking that a certificate really belongs to the \
stated owner, you can mark the certificate as authenticated \ stated owner, you can mark the certificate as authenticated \
using: \n\ using: \n\
\n sq link add FINGERPRINT\n"); \n sq link add FINGERPRINT\n");
@ -235,7 +235,7 @@ fn get_ca(config: &mut Config,
})?; })?;
if config.verbose { if config.verbose {
eprintln!( wprintln!(
"Created the local CA {:?} for certifying \ "Created the local CA {:?} for certifying \
certificates downloaded from this service. \ certificates downloaded from this service. \
The CA's trust amount is set to {} of {}. \ The CA's trust amount is set to {} of {}. \
@ -249,7 +249,7 @@ fn get_ca(config: &mut Config,
use std::sync::Once; use std::sync::Once;
static MSG: Once = Once::new(); static MSG: Once = Once::new();
MSG.call_once(|| { MSG.call_once(|| {
eprintln!("Note: Created a local CA to record \ wprintln!("Note: Created a local CA to record \
provenance information.\n\ provenance information.\n\
Note: See `sq link list --ca` \ Note: See `sq link list --ca` \
and `sq link --help` for more \ and `sq link --help` for more \
@ -490,12 +490,12 @@ impl Response {
certs.push(cert); certs.push(cert);
} }
}, },
Err(e) => eprintln!("{}: {}: {}", Err(e) => wprintln!("{}: {}: {}",
response.method, response.query, e), response.method, response.query, e),
} }
}, },
Err(e) => Err(e) =>
eprintln!("{}: {}: {}", response.method, response.query, e), wprintln!("{}: {}: {}", response.method, response.query, e),
} }
} }
@ -676,14 +676,14 @@ pub fn dispatch_keyserver(config: Config, c: cli::keyserver::Command)
let (url, response) = response?; let (url, response) = response?;
match response { match response {
Ok(()) => { Ok(()) => {
eprintln!("{}: ok", url); wprintln!("{}: ok", url);
one_ok = true; one_ok = true;
}, },
Err(e) => { Err(e) => {
if result.is_ok() { if result.is_ok() {
result = Err((url, e)); result = Err((url, e));
} else { } else {
eprintln!("{}: {}", url, e); wprintln!("{}: {}", url, e);
} }
}, },
} }
@ -695,7 +695,7 @@ pub fn dispatch_keyserver(config: Config, c: cli::keyserver::Command)
// error that we didn't yet report. Report that now, // error that we didn't yet report. Report that now,
// and clear it. // and clear it.
let (url, e) = result.unwrap_err(); let (url, e) = result.unwrap_err();
eprintln!("{}: {}", url, e); wprintln!("{}: {}", url, e);
result = Ok(()); result = Ok(());
} }

View File

@ -76,8 +76,8 @@ fn compare_and_write_literal<'a, 'b, 'c>(
let lp1 = normalize_literal(lp1)?; let lp1 = normalize_literal(lp1)?;
let lp2 = normalize_literal(lp2)?; let lp2 = normalize_literal(lp2)?;
eprintln!("lp1: {:?}", lp1); wprintln!("lp1: {:?}", lp1);
eprintln!("lp2: {:?}", lp2); wprintln!("lp2: {:?}", lp2);
if lp1 == lp2 { if lp1 == lp2 {
Ok((sink, ppr1, ppr2)) Ok((sink, ppr1, ppr2))

View File

@ -308,7 +308,7 @@ fn authenticate<S>(
if let Some(kh) = certificate { if let Some(kh) = certificate {
match q.network().lookup_synopses(kh) { match q.network().lookup_synopses(kh) {
Err(err) => { Err(err) => {
eprintln!("Looking up target certificate ({}): {}", wprintln!("Looking up target certificate ({}): {}",
kh, err); kh, err);
} }
Ok(certs) => { Ok(certs) => {
@ -325,7 +325,7 @@ fn authenticate<S>(
match cert.revocation_status() { match cert.revocation_status() {
RevocationStatus::Soft(_) RevocationStatus::Soft(_)
| RevocationStatus::Hard => { | RevocationStatus::Hard => {
eprintln!("Warning: {} is revoked.", kh); wprintln!("Warning: {} is revoked.", kh);
} }
RevocationStatus::NotAsFarAsWeKnow => (), RevocationStatus::NotAsFarAsWeKnow => (),
} }
@ -333,14 +333,14 @@ fn authenticate<S>(
// Check if the certificate has expired. // Check if the certificate has expired.
if let Some(e) = cert.expiration_time() { if let Some(e) = cert.expiration_time() {
if e <= q.network().reference_time() { if e <= q.network().reference_time() {
eprintln!("Warning: {} is expired.", kh); wprintln!("Warning: {} is expired.", kh);
} }
} }
// See if there is a matching self-signed User ID. // See if there is a matching self-signed User ID.
if let Some(userid) = userid { if let Some(userid) = userid {
if ! have_self_signed_userid(cert, userid, email) { if ! have_self_signed_userid(cert, userid, email) {
eprintln!("Warning: {} is not a \ wprintln!("Warning: {} is not a \
self-signed User ID for {}.", self-signed User ID for {}.",
userid, kh); userid, kh);
} }
@ -358,7 +358,7 @@ fn authenticate<S>(
}) })
}) })
{ {
eprintln!("Warning: {} has no valid \ wprintln!("Warning: {} has no valid \
certifications.", certifications.",
kh); kh);
} }
@ -377,7 +377,7 @@ fn authenticate<S>(
let userid_check = UserID::from(format!("<{}>", email)); let userid_check = UserID::from(format!("<{}>", email));
if let Ok(Some(email_check)) = userid_check.email2() { if let Ok(Some(email_check)) = userid_check.email2() {
if email == email_check { if email == email_check {
eprintln!("WARNING: {} appears to be a bare \ wprintln!("WARNING: {} appears to be a bare \
email address. Perhaps you forgot \ email address. Perhaps you forgot \
to specify --email.", to specify --email.",
email); email);
@ -392,7 +392,7 @@ fn authenticate<S>(
if q.roots().iter().all(|r| { if q.roots().iter().all(|r| {
let fpr = r.fingerprint(); let fpr = r.fingerprint();
if let Err(err) = q.network().lookup_synopsis_by_fpr(&fpr) { if let Err(err) = q.network().lookup_synopsis_by_fpr(&fpr) {
eprintln!("Looking up trust root ({}): {}.", wprintln!("Looking up trust root ({}): {}.",
fpr, err); fpr, err);
true true
} else { } else {
@ -400,16 +400,16 @@ fn authenticate<S>(
} }
}) })
{ {
eprintln!("No trust roots found."); wprintln!("No trust roots found.");
} }
} }
} }
if ! authenticated { if ! authenticated {
if ! lint_input { if ! lint_input {
eprintln!("Could not authenticate any paths."); wprintln!("Could not authenticate any paths.");
} else { } else {
eprintln!("No paths found."); wprintln!("No paths found.");
} }
std::process::exit(1); std::process::exit(1);
} }
@ -446,7 +446,7 @@ where S: wot::store::Store + wot::store::Backend<'a>
match config.output_format { match config.output_format {
#[cfg(feature = "dot-writer")] #[cfg(feature = "dot-writer")]
crate::output::OutputFormat::DOT => { crate::output::OutputFormat::DOT => {
eprintln!( wprintln!(
"DOT output for \"sq wot path\" is not yet \ "DOT output for \"sq wot path\" is not yet \
implemented!"); implemented!");
} }
@ -469,7 +469,7 @@ where S: wot::store::Store + wot::store::Backend<'a>
match config.output_format { match config.output_format {
#[cfg(feature = "dot-writer")] #[cfg(feature = "dot-writer")]
crate::output::OutputFormat::DOT => { crate::output::OutputFormat::DOT => {
eprintln!( wprintln!(
"DOT output for \"sq wot path\" is not yet \ "DOT output for \"sq wot path\" is not yet \
implemented!"); implemented!");
} }
@ -494,7 +494,7 @@ struct KeyServerUpdate {
impl StatusListener for KeyServerUpdate { impl StatusListener for KeyServerUpdate {
fn update(&self, update: &StatusUpdate) { fn update(&self, update: &StatusUpdate) {
eprintln!("{}", update); wprintln!("{}", update);
} }
} }

View File

@ -12,3 +12,13 @@ macro_rules! platform {
} }
} }
} }
/// Like eprintln, but nicely wraps lines.
macro_rules! wprintln {
{} => {
eprintln!();
};
{ $($arg: expr),* } => {
crate::output::wrapping::wprintln(format_args!($($arg),*))
};
}

View File

@ -11,6 +11,7 @@ use anyhow::{anyhow, Result};
use serde::Serialize; use serde::Serialize;
pub mod sanitize; pub mod sanitize;
pub mod wrapping;
pub use keyring::ListItem as KeyringListItem; pub use keyring::ListItem as KeyringListItem;
pub use wkd::WkdUrlVariant; pub use wkd::WkdUrlVariant;

28
src/output/wrapping.rs Normal file
View File

@ -0,0 +1,28 @@
//! Line wrapping human-readable output.
use std::fmt;
use std::sync::OnceLock;
/// Prints the given message to stderr.
///
/// Hint: Use `wprintln!(..)` instead of invoking this function
/// directly.
pub fn wprintln(msg: fmt::Arguments) {
static OPTIONS: OnceLock<textwrap::Options> = OnceLock::new();
let options = OPTIONS.get_or_init(|| {
// It is better to use terminal_size instead of letting
// textwrap do it, because textwrap uses an older version,
// leading to duplicate crates.
let width =
terminal_size::terminal_size().map(|(w, _h)| w.0)
.unwrap_or(80)
.into();
textwrap::Options::new(width)
}).clone();
let m = format!("{}", msg);
for l in textwrap::wrap(&m, options) {
eprintln!("{}", l);
}
}

View File

@ -292,7 +292,7 @@ fn decrypt_key<R>(key: Key<key::SecretParts, R>, passwords: &mut Vec<String>)
} }
} }
Err(err) => { Err(err) => {
eprintln!("While reading password: {}", err); wprintln!("While reading password: {}", err);
break; break;
} }
} }
@ -313,7 +313,7 @@ fn decrypt_key<R>(key: Key<key::SecretParts, R>, passwords: &mut Vec<String>)
#[allow(dead_code)] #[allow(dead_code)]
fn help_warning(arg: &str) { fn help_warning(arg: &str) {
if arg == "help" { if arg == "help" {
eprintln!("Warning: \"help\" is not a subcommand here. \ wprintln!("Warning: \"help\" is not a subcommand here. \
Did you mean --help?"); Did you mean --help?");
} }
} }
@ -611,11 +611,11 @@ impl<'store> Config<'store> {
} }
if checked_id { if checked_id {
eprintln!("Error: {} does not have a key with \ wprintln!("Error: {} does not have a key with \
the required capabilities ({:?})", the required capabilities ({:?})",
cert.keyid(), keyflags); cert.keyid(), keyflags);
} else { } else {
eprintln!("Error: The subkey {} (cert: {}) \ wprintln!("Error: The subkey {} (cert: {}) \
does not the required capabilities \ does not the required capabilities \
({:?})", ({:?})",
kh, cert.keyid(), keyflags); kh, cert.keyid(), keyflags);
@ -685,7 +685,7 @@ impl<'store> Config<'store> {
for userid in userid.iter() { for userid in userid.iter() {
let matches: Vec<(Fingerprint, UserID)> = if email { let matches: Vec<(Fingerprint, UserID)> = if email {
if let Err(err) = UserIDQueryParams::is_email(userid) { if let Err(err) = UserIDQueryParams::is_email(userid) {
eprintln!("{:?} is not a valid email address", userid); wprintln!("{:?} is not a valid email address", userid);
if error.is_none() { if error.is_none() {
error = Some(err); error = Some(err);
} }
@ -836,14 +836,14 @@ impl<'store> Config<'store> {
} }
}; };
eprintln!("{:?}:\n", err); wprintln!("{:?}:\n", err);
if error.is_none() { if error.is_none() {
error = Some(err); error = Some(err);
} }
// Print the errors. // Print the errors.
for (i, Entry { fpr, userid, cert }) in bad.into_iter().enumerate() { for (i, Entry { fpr, userid, cert }) in bad.into_iter().enumerate() {
eprintln!("{}. When considering {} ({}):", wprintln!("{}. When considering {} ({}):",
i + 1, fpr, i + 1, fpr,
String::from_utf8_lossy(userid.value())); String::from_utf8_lossy(userid.value()));
let err = match cert { let err = match cert {
@ -1008,7 +1008,7 @@ impl<'store> Config<'store> {
// Not found. // Not found.
Ok(None) => None, Ok(None) => None,
Err(err) => { Err(err) => {
eprintln!("Error looking up local trust root: {}", wprintln!("Error looking up local trust root: {}",
err); err);
None None
} }
@ -1020,20 +1020,20 @@ impl<'store> Config<'store> {
match parser.next() { match parser.next() {
Some(Ok(cert)) => Some(cert.fingerprint()), Some(Ok(cert)) => Some(cert.fingerprint()),
Some(Err(err)) => { Some(Err(err)) => {
eprintln!("Local trust root is \ wprintln!("Local trust root is \
corrupted: {}", corrupted: {}",
err); err);
None None
} }
None => { None => {
eprintln!("Local trust root is \ wprintln!("Local trust root is \
corrupted: no data"); corrupted: no data");
None None
} }
} }
} }
Err(err) => { Err(err) => {
eprintln!("Error parsing local trust root: {}", wprintln!("Error parsing local trust root: {}",
err); err);
None None
} }
@ -1053,7 +1053,7 @@ impl<'store> Config<'store> {
/// Prints additional information in verbose mode. /// Prints additional information in verbose mode.
fn info(&self, msg: fmt::Arguments) { fn info(&self, msg: fmt::Arguments) {
if self.verbose { if self.verbose {
eprintln!("{}", msg); wprintln!("{}", msg);
} }
} }
} }
@ -1254,6 +1254,6 @@ fn error_chain(err: &anyhow::Error) -> Vec<String> {
/// Prints the error and causes, if any. /// Prints the error and causes, if any.
pub fn print_error_chain(err: &anyhow::Error) { pub fn print_error_chain(err: &anyhow::Error) {
eprintln!(" {}", err); wprintln!(" {}", err);
err.chain().skip(1).for_each(|cause| eprintln!(" because: {}", cause)); err.chain().skip(1).for_each(|cause| wprintln!(" because: {}", cause));
} }

View File

@ -523,7 +523,7 @@ fn sq_link_update_detection() -> Result<()> {
// Make Alice a CA. // Make Alice a CA.
let output = sq_link(&certd, &alice_fpr, &[], let output = sq_link(&certd, &alice_fpr, &[],
&["--ca", "*", "--all"], true); &["--ca", "*", "--all"], true);
assert!(output.2.contains("was already linked at"), assert!(output.2.contains("was already linked"),
"stdout:\n{}\nstderr:\n{}", output.1, output.2); "stdout:\n{}\nstderr:\n{}", output.1, output.2);
let bytes = compare(bytes, &alice_cert_pgp, false); let bytes = compare(bytes, &alice_cert_pgp, false);
@ -536,7 +536,7 @@ fn sq_link_update_detection() -> Result<()> {
// Make her a partially trusted CA. // Make her a partially trusted CA.
let output = sq_link(&certd, &alice_fpr, &[], let output = sq_link(&certd, &alice_fpr, &[],
&["--amount", "30", "--all"], true); &["--amount", "30", "--all"], true);
assert!(output.2.contains("was already linked at"), assert!(output.2.contains("was already linked"),
"stdout:\n{}\nstderr:\n{}", output.1, output.2); "stdout:\n{}\nstderr:\n{}", output.1, output.2);
let bytes = compare(bytes, &alice_cert_pgp, false); let bytes = compare(bytes, &alice_cert_pgp, false);