Matteo Cafasso
2016-Jul-03  21:00 UTC
[Libguestfs] [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
Matteo Cafasso
2016-Jul-03  21:00 UTC
[Libguestfs] [PATCH 1/2] filesystem_walk: more information into tsk_dirent
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
Matteo Cafasso
2016-Jul-03  21:01 UTC
[Libguestfs] [PATCH 2/2] filesystem_walk: update tests
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
Pino Toscano
2016-Jul-04  13:25 UTC
Re: [Libguestfs] [PATCH 1/2] filesystem_walk: more information into tsk_dirent
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
Pino Toscano
2016-Jul-04  13:27 UTC
Re: [Libguestfs] [PATCH 2/2] filesystem_walk: update tests
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
Possibly Parallel Threads
- [PATCH] Reserve entries to tsk_dirent struct
- Re: [PATCH 1/2] filesystem_walk: more information into tsk_dirent
- [PATCH] filesystem_walk: more information into tsk_dirent
- [PATCH v9 0/3] New API: filesystem_walk
- Re: [PATCH v8 1/3] New API: internal_filesystem_walk