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