Implement the ability to test the integrity of the file written to disk on decompression.

This commit is contained in:
Con Kolivas 2011-02-20 22:29:49 +11:00
parent a9881db04a
commit 9b264959f5
3 changed files with 40 additions and 1 deletions

10
main.c
View file

@ -53,6 +53,7 @@ static void usage(void)
print_output(" -t test compressed file integrity\n");
print_output(" -i show compressed file information\n");
print_output(" -H display md5 Hash integrity information\n");
print_output(" -c check integrity of file written on decompression\n");
print_output("\nIf no filenames or \"-\" is specified, stdin/out will be used.\n");
}
@ -605,7 +606,7 @@ int main(int argc, char *argv[])
else if (!strstr(eptr,"NOCONFIG"))
read_config(&control);
while ((c = getopt(argc, argv, "L:hdS:tVvDfqo:w:nlbMUO:T:N:p:gziH")) != -1) {
while ((c = getopt(argc, argv, "L:hdS:tVvDfqo:w:nlbMUO:T:N:p:gziHc")) != -1) {
switch (c) {
case 'L':
control.compression_level = atoi(optarg);
@ -722,6 +723,10 @@ int main(int argc, char *argv[])
case 'H':
control.flags |= FLAG_HASH;
break;
case 'c':
control.flags |= FLAG_CHECK;
control.flags |= FLAG_HASH;
break;
case 'h':
usage();
return -1;
@ -747,6 +752,9 @@ int main(int argc, char *argv[])
control.flags &= ~ FLAG_UNLIMITED;
}
if (CHECK_FILE && (!DECOMPRESS || !TEST_ONLY))
print_err("Can only check file written on decompression or testing.\n");
/* OK, if verbosity set, print summary of options selected */
if (!INFO) {
if (!TEST_ONLY)

View file

@ -276,6 +276,35 @@ i64 runzip_fd(int fd_in, int fd_out, int fd_hist, i64 expected_size)
print_output("%02x", md5_resblock[i] & 0xFF);
print_output("\n");
}
if (CHECK_FILE) {
FILE *md5_fstream;
int i, j;
memcpy(md5_stored, md5_resblock, MD5_DIGEST_SIZE);
if (unlikely(lseek(fd_out, 0, SEEK_SET) == -1))
fatal("Failed to lseek fd_out in runzip_fd\n");
if (unlikely((md5_fstream = fdopen(fd_out, "r")) == NULL))
fatal("Failed to fdopen fd_out in runzip_fd\n");
if (unlikely(md5_stream(md5_fstream, md5_resblock)))
fatal("Failed to md5_stream in runzip_fd\n");
/* We dont' close the file here as it's closed in main */
for (i = 0; i < MD5_DIGEST_SIZE; i++)
if (md5_stored[i] != md5_resblock[i]) {
print_output("MD5 CHECK FAILED.\nStored:");
for (j = 0; j < MD5_DIGEST_SIZE; j++)
print_output("%02x", md5_stored[j] & 0xFF);
print_output("\nOutput file:");
for (j = 0; j < MD5_DIGEST_SIZE; j++)
print_output("%02x", md5_resblock[j] & 0xFF);
fatal("\n");
}
print_output("MD5 integrity of written file matches archive\n");
if (!HAS_MD5)
print_output("Note this lrzip archive did not have a stored md5 value.\n"
"The archive decompression was validated with crc32 and the md5 hash was "
"calculated on decompression\n");
}
}
return total;

2
rzip.h
View file

@ -214,6 +214,7 @@ static inline i64 get_ram(void)
#define FLAG_UNLIMITED (1 << 16)
#define FLAG_HASH (1 << 17)
#define FLAG_MD5 (1 << 18)
#define FLAG_CHECK (1 << 19)
#define FLAG_VERBOSE (FLAG_VERBOSITY | FLAG_VERBOSITY_MAX)
#define FLAG_NOT_LZMA (FLAG_NO_COMPRESS | FLAG_LZO_COMPRESS | FLAG_BZIP2_COMPRESS | FLAG_ZLIB_COMPRESS | FLAG_ZPAQ_COMPRESS)
@ -239,6 +240,7 @@ static inline i64 get_ram(void)
#define UNLIMITED (control.flags & FLAG_UNLIMITED)
#define HASH_CHECK (control.flags & FLAG_HASH)
#define HAS_MD5 (control.flags & FLAG_MD5)
#define CHECK_FILE (control.flags & FLAG_CHECK)
#define NO_MD5 (!(HASH_CHECK) && !(HAS_MD5))