diff --git a/include/filetypes/checktypes.h b/include/filetypes/checktypes.h index b2a78b8..4849829 100644 --- a/include/filetypes/checktypes.h +++ b/include/filetypes/checktypes.h @@ -11,7 +11,8 @@ struct laser_magicnumber int laser_checktype(const char *filename, const struct laser_magicnumber formats[]); - +int laser_checktype_ex(int fd, const char *filename, + const struct laser_magicnumber formats[]); extern const struct laser_magicnumber laser_archiveformats[]; extern const struct laser_magicnumber laser_mediaformats[]; extern const struct laser_magicnumber laser_documentformats[]; diff --git a/src/filetypes/checktype.c b/src/filetypes/checktype.c index 69abbc2..28c06b3 100644 --- a/src/filetypes/checktype.c +++ b/src/filetypes/checktype.c @@ -5,26 +5,27 @@ #include #include -int laser_checktype(const char *filename, - const struct laser_magicnumber formats[]) +enum check_type_return +{ + Success = 0, + NotOpened, + CannotRead, + Unknown +}; +static int laser_checktype_fd(int fd, const struct laser_magicnumber formats[]) { - int fd = open(filename, O_RDONLY); if (fd == -1) { - perror("open"); - return 0; + return NotOpened; } - // should be updated if there is a magic number larger than 8 bits unsigned char buffer[8]; ssize_t bytesRead = read(fd, buffer, sizeof(buffer)); - close(fd); if (bytesRead < 0) { - fprintf(stderr, "laser: cannot read %s", filename); - return 0; + return CannotRead; } size_t i = 0; @@ -33,9 +34,62 @@ int laser_checktype(const char *filename, { if (bytesRead >= formats[i].magic_size && memcmp(buffer, formats[i].magic, formats[i].magic_size) == 0) - return 1; + return Success; i++; } - return 0; + return Unknown; +} + +int laser_checktype(const char *filename, + const struct laser_magicnumber formats[]) +{ + int fd = open(filename, O_RDONLY); + if (fd == -1) + { + perror("open"); + return 0; + } + int rv = laser_checktype_fd(fd, formats); + // should be updated if there is a magic number larger than 8 bits + switch (rv) + { + case NotOpened: + perror("open"); + break; + case CannotRead: + fprintf(stderr, "laser: cannot read %s", filename); + break; + //Fallthrough + default: + break; + } + close(fd); + return rv == Success; +} + +int laser_checktype_ex(int fd, const char *filename, + const struct laser_magicnumber formats[]) +{ + + if (fd == -1) + { + perror("open"); + return 0; + } + int rv = laser_checktype_fd(fd, formats); + // should be updated if there is a magic number larger than 8 bits + switch (rv) + { + case NotOpened: + perror("open"); + break; + case CannotRead: + fprintf(stderr, "laser: cannot read %s", filename); + break; + //Fallthrough + default: + break; + } + return rv == Success; } diff --git a/src/laser.c b/src/laser.c index bc0efed..4f095e1 100644 --- a/src/laser.c +++ b/src/laser.c @@ -3,7 +3,7 @@ #include "filetypes/checktypes.h" #include "git/lgit.h" #include "utils.h" - +#include #define BRANCH_SIZE 8 char *strip_parent_dir(const char *full_path, const char *parent_dir) @@ -142,6 +142,8 @@ void laser_process_entries(laser_opts opts, int depth, int max_depth, } else { + int fd = open(full_path, O_RDONLY); + if (S_ISLNK(file_stat.st_mode) && opts.show_symlinks) { char symlink_target[PATH_MAX]; @@ -163,17 +165,17 @@ void laser_process_entries(laser_opts opts, int depth, int max_depth, LASER_COLORS[LASER_COLOR_EXEC].value, indent, depth, is_last); - else if (laser_checktype(full_path, laser_archiveformats)) + else if (laser_checktype_ex(fd, full_path, laser_archiveformats)) laser_print_entry(entries[i]->d_name, LASER_COLORS[LASER_COLOR_ARCHIVE].value, indent, depth, is_last); - else if (laser_checktype(full_path, laser_mediaformats)) + else if (laser_checktype_ex(fd, full_path, laser_mediaformats)) laser_print_entry(entries[i]->d_name, LASER_COLORS[LASER_COLOR_MEDIA].value, indent, depth, is_last); - else if (laser_checktype(full_path, laser_documentformats)) + else if (laser_checktype_ex(fd, full_path, laser_documentformats)) laser_print_entry(entries[i]->d_name, LASER_COLORS[LASER_COLOR_DOCUMENT].value, indent, depth, is_last); @@ -187,6 +189,7 @@ void laser_process_entries(laser_opts opts, int depth, int max_depth, laser_print_entry(entries[i]->d_name, LASER_COLORS[LASER_COLOR_FILE].value, indent, depth, is_last); + close(fd); } free(entries[i]);