Signed-off-by: Matteo Cafasso <noxdafox(a)gmail.com>
---
daemon/Makefile.am | 1 +
daemon/tsk.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++
generator/actions.ml | 13 ++++++
po/POTFILES | 1 +
src/MAX_PROC_NR | 2 +-
5 files changed, 130 insertions(+), 1 deletion(-)
create mode 100644 daemon/tsk.c
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index caba83e..4e2051b 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -179,6 +179,7 @@ guestfsd_SOURCES = \
syslinux.c \
tar.c \
truncate.c \
+ tsk.c \
umask.c \
upload.c \
utimens.c \
diff --git a/daemon/tsk.c b/daemon/tsk.c
new file mode 100644
index 0000000..647d1e7
--- /dev/null
+++ b/daemon/tsk.c
@@ -0,0 +1,114 @@
+/* libguestfs - the guestfsd daemon
+ * Copyright (C) 2016 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "guestfs_protocol.h"
+#include "daemon.h"
+#include "actions.h"
+#include "optgroups.h"
+
+static int file_out (const char *cmd);
+
+GUESTFSD_EXT_CMD(str_tsk_probe, icat);
+
+int
+optgroup_icat_available (void)
+{
+ return prog_exists (str_tsk_probe);
+}
+
+int
+do_icat (const mountable_t *mountable, int64_t inode)
+{
+ CLEANUP_FREE char *cmd = NULL;
+
+ /* Inode must be greater than 0 */
+ if (inode < 0) {
+ reply_with_error ("inode must be >= 0");
+ return -1;
+ }
+
+ /* Construct the command. */
+ if (asprintf (&cmd, "icat -r %s %" PRIi64, mountable->device, inode)
== -1) {
+ reply_with_perror ("asprintf");
+ return -1;
+ }
+
+ return file_out (cmd);
+}
+
+static int
+file_out (const char *cmd)
+{
+ int r;
+ FILE *fp;
+ CLEANUP_FREE char *buffer = NULL;
+
+ if (verbose)
+ fprintf (stderr, "%s\n", cmd);
+
+ buffer = malloc (GUESTFS_MAX_CHUNK_SIZE);
+ if (buffer == NULL) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+
+ 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: %m");
+ send_file_end (1); /* Cancel. */
+ pclose (fp);
+ return -1;
+ }
+
+ if (pclose (fp) != 0) {
+ fprintf (stderr, "pclose: %m");
+ 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 287d7f5..36d08ad 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12919,6 +12919,19 @@ within the C<$Extend> folder.
The filesystem from which to extract the file must be unmounted,
otherwise the call will fail." };
+ { defaults with
+ name = "icat"; added = (1, 33, 14);
+ style = RErr, [Mountable "device"; Int64 "inode"; FileOut
"filename"], [];
+ proc_nr = Some 464;
+ optional = Some "icat";
+ progress = true; cancellable = true;
+ shortdesc = "download a file to the local machine given its inode";
+ longdesc = "\
+Download a file given its inode from the disk partition (eg. F</dev/sda1>)
+and save it as F<filename> on the local machine.
+
+This allows to download deleted or inaccessible files." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/po/POTFILES b/po/POTFILES
index 0fb99b0..4fbc551 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -108,6 +108,7 @@ daemon/sync.c
daemon/syslinux.c
daemon/tar.c
daemon/truncate.c
+daemon/tsk.c
daemon/umask.c
daemon/upload.c
daemon/utimens.c
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 26551cf..3bb8a49 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-463
+464
--
2.7.0