1 use gpgme;
2 use structopt;
3 
4 use gpgme::{data, Context, Data, ImportFlags};
5 use std::{error::Error, fs::File, path::PathBuf};
6 use structopt::StructOpt;
7 
8 #[derive(Debug, StructOpt)]
9 struct Cli {
10     #[structopt(long)]
11     /// Import from given URLs
12     url: bool,
13     #[structopt(short = "0")]
14     /// URLS are delimited by a null
15     nul: bool,
16     #[structopt(min_values(1), parse(from_os_str))]
17     filenames: Vec<PathBuf>,
18 }
19 
main() -> Result<(), Box<dyn Error>>20 fn main() -> Result<(), Box<dyn Error>> {
21     let args = Cli::from_args();
22     let mode = if args.url {
23         if args.nul {
24             Some(data::Encoding::Url0)
25         } else {
26             Some(data::Encoding::Url)
27         }
28     } else {
29         None
30     };
31 
32     let mut ctx = Context::from_protocol(gpgme::Protocol::OpenPgp)?;
33     for file in args.filenames {
34         println!("reading file `{}'", &file.display());
35 
36         let input = File::open(file)?;
37         let mut data = Data::from_seekable_stream(input)?;
38         mode.map(|m| data.set_encoding(m));
39         print_import_result(
40             ctx.import(&mut data)
41                 .map_err(|e| format!("import failed {:?}", e))?,
42         );
43     }
44     Ok(())
45 }
46 
print_import_result(result: gpgme::ImportResult)47 fn print_import_result(result: gpgme::ImportResult) {
48     for import in result.imports() {
49         print!(
50             "  fpr: {} err: {:?} status:",
51             import.fingerprint().unwrap_or("[none]"),
52             import.result().err()
53         );
54         let status = import.status();
55         if status.contains(ImportFlags::NEW) {
56             print!(" new");
57         }
58         if status.contains(ImportFlags::UID) {
59             print!(" uid");
60         }
61         if status.contains(ImportFlags::SIG) {
62             print!(" sig");
63         }
64         if status.contains(ImportFlags::SUBKEY) {
65             print!(" subkey");
66         }
67         if status.contains(ImportFlags::SECRET) {
68             print!(" secret");
69         }
70         println!("");
71     }
72     println!("key import summary:");
73     println!("        considered: {}", result.considered());
74     println!("        no user id: {}", result.without_user_id());
75     println!("          imported: {}", result.imported());
76     println!("      imported rsa: {}", result.imported_rsa());
77     println!("         unchanged: {}", result.unchanged());
78     println!("      new user ids: {}", result.new_user_ids());
79     println!("       new subkeys: {}", result.new_subkeys());
80     println!("    new signatures: {}", result.new_signatures());
81     println!("   new revocations: {}", result.new_revocations());
82     println!("       secret read: {}", result.secret_considered());
83     println!("   secret imported: {}", result.secret_imported());
84     println!("  secret unchanged: {}", result.secret_unchanged());
85     println!("      not imported: {}", result.not_imported());
86 }
87