summaryrefslogtreecommitdiffstats
path: root/tool/src/commands/mod.rs
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-08-27 13:14:25 +0200
committerJustus Winter <justus@sequoia-pgp.org>2019-08-27 13:14:25 +0200
commit590732819a0dd1f517f70d7c0c68189078fe1703 (patch)
tree27c9bf51ecac03e30ab48ceb8eb35d201ea5d07d /tool/src/commands/mod.rs
parent564831c89db35de29fd769d140d8d7fcdbe5e7b0 (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.rs35
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);