diff --git a/liblrzip.h b/liblrzip.h index d817af0..d683b95 100644 --- a/liblrzip.h +++ b/liblrzip.h @@ -20,54 +20,4 @@ #ifndef LIBLRZIP_H #define LIBLRZIP_H -#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) -#define LZMA_COMPRESS (!(control->flags & FLAG_NOT_LZMA)) - -#define SHOW_PROGRESS (control->flags & FLAG_SHOW_PROGRESS) -#define KEEP_FILES (control->flags & FLAG_KEEP_FILES) -#define TEST_ONLY (control->flags & FLAG_TEST_ONLY) -#define FORCE_REPLACE (control->flags & FLAG_FORCE_REPLACE) -#define DECOMPRESS (control->flags & FLAG_DECOMPRESS) -#define NO_COMPRESS (control->flags & FLAG_NO_COMPRESS) -#define LZO_COMPRESS (control->flags & FLAG_LZO_COMPRESS) -#define BZIP2_COMPRESS (control->flags & FLAG_BZIP2_COMPRESS) -#define ZLIB_COMPRESS (control->flags & FLAG_ZLIB_COMPRESS) -#define ZPAQ_COMPRESS (control->flags & FLAG_ZPAQ_COMPRESS) -#define VERBOSE (control->flags & FLAG_VERBOSE) -#define VERBOSITY (control->flags & FLAG_VERBOSITY) -#define MAX_VERBOSE (control->flags & FLAG_VERBOSITY_MAX) -#define STDIN (control->flags & FLAG_STDIN) -#define STDOUT (control->flags & FLAG_STDOUT) -#define INFO (control->flags & FLAG_INFO) -#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 KEEP_BROKEN (control->flags & FLAG_KEEP_BROKEN) -#define LZO_TEST (control->flags & FLAG_THRESHOLD) -#define TMP_OUTBUF (control->flags & FLAG_TMP_OUTBUF) -#define TMP_INBUF (control->flags & FLAG_TMP_INBUF) -#define ENCRYPT (control->flags & FLAG_ENCRYPT) - -#define print_output(format, args...) do {\ - fprintf(control->msgout, format, ##args); \ - fflush(control->msgout); \ -} while (0) - -#define print_progress(format, args...) do {\ - if (SHOW_PROGRESS) \ - print_output(format, ##args); \ -} while (0) - -#define print_verbose(format, args...) do {\ - if (VERBOSE) \ - print_output(format, ##args); \ -} while (0) - -#define print_maxverbose(format, args...) do {\ - if (MAX_VERBOSE) \ - print_output(format, ##args); \ -} while (0) - #endif diff --git a/lrzip.c b/lrzip.c index aa03de0..2de8920 100644 --- a/lrzip.c +++ b/lrzip.c @@ -88,7 +88,7 @@ inline i64 get_ram(void) return ramsize; } #else /* __APPLE__ */ -inline i64 get_ram(void) +inline i64 get_ram(rzip_control *control) { i64 ramsize; FILE *meminfo; @@ -100,14 +100,14 @@ inline i64 get_ram(void) /* Workaround for uclibc which doesn't properly support sysconf */ if(!(meminfo = fopen("/proc/meminfo", "r"))) - fatal("fopen\n"); + fatal(control, "fopen\n"); while(!feof(meminfo) && !fscanf(meminfo, "MemTotal: %Lu kB", &ramsize)) { if (unlikely(fgets(aux, sizeof(aux), meminfo) == NULL)) - fatal("Failed to fgets in get_ram\n"); + fatal(control, "Failed to fgets in get_ram\n"); } if (fclose(meminfo) == -1) - fatal("fclose"); + fatal(control, "fclose"); ramsize *= 1000; return ramsize; @@ -168,10 +168,10 @@ void write_magic(rzip_control *control) magic[22] = 1; if (unlikely(fdout_seekto(control, 0))) - fatal("Failed to seek to BOF to write Magic Header\n"); + fatal(control, "Failed to seek to BOF to write Magic Header\n"); if (unlikely(put_fdout(control, magic, MAGIC_LEN) != MAGIC_LEN)) - fatal("Failed to write magic header\n"); + fatal(control, "Failed to write magic header\n"); control->magic_written = 1; } @@ -187,7 +187,7 @@ static void get_magic(rzip_control *control, char *magic) uint32_t v; if (unlikely(strncmp(magic, "LRZI", 4))) - failure("Not an lrzip file\n"); + failure(control, "Not an lrzip file\n"); memcpy(&control->major_version, &magic[4], 1); memcpy(&control->minor_version, &magic[5], 1); @@ -230,7 +230,7 @@ static void get_magic(rzip_control *control, char *magic) if (encrypted == 1) control->flags |= FLAG_ENCRYPT; else - failure("Unknown encryption\n"); + failure(control, "Unknown encryption\n"); /* In encrypted files, the size field is used to store the salt * instead and the size is unknown, just like a STDOUT chunked * file */ @@ -251,7 +251,7 @@ void read_magic(rzip_control *control, int fd_in, i64 *expected_size) memset(magic, 0, sizeof(magic)); /* Initially read only st_size; @@ -263,7 +263,7 @@ void preserve_perms(rzip_control *control, int fd_in, int fd_out) struct stat st; if (unlikely(fstat(fd_in, &st))) - fatal("Failed to fstat input file\n"); + fatal(control, "Failed to fstat input file\n"); if (unlikely(fchmod(fd_out, (st.st_mode & 0666)))) print_err("Warning, unable to set permissions on %s\n", control->outfile); @@ -282,24 +282,24 @@ int open_tmpoutfile(rzip_control *control) if (control->tmpdir) { control->outfile = realloc(NULL, strlen(control->tmpdir) + 16); if (unlikely(!control->outfile)) - fatal("Failed to allocate outfile name\n"); + fatal(control, "Failed to allocate outfile name\n"); strcpy(control->outfile, control->tmpdir); strcat(control->outfile, "lrzipout.XXXXXX"); } else { control->outfile = realloc(NULL, 16); if (unlikely(!control->outfile)) - fatal("Failed to allocate outfile name\n"); + fatal(control, "Failed to allocate outfile name\n"); strcpy(control->outfile, "lrzipout.XXXXXX"); } fd_out = mkstemp(control->outfile); if (unlikely(fd_out == -1)) - fatal("Failed to create out tmpfile: %s\n", control->outfile); - register_outfile(control->outfile, TEST_ONLY || STDOUT || !KEEP_BROKEN); + fatal(control, "Failed to create out tmpfile: %s\n", control->outfile); + register_outfile(control, control->outfile, TEST_ONLY || STDOUT || !KEEP_BROKEN); return fd_out; } -static void fwrite_stdout(void *buf, i64 len) +static void fwrite_stdout(rzip_control *control, void *buf, i64 len) { uchar *offset_buf = buf; ssize_t ret; @@ -313,7 +313,7 @@ static void fwrite_stdout(void *buf, i64 len) ret = len; ret = fwrite(offset_buf, 1, ret, stdout); if (unlikely(ret <= 0)) - fatal("Failed to fwrite in fwrite_stdout\n"); + fatal(control, "Failed to fwrite in fwrite_stdout\n"); len -= ret; offset_buf += ret; total += ret; @@ -330,7 +330,7 @@ void write_fdout(rzip_control *control, void *buf, i64 len) ret = MIN(len, one_g); ret = write(control->fd_out, offset_buf, (size_t)ret); if (unlikely(ret <= 0)) - fatal("Failed to write to fd_out in write_fdout\n"); + fatal(control, "Failed to write to fd_out in write_fdout\n"); len -= ret; offset_buf += ret; } @@ -341,7 +341,7 @@ void flush_tmpoutbuf(rzip_control *control) if (!TEST_ONLY) { print_maxverbose("Dumping buffer to physical file.\n"); if (STDOUT) - fwrite_stdout(control->tmp_outbuf, control->out_len); + fwrite_stdout(control, control->tmp_outbuf, control->out_len); else write_fdout(control, control->tmp_outbuf, control->out_len); } @@ -359,7 +359,7 @@ void dump_tmpoutfile(rzip_control *control, int fd_out) fsync(fd_out); tmpoutfp = fdopen(fd_out, "r"); if (unlikely(tmpoutfp == NULL)) - fatal("Failed to fdopen out tmpfile\n"); + fatal(control, "Failed to fdopen out tmpfile\n"); rewind(tmpoutfp); if (!TEST_ONLY) { @@ -371,7 +371,7 @@ void dump_tmpoutfile(rzip_control *control, int fd_out) } if (unlikely(ftruncate(fd_out, 0))) - fatal("Failed to ftruncate fd_out in dump_tmpoutfile\n"); + fatal(control, "Failed to ftruncate fd_out in dump_tmpoutfile\n"); } /* Used if we're unable to read STDIN into the temporary buffer, shunts data @@ -386,7 +386,7 @@ void write_fdin(rzip_control *control) ret = MIN(len, one_g); ret = write(control->fd_in, offset_buf, (size_t)ret); if (unlikely(ret <= 0)) - fatal("Failed to write to fd_in in write_fdin\n"); + fatal(control, "Failed to write to fd_in in write_fdin\n"); len -= ret; offset_buf += ret; } @@ -400,24 +400,24 @@ int open_tmpinfile(rzip_control *control) if (control->tmpdir) { control->infile = malloc(strlen(control->tmpdir) + 15); if (unlikely(!control->infile)) - fatal("Failed to allocate infile name\n"); + fatal(control, "Failed to allocate infile name\n"); strcpy(control->infile, control->tmpdir); strcat(control->infile, "lrzipin.XXXXXX"); } else { control->infile = malloc(15); if (unlikely(!control->infile)) - fatal("Failed to allocate infile name\n"); + fatal(control, "Failed to allocate infile name\n"); strcpy(control->infile, "lrzipin.XXXXXX"); } fd_in = mkstemp(control->infile); if (unlikely(fd_in == -1)) - fatal("Failed to create in tmpfile: %s\n", control->infile); - register_infile(control->infile, (DECOMPRESS || TEST_ONLY) && STDIN); + fatal(control, "Failed to create in tmpfile: %s\n", control->infile); + register_infile(control, control->infile, (DECOMPRESS || TEST_ONLY) && STDIN); /* Unlink temporary file immediately to minimise chance of files left * lying around in cases of failure. */ if (unlikely(unlink(control->infile))) - fatal("Failed to unlink tmpfile: %s\n", control->infile); + fatal(control, "Failed to unlink tmpfile: %s\n", control->infile); return fd_in; } @@ -430,7 +430,7 @@ static void read_tmpinmagic(rzip_control *control) for (i = 0; i < 24; i++) { tmpchar = getchar(); if (unlikely(tmpchar == EOF)) - failure("Reached end of file on STDIN prematurely on v05 magic read\n"); + failure(control, "Reached end of file on STDIN prematurely on v05 magic read\n"); magic[i] = (char)tmpchar; } get_magic(control, magic); @@ -446,7 +446,7 @@ void read_tmpinfile(rzip_control *control, int fd_in) fprintf(control->msgout, "Copying from stdin.\n"); tmpinfp = fdopen(fd_in, "w+"); if (unlikely(tmpinfp == NULL)) - fatal("Failed to fdopen in tmpfile\n"); + fatal(control, "Failed to fdopen in tmpfile\n"); while ((tmpchar = getchar()) != EOF) fputc(tmpchar, tmpinfp); @@ -465,7 +465,7 @@ static void open_tmpoutbuf(rzip_control *control) * fall back to a real temporary file */ control->tmp_outbuf = malloc(control->maxram + control->page_size); if (unlikely(!control->tmp_outbuf)) - fatal("Failed to malloc tmp_outbuf in open_tmpoutbuf\n"); + fatal(control, "Failed to malloc tmp_outbuf in open_tmpoutbuf\n"); if (!DECOMPRESS && !TEST_ONLY) control->out_ofs = control->out_len = MAGIC_LEN; } @@ -482,7 +482,7 @@ static void open_tmpinbuf(rzip_control *control) control->in_maxlen = control->maxram; control->tmp_inbuf = malloc(control->maxram + control->page_size); if (unlikely(!control->tmp_inbuf)) - fatal("Failed to malloc tmp_inbuf in open_tmpinbuf\n"); + fatal(control, "Failed to malloc tmp_inbuf in open_tmpinbuf\n"); } inline void clear_tmpinbuf(rzip_control *control) @@ -493,9 +493,9 @@ inline void clear_tmpinbuf(rzip_control *control) void clear_tmpinfile(rzip_control *control) { if (unlikely(lseek(control->fd_in, 0, SEEK_SET))) - fatal("Failed to lseek on fd_in in clear_tmpinfile\n"); + fatal(control, "Failed to lseek on fd_in in clear_tmpinfile\n"); if (unlikely(ftruncate(control->fd_in, 0))) - fatal("Failed to truncate fd_in in clear_tmpinfile\n"); + fatal(control, "Failed to truncate fd_in in clear_tmpinfile\n"); } void close_tmpinbuf(rzip_control *control) @@ -504,13 +504,13 @@ void close_tmpinbuf(rzip_control *control) free(control->tmp_inbuf); } -static int get_pass(char *s) +static int get_pass(rzip_control *control, char *s) { int len; memset(s, 0, PASS_LEN - SALT_LEN); if (unlikely(fgets(s, PASS_LEN - SALT_LEN, stdin) == NULL)) - failure("Failed to retrieve passphrase\n"); + failure(control, "Failed to retrieve passphrase\n"); len = strlen(s); if (len > 0 && ('\r' == s[len - 1] || '\n' == s[len - 1])) s[len - 1] = '\0'; @@ -518,7 +518,7 @@ static int get_pass(char *s) s[len - 2] = '\0'; len = strlen(s); if (unlikely(0 == len)) - failure("Empty passphrase\n"); + failure(control, "Empty passphrase\n"); return len; } @@ -532,7 +532,7 @@ static void get_hash(rzip_control *control, int make_hash) control->salt_pass = calloc(PASS_LEN, 1); control->hash = calloc(HASH_LEN, 1); if (unlikely(!passphrase || !testphrase || !control->salt_pass || !control->hash)) - fatal("Failed to calloc encrypt buffers in compress_file\n"); + fatal(control, "Failed to calloc encrypt buffers in compress_file\n"); mlock(passphrase, PASS_LEN); mlock(testphrase, PASS_LEN); mlock(control->salt_pass, PASS_LEN); @@ -544,11 +544,11 @@ static void get_hash(rzip_control *control, int make_hash) tcsetattr(fileno(stdin), 0, &termios_p); retry_pass: print_output("Enter passphrase: "); - control->salt_pass_len = get_pass(passphrase) + SALT_LEN; + control->salt_pass_len = get_pass(control, passphrase) + SALT_LEN; print_output("\n"); if (make_hash) { print_output("Re-enter passphrase: "); - get_pass(testphrase); + get_pass(control, testphrase); print_output("\n"); if (strcmp(passphrase, testphrase)) { print_output("Passwords do not match. Try again.\n"); @@ -600,7 +600,7 @@ void decompress_file(rzip_control *control) */ infilecopy = malloc(strlen(control->infile) + strlen(control->suffix) + 1); if (unlikely(infilecopy == NULL)) - fatal("Failed to allocate memory for infile suffix\n"); + fatal(control, "Failed to allocate memory for infile suffix\n"); else { strcpy(infilecopy, control->infile); strcat(infilecopy, control->suffix); @@ -630,7 +630,7 @@ void decompress_file(rzip_control *control) control->outfile = malloc((control->outdir == NULL? 0: strlen(control->outdir)) + strlen(tmpoutfile) + 1); if (unlikely(!control->outfile)) - fatal("Failed to allocate outfile name\n"); + fatal(control, "Failed to allocate outfile name\n"); if (control->outdir) { /* prepend control->outdir */ strcpy(control->outfile, control->outdir); @@ -648,13 +648,13 @@ void decompress_file(rzip_control *control) fd_in = open_tmpinfile(control); read_tmpinmagic(control); if (ENCRYPT) - failure("Cannot decompress encrypted file from STDIN\n"); + failure(control, "Cannot decompress encrypted file from STDIN\n"); expected_size = control->st_size; open_tmpinbuf(control); } else { fd_in = open(infilecopy, O_RDONLY); if (unlikely(fd_in == -1)) { - fatal("Failed to open %s\n", infilecopy); + fatal(control, "Failed to open %s\n", infilecopy); } } control->fd_in = fd_in; @@ -663,18 +663,18 @@ void decompress_file(rzip_control *control) fd_out = open(control->outfile, O_WRONLY | O_CREAT | O_EXCL, 0666); if (FORCE_REPLACE && (-1 == fd_out) && (EEXIST == errno)) { if (unlikely(unlink(control->outfile))) - fatal("Failed to unlink an existing file: %s\n", control->outfile); + fatal(control, "Failed to unlink an existing file: %s\n", control->outfile); fd_out = open(control->outfile, O_WRONLY | O_CREAT | O_EXCL, 0666); } if (unlikely(fd_out == -1)) { /* We must ensure we don't delete a file that already * exists just because we tried to create a new one */ control->flags |= FLAG_KEEP_BROKEN; - fatal("Failed to create %s\n", control->outfile); + fatal(control, "Failed to create %s\n", control->outfile); } fd_hist = open(control->outfile, O_RDONLY); if (unlikely(fd_hist == -1)) - fatal("Failed to open history file %s\n", control->outfile); + fatal(control, "Failed to open history file %s\n", control->outfile); /* Can't copy permissions from STDIN */ if (!STDIN) @@ -682,13 +682,13 @@ void decompress_file(rzip_control *control) } else { fd_out = open_tmpoutfile(control); if (unlikely(fd_out == -1)) - fatal("Failed to create %s\n", control->outfile); + fatal(control, "Failed to create %s\n", control->outfile); fd_hist = open(control->outfile, O_RDONLY); if (unlikely(fd_hist == -1)) - fatal("Failed to open history file %s\n", control->outfile); + fatal(control, "Failed to open history file %s\n", control->outfile); /* Unlink temporary file as soon as possible */ if (unlikely(unlink(control->outfile))) - fatal("Failed to unlink tmpfile: %s\n", control->outfile); + fatal(control, "Failed to unlink tmpfile: %s\n", control->outfile); } open_tmpoutbuf(control); @@ -700,13 +700,13 @@ void decompress_file(rzip_control *control) /* Check if there's enough free space on the device chosen to fit the * decompressed file. */ if (unlikely(fstatvfs(fd_out, &fbuf))) - fatal("Failed to fstatvfs in decompress_file\n"); + fatal(control, "Failed to fstatvfs in decompress_file\n"); free_space = (i64)fbuf.f_bsize * (i64)fbuf.f_bavail; if (free_space < expected_size) { if (FORCE_REPLACE) print_err("Warning, inadequate free space detected, but attempting to decompress due to -f option being used.\n"); else - failure("Inadequate free space to decompress file, use -f to override.\n"); + failure(control, "Inadequate free space to decompress file, use -f to override.\n"); } } control->fd_out = fd_out; @@ -742,13 +742,13 @@ void decompress_file(rzip_control *control) print_progress("[OK] \n"); if (unlikely(close(fd_hist) || close(fd_out))) - fatal("Failed to close files\n"); + fatal(control, "Failed to close files\n"); close(fd_in); if (!KEEP_FILES) { if (unlikely(unlink(control->infile))) - fatal("Failed to unlink %s\n", infilecopy); + fatal(control, "Failed to unlink %s\n", infilecopy); } if (ENCRYPT) @@ -762,18 +762,18 @@ void get_header_info(rzip_control *control, int fd_in, uchar *ctype, i64 *c_len, i64 *u_len, i64 *last_head, int chunk_bytes) { if (unlikely(read(fd_in, ctype, 1) != 1)) - fatal("Failed to read in get_header_info\n"); + fatal(control, "Failed to read in get_header_info\n"); *c_len = *u_len = *last_head = 0; if (control->major_version == 0 && control->minor_version < 4) { u32 c_len32, u_len32, last_head32; if (unlikely(read(fd_in, &c_len32, 4) != 4)) - fatal("Failed to read in get_header_info"); + fatal(control, "Failed to read in get_header_info"); if (unlikely(read(fd_in, &u_len32, 4) != 4)) - fatal("Failed to read in get_header_info"); + fatal(control, "Failed to read in get_header_info"); if (unlikely(read(fd_in, &last_head32, 4) != 4)) - fatal("Failed to read in get_header_info"); + fatal(control, "Failed to read in get_header_info"); c_len32 = le32toh(c_len32); u_len32 = le32toh(u_len32); last_head32 = le32toh(last_head32); @@ -788,11 +788,11 @@ void get_header_info(rzip_control *control, int fd_in, uchar *ctype, i64 *c_len, else read_len = chunk_bytes; if (unlikely(read(fd_in, c_len, read_len) != read_len)) - fatal("Failed to read in get_header_info"); + fatal(control, "Failed to read in get_header_info"); if (unlikely(read(fd_in, u_len, read_len) != read_len)) - fatal("Failed to read in get_header_info"); + fatal(control, "Failed to read in get_header_info"); if (unlikely(read(fd_in, last_head, read_len) != read_len)) - fatal("Failed to read_i64 in get_header_info"); + fatal(control, "Failed to read_i64 in get_header_info"); *c_len = le64toh(*c_len); *u_len = le64toh(*u_len); *last_head = le64toh(*last_head); @@ -833,7 +833,7 @@ void get_fileinfo(rzip_control *control) strcmp(tmp,control->suffix)) { infilecopy = malloc(strlen(control->infile) + strlen(control->suffix) + 1); if (unlikely(infilecopy == NULL)) - fatal("Failed to allocate memory for infile suffix\n"); + fatal(control, "Failed to allocate memory for infile suffix\n"); else { strcpy(infilecopy, control->infile); strcat(infilecopy, control->suffix); @@ -847,12 +847,12 @@ void get_fileinfo(rzip_control *control) else { fd_in = open(infilecopy, O_RDONLY); if (unlikely(fd_in == -1)) - fatal("Failed to open %s\n", infilecopy); + fatal(control, "Failed to open %s\n", infilecopy); } /* Get file size */ if (unlikely(fstat(fd_in, &st))) - fatal("bad magic file descriptor!?\n"); + fatal(control, "bad magic file descriptor!?\n"); infile_size = st.st_size; /* Get decompressed size */ @@ -865,12 +865,12 @@ void get_fileinfo(rzip_control *control) if (control->major_version == 0 && control->minor_version > 4) { if (unlikely(read(fd_in, &chunk_byte, 1) != 1)) - fatal("Failed to read chunk_byte in get_fileinfo\n"); + fatal(control, "Failed to read chunk_byte in get_fileinfo\n"); if (control->major_version == 0 && control->minor_version > 5) { if (unlikely(read(fd_in, &control->eof, 1) != 1)) - fatal("Failed to read eof in get_fileinfo\n"); + fatal(control, "Failed to read eof in get_fileinfo\n"); if (unlikely(read(fd_in, &chunk_size, chunk_byte) != chunk_byte)) - fatal("Failed to read chunk_size in get_fileinfo\n"); + fatal(control, "Failed to read chunk_size in get_fileinfo\n"); chunk_size = le64toh(chunk_size); } } @@ -907,7 +907,7 @@ next_chunk: int block = 1; if (unlikely(lseek(fd_in, stream_head[stream] + ofs, SEEK_SET)) == -1) - fatal("Failed to seek to header data in get_fileinfo\n"); + fatal(control, "Failed to seek to header data in get_fileinfo\n"); get_header_info(control, fd_in, &ctype, &c_len, &u_len, &last_head, chunk_byte); print_verbose("Stream: %d\n", stream); @@ -917,13 +917,13 @@ next_chunk: i64 head_off; if (unlikely(last_head + ofs > infile_size)) - failure("Offset greater than archive size, likely corrupted/truncated archive.\n"); + failure(control, "Offset greater than archive size, likely corrupted/truncated archive.\n"); if (unlikely(head_off = lseek(fd_in, last_head + ofs, SEEK_SET)) == -1) - fatal("Failed to seek to header data in get_fileinfo\n"); + fatal(control, "Failed to seek to header data in get_fileinfo\n"); get_header_info(control, fd_in, &ctype, &c_len, &u_len, &last_head, chunk_byte); if (unlikely(last_head < 0 || c_len < 0 || u_len < 0)) - failure("Entry negative, likely corrupted archive.\n"); + failure(control, "Entry negative, likely corrupted archive.\n"); print_verbose("%d\t", block); if (ctype == CTYPE_NONE) print_verbose("none"); @@ -950,20 +950,20 @@ next_chunk: } if (unlikely((ofs = lseek(fd_in, c_len, SEEK_CUR)) == -1)) - fatal("Failed to lseek c_len in get_fileinfo\n"); + fatal(control, "Failed to lseek c_len in get_fileinfo\n"); if (ofs >= infile_size - (HAS_MD5 ? MD5_DIGEST_SIZE : 0)) goto done; /* Chunk byte entry */ if (control->major_version == 0 && control->minor_version > 4) { if (unlikely(read(fd_in, &chunk_byte, 1) != 1)) - fatal("Failed to read chunk_byte in get_fileinfo\n"); + fatal(control, "Failed to read chunk_byte in get_fileinfo\n"); ofs++; if (control->major_version == 0 && control->minor_version > 5) { if (unlikely(read(fd_in, &control->eof, 1) != 1)) - fatal("Failed to read eof in get_fileinfo\n"); + fatal(control, "Failed to read eof in get_fileinfo\n"); if (unlikely(read(fd_in, &chunk_size, chunk_byte) != chunk_byte)) - fatal("Failed to read chunk_size in get_fileinfo\n"); + fatal(control, "Failed to read chunk_size in get_fileinfo\n"); chunk_size = le64toh(chunk_size); ofs += 1 + chunk_byte; header_length = 1 + (chunk_byte * 3); @@ -972,7 +972,7 @@ next_chunk: goto next_chunk; done: if (unlikely(ofs > infile_size)) - failure("Offset greater than archive size, likely corrupted/truncated archive.\n"); + failure(control, "Offset greater than archive size, likely corrupted/truncated archive.\n"); if (chunk_total > expected_size) expected_size = chunk_total; print_verbose("Rzip compression: %.1f%% %lld / %lld\n", @@ -1014,9 +1014,9 @@ done: print_output("MD5 used for integrity testing\n"); if (unlikely(lseek(fd_in, -MD5_DIGEST_SIZE, SEEK_END)) == -1) - fatal("Failed to seek to md5 data in runzip_fd\n"); + fatal(control, "Failed to seek to md5 data in runzip_fd\n"); if (unlikely(read(fd_in, md5_stored, MD5_DIGEST_SIZE) != MD5_DIGEST_SIZE)) - fatal("Failed to read md5 data in runzip_fd\n"); + fatal(control, "Failed to read md5 data in runzip_fd\n"); print_output("MD5: "); for (i = 0; i < MD5_DIGEST_SIZE; i++) print_output("%02x", md5_stored[i] & 0xFF); @@ -1024,7 +1024,7 @@ done: } else print_output("CRC32 used for integrity testing\n"); if (unlikely(close(fd_in))) - fatal("Failed to close fd_in in get_fileinfo\n"); + fatal(control, "Failed to close fd_in in get_fileinfo\n"); out: free(control->outfile); @@ -1057,7 +1057,7 @@ void compress_file(rzip_control *control) fd_in = open(control->infile, O_RDONLY); if (unlikely(fd_in == -1)) - fatal("Failed to open %s\n", control->infile); + fatal(control, "Failed to open %s\n", control->infile); } else fd_in = 0; @@ -1069,7 +1069,7 @@ void compress_file(rzip_control *control) else if ((tmp=strrchr(control->outname, '.')) && strcmp(tmp, control->suffix)) { control->outfile = malloc(strlen(control->outname) + strlen(control->suffix) + 1); if (unlikely(!control->outfile)) - fatal("Failed to allocate outfile name\n"); + fatal(control, "Failed to allocate outfile name\n"); strcpy(control->outfile, control->outname); strcat(control->outfile, control->suffix); print_output("Suffix added to %s.\nFull pathname is: %s\n", control->outname, control->outfile); @@ -1087,7 +1087,7 @@ void compress_file(rzip_control *control) control->outfile = malloc((control->outdir == NULL? 0: strlen(control->outdir)) + strlen(tmpinfile) + strlen(control->suffix) + 1); if (unlikely(!control->outfile)) - fatal("Failed to allocate outfile name\n"); + fatal(control, "Failed to allocate outfile name\n"); if (control->outdir) { /* prepend control->outdir */ strcpy(control->outfile, control->outdir); @@ -1101,14 +1101,14 @@ void compress_file(rzip_control *control) fd_out = open(control->outfile, O_RDWR | O_CREAT | O_EXCL, 0666); if (FORCE_REPLACE && (-1 == fd_out) && (EEXIST == errno)) { if (unlikely(unlink(control->outfile))) - fatal("Failed to unlink an existing file: %s\n", control->outfile); + fatal(control, "Failed to unlink an existing file: %s\n", control->outfile); fd_out = open(control->outfile, O_RDWR | O_CREAT | O_EXCL, 0666); } if (unlikely(fd_out == -1)) { /* We must ensure we don't delete a file that already * exists just because we tried to create a new one */ control->flags |= FLAG_KEEP_BROKEN; - fatal("Failed to create %s\n", control->outfile); + fatal(control, "Failed to create %s\n", control->outfile); } control->fd_out = fd_out; if (!STDIN) @@ -1118,7 +1118,7 @@ void compress_file(rzip_control *control) /* Write zeroes to header at beginning of file */ if (unlikely(!STDOUT && write(fd_out, header, sizeof(header)) != sizeof(header))) - fatal("Cannot write file header\n"); + fatal(control, "Cannot write file header\n"); rzip_fd(control, fd_in, fd_out); @@ -1130,15 +1130,15 @@ void compress_file(rzip_control *control) release_hashes(control); if (unlikely(close(fd_in))) - fatal("Failed to close fd_in\n"); + fatal(control, "Failed to close fd_in\n"); if (unlikely(!STDOUT && close(fd_out))) - fatal("Failed to close fd_out\n"); + fatal(control, "Failed to close fd_out\n"); if (TMP_OUTBUF) close_tmpoutbuf(control); if (!KEEP_FILES) { if (unlikely(unlink(control->infile))) - fatal("Failed to unlink %s\n", control->infile); + fatal(control, "Failed to unlink %s\n", control->infile); } free(control->outfile); @@ -1151,11 +1151,11 @@ void initialize_control(rzip_control *control) memset(control, 0, sizeof(rzip_control)); control->msgout = stderr; - register_outputfile(control->msgout); + register_outputfile(control, control->msgout); control->flags = FLAG_SHOW_PROGRESS | FLAG_KEEP_FILES | FLAG_THRESHOLD; control->suffix = ".lrz"; control->compression_level = 7; - control->ramsize = get_ram(); + control->ramsize = get_ram(control); /* for testing single CPU */ control->threads = PROCESSORS; /* get CPUs for LZMA */ control->page_size = PAGE_SIZE; @@ -1165,10 +1165,10 @@ void initialize_control(rzip_control *control) * The next 2 bytes encode how many times to hash the password. * The last 9 bytes are random data, making 16 bytes of salt */ if (unlikely(gettimeofday(&tv, NULL))) - fatal("Failed to gettimeofday in main\n"); + fatal(control, "Failed to gettimeofday in main\n"); control->secs = tv.tv_sec; control->encloops = nloops(control->secs, control->salt, control->salt + 1); - get_rand(control->salt + 2, 6); + get_rand(control, control->salt + 2, 6); /* Get Temp Dir */ eptr = getenv("TMP"); @@ -1176,7 +1176,7 @@ void initialize_control(rzip_control *control) size_t len = strlen(eptr); control->tmpdir = malloc(len+2); if (control->tmpdir == NULL) - fatal("Failed to allocate for tmpdir\n"); + fatal(control, "Failed to allocate for tmpdir\n"); strcpy(control->tmpdir, eptr); if (eptr[len - 2] != '/') eptr[len - 2] = '/'; /* need a trailing slash */ diff --git a/lrzip.h b/lrzip.h index e263f20..9ff6649 100644 --- a/lrzip.h +++ b/lrzip.h @@ -21,7 +21,7 @@ #include "lrzip_private.h" -inline i64 get_ram(void); +inline i64 get_ram(rzip_control *control); i64 nloops(i64 seconds, uchar *b1, uchar *b2); void write_magic(rzip_control *control); void read_magic(rzip_control *control, int fd_in, i64 *expected_size); diff --git a/lrzip_private.h b/lrzip_private.h index 02e2ac5..f080323 100644 --- a/lrzip_private.h +++ b/lrzip_private.h @@ -203,6 +203,57 @@ typedef struct md5_ctx md5_ctx; #define MOORE_TIMES_PER_SECOND pow (MOORE, 1.0 / SECONDS_IN_A_YEAR) #define ARBITRARY_AT_EPOCH (ARBITRARY * pow (MOORE_TIMES_PER_SECOND, -T_ZERO)) +#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) +#define LZMA_COMPRESS (!(control->flags & FLAG_NOT_LZMA)) + +#define SHOW_PROGRESS (control->flags & FLAG_SHOW_PROGRESS) +#define KEEP_FILES (control->flags & FLAG_KEEP_FILES) +#define TEST_ONLY (control->flags & FLAG_TEST_ONLY) +#define FORCE_REPLACE (control->flags & FLAG_FORCE_REPLACE) +#define DECOMPRESS (control->flags & FLAG_DECOMPRESS) +#define NO_COMPRESS (control->flags & FLAG_NO_COMPRESS) +#define LZO_COMPRESS (control->flags & FLAG_LZO_COMPRESS) +#define BZIP2_COMPRESS (control->flags & FLAG_BZIP2_COMPRESS) +#define ZLIB_COMPRESS (control->flags & FLAG_ZLIB_COMPRESS) +#define ZPAQ_COMPRESS (control->flags & FLAG_ZPAQ_COMPRESS) +#define VERBOSE (control->flags & FLAG_VERBOSE) +#define VERBOSITY (control->flags & FLAG_VERBOSITY) +#define MAX_VERBOSE (control->flags & FLAG_VERBOSITY_MAX) +#define STDIN (control->flags & FLAG_STDIN) +#define STDOUT (control->flags & FLAG_STDOUT) +#define INFO (control->flags & FLAG_INFO) +#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 KEEP_BROKEN (control->flags & FLAG_KEEP_BROKEN) +#define LZO_TEST (control->flags & FLAG_THRESHOLD) +#define TMP_OUTBUF (control->flags & FLAG_TMP_OUTBUF) +#define TMP_INBUF (control->flags & FLAG_TMP_INBUF) +#define ENCRYPT (control->flags & FLAG_ENCRYPT) + +#define print_output(format, args...) do {\ + fprintf(control->msgout, format, ##args); \ + fflush(control->msgout); \ +} while (0) + +#define print_progress(format, args...) do {\ + if (SHOW_PROGRESS) \ + print_output(format, ##args); \ +} while (0) + +#define print_verbose(format, args...) do {\ + if (VERBOSE) \ + print_output(format, ##args); \ +} while (0) + +#define print_maxverbose(format, args...) do {\ + if (MAX_VERBOSE) \ + print_output(format, ##args); \ +} while (0) + + #define print_err(format, args...) do {\ fprintf(stderr, format, ##args); \ } while (0) @@ -268,6 +319,11 @@ struct rzip_control { unsigned char magic_written; md5_ctx ctx; i64 md5_read; // How far into the file the md5 has done so far + const char *util_infile; + char delete_infile; + const char *util_outfile; + char delete_outfile; + FILE *outputfile; }; struct stream { diff --git a/main.c b/main.c index 654c12b..9aae29f 100644 --- a/main.c +++ b/main.c @@ -122,7 +122,7 @@ static void sighandler(int sig __UNUSED__) termios_p.c_lflag |= ECHO; tcsetattr(fileno(stdin), 0, &termios_p); - unlink_files(); + unlink_files(control); exit(0); } @@ -204,7 +204,7 @@ static void read_config(rzip_control *control) line = malloc(255); homeconf = malloc(255); if (line == NULL || homeconf == NULL) - fatal("Fatal Memory Error in read_config"); + fatal(control, "Fatal Memory Error in read_config"); fp = fopen("lrzip.conf", "r"); if (fp) @@ -255,11 +255,11 @@ static void read_config(rzip_control *control) } else if (isparameter(parameter, "compressionlevel")) { control->compression_level = atoi(parametervalue); if ( control->compression_level < 1 || control->compression_level > 9 ) - failure("CONF.FILE error. Compression Level must between 1 and 9"); + failure(control, "CONF.FILE error. Compression Level must between 1 and 9"); } else if (isparameter(parameter, "compressionmethod")) { /* valid are rzip, gzip, bzip2, lzo, lzma (default), and zpaq */ if (control->flags & FLAG_NOT_LZMA) - failure("CONF.FILE error. Can only specify one compression method"); + failure(control, "CONF.FILE error. Can only specify one compression method"); if (isparameter(parametervalue, "bzip2")) control->flags |= FLAG_BZIP2_COMPRESS; else if (isparameter(parametervalue, "gzip")) @@ -271,7 +271,7 @@ static void read_config(rzip_control *control) else if (isparameter(parametervalue, "zpaq")) control->flags |= FLAG_ZPAQ_COMPRESS; else if (!isparameter(parametervalue, "lzma")) /* oops, not lzma! */ - failure("CONF.FILE error. Invalid compression method %s specified\n",parametervalue); + failure(control, "CONF.FILE error. Invalid compression method %s specified\n",parametervalue); } else if (isparameter(parameter, "lzotest")) { /* default is yes */ if (isparameter(parametervalue, "no")) @@ -287,13 +287,13 @@ static void read_config(rzip_control *control) } else if (isparameter(parameter, "outputdirectory")) { control->outdir = malloc(strlen(parametervalue) + 2); if (!control->outdir) - fatal("Fatal Memory Error in read_config"); + fatal(control, "Fatal Memory Error in read_config"); strcpy(control->outdir, parametervalue); if (strcmp(parametervalue + strlen(parametervalue) - 1, "/")) strcat(control->outdir, "/"); } else if (isparameter(parameter,"verbosity")) { if (control->flags & FLAG_VERBOSE) - failure("CONF.FILE error. Verbosity already defined."); + failure(control, "CONF.FILE error. Verbosity already defined."); if (isparameter(parametervalue, "yes")) control->flags |= FLAG_VERBOSITY; else if (isparameter(parametervalue,"max")) @@ -307,7 +307,7 @@ static void read_config(rzip_control *control) } else if (isparameter(parameter,"nice")) { control->nice_val = atoi(parametervalue); if (control->nice_val < -20 || control->nice_val > 19) - failure("CONF.FILE error. Nice must be between -20 and 19"); + failure(control, "CONF.FILE error. Nice must be between -20 and 19"); } else if (isparameter(parameter, "keepbroken")) { if (isparameter(parametervalue, "yes" )) control->flags |= FLAG_KEEP_BROKEN; @@ -322,7 +322,7 @@ static void read_config(rzip_control *control) } else if (isparameter(parameter, "tmpdir")) { control->tmpdir = realloc(NULL, strlen(parametervalue) + 2); if (!control->tmpdir) - fatal("Fatal Memory Error in read_config"); + fatal(control, "Fatal Memory Error in read_config"); strcpy(control->tmpdir, parametervalue); if (strcmp(parametervalue + strlen(parametervalue) - 1, "/")) strcat(control->tmpdir, "/"); @@ -336,7 +336,7 @@ static void read_config(rzip_control *control) } if (unlikely(fclose(fp))) - fatal("Failed to fclose fp in read_config\n"); + fatal(control, "Failed to fclose fp in read_config\n"); out: /* clean up */ free(line); @@ -387,7 +387,7 @@ int main(int argc, char *argv[]) switch (c) { case 'b': if (control->flags & FLAG_NOT_LZMA) - failure("Can only use one of -l, -b, -g, -z or -n\n"); + failure(control, "Can only use one of -l, -b, -g, -z or -n\n"); control->flags |= FLAG_BZIP2_COMPRESS; break; case 'c': @@ -408,7 +408,7 @@ int main(int argc, char *argv[]) break; case 'g': if (control->flags & FLAG_NOT_LZMA) - failure("Can only use one of -l, -b, -g, -z or -n\n"); + failure(control, "Can only use one of -l, -b, -g, -z or -n\n"); control->flags |= FLAG_ZLIB_COMPRESS; break; case 'h': @@ -426,40 +426,40 @@ int main(int argc, char *argv[]) break; case 'l': if (control->flags & FLAG_NOT_LZMA) - failure("Can only use one of -l, -b, -g, -z or -n\n"); + failure(control, "Can only use one of -l, -b, -g, -z or -n\n"); control->flags |= FLAG_LZO_COMPRESS; break; case 'L': control->compression_level = atoi(optarg); if (control->compression_level < 1 || control->compression_level > 9) - failure("Invalid compression level (must be 1-9)\n"); + failure(control, "Invalid compression level (must be 1-9)\n"); break; case 'n': if (control->flags & FLAG_NOT_LZMA) - failure("Can only use one of -l, -b, -g, -z or -n\n"); + failure(control, "Can only use one of -l, -b, -g, -z or -n\n"); control->flags |= FLAG_NO_COMPRESS; break; case 'N': control->nice_val = atoi(optarg); if (control->nice_val < -20 || control->nice_val > 19) - failure("Invalid nice value (must be -20..19)\n"); + failure(control, "Invalid nice value (must be -20..19)\n"); break; case 'o': if (control->outdir) - failure("Cannot have -o and -O together\n"); + failure(control, "Cannot have -o and -O together\n"); if (unlikely(STDOUT)) - failure("Cannot specify an output filename when outputting to stdout\n"); + failure(control, "Cannot specify an output filename when outputting to stdout\n"); control->outname = optarg; control->suffix = ""; break; case 'O': if (control->outname) /* can't mix -o and -O */ - failure("Cannot have options -o and -O together\n"); + failure(control, "Cannot have options -o and -O together\n"); if (unlikely(STDOUT)) - failure("Cannot specify an output directory when outputting to stdout\n"); + failure(control, "Cannot specify an output directory when outputting to stdout\n"); control->outdir = malloc(strlen(optarg) + 2); if (control->outdir == NULL) - fatal("Failed to allocate for outdir\n"); + fatal(control, "Failed to allocate for outdir\n"); strcpy(control->outdir,optarg); if (strcmp(optarg+strlen(optarg) - 1, "/")) /* need a trailing slash */ strcat(control->outdir, "/"); @@ -467,23 +467,23 @@ int main(int argc, char *argv[]) case 'p': control->threads = atoi(optarg); if (control->threads < 1) - failure("Must have at least one thread\n"); + failure(control, "Must have at least one thread\n"); break; case 'q': control->flags &= ~FLAG_SHOW_PROGRESS; break; case 'S': if (control->outname) - failure("Specified output filename already, can't specify an extension.\n"); + failure(control, "Specified output filename already, can't specify an extension.\n"); if (unlikely(STDOUT)) - failure("Cannot specify a filename suffix when outputting to stdout\n"); + failure(control, "Cannot specify a filename suffix when outputting to stdout\n"); control->suffix = optarg; break; case 't': if (control->outname) - failure("Cannot specify an output file name when just testing.\n"); + failure(control, "Cannot specify an output file name when just testing.\n"); if (!KEEP_FILES) - failure("Doubt that you want to delete a file when just testing.\n"); + failure(control, "Doubt that you want to delete a file when just testing.\n"); control->flags |= FLAG_TEST_ONLY; break; case 'T': @@ -510,7 +510,7 @@ int main(int argc, char *argv[]) break; case 'z': if (control->flags & FLAG_NOT_LZMA) - failure("Can only use one of -l, -b, -g, -z or -n\n"); + failure(control, "Can only use one of -l, -b, -g, -z or -n\n"); control->flags |= FLAG_ZPAQ_COMPRESS; break; } @@ -520,7 +520,7 @@ int main(int argc, char *argv[]) argv += optind; if (control->outname && argc > 1) - failure("Cannot specify output filename with more than 1 file\n"); + failure(control, "Cannot specify output filename with more than 1 file\n"); if (VERBOSE && !SHOW_PROGRESS) { print_err("Cannot have -v and -q options. -v wins.\n"); @@ -566,18 +566,18 @@ int main(int argc, char *argv[]) stat(control->infile, &infile_stat); if (unlikely(S_ISDIR(infile_stat.st_mode))) - failure("lrzip only works directly on FILES.\n" + failure(control, "lrzip only works directly on FILES.\n" "Use lrztar or pipe through tar for compressing directories.\n"); } } if (INFO && STDIN) - failure("Will not get file info from STDIN\n"); + failure(control, "Will not get file info from STDIN\n"); if (control->outname && (strcmp(control->outname, "-") == 0)) { control->flags |= FLAG_STDOUT; control->msgout = stderr; - register_outputfile(control->msgout); + register_outputfile(control, control->msgout); } /* If no output filename is specified, and we're using stdin, @@ -585,12 +585,12 @@ int main(int argc, char *argv[]) if (!control->outname && STDIN) { control->flags |= FLAG_STDOUT; control->msgout = stderr; - register_outputfile(control->msgout); + register_outputfile(control, control->msgout); } if (!STDOUT) { control->msgout = stdout; - register_outputfile(control->msgout); + register_outputfile(control, control->msgout); } /* Implement signal handler only once flags are set */ handler.sa_handler = &sighandler; @@ -626,7 +626,7 @@ int main(int argc, char *argv[]) gettimeofday(&start_time, NULL); if (unlikely(STDIN && ENCRYPT)) - failure("Unable to work from STDIN while reading password\n"); + failure(control, "Unable to work from STDIN while reading password\n"); if (DECOMPRESS || TEST_ONLY) decompress_file(control); diff --git a/runzip.c b/runzip.c index 62e090d..e882c53 100644 --- a/runzip.c +++ b/runzip.c @@ -54,7 +54,7 @@ static inline uchar read_u8(rzip_control *control, void *ss, int stream) uchar b; if (unlikely(read_stream(control, ss, stream, &b, 1) != 1)) - fatal("Stream read u8 failed\n"); + fatal(control, "Stream read u8 failed\n"); return b; } @@ -63,7 +63,7 @@ static inline u32 read_u32(rzip_control *control, void *ss, int stream) u32 ret; if (unlikely(read_stream(control, ss, stream, (uchar *)&ret, 4) != 4)) - fatal("Stream read u32 failed\n"); + fatal(control, "Stream read u32 failed\n"); ret = le32toh(ret); return ret; } @@ -74,7 +74,7 @@ static inline i64 read_vchars(rzip_control *control, void *ss, int stream, int l i64 s = 0; if (unlikely(read_stream(control, ss, stream, (uchar *)&s, length) != length)) - fatal("Stream read of %d bytes failed\n", length); + fatal(control, "Stream read of %d bytes failed\n", length); s = le64toh(s); return s; } @@ -128,7 +128,7 @@ static i64 seekto_fdinend(rzip_control *control) while ((tmpchar = getchar()) != EOF) { control->tmp_inbuf[control->in_len++] = (char)tmpchar; if (unlikely(control->in_len > control->in_maxlen)) - failure("Trying to read greater than max_len\n"); + failure(control, "Trying to read greater than max_len\n"); } control->in_ofs = control->in_len; return control->in_ofs; @@ -151,18 +151,18 @@ static i64 unzip_literal(rzip_control *control, void *ss, i64 len, uint32 *cksum uchar *buf; if (unlikely(len < 0)) - failure("len %lld is negative in unzip_literal!\n",len); + failure(control, "len %lld is negative in unzip_literal!\n",len); buf = (uchar *)malloc(len); if (unlikely(!buf)) - fatal("Failed to malloc literal buffer of size %lld\n", len); + fatal(control, "Failed to malloc literal buffer of size %lld\n", len); stream_read = read_stream(control, ss, 1, buf, len); if (unlikely(stream_read == -1 )) - fatal("Failed to read_stream in unzip_literal\n"); + fatal(control, "Failed to read_stream in unzip_literal\n"); if (unlikely(write_1g(control, buf, (size_t)stream_read) != (ssize_t)stream_read)) - fatal("Failed to write literal buffer of size %lld\n", stream_read); + fatal(control, "Failed to write literal buffer of size %lld\n", stream_read); if (!HAS_MD5) *cksum = CrcUpdate(*cksum, buf, stream_read); @@ -191,32 +191,32 @@ static i64 unzip_match(rzip_control *control, void *ss, i64 len, uint32 *cksum, uchar *buf, *off_buf; if (unlikely(len < 0)) - failure("len %lld is negative in unzip_match!\n",len); + failure(control, "len %lld is negative in unzip_match!\n",len); total = 0; cur_pos = seekcur_fdout(control); if (unlikely(cur_pos == -1)) - fatal("Seek failed on out file in unzip_match.\n"); + fatal(control, "Seek failed on out file in unzip_match.\n"); /* Note the offset is in a different format v0.40+ */ offset = read_vchars(control, ss, 0, chunk_bytes); if (unlikely(seekto_fdhist(control, cur_pos - offset) == -1)) - fatal("Seek failed by %d from %d on history file in unzip_match\n", + fatal(control, "Seek failed by %d from %d on history file in unzip_match\n", offset, cur_pos); buf = (uchar *)malloc(len); if (unlikely(!buf)) - fatal("Failed to malloc match buffer of size %lld\n", len); + fatal(control, "Failed to malloc match buffer of size %lld\n", len); off_buf = buf; while (len) { n = MIN(len, offset); if (unlikely(read_fdhist(control, off_buf, (size_t)n) != (ssize_t)n)) - fatal("Failed to read %d bytes in unzip_match\n", n); + fatal(control, "Failed to read %d bytes in unzip_match\n", n); if (unlikely(write_1g(control, off_buf, (size_t)n) != (ssize_t)n)) - fatal("Failed to write %d bytes in unzip_match\n", n); + fatal(control, "Failed to write %d bytes in unzip_match\n", n); if (!HAS_MD5) *cksum = CrcUpdate(*cksum, off_buf, n); @@ -233,7 +233,7 @@ static i64 unzip_match(rzip_control *control, void *ss, i64 len, uint32 *cksum, return total; } -/* decompress a section of an open file. Call fatal() on error +/* decompress a section of an open file. Call fatal(control, ) on error return the number of bytes that have been retrieved */ static i64 runzip_chunk(rzip_control *control, int fd_in, i64 expected_size, i64 tally) @@ -273,9 +273,9 @@ static i64 runzip_chunk(rzip_control *control, int fd_in, i64 expected_size, i64 else { /* Read in the stored chunk byte width from the file */ if (unlikely(read_1g(control, fd_in, &chunk_bytes, 1) != 1)) - fatal("Failed to read chunk_bytes size in runzip_chunk\n"); + fatal(control, "Failed to read chunk_bytes size in runzip_chunk\n"); if (unlikely(chunk_bytes < 1 || chunk_bytes > 8)) - failure("chunk_bytes %d is invalid in runzip_chunk\n", chunk_bytes); + failure(control, "chunk_bytes %d is invalid in runzip_chunk\n", chunk_bytes); } if (!tally && expected_size) print_maxverbose("Expected size: %lld\n", expected_size); @@ -283,14 +283,14 @@ static i64 runzip_chunk(rzip_control *control, int fd_in, i64 expected_size, i64 ofs = seekcur_fdin(control); if (unlikely(ofs == -1)) - fatal("Failed to seek input file in runzip_fd\n"); + fatal(control, "Failed to seek input file in runzip_fd\n"); if (fstat(fd_in, &st) || st.st_size - ofs == 0) return 0; ss = open_stream_in(control, fd_in, NUM_STREAMS, chunk_bytes); if (unlikely(!ss)) - failure("Failed to open_stream_in in runzip_chunk\n"); + failure(control, "Failed to open_stream_in in runzip_chunk\n"); while ((len = read_header(control, ss, &head)) || head) { switch (head) { @@ -316,17 +316,17 @@ static i64 runzip_chunk(rzip_control *control, int fd_in, i64 expected_size, i64 if (!HAS_MD5) { good_cksum = read_u32(control, ss, 0); if (unlikely(good_cksum != cksum)) - failure("Bad checksum: 0x%08x - expected: 0x%08x\n", cksum, good_cksum); + failure(control, "Bad checksum: 0x%08x - expected: 0x%08x\n", cksum, good_cksum); print_maxverbose("Checksum for block: 0x%08x\n", cksum); } if (unlikely(close_stream_in(ss))) - fatal("Failed to close stream!\n"); + fatal(control, "Failed to close stream!\n"); return total; } -/* Decompress an open file. Call fatal() on error +/* Decompress an open file. Call fatal(control, ) on error return the number of bytes that have been retrieved */ i64 runzip_fd(rzip_control *control, int fd_in, int fd_out, int fd_hist, i64 expected_size) @@ -365,12 +365,12 @@ i64 runzip_fd(rzip_control *control, int fd_in, int fd_out, int fd_hist, i64 exp i64 fdinend = seekto_fdinend(control); if (unlikely(fdinend == -1)) - failure("Failed to seekto_fdinend in rzip_fd\n"); + failure(control, "Failed to seekto_fdinend in rzip_fd\n"); if (unlikely(seekto_fdin(control, fdinend - MD5_DIGEST_SIZE) == -1)) - failure("Failed to seekto_fdin in rzip_fd\n"); + failure(control, "Failed to seekto_fdin in rzip_fd\n"); if (unlikely(read_1g(control, fd_in, md5_stored, MD5_DIGEST_SIZE) != MD5_DIGEST_SIZE)) - fatal("Failed to read md5 data in runzip_fd\n"); + fatal(control, "Failed to read md5 data in runzip_fd\n"); if (ENCRYPT) lrz_decrypt(control, md5_stored, MD5_DIGEST_SIZE, control->salt_pass); for (i = 0; i < MD5_DIGEST_SIZE; i++) @@ -381,7 +381,7 @@ i64 runzip_fd(rzip_control *control, int fd_in, int fd_out, int fd_hist, i64 exp print_output("\nOutput file:"); for (j = 0; j < MD5_DIGEST_SIZE; j++) print_output("%02x", md5_resblock[j] & 0xFF); - failure("\n"); + failure(control, "\n"); } } @@ -400,11 +400,11 @@ i64 runzip_fd(rzip_control *control, int fd_in, int fd_out, int fd_hist, i64 exp close_tmpoutbuf(control); memcpy(md5_stored, md5_resblock, MD5_DIGEST_SIZE); if (unlikely(seekto_fdhist(control, 0) == -1)) - fatal("Failed to seekto_fdhist in runzip_fd\n"); + fatal(control, "Failed to seekto_fdhist in runzip_fd\n"); if (unlikely((md5_fstream = fdopen(fd_hist, "r")) == NULL)) - fatal("Failed to fdopen fd_hist in runzip_fd\n"); + fatal(control, "Failed to fdopen fd_hist in runzip_fd\n"); if (unlikely(md5_stream(md5_fstream, md5_resblock))) - fatal("Failed to md5_stream in runzip_fd\n"); + fatal(control, "Failed to md5_stream in runzip_fd\n"); /* We don't 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]) { @@ -414,7 +414,7 @@ i64 runzip_fd(rzip_control *control, int fd_in, int fd_out, int fd_hist, i64 exp print_output("\nOutput file:"); for (j = 0; j < MD5_DIGEST_SIZE; j++) print_output("%02x", md5_resblock[j] & 0xFF); - failure("\n"); + failure(control, "\n"); } print_output("MD5 integrity of written file matches archive\n"); if (!HAS_MD5) diff --git a/rzip.c b/rzip.c index 58d2f31..6351450 100644 --- a/rzip.c +++ b/rzip.c @@ -150,19 +150,19 @@ static void remap_low_sb(rzip_control *control) round_to_page(&new_offset); print_maxverbose("Sliding main buffer to offset %lld\n", new_offset); if (unlikely(munmap(sb.buf_low, sb.size_low))) - fatal("Failed to munmap in remap_low_sb\n"); + fatal(control, "Failed to munmap in remap_low_sb\n"); if (new_offset + sb.size_low > sb.orig_size) sb.size_low = sb.orig_size - new_offset; sb.offset_low = new_offset; sb.buf_low = (uchar *)mmap(sb.buf_low, sb.size_low, PROT_READ, MAP_SHARED, sb.fd, sb.orig_offset + sb.offset_low); if (unlikely(sb.buf_low == MAP_FAILED)) - fatal("Failed to re mmap in remap_low_sb\n"); + fatal(control, "Failed to re mmap in remap_low_sb\n"); } static inline void remap_high_sb(rzip_control *control, i64 p) { if (unlikely(munmap(sb.buf_high, sb.size_high))) - fatal("Failed to munmap in remap_high_sb\n"); + fatal(control, "Failed to munmap in remap_high_sb\n"); sb.size_high = sb.high_length; /* In case we shrunk it when we hit the end of the file */ sb.offset_high = p; /* Make sure offset is rounded to page size of total offset */ @@ -171,7 +171,7 @@ static inline void remap_high_sb(rzip_control *control, i64 p) sb.size_high = sb.orig_size - sb.offset_high; sb.buf_high = (uchar *)mmap(sb.buf_high, sb.size_high, PROT_READ, MAP_SHARED, sb.fd, sb.orig_offset + sb.offset_high); if (unlikely(sb.buf_high == MAP_FAILED)) - fatal("Failed to re mmap in remap_high_sb\n"); + fatal(control, "Failed to re mmap in remap_high_sb\n"); } /* We use a "sliding mmap" to effectively read more than we can fit into the @@ -199,14 +199,14 @@ static uchar *get_sb(rzip_control *control, i64 p) static inline void put_u8(rzip_control *control, void *ss, uchar b) { if (unlikely(write_stream(control, ss, 0, &b, 1))) - fatal("Failed to put_u8\n"); + fatal(control, "Failed to put_u8\n"); } static inline void put_u32(rzip_control *control, void *ss, uint32_t s) { s = htole32(s); if (unlikely(write_stream(control, ss, 0, (uchar *)&s, 4))) - fatal("Failed to put_u32\n"); + fatal(control, "Failed to put_u32\n"); } /* Put a variable length of bytes dependant on how big the chunk is */ @@ -214,7 +214,7 @@ static inline void put_vchars(rzip_control *control, void *ss, i64 s, int length { s = htole64(s); if (unlikely(write_stream(control, ss, 0, (uchar *)&s, length))) - fatal("Failed to put_vchars\n"); + fatal(control, "Failed to put_vchars\n"); } static void put_header(rzip_control *control, void *ss, uchar head, i64 len) @@ -280,7 +280,7 @@ static void put_literal(rzip_control *control, struct rzip_state *st, i64 last, put_header(control, st->ss, 0, len); if (unlikely(len && write_sbstream(control, st->ss, 1, last, len))) - fatal("Failed to write_stream in put_literal\n"); + fatal(control, "Failed to write_stream in put_literal\n"); last += len; } while (p > last); } @@ -544,7 +544,7 @@ static void hash_search(rzip_control *control, struct rzip_state *st, double pct } if (unlikely(!st->hash_table)) - fatal("Failed to allocate hash table in hash_search\n"); + fatal(control, "Failed to allocate hash table in hash_search\n"); st->minimum_tag_mask = tag_mask; st->tag_clean_ptr = 0; @@ -621,7 +621,7 @@ static void hash_search(rzip_control *control, struct rzip_state *st, double pct uchar *ckbuf = malloc(n); if (unlikely(!ckbuf)) - fatal("Failed to malloc ckbuf in hash_search\n"); + fatal(control, "Failed to malloc ckbuf in hash_search\n"); for (i = 0; i < n; i++) memcpy(ckbuf + i, get_sb(control, cksum_limit + i), 1); st->cksum = CrcUpdate(st->cksum, ckbuf, n); @@ -643,7 +643,7 @@ static void hash_search(rzip_control *control, struct rzip_state *st, double pct uchar *ckbuf = malloc(n); if (unlikely(!ckbuf)) - fatal("Failed to malloc ckbuf in hash_search\n"); + fatal(control, "Failed to malloc ckbuf in hash_search\n"); for (i = 0; i < n; i++) memcpy(ckbuf + i, get_sb(control, cksum_limit + i), 1); st->cksum = CrcUpdate(st->cksum, ckbuf, n); @@ -688,7 +688,7 @@ static void mmap_stdin(rzip_control *control, uchar *buf, struct rzip_state *st) ret = MIN(len, one_g); ret = read(0, offset_buf, (size_t)ret); if (unlikely(ret < 0)) - fatal("Failed to read in mmap_stdin\n"); + fatal(control, "Failed to read in mmap_stdin\n"); total += ret; if (ret == 0) { /* Should be EOF */ @@ -703,7 +703,7 @@ static void mmap_stdin(rzip_control *control, uchar *buf, struct rzip_state *st) st->chunk_size = 0; } if (unlikely(buf == MAP_FAILED)) - fatal("Failed to remap to smaller buf in mmap_stdin\n"); + fatal(control, "Failed to remap to smaller buf in mmap_stdin\n"); control->eof = st->stdin_eof = 1; break; } @@ -723,7 +723,7 @@ static void init_sliding_mmap(rzip_control *control, struct rzip_state *st, int sb.high_length += control->page_size - (sb.high_length % control->page_size); sb.buf_high = (uchar *)mmap(NULL, sb.high_length, PROT_READ, MAP_SHARED, fd_in, offset); if (unlikely(sb.buf_high == MAP_FAILED)) - fatal("Unable to mmap buf_high in init_sliding_mmap\n"); + fatal(control, "Unable to mmap buf_high in init_sliding_mmap\n"); sb.size_high = sb.high_length; sb.offset_high = 0; } @@ -743,21 +743,21 @@ static void rzip_chunk(rzip_control *control, struct rzip_state *st, int fd_in, st->ss = open_stream_out(control, fd_out, NUM_STREAMS, st->chunk_size, st->chunk_bytes); if (unlikely(!st->ss)) - fatal("Failed to open streams in rzip_chunk\n"); + fatal(control, "Failed to open streams in rzip_chunk\n"); print_verbose("Beginning rzip pre-processing phase\n"); hash_search(control, st, pct_base, pct_multiple); /* unmap buffer before closing and reallocating streams */ if (unlikely(munmap(sb.buf_low, sb.size_low))) - fatal("Failed to munmap in rzip_chunk\n"); + fatal(control, "Failed to munmap in rzip_chunk\n"); if (!STDIN) { if (unlikely(munmap(sb.buf_high, sb.size_high))) - fatal("Failed to munmap in rzip_chunk\n"); + fatal(control, "Failed to munmap in rzip_chunk\n"); } if (unlikely(close_stream_out(control, st->ss))) - fatal("Failed to flush/close streams in rzip_chunk\n"); + fatal(control, "Failed to flush/close streams in rzip_chunk\n"); } /* compress a whole file chunks at a time */ @@ -784,15 +784,15 @@ void rzip_fd(rzip_control *control, int fd_in, int fd_out) st = calloc(sizeof(*st), 1); if (unlikely(!st)) - fatal("Failed to allocate control state in rzip_fd\n"); + fatal(control, "Failed to allocate control state in rzip_fd\n"); if (LZO_COMPRESS) { if (unlikely(lzo_init() != LZO_E_OK)) - fatal("lzo_init() failed\n"); + fatal(control, "lzo_init() failed\n"); } if (unlikely(fstat(fd_in, &s))) - fatal("Failed to stat fd_in in rzip_fd\n"); + fatal(control, "Failed to stat fd_in in rzip_fd\n"); if (!STDIN) { len = control->st_size = s.st_size; @@ -805,13 +805,13 @@ void rzip_fd(rzip_control *control, int fd_in, int fd_out) * compressed file, based on the compressed file being as large as the * uncompressed file. */ if (unlikely(fstatvfs(fd_out, &fbuf))) - fatal("Failed to fstatvfs in compress_file\n"); + fatal(control, "Failed to fstatvfs in compress_file\n"); free_space = (i64)fbuf.f_bsize * (i64)fbuf.f_bavail; if (free_space < control->st_size) { if (FORCE_REPLACE) print_err("Warning, possibly inadequate free space detected, but attempting to compress due to -f option being used.\n"); else - failure("Possibly inadequate free space to compress file, use -f to override.\n"); + failure(control, "Possibly inadequate free space to compress file, use -f to override.\n"); } } @@ -879,11 +879,11 @@ retry: /* Better to shrink the window to the largest size that works than fail */ if (sb.buf_low == MAP_FAILED) { if (unlikely(errno != ENOMEM)) - fatal("Failed to mmap %s\n", control->infile); + fatal(control, "Failed to mmap %s\n", control->infile); st->mmap_size = st->mmap_size / 10 * 9; round_to_page(&st->mmap_size); if (unlikely(!st->mmap_size)) - fatal("Unable to mmap any ram\n"); + fatal(control, "Unable to mmap any ram\n"); goto retry; } st->chunk_size = st->mmap_size; @@ -893,11 +893,11 @@ retry: sb.buf_low = (uchar *)mmap(sb.buf_low, st->mmap_size, PROT_READ, MAP_SHARED, fd_in, offset); if (sb.buf_low == MAP_FAILED) { if (unlikely(errno != ENOMEM)) - fatal("Failed to mmap %s\n", control->infile); + fatal(control, "Failed to mmap %s\n", control->infile); st->mmap_size = st->mmap_size / 10 * 9; round_to_page(&st->mmap_size); if (unlikely(!st->mmap_size)) - fatal("Unable to mmap any ram\n"); + fatal(control, "Unable to mmap any ram\n"); goto retry; } if (st->mmap_size < st->chunk_size) @@ -976,7 +976,7 @@ retry: last_chunk = st->chunk_size; len -= st->chunk_size; if (unlikely(len > 0 && control->eof)) - failure("Wrote EOF to file yet chunk_size was shrunk, corrupting archive.\n"); + failure(control, "Wrote EOF to file yet chunk_size was shrunk, corrupting archive.\n"); } close_streamout_threads(control); @@ -996,7 +996,7 @@ retry: if (ENCRYPT) lrz_encrypt(control, md5_resblock, MD5_DIGEST_SIZE, control->salt_pass); if (unlikely(write_1g(control, md5_resblock, MD5_DIGEST_SIZE) != MD5_DIGEST_SIZE)) - fatal("Failed to write md5 in rzip_fd\n"); + fatal(control, "Failed to write md5 in rzip_fd\n"); } if (TMP_OUTBUF) @@ -1026,3 +1026,11 @@ retry: free(st); } + +void rzip_control_free(rzip_control *control) +{ + if (!control) return; + + free(control->tmpdir); + free(control); +} diff --git a/rzip.h b/rzip.h index 9c10a65..29b2e17 100644 --- a/rzip.h +++ b/rzip.h @@ -22,5 +22,6 @@ #include "lrzip_private.h" void rzip_fd(rzip_control *control, int fd_in, int fd_out); +void rzip_control_free(rzip_control *control); #endif diff --git a/stream.c b/stream.c index 9a6f923..7f83c62 100644 --- a/stream.c +++ b/stream.c @@ -65,8 +65,8 @@ #ifdef __APPLE__ -# define fmemopen fake_fmemopen -# define open_memstream fake_open_memstream +# define fmemopen(s, len, modes) fake_fmemopen(control, (s), (len), (modes)) +# define open_memstream(bufloc, sizeloc) fake_open_memstream(control, (bufloc), (sizeloc)) # define memstream_update_buffer fake_open_memstream_update_buffer # define mremap fake_mremap #else @@ -105,53 +105,53 @@ static pthread_mutex_t output_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t output_cond = PTHREAD_COND_INITIALIZER; static pthread_t *threads; -static void init_mutex(pthread_mutex_t *mutex) +static void init_mutex(rzip_control *control, pthread_mutex_t *mutex) { if (unlikely(pthread_mutex_init(mutex, NULL))) - fatal("pthread_mutex_init failed"); + fatal(control, "pthread_mutex_init failed"); } -static void unlock_mutex(pthread_mutex_t *mutex) +static void unlock_mutex(rzip_control *control, pthread_mutex_t *mutex) { if (unlikely(pthread_mutex_unlock(mutex))) - fatal("pthread_mutex_unlock failed"); + fatal(control, "pthread_mutex_unlock failed"); } -static void lock_mutex(pthread_mutex_t *mutex) +static void lock_mutex(rzip_control *control, pthread_mutex_t *mutex) { if (unlikely(pthread_mutex_lock(mutex))) - fatal("pthread_mutex_lock failed"); + fatal(control, "pthread_mutex_lock failed"); } -static void cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +static void cond_wait(rzip_control *control, pthread_cond_t *cond, pthread_mutex_t *mutex) { if (unlikely(pthread_cond_wait(cond, mutex))) - fatal("pthread_cond_wait failed"); + fatal(control, "pthread_cond_wait failed"); } -static void cond_broadcast(pthread_cond_t *cond) +static void cond_broadcast(rzip_control *control, pthread_cond_t *cond) { if (unlikely(pthread_cond_broadcast(cond))) - fatal("pthread_cond_broadcast failed"); + fatal(control, "pthread_cond_broadcast failed"); } -void create_pthread(pthread_t *thread, pthread_attr_t * attr, +void create_pthread(rzip_control *control, pthread_t *thread, pthread_attr_t * attr, void * (*start_routine)(void *), void *arg) { if (unlikely(pthread_create(thread, attr, start_routine, arg))) - fatal("pthread_create"); + fatal(control, "pthread_create"); } -void detach_pthread(pthread_t *thread) +void detach_pthread(rzip_control *control, pthread_t *thread) { if (unlikely(pthread_detach(*thread))) - fatal("pthread_detach"); + fatal(control, "pthread_detach"); } -void join_pthread(pthread_t th, void **thread_return) +void join_pthread(rzip_control *control, pthread_t th, void **thread_return) { if (pthread_join(th, thread_return)) - fatal("pthread_join"); + fatal(control, "pthread_join"); } /* just to keep things clean, declare function here @@ -159,12 +159,12 @@ void join_pthread(pthread_t th, void **thread_return) */ static int lzo_compresses(rzip_control *control, uchar *s_buf, i64 s_len); -static inline FILE *fake_fmemopen(void *buf, size_t buflen, char *mode) +static inline FILE *fake_fmemopen(rzip_control *control, void *buf, size_t buflen, char *mode) { FILE *in; if (unlikely(strcmp(mode, "r"))) - failure("fake_fmemopen only supports mode \"r\"."); + failure(control, "fake_fmemopen only supports mode \"r\"."); in = tmpfile(); if (unlikely(!in)) return NULL; @@ -174,12 +174,12 @@ static inline FILE *fake_fmemopen(void *buf, size_t buflen, char *mode) return in; } -static inline FILE *fake_open_memstream(char **buf, size_t *length) +static inline FILE *fake_open_memstream(rzip_control *control, char **buf, size_t *length) { FILE *out; if (unlikely(buf == NULL || length == NULL)) - failure("NULL parameter to fake_open_memstream"); + failure(control, "NULL parameter to fake_open_memstream"); out = tmpfile(); if (unlikely(!out)) return NULL; @@ -239,7 +239,7 @@ static int zpaq_compress_buf(rzip_control *control, struct compress_thread *cthr (int)(SHOW_PROGRESS), thread); if (unlikely(memstream_update_buffer(out, &c_buf, &dlen))) - fatal("Failed to memstream_update_buffer in zpaq_compress_buf"); + fatal(control, "Failed to memstream_update_buffer in zpaq_compress_buf"); fclose(in); fclose(out); @@ -501,7 +501,7 @@ static int zpaq_decompress_buf(rzip_control *control, struct uncomp_thread *ucth zpipe_decompress(in, out, control->msgout, ucthread->u_len, (int)(SHOW_PROGRESS), thread); if (unlikely(memstream_update_buffer(out, &c_buf, &dlen))) - fatal("Failed to memstream_update_buffer in zpaq_decompress_buf"); + fatal(control, "Failed to memstream_update_buffer in zpaq_decompress_buf"); fclose(in); fclose(out); @@ -715,7 +715,7 @@ static void read_fdin(struct rzip_control *control, i64 len) for (i = 0; i < len; i++) { tmpchar = getchar(); if (unlikely(tmpchar == EOF)) - failure("Reached end of file on STDIN prematurely on read_fdin, asked for %lld got %lld\n", + failure(control, "Reached end of file on STDIN prematurely on read_fdin, asked for %lld got %lld\n", len, i); control->tmp_inbuf[control->in_ofs + i] = (char)tmpchar; } @@ -747,7 +747,7 @@ ssize_t read_1g(rzip_control *control, int fd, void *buf, i64 len) if (TMP_OUTBUF && fd == control->fd_out) { if (unlikely(control->out_ofs + len > control->out_maxlen)) - failure("Trying to read beyond out_ofs in tmpoutbuf\n"); + failure(control, "Trying to read beyond out_ofs in tmpoutbuf\n"); memcpy(buf, control->tmp_outbuf + control->out_ofs, len); control->out_ofs += len; return len; @@ -896,7 +896,7 @@ static i64 get_seek(rzip_control *control, int fd) return control->out_relofs + control->out_ofs; ret = lseek(fd, 0, SEEK_CUR); if (unlikely(ret == -1)) - fatal("Failed to lseek in get_seek\n"); + fatal(control, "Failed to lseek in get_seek\n"); return ret; } @@ -908,7 +908,7 @@ static i64 get_readseek(rzip_control *control, int fd) return control->in_ofs; ret = lseek(fd, 0, SEEK_CUR); if (unlikely(ret == -1)) - fatal("Failed to lseek in get_seek\n"); + fatal(control, "Failed to lseek in get_seek\n"); return ret; } @@ -926,14 +926,14 @@ void prepare_streamout_threads(rzip_control *control) control->threads = 1; threads = calloc(sizeof(pthread_t), control->threads); if (unlikely(!threads)) - fatal("Unable to calloc threads in prepare_streamout_threads\n"); + fatal(control, "Unable to calloc threads in prepare_streamout_threads\n"); cthread = calloc(sizeof(struct compress_thread), control->threads); if (unlikely(!cthread)) - fatal("Unable to calloc cthread in prepare_streamout_threads\n"); + fatal(control, "Unable to calloc cthread in prepare_streamout_threads\n"); for (i = 0; i < control->threads; i++) - init_mutex(&cthread[i].mutex); + init_mutex(control, &cthread[i].mutex); } @@ -944,7 +944,7 @@ void close_streamout_threads(rzip_control *control) /* Wait for the threads in the correct order in case they end up * serialised */ for (i = 0; i < control->threads; i++) { - lock_mutex(&cthread[close_thread].mutex); + lock_mutex(control, &cthread[close_thread].mutex); if (++close_thread == control->threads) close_thread = 0; } @@ -1045,7 +1045,7 @@ retest_malloc: for (i = 0; i < n; i++) { sinfo->s[i].buf = calloc(sinfo->bufsize , 1); if (unlikely(!sinfo->s[i].buf)) - fatal("Unable to malloc buffer of size %lld in open_stream_out\n", sinfo->bufsize); + fatal(control, "Unable to malloc buffer of size %lld in open_stream_out\n", sinfo->bufsize); } return (void *)sinfo; @@ -1095,7 +1095,7 @@ void *open_stream_in(rzip_control *control, int f, int n, char chunk_bytes) ucthread = calloc(sizeof(struct uncomp_thread), total_threads); if (unlikely(!ucthread)) - fatal("Unable to calloc cthread in open_stream_in\n"); + fatal(control, "Unable to calloc cthread in open_stream_in\n"); sinfo->num_streams = n; sinfo->fd = f; @@ -1227,22 +1227,22 @@ static void rewrite_encrypted(rzip_control *control, struct stream_info *sinfo, cur_ofs = get_seek(control, sinfo->fd) - sinfo->initial_pos; head = malloc(25 + SALT_LEN); if (unlikely(!head)) - fatal("Failed to malloc head in rewrite_encrypted\n"); + fatal(control, "Failed to malloc head in rewrite_encrypted\n"); buf = head + SALT_LEN; - get_rand(head, SALT_LEN); + get_rand(control, head, SALT_LEN); if (unlikely(seekto(control, sinfo, ofs - SALT_LEN))) - failure("Failed to seekto buf ofs in rewrite_encrypted\n"); + failure(control, "Failed to seekto buf ofs in rewrite_encrypted\n"); if (unlikely(write_buf(control, head, SALT_LEN))) - failure("Failed to write_buf head in rewrite_encrypted\n"); + failure(control, "Failed to write_buf head in rewrite_encrypted\n"); if (unlikely(read_buf(control, sinfo->fd, buf, 25))) - failure("Failed to read_buf buf in rewrite_encrypted\n"); + failure(control, "Failed to read_buf buf in rewrite_encrypted\n"); lrz_encrypt(control, buf, 25, head); if (unlikely(seekto(control, sinfo, ofs))) - failure("Failed to seek back to ofs in rewrite_encrypted\n"); + failure(control, "Failed to seek back to ofs in rewrite_encrypted\n"); if (unlikely(write_buf(control, buf, 25))) - failure("Failed to write_buf encrypted buf in rewrite_encrypted\n"); + failure(control, "Failed to write_buf encrypted buf in rewrite_encrypted\n"); free(head); seekto(control, sinfo, cur_ofs); } @@ -1287,7 +1287,7 @@ retry: ret = gzip_compress_buf(control, cti); else if (ZPAQ_COMPRESS) ret = zpaq_compress_buf(control, cti, i); - else failure("Dunno wtf compression to use!\n"); + else failure(control, "Dunno wtf compression to use!\n"); } padded_len = cti->c_len; @@ -1298,21 +1298,21 @@ retry: padded_len = MIN_SIZE; cti->s_buf = realloc(cti->s_buf, MIN_SIZE); if (unlikely(!cti->s_buf)) - fatal("Failed to realloc s_buf in compthread\n"); - get_rand(cti->s_buf + cti->c_len, MIN_SIZE - cti->c_len); + fatal(control, "Failed to realloc s_buf in compthread\n"); + get_rand(control, cti->s_buf + cti->c_len, MIN_SIZE - cti->c_len); } /* If compression fails for whatever reason multithreaded, then wait * for the previous thread to finish, serialising the work to decrease * the memory requirements, increasing the chance of success */ if (unlikely(ret && waited)) - failure("Failed to compress in compthread\n"); + failure(control, "Failed to compress in compthread\n"); if (!waited) { - lock_mutex(&output_lock); + lock_mutex(control, &output_lock); while (output_thread != i) - cond_wait(&output_cond, &output_lock); - unlock_mutex(&output_lock); + cond_wait(control, &output_cond, &output_lock); + unlock_mutex(control, &output_lock); waited = 1; } if (unlikely(ret)) { @@ -1352,7 +1352,7 @@ retry: * later */ if (ENCRYPT) { if (unlikely(write_val(control, 0, SALT_LEN))) - fatal("Failed to write_buf blank salt in compthread %d\n", i); + fatal(control, "Failed to write_buf blank salt in compthread %d\n", i); ctis->cur_pos += SALT_LEN; } ctis->s[j].last_head = ctis->cur_pos + 1 + (write_len * 2); @@ -1365,23 +1365,23 @@ retry: } if (unlikely(seekto(control, ctis, ctis->s[cti->streamno].last_head))) - fatal("Failed to seekto in compthread %d\n", i); + fatal(control, "Failed to seekto in compthread %d\n", i); if (unlikely(write_val(control, ctis->cur_pos, write_len))) - fatal("Failed to write_val cur_pos in compthread %d\n", i); + fatal(control, "Failed to write_val cur_pos in compthread %d\n", i); if (ENCRYPT) rewrite_encrypted(control, ctis, ctis->s[cti->streamno].last_head - 17); ctis->s[cti->streamno].last_head = ctis->cur_pos + 1 + (write_len * 2) + (ENCRYPT ? SALT_LEN : 0); if (unlikely(seekto(control, ctis, ctis->cur_pos))) - fatal("Failed to seekto cur_pos in compthread %d\n", i); + fatal(control, "Failed to seekto cur_pos in compthread %d\n", i); print_maxverbose("Thread %ld writing %lld compressed bytes from stream %d\n", i, padded_len, cti->streamno); if (ENCRYPT) { if (unlikely(write_val(control, 0, SALT_LEN))) - fatal("Failed to write_buf header salt in compthread %d\n", i); + fatal(control, "Failed to write_buf header salt in compthread %d\n", i); ctis->cur_pos += SALT_LEN; ctis->s[cti->streamno].last_headofs = ctis->cur_pos; } @@ -1390,30 +1390,30 @@ retry: write_val(control, cti->c_len, write_len) || write_val(control, cti->s_len, write_len) || write_val(control, 0, write_len))) { - fatal("Failed write in compthread %d\n", i); + fatal(control, "Failed write in compthread %d\n", i); } ctis->cur_pos += 1 + (write_len * 3); if (ENCRYPT) { - get_rand(cti->salt, SALT_LEN); + get_rand(control, cti->salt, SALT_LEN); if (unlikely(write_buf(control, cti->salt, SALT_LEN))) - fatal("Failed to write_buf block salt in compthread %d\n", i); + fatal(control, "Failed to write_buf block salt in compthread %d\n", i); lrz_encrypt(control, cti->s_buf, padded_len, cti->salt); ctis->cur_pos += SALT_LEN; } if (unlikely(write_buf(control, cti->s_buf, padded_len))) - fatal("Failed to write_buf s_buf in compthread %d\n", i); + fatal(control, "Failed to write_buf s_buf in compthread %d\n", i); ctis->cur_pos += padded_len; free(cti->s_buf); - lock_mutex(&output_lock); + lock_mutex(control, &output_lock); if (++output_thread == control->threads) output_thread = 0; - cond_broadcast(&output_cond); - unlock_mutex(&output_lock); + cond_broadcast(control, &output_cond); + unlock_mutex(control, &output_lock); - unlock_mutex(&cti->mutex); + unlock_mutex(control, &cti->mutex); return 0; } @@ -1424,7 +1424,7 @@ static void clear_buffer(rzip_control *control, struct stream_info *sinfo, int s stream_thread_struct *s; /* Make sure this thread doesn't already exist */ - lock_mutex(&cthread[i].mutex); + lock_mutex(control, &cthread[i].mutex); cthread[i].sinfo = sinfo; cthread[i].streamno = streamno; @@ -1436,18 +1436,18 @@ static void clear_buffer(rzip_control *control, struct stream_info *sinfo, int s s = malloc(sizeof(stream_thread_struct)); if (unlikely(!s)) - fatal("Unable to malloc in clear_buffer"); + fatal(control, "Unable to malloc in clear_buffer"); s->i = i; s->control = control; - create_pthread(&threads[i], NULL, compthread, s); - detach_pthread(&threads[i]); + create_pthread(control, &threads[i], NULL, compthread, s); + detach_pthread(control, &threads[i]); if (newbuf) { /* The stream buffer has been given to the thread, allocate a * new one. */ sinfo->s[streamno].buf = malloc(sinfo->bufsize); if (unlikely(!sinfo->s[streamno].buf)) - fatal("Unable to malloc buffer of size %lld in flush_buffer\n", sinfo->bufsize); + fatal(control, "Unable to malloc buffer of size %lld in flush_buffer\n", sinfo->bufsize); sinfo->s[streamno].buflen = 0; } @@ -1494,7 +1494,7 @@ retry: ret = zpaq_decompress_buf(control, uci, i); break; default: - failure("Dunno wtf decompression type to use!\n"); + failure(control, "Dunno wtf decompression type to use!\n"); break; } } @@ -1503,15 +1503,15 @@ retry: * parallel */ if (unlikely(ret)) { if (unlikely(waited)) - failure("Failed to decompress in ucompthread\n"); + failure(control, "Failed to decompress in ucompthread\n"); print_maxverbose("Unable to decompress in parallel, waiting for previous thread to complete before trying again\n"); /* We do not strictly need to wait for this, so it's used when * decompression fails due to inadequate memory to try again * serialised. */ - lock_mutex(&output_lock); + lock_mutex(control, &output_lock); while (output_thread != i) - cond_wait(&output_cond, &output_lock); - unlock_mutex(&output_lock); + cond_wait(control, &output_cond, &output_lock); + unlock_mutex(control, &output_lock); waited = 1; goto retry; } @@ -1536,7 +1536,7 @@ static int fill_buffer(rzip_control *control, struct stream_info *sinfo, int str goto out; fill_another: if (unlikely(ucthread[s->uthread_no].busy)) - failure("Trying to start a busy thread, this shouldn't happen!\n"); + failure(control, "Trying to start a busy thread, this shouldn't happen!\n"); if (unlikely(read_seekto(control, sinfo, s->last_head))) return -1; @@ -1589,7 +1589,7 @@ fill_another: s_buf = malloc(MAX(u_len, MIN_SIZE)); if (unlikely(u_len && !s_buf)) - fatal("Unable to malloc buffer of size %lld in fill_buffer\n", u_len); + fatal(control, "Unable to malloc buffer of size %lld in fill_buffer\n", u_len); sinfo->ram_alloced += u_len; if (unlikely(read_buf(control, sinfo->fd, s_buf, padded_len))) @@ -1612,10 +1612,10 @@ fill_another: st = malloc(sizeof(stream_thread_struct)); if (unlikely(!st)) - fatal("Unable to malloc in fill_buffer"); + fatal(control, "Unable to malloc in fill_buffer"); st->i = s->uthread_no; st->control = control; - create_pthread(&threads[s->uthread_no], NULL, ucompthread, st); + create_pthread(control, &threads[s->uthread_no], NULL, ucompthread, st); if (++s->uthread_no == s->base_thread + s->total_threads) s->uthread_no = s->base_thread; @@ -1630,13 +1630,13 @@ fill_another: sinfo->ram_alloced < control->maxram) goto fill_another; out: - lock_mutex(&output_lock); + lock_mutex(control, &output_lock); output_thread = s->unext_thread; - cond_broadcast(&output_cond); - unlock_mutex(&output_lock); + cond_broadcast(control, &output_cond); + unlock_mutex(control, &output_lock); /* join_pthread here will make it wait till the data is ready */ - join_pthread(threads[s->unext_thread], NULL); + join_pthread(control, threads[s->unext_thread], NULL); ucthread[s->unext_thread].busy = 0; print_maxverbose("Taking decompressed data from thread %ld\n", s->unext_thread); @@ -1722,8 +1722,8 @@ int close_stream_out(rzip_control *control, void *ss) int close_thread = output_thread; for (i = 0; i < control->threads; i++) { - lock_mutex(&cthread[close_thread].mutex); - unlock_mutex(&cthread[close_thread].mutex); + lock_mutex(control, &cthread[close_thread].mutex); + unlock_mutex(control, &cthread[close_thread].mutex); if (++close_thread == control->threads) close_thread = 0; } @@ -1779,14 +1779,14 @@ static int lzo_compresses(rzip_control *control, uchar *s_buf, i64 s_len) return 1; wrkmem = (lzo_bytep) malloc(LZO1X_1_MEM_COMPRESS); if (unlikely(wrkmem == NULL)) - fatal("Unable to allocate wrkmem in lzo_compresses\n"); + fatal(control, "Unable to allocate wrkmem in lzo_compresses\n"); in_len = MIN(test_len, buftest_size); dlen = STREAM_BUFSIZE + STREAM_BUFSIZE / 16 + 64 + 3; c_buf = malloc(dlen); if (unlikely(!c_buf)) - fatal("Unable to allocate c_buf in lzo_compresses\n"); + fatal(control, "Unable to allocate c_buf in lzo_compresses\n"); /* Test progressively larger blocks at a time and as soon as anything compressible is found, jump out as a success */ diff --git a/util.c b/util.c index a92fa7e..3ba7f95 100644 --- a/util.c +++ b/util.c @@ -57,40 +57,34 @@ #include "sha4.h" #include "aes.h" -static const char *infile = NULL; -static char delete_infile = 0; -static const char *outfile = NULL; -static char delete_outfile = 0; -static FILE *outputfile = NULL; - -void register_infile(const char *name, char delete) +void register_infile(rzip_control *control, const char *name, char delete) { - infile = name; - delete_infile = delete; + control->util_infile = name; + control->delete_infile = delete; } -void register_outfile(const char *name, char delete) +void register_outfile(rzip_control *control, const char *name, char delete) { - outfile = name; - delete_outfile = delete; + control->util_outfile = name; + control->delete_outfile = delete; } -void register_outputfile(FILE *f) +void register_outputfile(rzip_control *control, FILE *f) { - outputfile = f; + control->outputfile = f; } -void unlink_files(void) +void unlink_files(rzip_control *control) { /* Delete temporary files generated for testing or faking stdio */ - if (outfile && delete_outfile) - unlink(outfile); + if (control->util_outfile && control->delete_outfile) + unlink(control->util_outfile); - if (infile && delete_infile) - unlink(infile); + if (control->util_infile && control->delete_infile) + unlink(control->util_infile); } -static void fatal_exit(void) +static void fatal_exit(rzip_control *control) { struct termios termios_p; @@ -99,14 +93,14 @@ static void fatal_exit(void) termios_p.c_lflag |= ECHO; tcsetattr(fileno(stdin), 0, &termios_p); - unlink_files(); - fprintf(outputfile, "Fatal error - exiting\n"); - fflush(outputfile); + unlink_files(control); + fprintf(control->outputfile, "Fatal error - exiting\n"); + fflush(control->outputfile); abort(); } /* Failure when there is likely to be a meaningful error in perror */ -void fatal(const char *format, ...) +void fatal(const rzip_control *control, const char *format, ...) { va_list ap; @@ -117,10 +111,10 @@ void fatal(const char *format, ...) } perror(NULL); - fatal_exit(); + fatal_exit((rzip_control*)control); } -void failure(const char *format, ...) +void failure(const rzip_control *control, const char *format, ...) { va_list ap; @@ -130,7 +124,7 @@ void failure(const char *format, ...) va_end(ap); } - fatal_exit(); + fatal_exit((rzip_control*)control); } void setup_overhead(rzip_control *control) @@ -177,7 +171,7 @@ void round_to_page(i64 *size) *size = PAGE_SIZE; } -void get_rand(uchar *buf, int len) +void get_rand(rzip_control *control, uchar *buf, int len) { int fd, i; @@ -187,9 +181,9 @@ void get_rand(uchar *buf, int len) buf[i] = (uchar)random(); } else { if (unlikely(read(fd, buf, len) != len)) - fatal("Failed to read fd in get_rand\n"); + fatal(control, "Failed to read fd in get_rand\n"); if (unlikely(close(fd))) - fatal("Failed to close fd in get_rand\n"); + fatal(control, "Failed to close fd in get_rand\n"); } } @@ -243,7 +237,7 @@ void lrz_crypt(const rzip_control *control, uchar *buf, i64 len, const uchar *sa if (encrypt == LRZ_ENCRYPT) { print_maxverbose("Encrypting data \n"); if (unlikely(aes_setkey_enc(&aes_ctx, key, 128))) - failure("Failed to aes_setkey_enc in lrz_crypt\n"); + failure(control, "Failed to aes_setkey_enc in lrz_crypt\n"); aes_crypt_cbc(&aes_ctx, AES_ENCRYPT, N, iv, buf, buf); if (M) { @@ -256,7 +250,7 @@ void lrz_crypt(const rzip_control *control, uchar *buf, i64 len, const uchar *sa } } else { if (unlikely(aes_setkey_dec(&aes_ctx, key, 128))) - failure("Failed to aes_setkey_dec in lrz_crypt\n"); + failure(control, "Failed to aes_setkey_dec in lrz_crypt\n"); print_maxverbose("Decrypting data \n"); if (M) { aes_crypt_cbc(&aes_ctx, AES_DECRYPT, N - CBC_LEN, diff --git a/util.h b/util.h index d70a7a9..fe2167f 100644 --- a/util.h +++ b/util.h @@ -21,16 +21,16 @@ #include "lrzip_private.h" -void register_infile(const char *name, char delete); -void register_outfile(const char *name, char delete); -void unlink_files(void); -void register_outputfile(FILE *f); -void fatal(const char *format, ...); -void failure(const char *format, ...); +void register_infile(rzip_control *control, const char *name, char delete); +void register_outfile(rzip_control *control, const char *name, char delete); +void unlink_files(rzip_control *control); +void register_outputfile(rzip_control *control, FILE *f); +void fatal(const rzip_control *control, const char *format, ...); +void failure(const rzip_control *control, const char *format, ...); void setup_overhead(rzip_control *control); void setup_ram(rzip_control *control); void round_to_page(i64 *size); -void get_rand(uchar *buf, int len); +void get_rand(rzip_control *control, uchar *buf, int len); void lrz_stretch(rzip_control *control); void lrz_stretch2(rzip_control *control); void lrz_crypt(const rzip_control *control, uchar *buf, i64 len, const uchar *salt, int encrypt);