diff --git a/main.c b/main.c index 2b1c218..b161f3c 100644 --- a/main.c +++ b/main.c @@ -23,36 +23,36 @@ struct rzip_control control; static void usage(void) { - print_out("lrzip version %d.%d%d\n", LRZIP_MAJOR_VERSION, LRZIP_MINOR_VERSION, LRZIP_MINOR_SUBVERSION); - print_out("Copyright (C) Con Kolivas 2006-2010\n\n"); - print_out("Based on rzip "); - print_out("Copyright (C) Andrew Tridgell 1998-2003\n"); - print_out("usage: lrzip [options] \n"); - print_out(" Options:\n"); - print_out(" -w size compression window in hundreds of MB\n"); - print_out(" default chosen by heuristic dependent on ram and chosen compression\n"); - print_out(" -d decompress\n"); - print_out(" -o filename specify the output file name and/or path\n"); - print_out(" -O directory specify the output directory when -o is not used\n"); - print_out(" -S suffix specify compressed suffix (default '.lrz')\n"); - print_out(" -f force overwrite of any existing files\n"); - print_out(" -D delete existing files\n"); - print_out(" -P don't set permissions on output file - may leave it world-readable\n"); - print_out(" -q don't show compression progress\n"); - print_out(" -L level set lzma/bzip2/gzip compression level (1-9, default 7)\n"); - print_out(" -n no backend compression - prepare for other compressor\n"); - print_out(" -l lzo compression (ultra fast)\n"); - print_out(" -b bzip2 compression\n"); - print_out(" -g gzip compression using zlib\n"); - print_out(" -z zpaq compression (best, extreme compression, extremely slow)\n"); - print_out(" -M Maximum window and level - (all available ram and level 9)\n"); - print_out(" -T value Compression threshold with LZO test. (0 (nil) - 10 (high), default 1)\n"); - print_out(" -N value Set nice value to value (default 19)\n"); - print_out(" -v[v] Increase verbosity\n"); - print_out(" -V show version\n"); - print_out(" -t test compressed file integrity\n"); - print_out(" -i show compressed file information\n"); - print_out("\nIf no filenames or \"-\" is specified, stdin/out will be used.\n"); + print_output("lrzip version %d.%d%d\n", LRZIP_MAJOR_VERSION, LRZIP_MINOR_VERSION, LRZIP_MINOR_SUBVERSION); + print_output("Copyright (C) Con Kolivas 2006-2010\n\n"); + print_output("Based on rzip "); + print_output("Copyright (C) Andrew Tridgell 1998-2003\n"); + print_output("usage: lrzip [options] \n"); + print_output(" Options:\n"); + print_output(" -w size compression window in hundreds of MB\n"); + print_output(" default chosen by heuristic dependent on ram and chosen compression\n"); + print_output(" -d decompress\n"); + print_output(" -o filename specify the output file name and/or path\n"); + print_output(" -O directory specify the output directory when -o is not used\n"); + print_output(" -S suffix specify compressed suffix (default '.lrz')\n"); + print_output(" -f force overwrite of any existing files\n"); + print_output(" -D delete existing files\n"); + print_output(" -P don't set permissions on output file - may leave it world-readable\n"); + print_output(" -q don't show compression progress\n"); + print_output(" -L level set lzma/bzip2/gzip compression level (1-9, default 7)\n"); + print_output(" -n no backend compression - prepare for other compressor\n"); + print_output(" -l lzo compression (ultra fast)\n"); + print_output(" -b bzip2 compression\n"); + print_output(" -g gzip compression using zlib\n"); + print_output(" -z zpaq compression (best, extreme compression, extremely slow)\n"); + print_output(" -M Maximum window and level - (all available ram and level 9)\n"); + print_output(" -T value Compression threshold with LZO test. (0 (nil) - 10 (high), default 1)\n"); + print_output(" -N value Set nice value to value (default 19)\n"); + print_output(" -v[v] Increase verbosity\n"); + print_output(" -V show version\n"); + print_output(" -t test compressed file integrity\n"); + print_output(" -i show compressed file information\n"); + print_output("\nIf no filenames or \"-\" is specified, stdin/out will be used.\n"); } static void write_magic(int fd_in, int fd_out) @@ -162,7 +162,7 @@ static void dump_tmpoutfile(int fd_out) print_progress("Dumping to stdout.\n"); /* flush anything not yet in the temporary file */ - fflush(NULL); + fsync(fd_out); tmpoutfp = fdopen(fd_out, "r"); if (tmpoutfp == NULL) fatal("Failed to fdopen out tmpfile: %s\n", strerror(errno)); @@ -302,9 +302,6 @@ static void decompress_file(void) runzip_fd(fd_in, fd_out, fd_hist, expected_size); - if (STDOUT) - dump_tmpoutfile(fd_out); - /* if we get here, no fatal errors during decompression */ print_progress("\r"); if (!(STDOUT | TEST_ONLY)) @@ -390,17 +387,17 @@ static void get_fileinfo(void) print_output("%s:\nlrzip version: %d.%d file\n", infilecopy, control.major_version, control.minor_version); print_output("Compression: "); if (ctype == CTYPE_NONE) - print_out("rzip alone\n"); + print_output("rzip alone\n"); else if (ctype == CTYPE_BZIP2) - print_out("rzip + bzip2\n"); + print_output("rzip + bzip2\n"); else if (ctype == CTYPE_LZO) - print_out("rzip + lzo\n"); + print_output("rzip + lzo\n"); else if (ctype == CTYPE_LZMA) - print_out("rzip + lzma\n"); + print_output("rzip + lzma\n"); else if (ctype == CTYPE_GZIP) - print_out("rzip + gzip\n"); + print_output("rzip + gzip\n"); else if (ctype == CTYPE_ZPAQ) - print_out("rzip + zpaq\n"); + print_output("rzip + zpaq\n"); print_output("Decompressed file size: %llu\n", expected_size); print_output("Compressed file size: %llu\n", infile_size); print_output("Compression ratio: %.3Lf\n", cratio); @@ -453,7 +450,7 @@ static void compress_file(void) fatal("Failed to allocate outfile name\n"); strcpy(control.outfile, control.outname); strcat(control.outfile, control.suffix); - print_out("Suffix added to %s.\nFull pathname is: %s\n", control.outname, control.outfile); + print_output("Suffix added to %s.\nFull pathname is: %s\n", control.outname, control.outfile); } else /* no, already has suffix */ control.outfile = strdup(control.outname); } else { @@ -644,7 +641,7 @@ int main(int argc, char *argv[]) control.flags &= ~FLAG_SHOW_PROGRESS; break; case 'V': - print_out("lrzip version %d.%d%d\n", + print_output("lrzip version %d.%d%d\n", LRZIP_MAJOR_VERSION, LRZIP_MINOR_VERSION, LRZIP_MINOR_SUBVERSION); exit(0); break; @@ -758,45 +755,45 @@ int main(int argc, char *argv[]) /* OK, if verbosity set, print summary of options selected */ if (VERBOSE && !INFO) { print_err("The following options are in effect for this %s.\n", - control.flags & FLAG_DECOMPRESS ? "DECOMPRESSION" : "COMPRESSION"); + DECOMPRESS ? "DECOMPRESSION" : "COMPRESSION"); if (LZMA_COMPRESS(control.flags)) print_err("Threading is %s. Number of CPUs detected: %lu\n", control.threads > 1? "ENABLED" : "DISABLED", control.threads); print_err("Nice Value: %d\n", control.nice_val); - if (control.flags & FLAG_SHOW_PROGRESS) + if (SHOW_PROGRESS) print_err("Show Progress\n"); - if (control.flags & FLAG_VERBOSITY) + if (VERBOSITY) print_err("Verbose\n"); - else if (control.flags & FLAG_VERBOSITY_MAX) + else if (MAX_VERBOSE) print_err("Max Verbosity\n"); - if (control.flags & FLAG_FORCE_REPLACE) + if (FORCE_REPLACE) print_err("Overwrite Files\n"); - if (!(control.flags & FLAG_KEEP_FILES)) + if (!KEEP_FILES) print_err("Remove input files on completion\n"); if (control.outdir) print_err("Output Directory Specified: %s\n", control.outdir); else if (control.outname) print_err("Output Filename Specified: %s\n", control.outname); - if (control.flags & FLAG_TEST_ONLY) + if (TEST_ONLY) print_err("Test file integrity\n"); /* show compression options */ - if (!(control.flags & FLAG_DECOMPRESS)) { + if (!DECOMPRESS) { print_err("Compression mode is: "); if (LZMA_COMPRESS(control.flags)) print_err("LZMA. LZO Test Compression Threshold: %.f\n", (control.threshold < 1.05 ? 21 - control.threshold * 20 : 0)); - else if (control.flags & FLAG_LZO_COMPRESS) + else if (LZO_COMPRESS) print_err("LZO\n"); - else if (control.flags & FLAG_BZIP2_COMPRESS) + else if (BZIP2_COMPRESS) print_err("BZIP2. LZO Test Compression Threshold: %.f\n", (control.threshold < 1.05 ? 21 - control.threshold * 20 : 0)); - else if (control.flags & FLAG_ZLIB_COMPRESS) + else if (ZLIB_COMPRESS) print_err("GZIP\n"); - else if (control.flags & FLAG_ZPAQ_COMPRESS) + else if (ZPAQ_COMPRESS) print_err("ZPAQ. LZO Test Compression Threshold: %.f\n", (control.threshold < 1.05 ? 21 - control.threshold * 20 : 0)); - else if (control.flags & FLAG_NO_COMPRESS) + else if (NO_COMPRESS) print_err("RZIP\n"); print_err("Compression Window: %lld = %lldMB\n", control.window, control.window * 100ull); print_err("Compression Level: %d\n", control.compression_level); diff --git a/runzip.c b/runzip.c index 6c0801e..1d8c274 100644 --- a/runzip.c +++ b/runzip.c @@ -183,7 +183,7 @@ static i64 runzip_chunk(int fd_in, int fd_out, int fd_hist, i64 expected_size, i if (SHOW_PROGRESS) { if ( p != l ) { prog_done = (double)(tally + total) / (double)divisor[divisor_index]; - print_out("%3d%% %9.2f / %9.2f %s\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", + print_output("%3d%% %9.2f / %9.2f %s\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", p, prog_done, prog_tsize, suffix[divisor_index] ); fflush(control.msgout); l = p; diff --git a/rzip.c b/rzip.c index 97bde9e..053d81a 100644 --- a/rzip.c +++ b/rzip.c @@ -380,9 +380,9 @@ static void show_distrib(struct rzip_state *st) } if (total != st->hash_count) - print_out("/tWARNING: hash_count says total %lld\n", st->hash_count); + print_output("/tWARNING: hash_count says total %lld\n", st->hash_count); - print_out("\t%lld total hashes -- %lld in primary bucket (%-2.3f%%)\n", total, primary, + print_output("\t%lld total hashes -- %lld in primary bucket (%-2.3f%%)\n", total, primary, primary*100.0/total); } @@ -481,7 +481,7 @@ static void hash_search(struct rzip_state *st, uchar *buf, fstat(st->fd_in, &s1); fstat(st->fd_out, &s2); - print_out("%2lld%%\r", pct); + print_output("%2lld%%\r", pct); fflush(control.msgout); lastpct = pct; } @@ -654,7 +654,7 @@ void rzip_fd(int fd_in, int fd_out) eta_minutes = (unsigned int)((finish_time - elapsed_time) - eta_hours * 3600) / 60; eta_seconds = (unsigned int)(finish_time - elapsed_time) - eta_hours * 60 - eta_minutes * 60; chunkmbs=(last_chunk / 1024 / 1024) / (double)(current.tv_sec-last.tv_sec); - print_out("\nPass %d / %d -- Elapsed Time: %02d:%02d:%02d. ETA: %02d:%02d:%02d. Compress Speed: %3.3fMB/s.\n", + print_output("\nPass %d / %d -- Elapsed Time: %02d:%02d:%02d. ETA: %02d:%02d:%02d. Compress Speed: %3.3fMB/s.\n", pass, passes, elapsed_hours, elapsed_minutes, elapsed_seconds, eta_hours, eta_minutes, eta_seconds, chunkmbs); } diff --git a/rzip.h b/rzip.h index 1b7c132..a9ed840 100644 --- a/rzip.h +++ b/rzip.h @@ -144,7 +144,14 @@ typedef uint32_t u32; #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 NO_SET_PERMS (control.flags & FLAG_NO_SET_PERMS) #define STDIN (control.flags & FLAG_STDIN) @@ -196,10 +203,6 @@ ssize_t read_1g(int fd, void *buf, i64 len); extern void zpipe_compress(FILE *in, FILE *out, FILE *msgout, long long int buf_len, int progress); extern void zpipe_decompress(FILE *in, FILE *out, FILE *msgout, long long int buf_len, int progress); -#define print_out(format, args...) do {\ - fprintf(stdout, format, ##args); \ -} while (0) - #define print_err(format, args...) do {\ fprintf(stderr, format, ##args); \ } while (0) diff --git a/stream.c b/stream.c index 3df0d45..6727fdd 100644 --- a/stream.c +++ b/stream.c @@ -268,9 +268,9 @@ static void lzma_compress_buf(struct stream *s, int *c_type, i64 *c_len) *c_type = CTYPE_LZMA; out: if (MAX_VERBOSE) - print_out("\n"); + print_output("\n"); else if (SHOW_PROGRESS || VERBOSE) - print_out("\r\t \r"); + print_output("\r\t \r"); } static void lzo_compress_buf(struct stream *s, int *c_type, i64 *c_len) @@ -469,20 +469,25 @@ const i64 one_g = 1000 * 1024 * 1024; /* This is a custom version of write() which writes in 1GB chunks to avoid the overflows at the >= 2GB mark thanks to 32bit fuckage. This should help - even on the rare occasion write() fails to write 1GB as well. */ + even on the rare occasion write() fails to write 1GB as well. We can write + a null file if we're just testing. When decompressing to stdout we can + write directly to it since there will be no need to seek backwards. */ ssize_t write_1g(int fd, void *buf, i64 len) { uchar *offset_buf = buf; i64 total, offset; ssize_t ret; + if (DECOMPRESS && STDOUT) + fd = 1; total = offset = 0; while (len > 0) { if (len > one_g) ret = one_g; else ret = len; - ret = write(fd, offset_buf, (size_t)ret); + if (!TEST_ONLY) + ret = write(fd, offset_buf, (size_t)ret); if (ret < 0) return ret; len -= ret; @@ -771,13 +776,13 @@ static int flush_buffer(struct stream_info *sinfo, int stream) if (!(control.flags & FLAG_NO_COMPRESS)) { if (LZMA_COMPRESS(control.flags)) lzma_compress_buf(&sinfo->s[stream], &c_type, &c_len); - else if (control.flags & FLAG_LZO_COMPRESS) + else if (LZO_COMPRESS) lzo_compress_buf(&sinfo->s[stream], &c_type, &c_len); - else if (control.flags & FLAG_BZIP2_COMPRESS) + else if (BZIP2_COMPRESS) bzip2_compress_buf(&sinfo->s[stream], &c_type, &c_len); - else if (control.flags & FLAG_ZLIB_COMPRESS) + else if (ZLIB_COMPRESS) gzip_compress_buf(&sinfo->s[stream], &c_type, &c_len); - else if (control.flags & FLAG_ZPAQ_COMPRESS) + else if (ZPAQ_COMPRESS) zpaq_compress_buf(&sinfo->s[stream], &c_type, &c_len); else fatal("Dunno wtf compression to use!\n"); } @@ -1027,11 +1032,11 @@ static int lzo_compresses(struct stream *s) } } if (MAX_VERBOSE) - print_out("%s for chunk %ld. Compressed size = %5.2F%% of chunk, %d Passes\n", + print_output("%s for chunk %ld. Compressed size = %5.2F%% of chunk, %d Passes\n", (ret == 0? "FAILED - below threshold" : "OK"), save_len, 100 * ((double) best_dlen / (double) in_len), workcounter); else if (VERBOSE) - print_out("%s\r", (ret == 0? "FAILED - below threshold" : "OK")); + print_output("%s\r", (ret == 0? "FAILED - below threshold" : "OK")); else print_progress("\r\t \r"); free(wrkmem);