logrewrap.pl 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. #!/usr/bin/perl
  2. # Process a PuTTY SSH packet log that has gone through inappropriate
  3. # line wrapping, and try to make it legible again.
  4. #
  5. # Motivation: people often include PuTTY packet logs in email
  6. # messages, and if they're not careful, the sending MUA 'helpfully'
  7. # wraps the lines at 72 characters, corrupting all the hex dumps into
  8. # total unreadability.
  9. #
  10. # But as long as it's only the ASCII part of the dump at the end of
  11. # the line that gets wrapped, and the hex part is untouched, this is a
  12. # mechanically recoverable kind of corruption, because the ASCII is
  13. # redundant and can be reconstructed from the hex. Better still, you
  14. # can spot lines in which this has happened (because the ASCII at the
  15. # end of the line is a truncated version of what we think it should
  16. # say), and use that as a cue to remove the following line.
  17. use strict;
  18. use warnings;
  19. while (<<>>) {
  20. if (/^ ([0-9a-f]{8}) ((?:[0-9a-f]{2} ){0,15}(?:[0-9a-f]{2}))/) {
  21. my $addr = $1;
  22. my $hex = $2;
  23. my $ascii = "";
  24. for (my $i = 0; $i < length($2); $i += 3) {
  25. my $byte = hex(substr($hex, $i, 2));
  26. my $char = ($byte >= 32 && $byte < 127 ? chr($byte) : ".");
  27. $ascii .= $char;
  28. }
  29. $hex = substr($hex . (" " x 48), 0, 47);
  30. my $old_line = $_;
  31. chomp($old_line);
  32. my $new_line = " $addr $hex $ascii";
  33. if ($old_line ne $new_line and
  34. $old_line eq substr($new_line, 0, length($old_line))) {
  35. print "$new_line\n";
  36. <<>>; # eat the subsequent wrapped line
  37. next;
  38. }
  39. }
  40. print $_;
  41. }