Made mounted tar archive filename lookup case insensitive

This commit is contained in:
rxi
2017-01-17 19:25:46 +00:00
parent e14a6d4b9f
commit 918cacd296

View File

@@ -8,6 +8,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h>
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -95,15 +96,25 @@ static int concat_and_get_file_type(const char *dir, const char *filename) {
} }
static unsigned hash_string(const char *str) { static unsigned hash_string_ignore_case(const char *str) {
unsigned hash = 5381; unsigned hash = 5381;
while (*str) { while (*str) {
hash = ((hash << 5) + hash) ^ *str++; hash = ((hash << 5) + hash) ^ tolower(*str++);
} }
return hash; return hash;
} }
static int strings_equal_ignore_case(const char *a, const char *b) {
while (*a) {
if (tolower(*a++) != tolower(*b++)) {
return 0;
}
}
return !*b;
}
static void strip_trailing_slash(char *str) { static void strip_trailing_slash(char *str) {
int len = strlen(str); int len = strlen(str);
if (len > 0 && str[len - 1] == '/') { if (len > 0 && str[len - 1] == '/') {
@@ -143,7 +154,7 @@ static int make_dirs(const char *path) {
/*==================*/ /*==================*/
/* Directory mount_t */ /* Directory mount */
/*==================*/ /*==================*/
static void dir_unmount(mount_t *mnt) { static void dir_unmount(mount_t *mnt) {
@@ -214,7 +225,7 @@ static int dir_mount(mount_t *mnt, const char *path) {
/*==================*/ /*==================*/
/* Tar mount_t */ /* Tar mount */
/*==================*/ /*==================*/
typedef struct { unsigned hash, pos; } tar_file_ref_t; typedef struct { unsigned hash, pos; } tar_file_ref_t;
@@ -232,7 +243,7 @@ static int tar_find(mount_t *mnt, const char *filename, mtar_header_t *h) {
/* Hash filename and linear search map for matching hash, read header and /* Hash filename and linear search map for matching hash, read header and
* check against filename if the hashes match */ * check against filename if the hashes match */
tar_mount_t *tm = mnt->udata; tar_mount_t *tm = mnt->udata;
unsigned hash = hash_string(filename); unsigned hash = hash_string_ignore_case(filename);
int i; int i;
for (i = 0; i < tm->nfiles; i++) { for (i = 0; i < tm->nfiles; i++) {
@@ -242,7 +253,7 @@ static int tar_find(mount_t *mnt, const char *filename, mtar_header_t *h) {
mtar_read_header(&tm->tar, h); mtar_read_header(&tm->tar, h);
/* Compare names */ /* Compare names */
strip_trailing_slash(h->name); strip_trailing_slash(h->name);
if ( !strcmp(h->name, filename) ) { if (strings_equal_ignore_case(h->name, filename)) {
return FILESYSTEM_ESUCCESS; return FILESYSTEM_ESUCCESS;
} }
} }
@@ -389,7 +400,7 @@ static int tar_mount(mount_t *mnt, const char *path) {
} }
/* Store entry */ /* Store entry */
strip_trailing_slash(h.name); strip_trailing_slash(h.name);
tm->map[n].hash = hash_string(h.name); tm->map[n].hash = hash_string_ignore_case(h.name);
tm->map[n].pos = tar->pos; tm->map[n].pos = tar->pos;
/* Next */ /* Next */
mtar_next(tar); mtar_next(tar);