Renamed ffind API to find_inode. Renamed tsknode struct to tsk_node. Changed struct field from int64 to uint64. As pointed out on IRC it would be better to agree on some naming convention. One option would be to prefix all the forensics APIs with tsk_ as TSK (The Sleuth Kit) is the main tool used for implementing them. Other option could be giving generic names allowing us to change underlying tools without the need of deprecating the old APIs. Examples so far: * icat * tsk_icat * download_inode * blkcat * tsk_blkcat * download_blocks * blkls * tsk_blkls * download_unused_blocks * ffind * tsk_ffind * find_inode ... If we come to some final decision before the next stable release, I'll be glad to rename all the functions accordingly. Signed-off-by: Matteo Cafasso <noxdafox@gmail.com> --- daemon/tsk.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ generator/actions.ml | 20 ++++++++++++++++++ generator/structs.ml | 14 ++++++++++-- src/MAX_PROC_NR | 2 +- 4 files changed, 93 insertions(+), 3 deletions(-) diff --git a/daemon/tsk.c b/daemon/tsk.c index a00f3ee..b84dfae 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_tsk_node* 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_tsk_node* +do_find_inode (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_tsk_node* +parse_ffind (const char *out, int64_t inode) +{ + size_t len; + guestfs_int_tsk_node *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..2d291fb 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -12995,6 +12995,26 @@ 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 = "find_inode"; added = (1, 33, 14); + style = RStruct ("nodeinfo", "tsk_node"), [Mountable "device"; Int64 "inode";], []; + proc_nr = Some 467; + optional = Some "sleuthkit"; + progress = true; cancellable = true; + tests = [ + InitBasicFS, Always, TestResult ( + [["find_inode"; "/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 or directory in a disk partition (eg. F</dev/sda1>) +given its inode. + +On some filesystem, it can find deleted files." }; + ] (* Non-API meta-commands available only in guestfish. diff --git a/generator/structs.ml b/generator/structs.ml index 6017ba6..9d2f309 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 = "tsk_node"; + s_cols = [ + "tsk_name", FString; + "tsk_inode", FUInt64; + "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