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