From e14ffcf8e092758bc21d0d5c795b58ea0b1773f2 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Wed, 21 Aug 2019 12:23:01 +0200 Subject: Merge functionality of file on disk and file in sqfs compare functions Moving towards unified sqfs vs sqfs, sqfs vs dir, dir vs sqfs comparisions. Signed-off-by: David Oberhollenzer --- difftool/Makemodule.am | 2 +- difftool/compare_file.c | 78 ---------------------------------- difftool/compare_files.c | 97 +++++++++++++++++++++++++++++++++++++++++++ difftool/compare_files_sqfs.c | 54 ------------------------ difftool/difftool.h | 2 + difftool/extract.c | 4 +- difftool/sqfsdiff.c | 2 + 7 files changed, 104 insertions(+), 135 deletions(-) delete mode 100644 difftool/compare_file.c create mode 100644 difftool/compare_files.c delete mode 100644 difftool/compare_files_sqfs.c diff --git a/difftool/Makemodule.am b/difftool/Makemodule.am index 8d0a4e7..293143e 100644 --- a/difftool/Makemodule.am +++ b/difftool/Makemodule.am @@ -1,6 +1,6 @@ sqfsdiff_SOURCES = difftool/sqfsdiff.c difftool/difftool.h difftool/util.c sqfsdiff_SOURCES += difftool/compare_dir.c difftool/node_compare.c -sqfsdiff_SOURCES += difftool/compare_files_sqfs.c difftool/super.c +sqfsdiff_SOURCES += difftool/compare_files.c difftool/super.c sqfsdiff_SOURCES += difftool/extract.c sqfsdiff_LDADD = libsquashfs.a libfstree.a libcompress.a libutil.a sqfsdiff_LDADD += $(XZ_LIBS) $(ZLIB_LIBS) $(LZO_LIBS) $(LZ4_LIBS) $(ZSTD_LIBS) diff --git a/difftool/compare_file.c b/difftool/compare_file.c deleted file mode 100644 index c427f38..0000000 --- a/difftool/compare_file.c +++ /dev/null @@ -1,78 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * compare_file.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "difftool.h" - -int compare_files(file_info_t *a, file_info_t *b, const char *path) -{ - uint64_t offset, size, diff; - int ret = 0, afd, bfd; - void *aptr, *bptr; - - if (a->size != b->size) - return 1; - - if (pushd(first_path)) - return -1; - afd = open(path, O_RDONLY); - if (afd < 0) { - fprintf(stderr, "%s/%s: %s\n", first_path, path, - strerror(errno)); - return -1; - } - if (popd()) - goto fail_afd; - - if (pushd(second_path)) - goto fail_afd; - bfd = open(path, O_RDONLY); - if (bfd < 0) { - fprintf(stderr, "%s/%s: %s\n", second_path, path, - strerror(errno)); - goto fail_afd; - } - if (popd()) - goto fail_bfd; - - size = a->size; - - for (offset = 0; offset < size; offset += diff) { - diff = size - offset; - if (diff > MAX_WINDOW_SIZE) - diff = MAX_WINDOW_SIZE; - - aptr = mmap(NULL, diff, PROT_READ, MAP_SHARED, afd, offset); - if (aptr == MAP_FAILED) { - fprintf(stderr, "mmap %s/%s: %s\n", first_path, path, - strerror(errno)); - goto fail_bfd; - } - - bptr = mmap(NULL, diff, PROT_READ, MAP_SHARED, bfd, offset); - if (bptr == MAP_FAILED) { - fprintf(stderr, "mmap %s/%s: %s\n", second_path, path, - strerror(errno)); - munmap(aptr, diff); - goto fail_bfd; - } - - ret = memcmp(aptr, bptr, diff); - munmap(aptr, diff); - munmap(bptr, diff); - - if (ret != 0) - break; - } - - close(afd); - close(bfd); - return ret; -fail_bfd: - close(bfd); -fail_afd: - close(afd); - return -1; -} diff --git a/difftool/compare_files.c b/difftool/compare_files.c new file mode 100644 index 0000000..89c5f5c --- /dev/null +++ b/difftool/compare_files.c @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * compare_files.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "difftool.h" + +static unsigned char a_buf[MAX_WINDOW_SIZE]; +static unsigned char b_buf[MAX_WINDOW_SIZE]; + +int compare_files(file_info_t *a, file_info_t *b, const char *path) +{ + char second_name[strlen(second_path) + strlen(path) + 2]; + char first_name[strlen(first_path) + strlen(path) + 2]; + int afd = -1, bfd = -1, status = 0; + uint64_t offset, diff; + ssize_t ret; + + if (a->size != b->size) + goto out_different; + + if (compare_flags & COMPARE_NO_CONTENTS) + return 0; + + if (a_is_dir) { + sprintf(first_name, "%s/%s", first_path, path); + + afd = open(first_name, O_RDONLY); + if (afd < 0) { + perror(first_name); + goto fail; + } + } + + if (b_is_dir) { + sprintf(second_name, "%s/%s", second_path, path); + + bfd = open(second_name, O_RDONLY); + if (bfd < 0) { + perror(second_name); + goto fail; + } + } + + for (offset = 0; offset < a->size; offset += diff) { + diff = a->size - offset; + + if (diff > MAX_WINDOW_SIZE) + diff = MAX_WINDOW_SIZE; + + if (a_is_dir) { + if (read_data_at(first_name, offset, afd, a_buf, diff)) + goto out; + } else { + ret = data_reader_read(sqfs_a.data, a, offset, + a_buf, diff); + if (ret < 0 || (size_t)ret < diff) { + fprintf(stderr, "Failed to read %s from %s\n", + path, first_path); + return -1; + } + } + + if (b_is_dir) { + if (read_data_at(second_name, offset, bfd, b_buf, diff)) + goto out; + } else { + ret = data_reader_read(sqfs_b.data, b, offset, + b_buf, diff); + if (ret < 0 || (size_t)ret < diff) { + fprintf(stderr, "Failed to read %s from %s\n", + path, second_path); + return -1; + } + } + + if (memcmp(a_buf, b_buf, diff) != 0) + goto out_different; + } +out: + if (afd >= 0) + close(afd); + if (bfd >= 0) + close(bfd); + return status; +fail: + status = -1; + goto out; +out_different: + if (compare_flags & COMPARE_EXTRACT_FILES) { + if (extract_files(a, b, path)) + goto fail; + } + status = 1; + goto out; +} diff --git a/difftool/compare_files_sqfs.c b/difftool/compare_files_sqfs.c deleted file mode 100644 index 32b97b1..0000000 --- a/difftool/compare_files_sqfs.c +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * compare_file_sfqs.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "difftool.h" - -static unsigned char a_buf[MAX_WINDOW_SIZE]; -static unsigned char b_buf[MAX_WINDOW_SIZE]; - -int compare_files(file_info_t *a, file_info_t *b, const char *path) -{ - uint64_t offset, diff; - ssize_t ret; - - if (a->size != b->size) - goto out_different; - - if (compare_flags & COMPARE_NO_CONTENTS) - return 0; - - for (offset = 0; offset < a->size; offset += diff) { - diff = a->size - offset; - - if (diff > MAX_WINDOW_SIZE) - diff = MAX_WINDOW_SIZE; - - ret = data_reader_read(sqfs_a.data, a, offset, a_buf, diff); - if (ret < 0 || (size_t)ret < diff) { - fprintf(stderr, "Failed to read %s from %s\n", - path, first_path); - return -1; - } - - ret = data_reader_read(sqfs_b.data, b, offset, b_buf, diff); - if (ret < 0 || (size_t)ret < diff) { - fprintf(stderr, "Failed to read %s from %s\n", - path, second_path); - return -1; - } - - if (memcmp(a_buf, b_buf, diff) != 0) - goto out_different; - } - - return 0; -out_different: - if (compare_flags & COMPARE_EXTRACT_FILES) { - if (extract_files(a, b, path)) - return -1; - } - return 1; -} diff --git a/difftool/difftool.h b/difftool/difftool.h index bd04fd2..56f727a 100644 --- a/difftool/difftool.h +++ b/difftool/difftool.h @@ -28,6 +28,8 @@ extern const char *second_path; extern int compare_flags; extern sqfs_reader_t sqfs_a; extern sqfs_reader_t sqfs_b; +extern bool a_is_dir; +extern bool b_is_dir; enum { COMPARE_NO_PERM = 0x01, diff --git a/difftool/extract.c b/difftool/extract.c index 9d84265..9fee46d 100644 --- a/difftool/extract.c +++ b/difftool/extract.c @@ -39,12 +39,12 @@ static int extract(data_reader_t *data, file_info_t *fi, int extract_files(file_info_t *a, file_info_t *b, const char *path) { - if (a != NULL) { + if (a != NULL && !a_is_dir) { if (extract(sqfs_a.data, a, path, 'a')) return -1; } - if (b != NULL) { + if (b != NULL && !b_is_dir) { if (extract(sqfs_b.data, b, path, 'b')) return -1; } diff --git a/difftool/sqfsdiff.c b/difftool/sqfsdiff.c index baebc25..9197430 100644 --- a/difftool/sqfsdiff.c +++ b/difftool/sqfsdiff.c @@ -65,6 +65,8 @@ const char *first_path; const char *second_path; sqfs_reader_t sqfs_a; sqfs_reader_t sqfs_b; +bool a_is_dir; +bool b_is_dir; static bool compare_super = false; static const char *extract_dir; -- cgit v1.2.3