From 7e63a47fcd3fb7022019d3425472d800b9483f37 Mon Sep 17 00:00:00 2001
From: Brian Carrier <carrier@sleuthkit.org>
Date: Sun, 3 May 2009 23:06:12 +0000
Subject: [PATCH] Abstracted name comparison to file system specific function.

---
 CHANGES.txt            |  1 +
 tsk3/fs/ext2fs.c       |  1 +
 tsk3/fs/fatfs.c        |  1 +
 tsk3/fs/fatfs_dent.c   |  6 +++++
 tsk3/fs/ffs.c          |  1 +
 tsk3/fs/fs_attr.c      |  2 +-
 tsk3/fs/hfs.c          |  1 +
 tsk3/fs/hfs_dent.c     | 13 ++++++++--
 tsk3/fs/ifind_lib.c    | 57 ++++++++++--------------------------------
 tsk3/fs/iso9660.c      |  1 +
 tsk3/fs/iso9660_dent.c |  6 +++++
 tsk3/fs/nofs_misc.c    |  7 ++++++
 tsk3/fs/ntfs.c         |  1 +
 tsk3/fs/ntfs_dent.c    |  7 ++++++
 tsk3/fs/rawfs.c        |  1 +
 tsk3/fs/swapfs.c       |  1 +
 tsk3/fs/tsk_fatfs.h    |  2 ++
 tsk3/fs/tsk_fs.h       |  2 ++
 tsk3/fs/tsk_fs_i.h     |  5 +++-
 tsk3/fs/tsk_hfs.h      |  5 ++--
 tsk3/fs/tsk_iso9660.h  |  2 ++
 tsk3/fs/tsk_ntfs.h     |  2 ++
 tsk3/fs/unix_misc.c    |  7 ++++++
 23 files changed, 82 insertions(+), 50 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index fef021335..48f1f11a5 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -92,6 +92,7 @@ needing other image format  libraries.
 4/29/09: Bug Fix: Added the READ_SHARE option to the CreateFile command
 for split image files.  Patch by Christopher Siwy. 
 
+5/3/09: Update: Abstracted name comparison to file system-specific function.
 
 ---------------- VERSION 3.0.0 -------------- 
 0/00/00: Update: Many, many, many API changes.
diff --git a/tsk3/fs/ext2fs.c b/tsk3/fs/ext2fs.c
index 86dd77460..e2e9634c9 100644
--- a/tsk3/fs/ext2fs.c
+++ b/tsk3/fs/ext2fs.c
@@ -2193,6 +2193,7 @@ ext2fs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
     fs->fsstat = ext2fs_fsstat;
     fs->fscheck = ext2fs_fscheck;
     fs->istat = ext2fs_istat;
+    fs->name_cmp = tsk_fs_unix_name_cmp;
     fs->close = ext2fs_close;
 
 
diff --git a/tsk3/fs/fatfs.c b/tsk3/fs/fatfs.c
index 18cc02122..118ce5341 100644
--- a/tsk3/fs/fatfs.c
+++ b/tsk3/fs/fatfs.c
@@ -1681,6 +1681,7 @@ fatfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
     fs->load_attrs = fatfs_make_data_run;
 
     fs->dir_open_meta = fatfs_dir_open_meta;
+    fs->name_cmp = fatfs_name_cmp;
 
     fs->fsstat = fatfs_fsstat;
     fs->fscheck = fatfs_fscheck;
diff --git a/tsk3/fs/fatfs_dent.c b/tsk3/fs/fatfs_dent.c
index 15d5d7bdb..22b573576 100644
--- a/tsk3/fs/fatfs_dent.c
+++ b/tsk3/fs/fatfs_dent.c
@@ -748,3 +748,9 @@ fatfs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
 
     return retval;
 }
+
+int
+fatfs_name_cmp(TSK_FS_INFO * a_fs_info, const char *s1, const char *s2)
+{
+    return strcasecmp(s1, s2);
+}
diff --git a/tsk3/fs/ffs.c b/tsk3/fs/ffs.c
index b6078d85a..6df6df319 100644
--- a/tsk3/fs/ffs.c
+++ b/tsk3/fs/ffs.c
@@ -2096,6 +2096,7 @@ ffs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset, TSK_FS_TYPE_ENUM ftype)
 
     fs->get_default_attr_type = tsk_fs_unix_get_default_attr_type;
     fs->load_attrs = tsk_fs_unix_make_data_run;
+    fs->name_cmp = tsk_fs_unix_name_cmp;
 
     fs->file_add_meta = ffs_inode_lookup;
     fs->dir_open_meta = ffs_dir_open_meta;
diff --git a/tsk3/fs/fs_attr.c b/tsk3/fs/fs_attr.c
index e5b443b04..15b0830fc 100644
--- a/tsk3/fs/fs_attr.c
+++ b/tsk3/fs/fs_attr.c
@@ -1037,7 +1037,7 @@ tsk_fs_attr_read(const TSK_FS_ATTR * a_fs_attr, TSK_OFF_T a_offset,
         }
 
         if (a_offset + a_len > a_fs_attr->size)
-            read_len = (size_t)(a_fs_attr->size - a_offset);
+            read_len = (size_t) (a_fs_attr->size - a_offset);
         else
             read_len = a_len;
 
diff --git a/tsk3/fs/hfs.c b/tsk3/fs/hfs.c
index 845b0586f..494336481 100644
--- a/tsk3/fs/hfs.c
+++ b/tsk3/fs/hfs.c
@@ -3106,6 +3106,7 @@ hfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
     fs->jblk_walk = hfs_jblk_walk;
     fs->jentry_walk = hfs_jentry_walk;
     fs->jopen = hfs_jopen;
+    fs->name_cmp = hfs_name_cmp;
     fs->journ_inum = 0;
 
     return fs;
diff --git a/tsk3/fs/hfs_dent.c b/tsk3/fs/hfs_dent.c
index 48020d973..9d9fada4c 100644
--- a/tsk3/fs/hfs_dent.c
+++ b/tsk3/fs/hfs_dent.c
@@ -204,8 +204,7 @@ hfs_dir_open_meta_cb(HFS_INFO * hfs, int8_t level_type,
                 cur_key->parent_cnid) > *cnid_p)
             return HFS_BTREE_CB_LEAF_STOP;
 
-        rec_off2 =
-            2 + tsk_getu16(hfs->fs_info.endian, cur_key->key_len);
+        rec_off2 = 2 + tsk_getu16(hfs->fs_info.endian, cur_key->key_len);
         // @@@ NEED TO REPLACE THIS SOMEHOW, but need to figure out the max length
         /*
            if (rec_off2 > nodesize) {
@@ -422,3 +421,13 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
     tsk_fs_name_free(fs_name);
     return TSK_OK;
 }
+
+int
+hfs_name_cmp(TSK_FS_INFO * a_fs_info, const char *s1, const char *s2)
+{
+    HFS_INFO *hfs = (HFS_INFO *) a_fs_info;
+    if (hfs->is_case_sensitive)
+        return strcmp(s1, s2);
+    else
+        return strcasecmp(s1, s2);
+}
diff --git a/tsk3/fs/ifind_lib.c b/tsk3/fs/ifind_lib.c
index ac3164d77..bbfadbaec 100644
--- a/tsk3/fs/ifind_lib.c
+++ b/tsk3/fs/ifind_lib.c
@@ -247,29 +247,19 @@ tsk_fs_path2inum(TSK_FS_INFO * a_fs, const char *a_path,
                 return -1;
             }
 
-            // @@@ It seems that we could abstract this and have a name comparison
-            // function for each file system that hides the case sensitive details...
             /* 
              * Check if this is the name that we are currently looking for,
              * as identified in 'cur_dir'
              */
-            if (TSK_FS_TYPE_ISFFS(a_fs->ftype)
-                || TSK_FS_TYPE_ISEXT(a_fs->ftype)) {
+            /* FAT is a special case because we check the short name */
+            if (TSK_FS_TYPE_ISFAT(a_fs->ftype)) {
                 if ((fs_file->name->name)
-                    && (strcmp(fs_file->name->name, cur_dir) == 0)) {
-                    found_name = 1;
-                }
-            }
-            /* FAT is a special case because we do case insensitive and we check
-             * the short name 
-             */
-            else if (TSK_FS_TYPE_ISFAT(a_fs->ftype)) {
-                if ((fs_file->name->name)
-                    && (strcasecmp(fs_file->name->name, cur_dir) == 0)) {
+                    && (a_fs->name_cmp(a_fs, fs_file->name->name,
+                            cur_dir) == 0)) {
                     found_name = 1;
                 }
                 else if ((fs_file->name->shrt_name)
-                    && (strcasecmp(fs_file->name->shrt_name,
+                    && (a_fs->name_cmp(a_fs, fs_file->name->shrt_name,
                             cur_dir) == 0)) {
                     found_name = 1;
                 }
@@ -278,7 +268,8 @@ tsk_fs_path2inum(TSK_FS_INFO * a_fs, const char *a_path,
             /* NTFS gets a case insensitive comparison */
             else if (TSK_FS_TYPE_ISNTFS(a_fs->ftype)) {
                 if ((fs_file->name->name)
-                    && (strcasecmp(fs_file->name->name, cur_dir) == 0)) {
+                    && (a_fs->name_cmp(a_fs, fs_file->name->name,
+                            cur_dir) == 0)) {
                     /*  ensure we have the right attribute name */
                     if (cur_attr == NULL) {
                         found_name = 1;
@@ -296,7 +287,7 @@ tsk_fs_path2inum(TSK_FS_INFO * a_fs, const char *a_path,
                                     continue;
 
                                 if ((fs_attr->name)
-                                    && (strcasecmp(fs_attr->name,
+                                    && (a_fs->name_cmp(a_fs, fs_attr->name,
                                             cur_attr) == 0)) {
                                     found_name = 1;
                                 }
@@ -305,34 +296,12 @@ tsk_fs_path2inum(TSK_FS_INFO * a_fs, const char *a_path,
                     }
                 }
             }
-
-            /* HFS+ can be case-sensitive or case-insensitive */
-            else if (TSK_FS_TYPE_ISHFS(a_fs->ftype)) {
-                HFS_INFO *hfs = (HFS_INFO *) a_fs;
-                if (hfs->is_case_sensitive) {
-                    if ((fs_file->name->name)
-                        && (strcmp(fs_file->name->name, cur_dir) == 0)) {
-                        found_name = 1;
-                    }
-                }
-                else {
-                    if ((fs_file->name->name)
-                        && (strcasecmp(fs_file->name->name,
-                                cur_dir) == 0)) {
-                        found_name = 1;
-                    }
-                }
-            }
-
-            /* Unknown how to compare names in this filesystem */
             else {
-                tsk_fs_dir_close(fs_dir);
-                free(cpath);
-                tsk_errno = TSK_ERR_FS_GENFS;
-                snprintf(tsk_errstr, TSK_ERRSTR_L,
-                    "tsk_fs_path2inum: File System type not supported for file name comparison (%X)",
-                    a_fs->ftype);
-                return -1;
+                if ((fs_file->name->name)
+                    && (a_fs->name_cmp(a_fs, fs_file->name->name,
+                            cur_dir) == 0)) {
+                    found_name = 1;
+                }
             }
 
             if (found_name) {
diff --git a/tsk3/fs/iso9660.c b/tsk3/fs/iso9660.c
index 623b96dac..2d9ef6138 100644
--- a/tsk3/fs/iso9660.c
+++ b/tsk3/fs/iso9660.c
@@ -2267,6 +2267,7 @@ iso9660_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
     fs->fscheck = iso9660_fscheck;
     fs->istat = iso9660_istat;
     fs->close = iso9660_close;
+    fs->name_cmp = iso9660_name_cmp;
 
     fs->jblk_walk = iso9660_jblk_walk;
     fs->jentry_walk = iso9660_jentry_walk;
diff --git a/tsk3/fs/iso9660_dent.c b/tsk3/fs/iso9660_dent.c
index a07f7944f..b0a1d1b68 100644
--- a/tsk3/fs/iso9660_dent.c
+++ b/tsk3/fs/iso9660_dent.c
@@ -283,3 +283,9 @@ iso9660_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
 
     return retval;
 }
+
+int
+iso9660_name_cmp(TSK_FS_INFO * a_fs_info, const char *s1, const char *s2)
+{
+    return strcmp(s1, s2);
+}
diff --git a/tsk3/fs/nofs_misc.c b/tsk3/fs/nofs_misc.c
index 72173b9bd..7a34d0a3a 100644
--- a/tsk3/fs/nofs_misc.c
+++ b/tsk3/fs/nofs_misc.c
@@ -273,3 +273,10 @@ tsk_fs_nofs_jblk_walk(TSK_FS_INFO * a_fs, TSK_INUM_T start, TSK_INUM_T end,
         tsk_fs_type_toname(a_fs->ftype));
     return 1;
 }
+
+int
+tsk_fs_nofs_name_cmp(TSK_FS_INFO * a_fs_info, const char *s1,
+    const char *s2)
+{
+    return strcmp(s1, s2);
+}
diff --git a/tsk3/fs/ntfs.c b/tsk3/fs/ntfs.c
index 24713092f..b8c705229 100644
--- a/tsk3/fs/ntfs.c
+++ b/tsk3/fs/ntfs.c
@@ -4488,6 +4488,7 @@ ntfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
     fs->fscheck = ntfs_fscheck;
     fs->istat = ntfs_istat;
     fs->close = ntfs_close;
+    fs->name_cmp = ntfs_name_cmp;
 
     fs->jblk_walk = ntfs_jblk_walk;
     fs->jentry_walk = ntfs_jentry_walk;
diff --git a/tsk3/fs/ntfs_dent.c b/tsk3/fs/ntfs_dent.c
index 9a517305c..d6e74931a 100644
--- a/tsk3/fs/ntfs_dent.c
+++ b/tsk3/fs/ntfs_dent.c
@@ -1455,3 +1455,10 @@ ntfs_find_file(TSK_FS_INFO * fs, TSK_INUM_T inode_toid, uint32_t type_toid,
     tsk_fs_file_close(fs_file);
     return 0;
 }
+
+
+int
+ntfs_name_cmp(TSK_FS_INFO * a_fs_info, const char *s1, const char *s2)
+{
+    return strcasecmp(s1, s2);
+}
diff --git a/tsk3/fs/rawfs.c b/tsk3/fs/rawfs.c
index 3af1e7026..77a1c90ad 100644
--- a/tsk3/fs/rawfs.c
+++ b/tsk3/fs/rawfs.c
@@ -85,6 +85,7 @@ rawfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset)
     fs->load_attrs = tsk_fs_nofs_make_data_run;
 
     fs->dir_open_meta = tsk_fs_nofs_dir_open_meta;
+    fs->name_cmp = tsk_fs_nofs_name_cmp;
 
     fs->jblk_walk = tsk_fs_nofs_jblk_walk;
     fs->jentry_walk = tsk_fs_nofs_jentry_walk;
diff --git a/tsk3/fs/swapfs.c b/tsk3/fs/swapfs.c
index e3ce6e4ac..0c9954c82 100644
--- a/tsk3/fs/swapfs.c
+++ b/tsk3/fs/swapfs.c
@@ -83,6 +83,7 @@ swapfs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset)
     fs->load_attrs = tsk_fs_nofs_make_data_run;
 
     fs->dir_open_meta = tsk_fs_nofs_dir_open_meta;
+    fs->name_cmp = tsk_fs_nofs_name_cmp;
 
     fs->jblk_walk = tsk_fs_nofs_jblk_walk;
     fs->jentry_walk = tsk_fs_nofs_jentry_walk;
diff --git a/tsk3/fs/tsk_fatfs.h b/tsk3/fs/tsk_fatfs.h
index 8d693ca0c..73fb7e745 100644
--- a/tsk3/fs/tsk_fatfs.h
+++ b/tsk3/fs/tsk_fatfs.h
@@ -380,6 +380,8 @@ extern "C" {
         fatfs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
         TSK_INUM_T a_addr);
 
+    extern int fatfs_name_cmp(TSK_FS_INFO *, const char *, const char *);
+
 
 #ifdef __cplusplus
 }
diff --git a/tsk3/fs/tsk_fs.h b/tsk3/fs/tsk_fs.h
index 0f9522fd2..081013475 100644
--- a/tsk3/fs/tsk_fs.h
+++ b/tsk3/fs/tsk_fs.h
@@ -856,6 +856,8 @@ extern "C" {
 
          uint8_t(*fsstat) (TSK_FS_INFO * fs, FILE * hFile);     ///< \internal
 
+        int (*name_cmp) (TSK_FS_INFO *, const char *, const char *);    ///< \internal
+
          uint8_t(*fscheck) (TSK_FS_INFO *, FILE *);     ///< \internal
 
         void (*close) (TSK_FS_INFO * fs);       ///< FS-specific function: Call tsk_fs_close() instead. 
diff --git a/tsk3/fs/tsk_fs_i.h b/tsk3/fs/tsk_fs_i.h
index 71e4c7d7f..753815539 100644
--- a/tsk3/fs/tsk_fs_i.h
+++ b/tsk3/fs/tsk_fs_i.h
@@ -179,7 +179,8 @@ extern "C" {
     extern uint8_t tsk_fs_unix_make_data_run(TSK_FS_FILE * fs_file);
     extern TSK_FS_ATTR_TYPE_ENUM tsk_fs_unix_get_default_attr_type(const
         TSK_FS_FILE * a_file);
-
+    extern int tsk_fs_unix_name_cmp(TSK_FS_INFO * a_fs_info,
+        const char *s1, const char *s2);
 
     /* Specific file system routines */
     extern TSK_FS_INFO *ext2fs_open(TSK_IMG_INFO *, TSK_OFF_T,
@@ -203,6 +204,8 @@ extern "C" {
     extern TSK_FS_ATTR_TYPE_ENUM tsk_fs_nofs_get_default_attr_type(const
         TSK_FS_FILE * a_file);
     extern uint8_t tsk_fs_nofs_make_data_run(TSK_FS_FILE *);
+    extern int tsk_fs_nofs_name_cmp(TSK_FS_INFO *, const char *,
+        const char *);
 
     extern TSK_FS_BLOCK_FLAG_ENUM tsk_fs_nofs_block_getflags(TSK_FS_INFO *
         a_fs, TSK_DADDR_T a_addr);
diff --git a/tsk3/fs/tsk_hfs.h b/tsk3/fs/tsk_hfs.h
index 7a121b207..279e2d331 100644
--- a/tsk3/fs/tsk_hfs.h
+++ b/tsk3/fs/tsk_hfs.h
@@ -546,8 +546,9 @@ extern uint16_t hfs_get_idxkeylen(HFS_INFO * hfs, uint16_t keylen,
     const hfs_btree_header_record * header);
 
 
-extern TSK_RETVAL_ENUM
-hfs_dir_open_meta(TSK_FS_INFO *, TSK_FS_DIR **, TSK_INUM_T);
+extern TSK_RETVAL_ENUM hfs_dir_open_meta(TSK_FS_INFO *, TSK_FS_DIR **,
+    TSK_INUM_T);
+extern int hfs_name_cmp(TSK_FS_INFO *, const char *, const char *);
 
 extern uint8_t hfs_jopen(TSK_FS_INFO *, TSK_INUM_T);
 extern uint8_t hfs_jblk_walk(TSK_FS_INFO *, TSK_DADDR_T, TSK_DADDR_T, int,
diff --git a/tsk3/fs/tsk_iso9660.h b/tsk3/fs/tsk_iso9660.h
index 3de6908c5..afa7a1668 100644
--- a/tsk3/fs/tsk_iso9660.h
+++ b/tsk3/fs/tsk_iso9660.h
@@ -390,6 +390,8 @@ extern TSK_RETVAL_ENUM iso9660_dir_open_meta(TSK_FS_INFO * a_fs,
 
 extern uint8_t iso9660_dinode_load(ISO_INFO * iso, TSK_INUM_T inum);
 
+extern int iso9660_name_cmp(TSK_FS_INFO *, const char *, const char *);
+
 /**********************************************************
  *
  * RockRidge Extensions
diff --git a/tsk3/fs/tsk_ntfs.h b/tsk3/fs/tsk_ntfs.h
index 0544524d3..3ffcae401 100644
--- a/tsk3/fs/tsk_ntfs.h
+++ b/tsk3/fs/tsk_ntfs.h
@@ -705,6 +705,8 @@ extern "C" {
         TSK_INUM_T a_addr);
 
     extern void ntfs_orphan_map_free(NTFS_INFO * a_ntfs);
+
+    extern int ntfs_name_cmp(TSK_FS_INFO *, const char *, const char *);
 #ifdef __cplusplus
 }
 #endif
diff --git a/tsk3/fs/unix_misc.c b/tsk3/fs/unix_misc.c
index ad5cf8b58..140685c14 100644
--- a/tsk3/fs/unix_misc.c
+++ b/tsk3/fs/unix_misc.c
@@ -386,3 +386,10 @@ tsk_fs_unix_get_default_attr_type(const TSK_FS_FILE * a_file)
 {
     return TSK_FS_ATTR_TYPE_DEFAULT;
 }
+
+int
+tsk_fs_unix_name_cmp(TSK_FS_INFO * a_fs_info, const char *s1,
+    const char *s2)
+{
+    return strcmp(s1, s2);
+}
-- 
GitLab