/// A command-line frontend for Sequoia.
extern crate clap;
#[macro_use]
extern crate prettytable;
extern crate rpassword;
extern crate tempfile;
extern crate crossterm;
extern crate itertools;
extern crate tokio_core;
use crossterm::terminal;
use anyhow::Context as _;
use prettytable::{Table, Cell, Row};
use std::fs::{File, OpenOptions};
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::process::exit;
use chrono::{DateTime, offset::Utc};
extern crate sequoia_openpgp as openpgp;
extern crate sequoia_core;
extern crate sequoia_net;
extern crate sequoia_store as store;
use crate::openpgp::Result;
use crate::openpgp::{armor, Cert};
use sequoia_autocrypt as autocrypt;
use crate::openpgp::fmt::hex;
use crate::openpgp::types::KeyFlags;
use crate::openpgp::parse::Parse;
use crate::openpgp::serialize::{Serialize, stream::{Message, Armorer}};
use crate::openpgp::cert::prelude::*;
use crate::openpgp::policy::StandardPolicy as P;
use sequoia_core::{Context, NetworkPolicy};
use sequoia_net::{KeyServer, wkd};
use store::{Mapping, LogIter};
mod sq_cli;
mod commands;
use commands::dump::Convert;
fn open_or_stdin(f: Option<&str>) -> Result<Box<dyn io::Read>> {
match f {
Some(f) => Ok(Box::new(File::open(f)
.context("Failed to open input file")?)),
None => Ok(Box::new(io::stdin())),
}
}
fn create_or_stdout(f: Option<&str>, force: bool)
-> Result<Box<dyn io::Write>> {
match f {
None => Ok(Box::new(io::stdout())),
Some(p) if p == "-" => Ok(Box::new(io::stdout())),
Some(f) => {
let p = Path::new(f);
if !p.exists() || force {
Ok(Box::new(OpenOptions::new()
.write(true)
.truncate(true)
.create(true)
.open(f)
.context("Failed to create output file")?))
} else {
Err(anyhow::anyhow!(
format!("File {:?} exists, use --force to overwrite", p)))
}
}
}
}
fn create_or_stdout_pgp<'a>(f: Option<&str>, force: bool,
binary: bool, kind: armor::Kind)
-> Result<Message<'a>>
{
let sink = create_or_stdout(f, force)?;
let mut message = Message::new(sink);
if ! binary {
message = Armorer::new(message).kind(kind).build()?;
}
Ok(message)
}
fn load_certs<'a, I>(files: I) -> openpgp::Result<Vec<Cert>>
where I: Iterator<Item=&'a str>
{
let mut certs = vec![];
for f in files {
certs.push(Cert::from_file(f)
.context(format!("Failed to load key from file {:?}", f))?);
}
Ok(certs)
}
/// Serializes a keyring, adding descriptive headers if armored.
fn