Matteo Cafasso
2016-Mar-20 17:11 UTC
[Libguestfs] [PATCH] ffind API to retrieve a file name given its inode
The ffind API allows to retrieve a file name from a device given its inode. The function returns a struct "tsknode" which contains the file name, its inode and it's allocation status. The struct will be employed by other APIs as well (fls, ifind etc..). $ ./run guestfish --ro -a /home/noxdafox/disks/ubuntu.qcow2><fs> run ><fs> ffind /dev/sda1 2tsk_name: / tsk_inode: 2 tsk_allocated: 1><fs> ffind /dev/sda1 3tsk_name: /usr/bin/ tsk_inode: 3 tsk_allocated: 0 /usr/bin/ has been reallocated to node 786577><fs> mount /dev/sda1 / ><fs> stat /usr/bin/dev: 2049 ino: 786577 ... Matteo Cafasso (1): added ffind API daemon/tsk.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ generator/actions.ml | 18 ++++++++++++++++ generator/structs.ml | 14 ++++++++++-- src/MAX_PROC_NR | 2 +- 4 files changed, 91 insertions(+), 3 deletions(-) -- 2.7.0
Signed-off-by: Matteo Cafasso <noxdafox@gmail.com>
---
daemon/tsk.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
generator/actions.ml | 18 ++++++++++++++++
generator/structs.ml | 14 ++++++++++--
src/MAX_PROC_NR | 2 +-
4 files changed, 91 insertions(+), 3 deletions(-)
diff --git a/daemon/tsk.c b/daemon/tsk.c
index a00f3ee..9e1ad7e 100644
--- a/daemon/tsk.c
+++ b/daemon/tsk.c
@@ -30,6 +30,7 @@
#include "optgroups.h"
static int file_out (const char *cmd);
+static guestfs_int_tsknode* parse_ffind (const char *out, int64_t inode);
GUESTFSD_EXT_CMD(str_sleuthkit_probe, icat);
@@ -113,6 +114,65 @@ do_blkls (const mountable_t *mountable, int64_t start,
int64_t stop)
return file_out (cmd);
}
+guestfs_int_tsknode*
+do_ffind (const mountable_t *mountable, int64_t inode)
+{
+ int r;
+ char buf[32];
+ CLEANUP_FREE char *out = NULL, *err = NULL;
+
+ /* Inode must be greater than 0 */
+ if (inode < 0) {
+ reply_with_error ("inode must be >= 0");
+ return NULL;
+ }
+
+ snprintf (buf, sizeof buf, "%" PRIi64, inode);
+
+ r = command (&out, &err, "ffind", mountable->device,
buf, NULL);
+ if (r == -1) {
+ reply_with_error ("%s", err);
+ return NULL;
+ }
+
+ return parse_ffind(out, inode);
+}
+
+static guestfs_int_tsknode*
+parse_ffind (const char *out, int64_t inode)
+{
+ size_t len;
+ guestfs_int_tsknode *ret;
+
+ ret = calloc (1, sizeof *ret);
+ if (ret == NULL) {
+ reply_with_perror ("calloc");
+ return NULL;
+ }
+
+ len = strlen(out) - 1;
+ ret->tsk_inode = inode;
+
+ if STRPREFIX (out, "File name not found for inode") {
+ reply_with_error ("%ld Inode not in use", inode);
+ return NULL;
+ }
+ else if STRPREFIX (out, "* ") {
+ ret->tsk_allocated = 0;
+ ret->tsk_name = strndup (&out[2], len - 2);
+ }
+ else if STRPREFIX (out, "//") {
+ ret->tsk_allocated = 1;
+ ret->tsk_name = strndup (&out[1], len - 1);
+ }
+ else {
+ ret->tsk_allocated = 1;
+ ret->tsk_name = strndup (out, len);
+ }
+
+ return ret;
+}
+
static int
file_out (const char *cmd)
{
diff --git a/generator/actions.ml b/generator/actions.ml
index 8ecdace..e73796c 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12995,6 +12995,24 @@ The size of a data unit varies across filesystem
implementations.
On NTFS filesystems data units are referred as clusters
while on ExtX ones they are referred as fragments." };
+ { defaults with
+ name = "ffind"; added = (1, 33, 14);
+ style = RStruct ("nodeinfo", "tsknode"), [Mountable
"device"; Int64 "inode";], [];
+ proc_nr = Some 467;
+ optional = Some "sleuthkit";
+ progress = true; cancellable = true;
+ tests = [
+ InitBasicFS, Always, TestResult (
+ [["ffind"; "/dev/sdb1"; "2"]],
+ "STREQ (ret->tsk_name, \"/\") && "^
+ "ret->tsk_inode == 2 && "^
+ "ret->tsk_allocated == 1"), []
+ ];
+ shortdesc = "find the name of the file referenced by its inode";
+ longdesc = "\
+Resolves the name of a file in a disk partition (eg. F</dev/sda1>)
+given its inode." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/generator/structs.ml b/generator/structs.ml
index 6017ba6..d1fe66a 100644
--- a/generator/structs.ml
+++ b/generator/structs.ml
@@ -442,8 +442,18 @@ let structs = [
"im_device", FString;
"im_volume", FString;
];
- s_camel_name = "InternalMountable";
- };
+ s_camel_name = "InternalMountable" };
+
+ (* The Sleuth Kit node info struct. *)
+ { defaults with
+ s_name = "tsknode";
+ s_cols = [
+ "tsk_name", FString;
+ "tsk_inode", FInt64;
+ "tsk_allocated", FUInt32;
+ ];
+ s_camel_name = "TSKNode" };
+
] (* end of structs *)
let lookup_struct name diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index f27d46f..5873851 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-466
+467
--
2.7.0