diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2018-05-03 17:28:16 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2018-05-03 17:32:32 +0200 |
commit | 371346a8e3a322a4c4990ad14ec6b78688876d3c (patch) | |
tree | a5a8bec93f2bf6fe9788308f3db1fe6203fa0bad /tool | |
parent | fb73ab393c1235d57e6e72514e89f50b24fd14ee (diff) |
tool: Extend dump to write hexdumps with maps.
Diffstat (limited to 'tool')
-rw-r--r-- | tool/src/cli.rs | 6 | ||||
-rw-r--r-- | tool/src/commands.rs | 88 | ||||
-rw-r--r-- | tool/src/main.rs | 27 |
3 files changed, 95 insertions, 26 deletions
diff --git a/tool/src/cli.rs b/tool/src/cli.rs index be98bd6a..468d2438 100644 --- a/tool/src/cli.rs +++ b/tool/src/cli.rs @@ -63,7 +63,11 @@ pub fn build() -> App<'static, 'static> { .arg(Arg::with_name("dearmor") .long("dearmor") .short("A") - .help("Remove ASCII Armor from input"))) + .help("Remove ASCII Armor from input")) + .arg(Arg::with_name("hex") + .long("hex") + .short("x") + .help("Print a hexdump"))) .subcommand(SubCommand::with_name("keyserver") .about("Interacts with keyservers") .arg(Arg::with_name("server").value_name("URI") diff --git a/tool/src/commands.rs b/tool/src/commands.rs index 2f3f3422..a4db1c85 100644 --- a/tool/src/commands.rs +++ b/tool/src/commands.rs @@ -86,3 +86,91 @@ pub fn decrypt(input: &mut io::Read, output: &mut io::Write, dump: bool) } Ok(()) } + +pub fn dump(input: &mut io::Read, output: &mut io::Write, map: bool) + -> Result<(), failure::Error> { + let mut ppo + = openpgp::parse::PacketParserBuilder::from_reader(input)? + .map(map).finalize()?; + + while let Some(mut pp) = ppo { + if let Some(ref map) = pp.map { + let mut hd = HexDumper::new(); + writeln!(output, "{}{:?}\n", + &INDENT[0..pp.recursion_depth as usize], pp.packet)?; + for (field, bytes) in map.iter() { + hd.print(bytes, field); + } + println!(); + } else { + if let openpgp::Packet::Literal(_) = pp.packet { + // XXX: We should actually stream this. In fact, + // we probably only want to print out the first + // line or so and then print the total number of + // bytes. + pp.buffer_unread_content()?; + } + writeln!(output, "{}{:?}", + &INDENT[0..pp.recursion_depth as usize], pp.packet)?; + } + + let (_, _, ppo_, _) = pp.recurse()?; + ppo = ppo_; + } + Ok(()) +} + + +struct HexDumper { + offset: usize, +} + +impl HexDumper { + fn new() -> Self { + HexDumper { + offset: 0, + } + } + + fn print(&mut self, buf: &[u8], msg: &str) { + let mut msg_printed = false; + print!("{:08x} ", self.offset); + for i in 0 .. self.offset % 16 { + if i != 7 { + print!(" "); + } else { + print!(" "); + } + } + + for c in buf { + print!("{:02x} ", c); + self.offset += 1; + match self.offset % 16 { + 0 => { + if ! msg_printed { + print!(" {}", msg); + msg_printed = true; + } + + print!("\n{:08x} ", self.offset) + }, + 8 => print!(" "), + _ => (), + } + } + + for i in self.offset % 16 .. 16 { + if i != 7 { + print!(" "); + } else { + print!(" "); + } + } + + if ! msg_printed { + print!(" {}", msg); + } + println!(); + } +} diff --git a/tool/src/main.rs b/tool/src/main.rs index 670e2398..5b14e469 100644 --- a/tool/src/main.rs +++ b/tool/src/main.rs @@ -42,10 +42,6 @@ fn create_or_stdout(f: Option<&str>) -> Result<Box<io::Write>, failure::Error> { } } -// Indent packets according to their recursion level. -const INDENT: &'static str - = " "; - fn real_main() -> Result<(), failure::Error> { let matches = cli::build().get_matches(); @@ -90,31 +86,12 @@ fn real_main() -> Result<(), failure::Error> { ("dump", Some(m)) => { let mut input = open_or_stdin(m.value_of("input"))?; let mut output = create_or_stdout(m.value_of("output"))?; - let input = if m.is_present("dearmor") { + let mut input = if m.is_present("dearmor") { Box::new(armor::Reader::new(&mut input, armor::Kind::Any)) } else { input }; - - let mut ppo - = openpgp::parse::PacketParserBuilder::from_reader(input)? - .finalize()?; - while ppo.is_some() { - let mut pp = ppo.unwrap(); - - if let openpgp::Packet::Literal(_) = pp.packet { - // XXX: We should actually stream this. In fact, - // we probably only want to print out the first - // line or so and then print the total number of - // bytes. - pp.buffer_unread_content()?; - } - writeln!(output, "{}{:?}", - &INDENT[0..pp.recursion_depth as usize], pp.packet)?; - - let (_, _, ppo_tmp, _) = pp.recurse()?; - ppo = ppo_tmp; - } + commands::dump(&mut input, &mut output, m.is_present("hex"))?; }, ("keyserver", Some(m)) => { let mut ks = if let Some(uri) = m.value_of("server") { |