]> mj.ucw.cz Git - misc.git/blobdiff - ucw/ddigger.c
Merge branch 'master' of git+ssh://git.ucw.cz/home/mj/GIT/misc
[misc.git] / ucw / ddigger.c
index 3df69815431118909eeb9bd06e2acf40ca4efc7f..9c158cfb655942afdc157eb0eea9e3a402aa368f 100644 (file)
@@ -15,6 +15,7 @@ static uint block_size = 1048576;
 static uint error_skip;
 static u64 start_pos;
 static u64 end_pos = ~(u64)0;
+static int show_status;
 
 struct stat_rec {
   u64 pos;
@@ -70,9 +71,28 @@ static u64 stat_have(void)
   return have;
 }
 
+static void stat_show(void)
+{
+  u64 last = 0;
+  u64 total_missing = 0;
+  for (uint i=0; i<GARY_SIZE(status); i++)
+    {
+      if (status[i].pos > last)
+       {
+         u64 miss = status[i].pos - last;
+         printf("Missing: %ju +%ju\n", (intmax_t) last, (intmax_t) miss);
+         total_missing += miss;
+       }
+      last = status[i].pos + status[i].len;
+    }
+  printf("End at %ju\n", (intmax_t) last);
+  printf("Total missing: %ju\n", (intmax_t) total_missing);
+}
+
 static struct opt_section options = {
   OPT_ITEMS {
     OPT_HELP("Usage: ddigger [options] block-device output-file status-file"),
+    OPT_HELP("   or: ddigger [options] --status - - status-file"),
     OPT_HELP(""),
     OPT_HELP("Options:"),
     OPT_HELP_OPTION,
@@ -83,6 +103,7 @@ static struct opt_section options = {
     OPT_UINT('e', "error-skip", error_skip, OPT_REQUIRED_VALUE, "<bytes>\tHow far to skip on error (default=block size)"),
     OPT_U64(0, "start", start_pos, OPT_REQUIRED_VALUE, "<bytes>\tStart position (default=beginning of device)"),
     OPT_U64(0, "end", end_pos, OPT_REQUIRED_VALUE, "<bytes>\tEnd position (default=end of device)"),
+    OPT_SWITCH(0, "status", show_status, 1, 0, "\tShow contents of status file"),
     OPT_END
   }
 };
@@ -93,6 +114,17 @@ int main(int argc UNUSED, char **argv)
   if (!error_skip)
     error_skip = block_size;
 
+  int stat_fd = ucw_open(stat_name, (show_status ? O_RDONLY : O_RDWR | O_CREAT), 0666);
+  if (stat_fd < 0)
+    die("Cannot open %s: %m", stat_name);
+  stat_read(stat_fd);
+
+  if (show_status)
+    {
+      stat_show();
+      return 0;
+    }
+
   int dev_fd = ucw_open(dev_name, O_RDONLY | O_DIRECT);
   if (dev_fd < 0)
     die("Cannot open block device %s: %m", dev_name);
@@ -110,12 +142,7 @@ int main(int argc UNUSED, char **argv)
   if (ucw_ftruncate(out_fd, dev_size) < 0)
     die("Cannot resize %s: %m", out_name);
 
-  int stat_fd = ucw_open(stat_name, O_RDWR | O_CREAT, 0666);
-  if (stat_fd < 0)
-    die("Cannot open %s: %m", stat_name);
-  stat_read(stat_fd);
   u64 remains = (end_pos - start_pos) + stat_have();
-
   ucw_seek(stat_fd, 0, SEEK_END);
   *GARY_PUSH(status) = (struct stat_rec) { .pos = end_pos, .len = 0 };