We already have --length (aka --limit) for limiting how far the dump
goes; the obvious counterpart is --offset (aka --skip) for controlling
where to start the dump.

I did not bother to try and print an unaligned partial first line so
that subsequent lines can be nicely aligned, but rather the dump
always starts with a full line even when it displays with unusual
offsets.

Signed-off-by: Eric Blake <ebl...@redhat.com>
---
 dump/nbddump.pod |  8 +++++++-
 dump/dump.c      | 19 ++++++++++++++++---
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/dump/nbddump.pod b/dump/nbddump.pod
index b05472fe..6acac426 100644
--- a/dump/nbddump.pod
+++ b/dump/nbddump.pod
@@ -4,7 +4,7 @@ nbddump - hexdump the content of a disk over NBD

 =head1 SYNOPSIS

- nbddump [-n N|--length N] NBD
+ nbddump [-n N|--length N] [-o N|--offset N] NBD

 C<NBD> is an NBD URI or subprocess:

@@ -103,6 +103,12 @@ if the output seems to be a terminal, and disable them if 
not.

 Dump up to I<N> bytes and then stop.

+=item B<--offset=>N
+
+=item B<-o> N
+
+Start the dump at offset I<N> bytes.
+
 =item B<-V>

 =item B<--version>
diff --git a/dump/dump.c b/dump/dump.c
index 71bedf6a..7a475196 100644
--- a/dump/dump.c
+++ b/dump/dump.c
@@ -44,6 +44,7 @@ static const char *progname;
 static struct nbd_handle *nbd;
 bool colour;
 static uint64_t limit = UINT64_MAX; /* --length (unlimited by default) */
+static uint64_t skip;               /* --offset (0 by default) */
 static int64_t size;                /* actual size */
 static bool can_meta_context;       /* did we get extent data? */

@@ -72,6 +73,7 @@ usage (FILE *fp, int exitcode)
 "    --no-color, --no-colour\n"
 "                          Suppress ANSI color even on output to terminal\n"
 "    -n LEN, --length=LEN  Truncate output after LEN bytes dumped\n"
+"    -o OFF, --offset=OFF  Skip to offset OFF bytes before dumping\n"
 "\n"
 "Other options:\n"
 "\n"
@@ -99,7 +101,7 @@ main (int argc, char *argv[])
     COLOUR_OPTION,
     NO_COLOUR_OPTION,
   };
-  const char *short_options = "n:V";
+  const char *short_options = "n:o:V";
   const struct option long_options[] = {
     { "help",               no_argument,       NULL, HELP_OPTION },
     { "long-options",       no_argument,       NULL, LONG_OPTIONS },
@@ -116,6 +118,8 @@ main (int argc, char *argv[])
     { "no-colours",         no_argument,       NULL, NO_COLOUR_OPTION },
     { "length",             required_argument, NULL, 'n' },
     { "limit",              required_argument, NULL, 'n' },
+    { "offset",             required_argument, NULL, 'o' },
+    { "skip",               required_argument, NULL, 'o' },
     { NULL }
   };
   int c;
@@ -165,6 +169,15 @@ main (int argc, char *argv[])
       }
       break;

+    case 'o':
+      /* XXX Allow human sizes here. */
+      if (sscanf (optarg, "%" SCNu64, &skip) != 1) {
+        fprintf (stderr, "%s: could not parse --offset option: %s\n",
+                 progname, optarg);
+        exit (EXIT_FAILURE);
+      }
+      break;
+
     case 'V':
       display_version ("nbddump");
       exit (EXIT_SUCCESS);
@@ -342,8 +355,8 @@ do_dump (void)
   const char *splat = colour ? "☆" : "*";
   const char *pipe = colour ? "│" : "|";
   const char *dot = colour ? "·" : ".";
-  uint64_t offset = 0;
-  uint64_t count = size > limit ? limit : size;
+  uint64_t offset = skip;
+  uint64_t count = size - offset > limit ? limit : size - offset;
   size_t i, j;
   char last[16];
   bool printed_splat = false, same;
-- 
2.48.1
_______________________________________________
Libguestfs mailing list -- guestfs@lists.libguestfs.org
To unsubscribe send an email to guestfs-le...@lists.libguestfs.org

Reply via email to