diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-08-05 15:00:08 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-08-07 10:41:49 +0200 |
commit | 73b4ec8392541a27815bccbaeccbdf1cdd5e19dd (patch) | |
tree | 670e0b3f6e64ba7e957e29454e1f17261faf2ffe /difftool/compare_file.c | |
parent | 1fff8f3a1326bd82f8140a61d969994e635834fe (diff) |
Add a helper utility to compare filesystem trees
The intended use case is to compare two mounted or unpacke squashfs
images, so a repacked test image can be compared against its original
or an image unpacked with unsquashfs can be compared with an image
unpacked by rdsquashfs or sqfs2tar.
Since the tool is only intended to aid development (specifically
automated testing), it is not installed by `make install`.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'difftool/compare_file.c')
-rw-r--r-- | difftool/compare_file.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/difftool/compare_file.c b/difftool/compare_file.c new file mode 100644 index 0000000..c424220 --- /dev/null +++ b/difftool/compare_file.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * compare_file.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#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)); + 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; +} |