[PATCH 0/2] More information reported by filesystem_walk
Report access, modification, status update and creation time in Unix format. Report number of links pointing to a given entry. If the entry is a symbolic link, report the path of its target. If the filesystem supports native/transparent compression, report compressed files with dedicated flag (DIRENT_COMPRESSED 0x04). Matteo Cafasso (2): filesystem_walk: more information into tsk_dirent filesystem_walk: update tests daemon/tsk.c | 39 +++++++++++++++++++++++++++------- generator/actions.ml | 34 ++++++++++++++++++++++++++++++ generator/structs.ml | 20 +++++++++--------- tests/tsk/test-filesystem-walk.sh | 44 +++++++++++++++++++-------------------- 4 files changed, 97 insertions(+), 40 deletions(-) -- 2.8.1
Access, modification, last status change and creation time in Unix format as for statns. Number of links pointing to a given entry. If the entry is a symbolic link, report its target path. A new flag (DIRENT_COMPRESSED 0x04) indicating whether the file is compressed using native filesystem compression support. Signed-off-by: Matteo Cafasso <noxdafox@gmail.com> --- daemon/tsk.c | 39 +++++++++++++++++++++++++++++++-------- generator/actions.ml | 34 ++++++++++++++++++++++++++++++++++ generator/structs.ml | 20 ++++++++++---------- 3 files changed, 75 insertions(+), 18 deletions(-) diff --git a/daemon/tsk.c b/daemon/tsk.c index 446213e..8657bf3 100644 --- a/daemon/tsk.c +++ b/daemon/tsk.c @@ -38,7 +38,8 @@ enum tsk_dirent_flags { DIRENT_UNALLOC = 0x00, DIRENT_ALLOC = 0x01, - DIRENT_REALLOC = 0x02 + DIRENT_REALLOC = 0x02, + DIRENT_COMPRESSED = 0x04 }; static int open_filesystem (const char *, TSK_IMG_INFO **, TSK_FS_INFO **); @@ -108,6 +109,7 @@ fswalk_callback (TSK_FS_FILE *fsfile, const char *path, void *data) { int ret = 0; CLEANUP_FREE char *fname = NULL; + CLEANUP_FREE char *flink = NULL; struct guestfs_int_tsk_dirent dirent; /* Ignore ./ and ../ */ @@ -122,20 +124,38 @@ fswalk_callback (TSK_FS_FILE *fsfile, const char *path, void *data) return TSK_WALK_ERROR; } + /* Set dirent fields */ + memset (&dirent, 0, sizeof dirent); + dirent.tsk_inode = fsfile->name->meta_addr; dirent.tsk_type = file_type (fsfile); dirent.tsk_size = (fsfile->meta != NULL) ? fsfile->meta->size : -1; dirent.tsk_name = fname; dirent.tsk_flags = file_flags (fsfile); - dirent.tsk_spare1 = dirent.tsk_spare2 = dirent.tsk_spare3 = - dirent.tsk_spare4 = dirent.tsk_spare5 = dirent.tsk_spare6 = - dirent.tsk_spare7 = dirent.tsk_spare8 = dirent.tsk_spare9 = - dirent.tsk_spare10 = dirent.tsk_spare11 = 0; + + if (fsfile->meta != NULL) { + dirent.tsk_nlink = fsfile->meta->nlink; + dirent.tsk_atime_sec = fsfile->meta->atime; + dirent.tsk_atime_nsec = fsfile->meta->atime_nano; + dirent.tsk_mtime_sec = fsfile->meta->mtime; + dirent.tsk_mtime_nsec = fsfile->meta->mtime_nano; + dirent.tsk_ctime_sec = fsfile->meta->ctime; + dirent.tsk_ctime_nsec = fsfile->meta->ctime_nano; + dirent.tsk_crtime_sec = fsfile->meta->crtime; + dirent.tsk_crtime_nsec = fsfile->meta->crtime_nano; + + ret = asprintf (&flink, "%s", fsfile->meta->link); + if (ret < 0) { + perror ("asprintf"); + return TSK_WALK_ERROR; + } + + dirent.tsk_link = flink; + } ret = send_dirent_info (&dirent); - ret = (ret == 0) ? TSK_WALK_CONT : TSK_WALK_ERROR; - return ret; + return (ret == 0) ? TSK_WALK_CONT : TSK_WALK_ERROR; } /* Inspect fsfile to identify its type. */ @@ -175,7 +195,7 @@ file_type (TSK_FS_FILE *fsfile) return 'u'; } -/* Inspect fsfile to retrieve the file allocation state. */ +/* Inspect fsfile to retrieve file allocation and compression status. */ static int file_flags (TSK_FS_FILE *fsfile) { @@ -188,6 +208,9 @@ file_flags (TSK_FS_FILE *fsfile) else flags |= DIRENT_ALLOC; + if (fsfile->meta && fsfile->meta->flags & TSK_FS_META_FLAG_COMP) + flags |= DIRENT_COMPRESSED; + return flags; } diff --git a/generator/actions.ml b/generator/actions.ml index e0931b8..1591863 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -3615,8 +3615,42 @@ This generally implies the metadata has been reallocated to a new file. Therefore, information such as file type and file size might not correspond with the ones of the original deleted entry. +=item 0x0004 + +The bit is set to C<1> when the file is compressed using filesystem +native compression support (NTFS). The API is not able to detect +application level compression. + =back +=item 'tsk_atime_sec' + +=item 'tsk_atime_nsec' + +=item 'tsk_mtime_sec' + +=item 'tsk_mtime_nsec' + +=item 'tsk_ctime_sec' + +=item 'tsk_ctime_nsec' + +=item 'tsk_crtime_sec' + +=item 'tsk_crtime_nsec' + +Respectively, access, modification, last status change and creation +time in Unix format in seconds and nanoseconds. + +=item 'tsk_nlink' + +Number of file names pointing to this entry. + +=item 'tsk_link' + +If the entry is a symbolic link, this field will contain the path +to the target file. + =back The C<tsk_type> field will contain one of the following characters: diff --git a/generator/structs.ml b/generator/structs.ml index eb8931f..029bc3a 100644 --- a/generator/structs.ml +++ b/generator/structs.ml @@ -454,17 +454,17 @@ let structs = [ "tsk_size", FInt64; "tsk_name", FString; "tsk_flags", FUInt32; + "tsk_atime_sec", FInt64; + "tsk_atime_nsec", FInt64; + "tsk_mtime_sec", FInt64; + "tsk_mtime_nsec", FInt64; + "tsk_ctime_sec", FInt64; + "tsk_ctime_nsec", FInt64; + "tsk_crtime_sec", FInt64; + "tsk_crtime_nsec", FInt64; + "tsk_nlink", FInt64; + "tsk_link", FString; "tsk_spare1", FInt64; - "tsk_spare2", FInt64; - "tsk_spare3", FInt64; - "tsk_spare4", FInt64; - "tsk_spare5", FInt64; - "tsk_spare6", FInt64; - "tsk_spare7", FInt64; - "tsk_spare8", FInt64; - "tsk_spare9", FInt64; - "tsk_spare10", FInt64; - "tsk_spare11", FInt64; ]; s_camel_name = "TSKDirent" }; -- 2.8.1
On Monday 04 July 2016 00:00:59 Matteo Cafasso wrote:
Access, modification, last status change and creation time in Unix format as for statns.
Number of links pointing to a given entry.
If the entry is a symbolic link, report its target path.
A new flag (DIRENT_COMPRESSED 0x04) indicating whether the file is compressed using native filesystem compression support.
Signed-off-by: Matteo Cafasso <noxdafox@gmail.com> --- daemon/tsk.c | 39 +++++++++++++++++++++++++++++++-------- generator/actions.ml | 34 ++++++++++++++++++++++++++++++++++ generator/structs.ml | 20 ++++++++++---------- 3 files changed, 75 insertions(+), 18 deletions(-)
diff --git a/daemon/tsk.c b/daemon/tsk.c index 446213e..8657bf3 100644 --- a/daemon/tsk.c +++ b/daemon/tsk.c @@ -38,7 +38,8 @@ enum tsk_dirent_flags { DIRENT_UNALLOC = 0x00, DIRENT_ALLOC = 0x01, - DIRENT_REALLOC = 0x02 + DIRENT_REALLOC = 0x02, + DIRENT_COMPRESSED = 0x04 };
static int open_filesystem (const char *, TSK_IMG_INFO **, TSK_FS_INFO **); @@ -108,6 +109,7 @@ fswalk_callback (TSK_FS_FILE *fsfile, const char *path, void *data) { int ret = 0; CLEANUP_FREE char *fname = NULL; + CLEANUP_FREE char *flink = NULL; struct guestfs_int_tsk_dirent dirent;
/* Ignore ./ and ../ */ @@ -122,20 +124,38 @@ fswalk_callback (TSK_FS_FILE *fsfile, const char *path, void *data) return TSK_WALK_ERROR; }
+ /* Set dirent fields */ + memset (&dirent, 0, sizeof dirent); + dirent.tsk_inode = fsfile->name->meta_addr; dirent.tsk_type = file_type (fsfile); dirent.tsk_size = (fsfile->meta != NULL) ? fsfile->meta->size : -1; dirent.tsk_name = fname; dirent.tsk_flags = file_flags (fsfile); - dirent.tsk_spare1 = dirent.tsk_spare2 = dirent.tsk_spare3 = - dirent.tsk_spare4 = dirent.tsk_spare5 = dirent.tsk_spare6 = - dirent.tsk_spare7 = dirent.tsk_spare8 = dirent.tsk_spare9 = - dirent.tsk_spare10 = dirent.tsk_spare11 = 0; + + if (fsfile->meta != NULL) { + dirent.tsk_nlink = fsfile->meta->nlink; + dirent.tsk_atime_sec = fsfile->meta->atime; + dirent.tsk_atime_nsec = fsfile->meta->atime_nano; + dirent.tsk_mtime_sec = fsfile->meta->mtime; + dirent.tsk_mtime_nsec = fsfile->meta->mtime_nano; + dirent.tsk_ctime_sec = fsfile->meta->ctime; + dirent.tsk_ctime_nsec = fsfile->meta->ctime_nano; + dirent.tsk_crtime_sec = fsfile->meta->crtime; + dirent.tsk_crtime_nsec = fsfile->meta->crtime_nano; + + ret = asprintf (&flink, "%s", fsfile->meta->link); + if (ret < 0) { + perror ("asprintf"); + return TSK_WALK_ERROR; + }
The asprintf is simply duplicating the string, so strdup can be a better (and faster) alternative. OTOH, why do you need to duplicate fsfile->meta->link at all, given that the copy will be free'd at the end of the function?
+ + dirent.tsk_link = flink; + }
Also note that NULL values for FString in structs cannot be returned in daemon calls, you need to have empty strings for the unset values.
ret = send_dirent_info (&dirent); - ret = (ret == 0) ? TSK_WALK_CONT : TSK_WALK_ERROR;
- return ret; + return (ret == 0) ? TSK_WALK_CONT : TSK_WALK_ERROR;
Unrelated change.
}
/* Inspect fsfile to identify its type. */ @@ -175,7 +195,7 @@ file_type (TSK_FS_FILE *fsfile) return 'u'; }
-/* Inspect fsfile to retrieve the file allocation state. */ +/* Inspect fsfile to retrieve file allocation and compression status. */ static int file_flags (TSK_FS_FILE *fsfile) { @@ -188,6 +208,9 @@ file_flags (TSK_FS_FILE *fsfile) else flags |= DIRENT_ALLOC;
+ if (fsfile->meta && fsfile->meta->flags & TSK_FS_META_FLAG_COMP) + flags |= DIRENT_COMPRESSED; + return flags; }
diff --git a/generator/actions.ml b/generator/actions.ml index e0931b8..1591863 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -3615,8 +3615,42 @@ This generally implies the metadata has been reallocated to a new file. Therefore, information such as file type and file size might not correspond with the ones of the original deleted entry.
+=item 0x0004 + +The bit is set to C<1> when the file is compressed using filesystem +native compression support (NTFS). The API is not able to detect +application level compression. + =back
+=item 'tsk_atime_sec' + +=item 'tsk_atime_nsec' + +=item 'tsk_mtime_sec' + +=item 'tsk_mtime_nsec' + +=item 'tsk_ctime_sec' + +=item 'tsk_ctime_nsec' + +=item 'tsk_crtime_sec' + +=item 'tsk_crtime_nsec' + +Respectively, access, modification, last status change and creation +time in Unix format in seconds and nanoseconds. + +=item 'tsk_nlink' + +Number of file names pointing to this entry. + +=item 'tsk_link' + +If the entry is a symbolic link, this field will contain the path +to the target file. + =back
The C<tsk_type> field will contain one of the following characters: diff --git a/generator/structs.ml b/generator/structs.ml index eb8931f..029bc3a 100644 --- a/generator/structs.ml +++ b/generator/structs.ml @@ -454,17 +454,17 @@ let structs = [ "tsk_size", FInt64; "tsk_name", FString; "tsk_flags", FUInt32; + "tsk_atime_sec", FInt64; + "tsk_atime_nsec", FInt64; + "tsk_mtime_sec", FInt64; + "tsk_mtime_nsec", FInt64; + "tsk_ctime_sec", FInt64; + "tsk_ctime_nsec", FInt64; + "tsk_crtime_sec", FInt64; + "tsk_crtime_nsec", FInt64; + "tsk_nlink", FInt64; + "tsk_link", FString; "tsk_spare1", FInt64; - "tsk_spare2", FInt64; - "tsk_spare3", FInt64; - "tsk_spare4", FInt64; - "tsk_spare5", FInt64; - "tsk_spare6", FInt64; - "tsk_spare7", FInt64; - "tsk_spare8", FInt64; - "tsk_spare9", FInt64; - "tsk_spare10", FInt64; - "tsk_spare11", FInt64; ]; s_camel_name = "TSKDirent" };
-- 2.8.1
_______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
-- Pino Toscano
On 04/07/16 16:25, Pino Toscano wrote:
Access, modification, last status change and creation time in Unix format as for statns.
Number of links pointing to a given entry.
If the entry is a symbolic link, report its target path.
A new flag (DIRENT_COMPRESSED 0x04) indicating whether the file is compressed using native filesystem compression support.
Signed-off-by: Matteo Cafasso <noxdafox@gmail.com> --- daemon/tsk.c | 39 +++++++++++++++++++++++++++++++-------- generator/actions.ml | 34 ++++++++++++++++++++++++++++++++++ generator/structs.ml | 20 ++++++++++---------- 3 files changed, 75 insertions(+), 18 deletions(-)
diff --git a/daemon/tsk.c b/daemon/tsk.c index 446213e..8657bf3 100644 --- a/daemon/tsk.c +++ b/daemon/tsk.c @@ -38,7 +38,8 @@ enum tsk_dirent_flags { DIRENT_UNALLOC = 0x00, DIRENT_ALLOC = 0x01, - DIRENT_REALLOC = 0x02 + DIRENT_REALLOC = 0x02, + DIRENT_COMPRESSED = 0x04 };
static int open_filesystem (const char *, TSK_IMG_INFO **, TSK_FS_INFO **); @@ -108,6 +109,7 @@ fswalk_callback (TSK_FS_FILE *fsfile, const char *path, void *data) { int ret = 0; CLEANUP_FREE char *fname = NULL; + CLEANUP_FREE char *flink = NULL; struct guestfs_int_tsk_dirent dirent;
/* Ignore ./ and ../ */ @@ -122,20 +124,38 @@ fswalk_callback (TSK_FS_FILE *fsfile, const char *path, void *data) return TSK_WALK_ERROR; }
+ /* Set dirent fields */ + memset (&dirent, 0, sizeof dirent); + dirent.tsk_inode = fsfile->name->meta_addr; dirent.tsk_type = file_type (fsfile); dirent.tsk_size = (fsfile->meta != NULL) ? fsfile->meta->size : -1; dirent.tsk_name = fname; dirent.tsk_flags = file_flags (fsfile); - dirent.tsk_spare1 = dirent.tsk_spare2 = dirent.tsk_spare3 = - dirent.tsk_spare4 = dirent.tsk_spare5 = dirent.tsk_spare6 = - dirent.tsk_spare7 = dirent.tsk_spare8 = dirent.tsk_spare9 = - dirent.tsk_spare10 = dirent.tsk_spare11 = 0; + + if (fsfile->meta != NULL) { + dirent.tsk_nlink = fsfile->meta->nlink; + dirent.tsk_atime_sec = fsfile->meta->atime; + dirent.tsk_atime_nsec = fsfile->meta->atime_nano; + dirent.tsk_mtime_sec = fsfile->meta->mtime; + dirent.tsk_mtime_nsec = fsfile->meta->mtime_nano; + dirent.tsk_ctime_sec = fsfile->meta->ctime; + dirent.tsk_ctime_nsec = fsfile->meta->ctime_nano; + dirent.tsk_crtime_sec = fsfile->meta->crtime; + dirent.tsk_crtime_nsec = fsfile->meta->crtime_nano; + + ret = asprintf (&flink, "%s", fsfile->meta->link); + if (ret < 0) { + perror ("asprintf"); + return TSK_WALK_ERROR; + } The asprintf is simply duplicating the string, so strdup can be a better (and faster) alternative. OTOH, why do you need to duplicate fsfile->meta->link at all, given
On Monday 04 July 2016 00:00:59 Matteo Cafasso wrote: that the copy will be free'd at the end of the function? Was not sure what to return in case of NULL value and asprintf was "nicely" replacing it with a (null) string. If empty string is the way I'll fix it then.
Will fix the rest as well.
+ + dirent.tsk_link = flink; + } Also note that NULL values for FString in structs cannot be returned in daemon calls, you need to have empty strings for the unset values.
ret = send_dirent_info (&dirent); - ret = (ret == 0) ? TSK_WALK_CONT : TSK_WALK_ERROR;
- return ret; + return (ret == 0) ? TSK_WALK_CONT : TSK_WALK_ERROR;
Unrelated change.
}
/* Inspect fsfile to identify its type. */ @@ -175,7 +195,7 @@ file_type (TSK_FS_FILE *fsfile) return 'u'; }
-/* Inspect fsfile to retrieve the file allocation state. */ +/* Inspect fsfile to retrieve file allocation and compression status. */ static int file_flags (TSK_FS_FILE *fsfile) { @@ -188,6 +208,9 @@ file_flags (TSK_FS_FILE *fsfile) else flags |= DIRENT_ALLOC;
+ if (fsfile->meta && fsfile->meta->flags & TSK_FS_META_FLAG_COMP) + flags |= DIRENT_COMPRESSED; + return flags; }
diff --git a/generator/actions.ml b/generator/actions.ml index e0931b8..1591863 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -3615,8 +3615,42 @@ This generally implies the metadata has been reallocated to a new file. Therefore, information such as file type and file size might not correspond with the ones of the original deleted entry.
+=item 0x0004 + +The bit is set to C<1> when the file is compressed using filesystem +native compression support (NTFS). The API is not able to detect +application level compression. + =back
+=item 'tsk_atime_sec' + +=item 'tsk_atime_nsec' + +=item 'tsk_mtime_sec' + +=item 'tsk_mtime_nsec' + +=item 'tsk_ctime_sec' + +=item 'tsk_ctime_nsec' + +=item 'tsk_crtime_sec' + +=item 'tsk_crtime_nsec' + +Respectively, access, modification, last status change and creation +time in Unix format in seconds and nanoseconds. + +=item 'tsk_nlink' + +Number of file names pointing to this entry. + +=item 'tsk_link' + +If the entry is a symbolic link, this field will contain the path +to the target file. + =back
The C<tsk_type> field will contain one of the following characters: diff --git a/generator/structs.ml b/generator/structs.ml index eb8931f..029bc3a 100644 --- a/generator/structs.ml +++ b/generator/structs.ml @@ -454,17 +454,17 @@ let structs = [ "tsk_size", FInt64; "tsk_name", FString; "tsk_flags", FUInt32; + "tsk_atime_sec", FInt64; + "tsk_atime_nsec", FInt64; + "tsk_mtime_sec", FInt64; + "tsk_mtime_nsec", FInt64; + "tsk_ctime_sec", FInt64; + "tsk_ctime_nsec", FInt64; + "tsk_crtime_sec", FInt64; + "tsk_crtime_nsec", FInt64; + "tsk_nlink", FInt64; + "tsk_link", FString; "tsk_spare1", FInt64; - "tsk_spare2", FInt64; - "tsk_spare3", FInt64; - "tsk_spare4", FInt64; - "tsk_spare5", FInt64; - "tsk_spare6", FInt64; - "tsk_spare7", FInt64; - "tsk_spare8", FInt64; - "tsk_spare9", FInt64; - "tsk_spare10", FInt64; - "tsk_spare11", FInt64; ]; s_camel_name = "TSKDirent" };
-- 2.8.1
_______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
_______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Signed-off-by: Matteo Cafasso <noxdafox@gmail.com> --- tests/tsk/test-filesystem-walk.sh | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/tsk/test-filesystem-walk.sh b/tests/tsk/test-filesystem-walk.sh index 6ee3f71..d0f0df6 100755 --- a/tests/tsk/test-filesystem-walk.sh +++ b/tests/tsk/test-filesystem-walk.sh @@ -51,17 +51,17 @@ tsk_type: r tsk_size: .* tsk_name: \$MFT tsk_flags: 1 -tsk_spare1: 0 -tsk_spare2: 0 -tsk_spare3: 0 -tsk_spare4: 0 -tsk_spare5: 0 -tsk_spare6: 0 -tsk_spare7: 0 -tsk_spare8: 0 -tsk_spare9: 0 -tsk_spare10: 0 -tsk_spare11: 0 }' +tsk_atime_sec: .* +tsk_atime_nsec: .* +tsk_mtime_sec: .* +tsk_mtime_nsec: .* +tsk_ctime_sec: .* +tsk_ctime_nsec: .* +tsk_crtime_sec: .* +tsk_crtime_nsec: .* +tsk_nlink: 1 +tsk_link: .*; +tsk_spare1: 0 }' if [ $? != 0 ]; then echo "$0: \$MFT not found in files list." echo "File list:" @@ -75,17 +75,17 @@ tsk_type: [ru] tsk_size: .* tsk_name: test.txt tsk_flags: 0 -tsk_spare1: 0 -tsk_spare2: 0 -tsk_spare3: 0 -tsk_spare4: 0 -tsk_spare5: 0 -tsk_spare6: 0 -tsk_spare7: 0 -tsk_spare8: 0 -tsk_spare9: 0 -tsk_spare10: 0 -tsk_spare11: 0 }' +tsk_atime_sec: .* +tsk_atime_nsec: .* +tsk_mtime_sec: .* +tsk_mtime_nsec: .* +tsk_ctime_sec: .* +tsk_ctime_nsec: .* +tsk_crtime_sec: .* +tsk_crtime_nsec: .* +tsk_nlink: .* +tsk_link: .*; +tsk_spare1: 0 }' if [ $? != 0 ]; then echo "$0: /test.txt not found in files list." echo "File list:" -- 2.8.1
On Monday 04 July 2016 00:01:00 Matteo Cafasso wrote:
Signed-off-by: Matteo Cafasso <noxdafox@gmail.com> --- tests/tsk/test-filesystem-walk.sh | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-)
This must be together with patch #1: testing patch #1 without this breaks the test suite. -- Pino Toscano
participants (3)
-
Matteo Cafasso -
noxdafox -
Pino Toscano