[Libguestfs] [PATCH] added ntfscat_i api

Matteo Cafasso noxdafox at gmail.com
Sun Feb 21 21:22:23 UTC 2016


Adding ntfscat_i command for downloading files based on their inode number.

This allows the dowload of files unaccessible otherwise from a NTFS guest disk image.

---
 daemon/ntfs.c        | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 generator/actions.ml | 15 +++++++++++++
 2 files changed, 77 insertions(+)

diff --git a/daemon/ntfs.c b/daemon/ntfs.c
index 568899e..58f62fa 100644
--- a/daemon/ntfs.c
+++ b/daemon/ntfs.c
@@ -266,3 +266,65 @@ do_ntfsfix (const char *device, int clearbadsectors)

   return 0;
 }
+
+int
+do_ntfscat_i (const mountable_t *mountable, int64_t inode)
+{
+  int r;
+  FILE *fp;
+  CLEANUP_FREE char *cmd = NULL;
+  char buffer[GUESTFS_MAX_CHUNK_SIZE];
+
+  /* Inode must be greater than 0 */
+  if (inode < 0) {
+    reply_with_error("Inode must be greater than 0");
+    return -1;
+  }
+
+  /* Construct the command. */
+  if (asprintf_nowarn (&cmd, "ntfscat -i %ld %s",
+                       inode, mountable->device) == -1) {
+    reply_with_perror ("asprintf");
+    return -1;
+  }
+
+  if (verbose)
+    fprintf (stderr, "%s\n", cmd);
+
+  fp = popen (cmd, "r");
+  if (fp == NULL) {
+    reply_with_perror ("%s", cmd);
+    return -1;
+  }
+
+  /* Now we must send the reply message, before the file contents.  After
+   * this there is no opportunity in the protocol to send any error
+   * message back.  Instead we can only cancel the transfer.
+   */
+  reply (NULL, NULL);
+
+  while ((r = fread (buffer, 1, sizeof buffer, fp)) > 0) {
+    if (send_file_write (buffer, r) < 0) {
+      pclose (fp);
+      return -1;
+    }
+  }
+
+  if (ferror (fp)) {
+    fprintf (stderr, "fread: %ld: %m\n", inode);
+    send_file_end (1);		/* Cancel. */
+    pclose (fp);
+    return -1;
+  }
+
+  if (pclose (fp) != 0) {
+    fprintf (stderr, "pclose: %ld: %m\n", inode);
+    send_file_end (1);		/* Cancel. */
+    return -1;
+  }
+
+  if (send_file_end (0))	/* Normal end of file. */
+    return -1;
+
+  return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index eb45392..18418aa 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12891,6 +12891,21 @@ This is equivalent to C<sgdisk -e>.

 See also L<sgdisk(8)>." };

+  { defaults with
+    name = "ntfscat_i"; added = (1, 33, 12);
+    style = RErr, [Mountable "device"; Int64 "inode"; FileOut "filename"], [];
+    proc_nr = Some 463;
+    progress = true; cancellable = true;
+    shortdesc = "download a file to the local machine given its inode";
+    longdesc = "\
+Download a file given its inode from a NTFS filesystem and save it as F<filename>
+on the local machine.
+
+This allows to download some otherwise unaccessible files such as the ones
+within the $Extend folder.
+
+F<filename> can also be a named pipe." };
+
 ]

 (* Non-API meta-commands available only in guestfish.
--
2.7.0




More information about the Libguestfs mailing list