parent
35fcfc29ae
commit
b8cb988182
@ -10,11 +10,14 @@ use sequoia_openpgp as openpgp;
|
|||||||
use openpgp::{
|
use openpgp::{
|
||||||
armor::{
|
armor::{
|
||||||
Kind,
|
Kind,
|
||||||
|
ReaderMode,
|
||||||
Writer,
|
Writer,
|
||||||
},
|
},
|
||||||
packet::{Packet, Tag},
|
packet::{Packet, Tag},
|
||||||
parse::{
|
parse::{
|
||||||
|
Dearmor,
|
||||||
Parse,
|
Parse,
|
||||||
|
PacketParserBuilder,
|
||||||
PacketParserResult,
|
PacketParserResult,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -216,11 +219,11 @@ pub fn join(config: Config, c: JoinCommand) -> Result<()> {
|
|||||||
|
|
||||||
/// Writes a bit-accurate copy of all top-level packets in PPR to
|
/// Writes a bit-accurate copy of all top-level packets in PPR to
|
||||||
/// OUTPUT.
|
/// OUTPUT.
|
||||||
fn copy<'a, 'b>(config: &Config,
|
fn copy<'a, 'b, 'pp>(config: &Config,
|
||||||
mut ppr: PacketParserResult,
|
mut ppr: PacketParserResult<'pp>,
|
||||||
output: &'a FileOrStdout,
|
output: &'a FileOrStdout,
|
||||||
sink: &'b mut Option<Message<'a>>)
|
sink: &'b mut Option<Message<'a>>)
|
||||||
-> Result<()> {
|
-> Result<PacketParserResult<'pp>> {
|
||||||
while let PacketParserResult::Some(pp) = ppr {
|
while let PacketParserResult::Some(pp) = ppr {
|
||||||
if sink.is_none() {
|
if sink.is_none() {
|
||||||
// Autodetect using the first packet.
|
// Autodetect using the first packet.
|
||||||
@ -247,7 +250,56 @@ pub fn join(config: Config, c: JoinCommand) -> Result<()> {
|
|||||||
|
|
||||||
ppr = pp.next()?.1;
|
ppr = pp.next()?.1;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(ppr)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes a bit-accurate copy of all top-level packets in all
|
||||||
|
/// armored sections in the input to OUTPUT.
|
||||||
|
fn copy_all<'a, 'b>(config: &Config,
|
||||||
|
mut ppr: PacketParserResult,
|
||||||
|
output: &'a FileOrStdout,
|
||||||
|
sink: &'b mut Option<Message<'a>>)
|
||||||
|
-> Result<()>
|
||||||
|
{
|
||||||
|
// First, copy all the packets, armored or not.
|
||||||
|
ppr = copy(config, ppr, output, sink)?;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// Now, the parser is exhausted, but we may find another
|
||||||
|
// armored blob. Note that this can only happen if the
|
||||||
|
// first set of packets was also armored.
|
||||||
|
match ppr {
|
||||||
|
PacketParserResult::Some(_) =>
|
||||||
|
unreachable!("copy exhausted the packet parser"),
|
||||||
|
PacketParserResult::EOF(eof) => {
|
||||||
|
// See if there is another armor block.
|
||||||
|
let reader = eof.into_reader();
|
||||||
|
ppr = match
|
||||||
|
PacketParserBuilder::from_buffered_reader(reader)
|
||||||
|
.and_then(
|
||||||
|
|builder| builder.map(true)
|
||||||
|
.dearmor(Dearmor::Enabled(
|
||||||
|
ReaderMode::Tolerant(None)))
|
||||||
|
.build())
|
||||||
|
{
|
||||||
|
Ok(ppr) => ppr,
|
||||||
|
Err(e) => {
|
||||||
|
// There isn't, or we encountered an error.
|
||||||
|
if let Some(e) = e.downcast_ref::<io::Error>() {
|
||||||
|
if e.kind() == io::ErrorKind::UnexpectedEof {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Err(e);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// We found another armor block, copy all the packets.
|
||||||
|
ppr = copy(config, ppr, output, sink)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.input.is_empty() {
|
if !c.input.is_empty() {
|
||||||
@ -255,13 +307,13 @@ pub fn join(config: Config, c: JoinCommand) -> Result<()> {
|
|||||||
let ppr =
|
let ppr =
|
||||||
openpgp::parse::PacketParserBuilder::from_file(name)?
|
openpgp::parse::PacketParserBuilder::from_file(name)?
|
||||||
.map(true).build()?;
|
.map(true).build()?;
|
||||||
copy(&config, ppr, &output, &mut sink)?;
|
copy_all(&config, ppr, &output, &mut sink)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let ppr =
|
let ppr =
|
||||||
openpgp::parse::PacketParserBuilder::from_reader(io::stdin())?
|
openpgp::parse::PacketParserBuilder::from_reader(io::stdin())?
|
||||||
.map(true).build()?;
|
.map(true).build()?;
|
||||||
copy(&config, ppr, &output, &mut sink)?;
|
copy_all(&config, ppr, &output, &mut sink)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
sink.unwrap().finalize()?;
|
sink.unwrap().finalize()?;
|
||||||
|
Loading…
Reference in New Issue
Block a user