diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-08-27 13:14:25 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-08-27 13:14:25 +0200 |
commit | 590732819a0dd1f517f70d7c0c68189078fe1703 (patch) | |
tree | 27c9bf51ecac03e30ab48ceb8eb35d201ea5d07d /tool/src/commands/mod.rs | |
parent | 564831c89db35de29fd769d140d8d7fcdbe5e7b0 (diff) |
tool: Add 'sq packet join', the inverse to split.
- In contrast with cat, this also works on armored fragments.
- Fixes #288.
Diffstat (limited to 'tool/src/commands/mod.rs')
-rw-r--r-- | tool/src/commands/mod.rs | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/tool/src/commands/mod.rs b/tool/src/commands/mod.rs index 4593d95d..229a6854 100644 --- a/tool/src/commands/mod.rs +++ b/tool/src/commands/mod.rs @@ -402,6 +402,41 @@ pub fn split(input: &mut io::Read, prefix: &str) Ok(()) } +/// Joins the given files. +pub fn join(inputs: Option<clap::Values>, output: &mut io::Write) + -> Result<()> { + /// Writes a bit-accurate copy of all top-level packets in PPR to + /// OUTPUT. + fn copy(mut ppr: PacketParserResult, output: &mut io::Write) + -> Result<()> { + while let PacketParserResult::Some(pp) = ppr { + // We (ab)use the mapping feature to create byte-accurate + // copies. + for field in pp.map().expect("must be mapped").iter() { + output.write_all(field.data)?; + } + + ppr = pp.next()?.1; + } + Ok(()) + } + + if let Some(inputs) = inputs { + for name in inputs { + let ppr = + openpgp::parse::PacketParserBuilder::from_file(name)? + .map(true).finalize()?; + copy(ppr, output)?; + } + } else { + let ppr = + openpgp::parse::PacketParserBuilder::from_reader(io::stdin())? + .map(true).finalize()?; + copy(ppr, output)?; + } + Ok(()) +} + pub fn store_print_stats(store: &store::Store, label: &str) -> Result<()> { fn print_stamps(st: &store::Stamps) -> Result<()> { println!("{} messages using this key", st.count); |