use std::{ env, fs::File, path::{Path, PathBuf}, process::ExitCode, }; use keyfork_shard::openpgp::{decrypt, discover_certs, openpgp::Cert, parse_messages}; type Result> = std::result::Result; fn validate<'a>( messages_file: impl AsRef, key_discovery: impl Into>, ) -> Result<(File, Vec)> { let key_discovery = key_discovery.into().map(PathBuf::from); key_discovery.as_ref().map(std::fs::metadata).transpose()?; // Load certs from path let certs = key_discovery .map(discover_certs) .transpose()? .unwrap_or(vec![]); Ok((File::open(messages_file)?, certs)) } fn run() -> Result<()> { let mut args = env::args(); let program_name = args.next().expect("program name"); let args = args.collect::>(); let (messages_file, cert_list) = match args.as_slice() { [messages_file, key_discovery] => validate(messages_file, key_discovery.as_str())?, [messages_file] => validate(messages_file, None)?, _ => panic!("Usage: {program_name} messages_file [key_discovery]"), }; let mut encrypted_messages = parse_messages(messages_file)?; let encrypted_metadata = encrypted_messages .pop_front() .expect("any pgp encrypted message"); decrypt( &cert_list, encrypted_metadata, encrypted_messages.make_contiguous(), )?; Ok(()) } fn main() -> ExitCode { let result = run(); if let Err(e) = result { eprintln!("Error: {e}"); let mut source = e.source(); while let Some(new_error) = source.take() { eprintln!("Source: {new_error}"); source = new_error.source(); } return ExitCode::FAILURE; } ExitCode::SUCCESS }