summaryrefslogtreecommitdiffstats
path: root/tool
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2018-05-03 17:28:16 +0200
committerJustus Winter <justus@sequoia-pgp.org>2018-05-03 17:32:32 +0200
commit371346a8e3a322a4c4990ad14ec6b78688876d3c (patch)
treea5a8bec93f2bf6fe9788308f3db1fe6203fa0bad /tool
parentfb73ab393c1235d57e6e72514e89f50b24fd14ee (diff)
tool: Extend dump to write hexdumps with maps.
Diffstat (limited to 'tool')
-rw-r--r--tool/src/cli.rs6
-rw-r--r--tool/src/commands.rs88
-rw-r--r--tool/src/main.rs27
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") {