2010-03-29 01:07:08 +02:00
|
|
|
/*
|
2011-02-20 13:04:44 +01:00
|
|
|
Copyright (C) 2006-2011 Con Kolivas
|
2011-02-21 06:11:59 +01:00
|
|
|
Copyright (C) 2011 Peter Hyman
|
2010-12-15 23:45:21 +01:00
|
|
|
Copyright (C) 1998-2003 Andrew Tridgell
|
2010-03-29 01:07:08 +02:00
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2010-12-15 23:45:21 +01:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2010-03-29 01:07:08 +02:00
|
|
|
*/
|
|
|
|
|
/* lrzip compression - main program */
|
2011-03-08 22:34:44 +01:00
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
# include "config.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2011-03-08 22:37:26 +01:00
|
|
|
#include <signal.h>
|
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
|
# include <unistd.h>
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef HAVE_CTYPE_H
|
|
|
|
|
# include <ctype.h>
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef HAVE_SYS_TIME_H
|
|
|
|
|
# include <sys/time.h>
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef HAVE_SYS_RESOURCE_H
|
|
|
|
|
# include <sys/resource.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
2010-03-29 01:07:08 +02:00
|
|
|
#include "rzip.h"
|
2011-03-08 22:37:26 +01:00
|
|
|
#include "lrzip.h"
|
2011-03-08 22:34:44 +01:00
|
|
|
#include "util.h"
|
2011-03-08 22:33:44 +01:00
|
|
|
|
2011-03-08 22:37:26 +01:00
|
|
|
/* needed for CRC routines */
|
|
|
|
|
#include "lzma/C/7zCrc.h"
|
|
|
|
|
|
|
|
|
|
/* Macros for testing parameters */
|
|
|
|
|
#define isparameter( parmstring, value ) (!strcasecmp( parmstring, value ))
|
|
|
|
|
#define iscaseparameter( parmvalue, value ) (!strcmp( parmvalue, value ))
|
|
|
|
|
|
2011-03-08 22:32:14 +01:00
|
|
|
/* main() defines, different from liblrzip defines */
|
|
|
|
|
#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 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)
|
2010-03-29 01:07:08 +02:00
|
|
|
|
2011-03-08 22:37:26 +01:00
|
|
|
|
|
|
|
|
#if defined(NOTHREAD) || !defined(_SC_NPROCESSORS_ONLN)
|
|
|
|
|
# define PROCESSORS (1)
|
|
|
|
|
#else
|
|
|
|
|
# define PROCESSORS (sysconf(_SC_NPROCESSORS_ONLN))
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef _SC_PAGE_SIZE
|
|
|
|
|
# define PAGE_SIZE (sysconf(_SC_PAGE_SIZE))
|
|
|
|
|
#else
|
|
|
|
|
# define PAGE_SIZE (4096)
|
|
|
|
|
#endif
|
2011-03-08 22:33:44 +01:00
|
|
|
|
|
|
|
|
#ifdef __APPLE__
|
|
|
|
|
# include <sys/sysctl.h>
|
|
|
|
|
static inline i64 get_ram(void)
|
|
|
|
|
{
|
|
|
|
|
int mib[2];
|
|
|
|
|
size_t len;
|
|
|
|
|
i64 *p, ramsize;
|
|
|
|
|
|
|
|
|
|
mib[0] = CTL_HW;
|
|
|
|
|
mib[1] = HW_MEMSIZE;
|
|
|
|
|
sysctl(mib, 2, NULL, &len, NULL, 0);
|
|
|
|
|
p = malloc(len);
|
|
|
|
|
sysctl(mib, 2, p, &len, NULL, 0);
|
|
|
|
|
ramsize = *p;
|
|
|
|
|
|
|
|
|
|
return ramsize;
|
|
|
|
|
}
|
|
|
|
|
#else /* __APPLE__ */
|
|
|
|
|
static inline i64 get_ram(void)
|
|
|
|
|
{
|
|
|
|
|
i64 ramsize;
|
|
|
|
|
FILE *meminfo;
|
|
|
|
|
char aux[256];
|
|
|
|
|
char *ignore;
|
|
|
|
|
|
|
|
|
|
ramsize = (i64)sysconf(_SC_PHYS_PAGES) * PAGE_SIZE;
|
|
|
|
|
if (ramsize > 0)
|
|
|
|
|
return ramsize;
|
|
|
|
|
|
|
|
|
|
/* Workaround for uclibc which doesn't properly support sysconf */
|
|
|
|
|
if(!(meminfo = fopen("/proc/meminfo", "r")))
|
|
|
|
|
fatal("fopen\n");
|
|
|
|
|
|
|
|
|
|
while(!feof(meminfo) && !fscanf(meminfo, "MemTotal: %Lu kB", &ramsize))
|
|
|
|
|
ignore = fgets(aux, sizeof(aux), meminfo);
|
|
|
|
|
if (fclose(meminfo) == -1)
|
|
|
|
|
fatal("fclose");
|
|
|
|
|
ramsize *= 1000;
|
|
|
|
|
|
|
|
|
|
return ramsize;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2010-03-29 01:07:08 +02:00
|
|
|
|
2011-03-08 22:37:26 +01:00
|
|
|
static rzip_control control;
|
|
|
|
|
|
2010-03-29 01:07:08 +02:00
|
|
|
static void usage(void)
|
|
|
|
|
{
|
2010-11-08 00:43:05 +01:00
|
|
|
print_output("lrzip version %d.%d%d\n", LRZIP_MAJOR_VERSION, LRZIP_MINOR_VERSION, LRZIP_MINOR_SUBVERSION);
|
2011-02-21 06:11:59 +01:00
|
|
|
print_output("Copyright (C) Con Kolivas 2006-2011\n");
|
2010-11-01 01:18:58 +01:00
|
|
|
print_output("Based on rzip ");
|
2011-02-21 06:11:59 +01:00
|
|
|
print_output("Copyright (C) Andrew Tridgell 1998-2003\n\n");
|
|
|
|
|
print_output("Usage: lrzip [options] <file...>\n");
|
2011-02-21 02:49:44 +01:00
|
|
|
print_output("General options:\n");
|
|
|
|
|
print_output(" -c check integrity of file written on decompression\n");
|
2010-11-01 01:18:58 +01:00
|
|
|
print_output(" -d decompress\n");
|
2011-02-25 00:55:27 +01:00
|
|
|
print_output(" -h|-? show help\n");
|
2011-02-21 02:49:44 +01:00
|
|
|
print_output(" -H display md5 hash integrity information\n");
|
|
|
|
|
print_output(" -i show compressed file information\n");
|
|
|
|
|
print_output(" -q don't show compression progress\n");
|
|
|
|
|
print_output(" -t test compressed file integrity\n");
|
|
|
|
|
print_output(" -v[v] Increase verbosity\n");
|
|
|
|
|
print_output(" -V show version\n");
|
|
|
|
|
print_output("Options affecting output:\n");
|
|
|
|
|
print_output(" -D delete existing files\n");
|
|
|
|
|
print_output(" -f force overwrite of any existing files\n");
|
|
|
|
|
print_output(" -k keep broken or damaged output files\n");
|
2010-11-01 01:18:58 +01:00
|
|
|
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");
|
2011-02-21 02:49:44 +01:00
|
|
|
print_output("Options affecting compression:\n");
|
2010-11-01 01:18:58 +01:00
|
|
|
print_output(" -b bzip2 compression\n");
|
|
|
|
|
print_output(" -g gzip compression using zlib\n");
|
2011-02-21 02:49:44 +01:00
|
|
|
print_output(" -l lzo compression (ultra fast)\n");
|
|
|
|
|
print_output(" -n no backend compression - prepare for other compressor\n");
|
2010-11-01 01:18:58 +01:00
|
|
|
print_output(" -z zpaq compression (best, extreme compression, extremely slow)\n");
|
2011-02-21 02:49:44 +01:00
|
|
|
print_output("Low level options:\n");
|
|
|
|
|
print_output(" -L level set lzma/bzip2/gzip compression level (1-9, default 7)\n");
|
2010-11-01 01:18:58 +01:00
|
|
|
print_output(" -N value Set nice value to value (default 19)\n");
|
2010-11-13 07:36:21 +01:00
|
|
|
print_output(" -p value Set processor count to override number of threads\n");
|
2011-02-22 15:15:18 +01:00
|
|
|
print_output(" -T Disable LZO compressibility testing\n");
|
2011-02-21 02:49:44 +01:00
|
|
|
print_output(" -U Use unlimited window size beyond ramsize (potentially much slower)\n");
|
|
|
|
|
print_output(" -w size maximum compression window in hundreds of MB\n");
|
|
|
|
|
print_output(" default chosen by heuristic dependent on ram and chosen compression\n");
|
2011-02-21 02:06:49 +01:00
|
|
|
print_output("\nLRZIP=NOCONFIG environment variable setting can be used to bypass lrzip.conf.\n");
|
2011-02-22 15:29:17 +01:00
|
|
|
print_output("TMP environment variable will be used for storage of temporary files when needed.\n");
|
|
|
|
|
print_output("TMPDIR may also be stored in lrzip.conf file.\n");
|
2011-02-21 02:49:44 +01:00
|
|
|
print_output("\nIf no filenames or \"-\" is specified, stdin/out will be used.\n");
|
2011-02-21 02:03:08 +01:00
|
|
|
|
2010-03-29 01:07:08 +02:00
|
|
|
}
|
|
|
|
|
|
2011-03-08 22:33:44 +01:00
|
|
|
|
2011-03-08 22:34:44 +01:00
|
|
|
static void sighandler(int sig __UNUSED__)
|
|
|
|
|
{
|
|
|
|
|
unlink_files();
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-01 04:21:10 +01:00
|
|
|
static void show_summary(void)
|
|
|
|
|
{
|
|
|
|
|
/* OK, if verbosity set, print summary of options selected */
|
|
|
|
|
if (!INFO) {
|
|
|
|
|
i64 temp_chunk, temp_window, temp_ramsize; /* to show heurisitic computed values */
|
|
|
|
|
|
|
|
|
|
if (!TEST_ONLY)
|
|
|
|
|
print_verbose("The following options are in effect for this %s.\n",
|
|
|
|
|
DECOMPRESS ? "DECOMPRESSION" : "COMPRESSION");
|
|
|
|
|
print_verbose("Threading is %s. Number of CPUs detected: %d\n", control.threads > 1? "ENABLED" : "DISABLED",
|
|
|
|
|
control.threads);
|
|
|
|
|
print_verbose("Detected %lld bytes ram\n", control.ramsize);
|
|
|
|
|
print_verbose("Compression level %d\n", control.compression_level);
|
|
|
|
|
print_verbose("Nice Value: %d\n", control.nice_val);
|
|
|
|
|
print_verbose("Show Progress\n");
|
|
|
|
|
print_maxverbose("Max ");
|
|
|
|
|
print_verbose("Verbose\n");
|
|
|
|
|
if (FORCE_REPLACE)
|
|
|
|
|
print_verbose("Overwrite Files\n");
|
|
|
|
|
if (!KEEP_FILES)
|
|
|
|
|
print_verbose("Remove input files on completion\n");
|
|
|
|
|
if (control.outdir)
|
|
|
|
|
print_verbose("Output Directory Specified: %s\n", control.outdir);
|
|
|
|
|
else if (control.outname)
|
|
|
|
|
print_verbose("Output Filename Specified: %s\n", control.outname);
|
|
|
|
|
if (TEST_ONLY)
|
|
|
|
|
print_verbose("Test file integrity\n");
|
|
|
|
|
if (control.tmpdir)
|
|
|
|
|
print_verbose("Temporary Directory set as: %s\n", control.tmpdir);
|
|
|
|
|
|
|
|
|
|
/* show compression options */
|
|
|
|
|
if (!DECOMPRESS && !TEST_ONLY) {
|
|
|
|
|
print_verbose("Compression mode is: ");
|
|
|
|
|
if (LZMA_COMPRESS)
|
|
|
|
|
print_verbose("LZMA. LZO Compressibility testing %s\n", (LZO_TEST? "enabled" : "disabled"));
|
|
|
|
|
else if (LZO_COMPRESS)
|
|
|
|
|
print_verbose("LZO\n");
|
|
|
|
|
else if (BZIP2_COMPRESS)
|
|
|
|
|
print_verbose("BZIP2. LZO Compressibility testing %s\n", (LZO_TEST? "enabled" : "disabled"));
|
|
|
|
|
else if (ZLIB_COMPRESS)
|
|
|
|
|
print_verbose("GZIP\n");
|
|
|
|
|
else if (ZPAQ_COMPRESS)
|
|
|
|
|
print_verbose("ZPAQ. LZO Compressibility testing %s\n", (LZO_TEST? "enabled" : "disabled"));
|
|
|
|
|
else if (NO_COMPRESS)
|
|
|
|
|
print_verbose("RZIP pre-processing only\n");
|
2011-03-08 22:50:46 +01:00
|
|
|
if (control.window)
|
2011-03-01 04:21:10 +01:00
|
|
|
print_verbose("Compression Window: %lld = %lldMB\n", control.window, control.window * 100ull);
|
|
|
|
|
/* show heuristically computed window size */
|
|
|
|
|
if (!control.window && !UNLIMITED) {
|
|
|
|
|
temp_ramsize = control.ramsize;
|
|
|
|
|
if (BITS32)
|
|
|
|
|
temp_ramsize = MAX(temp_ramsize - 900000000ll, 900000000ll);
|
2011-03-07 22:24:05 +01:00
|
|
|
if (STDIN)
|
|
|
|
|
temp_chunk = temp_ramsize / 3;
|
|
|
|
|
else
|
2011-03-01 04:21:10 +01:00
|
|
|
temp_chunk = temp_ramsize / 3 * 2;
|
2011-03-08 22:50:46 +01:00
|
|
|
temp_window = temp_chunk / (100 * 1024 * 1024);
|
2011-03-01 04:21:10 +01:00
|
|
|
print_verbose("Heuristically Computed Compression Window: %lld = %lldMB\n", temp_window, temp_window * 100ull);
|
|
|
|
|
}
|
|
|
|
|
if (UNLIMITED)
|
|
|
|
|
print_verbose("Using Unlimited Window size\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-08 22:33:44 +01:00
|
|
|
static void read_config( struct rzip_control *control )
|
|
|
|
|
{
|
|
|
|
|
/* check for lrzip.conf in ., $HOME/.lrzip and /etc/lrzip */
|
|
|
|
|
|
|
|
|
|
FILE *fp;
|
|
|
|
|
char *parameter;
|
|
|
|
|
char *parametervalue;
|
|
|
|
|
char *line, *s;
|
|
|
|
|
char *HOME, *homeconf;
|
|
|
|
|
|
|
|
|
|
line = malloc(255);
|
|
|
|
|
homeconf = malloc(255);
|
|
|
|
|
if (line == NULL || homeconf == NULL)
|
|
|
|
|
fatal("Fatal Memory Error in read_config");
|
|
|
|
|
|
|
|
|
|
fp = fopen("lrzip.conf", "r");
|
|
|
|
|
if (fp)
|
|
|
|
|
fprintf(control->msgout, "Using configuration file ./lrzip.conf\n");
|
|
|
|
|
if (fp == NULL) {
|
|
|
|
|
fp = fopen("/etc/lrzip/lrzip.conf", "r");
|
|
|
|
|
if (fp)
|
|
|
|
|
fprintf(control->msgout, "Using configuration file /etc/lrzip/lrzip.conf\n");
|
|
|
|
|
}
|
|
|
|
|
if (fp == NULL) {
|
|
|
|
|
HOME=getenv("HOME");
|
|
|
|
|
if (HOME) {
|
|
|
|
|
strcpy(homeconf, HOME);
|
|
|
|
|
strcat(homeconf,"/.lrzip/lrzip.conf");
|
|
|
|
|
fp = fopen(homeconf, "r");
|
|
|
|
|
if (fp)
|
|
|
|
|
fprintf(control->msgout, "Using configuration file %s\n", homeconf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (fp == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* if we get here, we have a file. read until no more. */
|
|
|
|
|
|
|
|
|
|
while ((s = fgets(line, 255, fp)) != NULL) {
|
|
|
|
|
if (strlen(line))
|
|
|
|
|
line[strlen(line) - 1] = '\0';
|
|
|
|
|
parameter = strtok(line, " =");
|
|
|
|
|
if (parameter == NULL)
|
|
|
|
|
continue;
|
|
|
|
|
/* skip if whitespace or # */
|
|
|
|
|
if (isspace(*parameter))
|
|
|
|
|
continue;
|
|
|
|
|
if (*parameter == '#')
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
parametervalue = strtok(NULL, " =");
|
|
|
|
|
if (parametervalue == NULL)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* have valid parameter line, now assign to control */
|
|
|
|
|
|
|
|
|
|
if (isparameter(parameter, "window"))
|
|
|
|
|
control->window = atoi(parametervalue);
|
|
|
|
|
else if (isparameter(parameter, "unlimited")) {
|
|
|
|
|
if (isparameter(parametervalue, "yes"))
|
|
|
|
|
control->flags |= FLAG_UNLIMITED;
|
|
|
|
|
} 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");
|
|
|
|
|
} 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");
|
|
|
|
|
if (isparameter(parametervalue, "bzip2"))
|
|
|
|
|
control->flags |= FLAG_BZIP2_COMPRESS;
|
|
|
|
|
else if (isparameter(parametervalue, "gzip"))
|
|
|
|
|
control->flags |= FLAG_ZLIB_COMPRESS;
|
|
|
|
|
else if (isparameter(parametervalue, "lzo"))
|
|
|
|
|
control->flags |= FLAG_LZO_COMPRESS;
|
|
|
|
|
else if (isparameter(parametervalue, "rzip"))
|
|
|
|
|
control->flags |= FLAG_NO_COMPRESS;
|
|
|
|
|
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);
|
|
|
|
|
} else if (isparameter(parameter, "lzotest")) {
|
|
|
|
|
/* default is yes */
|
|
|
|
|
if (isparameter(parametervalue, "no"))
|
|
|
|
|
control->flags &= ~FLAG_THRESHOLD;
|
|
|
|
|
} else if (isparameter(parameter, "hashcheck")) {
|
|
|
|
|
if (isparameter(parametervalue, "yes")) {
|
|
|
|
|
control->flags |= FLAG_CHECK;
|
|
|
|
|
control->flags |= FLAG_HASH;
|
|
|
|
|
}
|
|
|
|
|
} else if (isparameter(parameter, "showhash")) {
|
|
|
|
|
if (isparameter(parametervalue, "yes"))
|
|
|
|
|
control->flags |= FLAG_HASH;
|
|
|
|
|
} else if (isparameter(parameter, "outputdirectory")) {
|
|
|
|
|
control->outdir = malloc(strlen(parametervalue) + 2);
|
|
|
|
|
if (!control->outdir)
|
|
|
|
|
fatal("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.");
|
|
|
|
|
if (isparameter(parametervalue, "yes"))
|
|
|
|
|
control->flags |= FLAG_VERBOSITY;
|
|
|
|
|
else if (isparameter(parametervalue,"max"))
|
|
|
|
|
control->flags |= FLAG_VERBOSITY_MAX;
|
|
|
|
|
else /* oops, unrecognized value */
|
|
|
|
|
print_err("lrzip.conf: Unrecognized verbosity value %s. Ignored.\n", parametervalue);
|
|
|
|
|
} else if (isparameter(parameter, "showprogress")) {
|
|
|
|
|
/* Yes by default */
|
|
|
|
|
if (isparameter(parametervalue, "NO"))
|
|
|
|
|
control->flags &= ~FLAG_SHOW_PROGRESS;
|
|
|
|
|
} 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");
|
|
|
|
|
} else if (isparameter(parameter, "keepbroken")) {
|
|
|
|
|
if (isparameter(parametervalue, "yes" ))
|
|
|
|
|
control->flags |= FLAG_KEEP_BROKEN;
|
|
|
|
|
} else if (iscaseparameter(parameter, "DELETEFILES")) {
|
|
|
|
|
/* delete files must be case sensitive */
|
|
|
|
|
if (iscaseparameter(parametervalue, "YES"))
|
|
|
|
|
control->flags &= ~FLAG_KEEP_FILES;
|
|
|
|
|
} else if (iscaseparameter(parameter, "REPLACEFILE")) {
|
|
|
|
|
/* replace lrzip file must be case sensitive */
|
|
|
|
|
if (iscaseparameter(parametervalue, "YES"))
|
|
|
|
|
control->flags |= FLAG_FORCE_REPLACE;
|
|
|
|
|
} else if (isparameter(parameter, "tmpdir")) {
|
|
|
|
|
control->tmpdir = realloc(NULL, strlen(parametervalue) + 2);
|
|
|
|
|
if (!control->tmpdir)
|
|
|
|
|
fatal("Fatal Memory Error in read_config");
|
|
|
|
|
strcpy(control->tmpdir, parametervalue);
|
|
|
|
|
if (strcmp(parametervalue + strlen(parametervalue) - 1, "/"))
|
|
|
|
|
strcat(control->tmpdir, "/");
|
|
|
|
|
} else
|
|
|
|
|
/* oops, we have an invalid parameter, display */
|
|
|
|
|
print_err("lrzip.conf: Unrecognized parameter value, %s = %s. Continuing.\n",\
|
|
|
|
|
parameter, parametervalue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* clean up */
|
|
|
|
|
free(line);
|
|
|
|
|
free(homeconf);
|
|
|
|
|
|
|
|
|
|
/* fprintf(stderr, "\nWindow = %d \
|
|
|
|
|
\nCompression Level = %d \
|
|
|
|
|
\nThreshold = %1.2f \
|
|
|
|
|
\nOutput Directory = %s \
|
|
|
|
|
\nFlags = %d\n", control->window,control->compression_level, control->threshold, control->outdir, control->flags);
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-29 01:07:08 +02:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
|
{
|
|
|
|
|
struct timeval start_time, end_time;
|
|
|
|
|
struct sigaction handler;
|
|
|
|
|
double seconds,total_time; // for timers
|
2010-11-04 11:14:55 +01:00
|
|
|
int c, i;
|
2010-10-31 05:17:04 +01:00
|
|
|
int hours,minutes;
|
|
|
|
|
extern int optind;
|
2010-03-29 01:07:08 +02:00
|
|
|
char *eptr; /* for environment */
|
|
|
|
|
|
|
|
|
|
memset(&control, 0, sizeof(control));
|
|
|
|
|
|
2010-04-25 08:26:00 +02:00
|
|
|
control.msgout = stderr;
|
2011-03-08 22:32:14 +01:00
|
|
|
register_outputfile(control.msgout);
|
2011-02-22 15:15:18 +01:00
|
|
|
control.flags = FLAG_SHOW_PROGRESS | FLAG_KEEP_FILES | FLAG_THRESHOLD;
|
2010-03-29 01:07:08 +02:00
|
|
|
control.suffix = ".lrz";
|
|
|
|
|
control.outdir = NULL;
|
2011-02-21 02:03:08 +01:00
|
|
|
control.tmpdir = NULL;
|
2010-03-29 01:07:08 +02:00
|
|
|
|
2010-11-02 01:14:00 +01:00
|
|
|
if (strstr(argv[0], "lrunzip"))
|
2010-03-29 01:07:08 +02:00
|
|
|
control.flags |= FLAG_DECOMPRESS;
|
|
|
|
|
|
2010-11-13 07:36:21 +01:00
|
|
|
control.compression_level = 7;
|
2010-11-04 11:14:55 +01:00
|
|
|
control.ramsize = get_ram();
|
2010-03-29 01:07:08 +02:00
|
|
|
/* for testing single CPU */
|
2010-11-06 08:17:33 +01:00
|
|
|
control.threads = PROCESSORS; /* get CPUs for LZMA */
|
|
|
|
|
control.page_size = PAGE_SIZE;
|
2010-03-29 01:07:08 +02:00
|
|
|
control.nice_val = 19;
|
|
|
|
|
|
|
|
|
|
/* generate crc table */
|
|
|
|
|
CrcGenerateTable();
|
|
|
|
|
|
2011-02-21 02:03:08 +01:00
|
|
|
/* Get Temp Dir */
|
|
|
|
|
eptr = getenv("TMP");
|
|
|
|
|
if (eptr != NULL) {
|
|
|
|
|
control.tmpdir = malloc(strlen(eptr)+2);
|
|
|
|
|
if (control.tmpdir == NULL)
|
|
|
|
|
fatal("Failed to allocate for tmpdir\n");
|
|
|
|
|
strcpy(control.tmpdir, eptr);
|
|
|
|
|
if (strcmp(eptr+strlen(eptr) - 1, "/")) /* need a trailing slash */
|
|
|
|
|
strcat(control.tmpdir, "/");
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-29 01:07:08 +02:00
|
|
|
/* Get Preloaded Defaults from lrzip.conf
|
|
|
|
|
* Look in ., $HOME/.lrzip/, /etc/lrzip.
|
|
|
|
|
* If LRZIP=NOCONFIG is set, then ignore config
|
|
|
|
|
*/
|
|
|
|
|
eptr = getenv("LRZIP");
|
|
|
|
|
if (eptr == NULL)
|
|
|
|
|
read_config(&control);
|
|
|
|
|
else if (!strstr(eptr,"NOCONFIG"))
|
|
|
|
|
read_config(&control);
|
|
|
|
|
|
2011-02-22 15:15:18 +01:00
|
|
|
while ((c = getopt(argc, argv, "L:h?dS:tVvDfqo:w:nlbUO:TN:p:gziHck")) != -1) {
|
2010-03-29 01:07:08 +02:00
|
|
|
switch (c) {
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'b':
|
|
|
|
|
if (control.flags & FLAG_NOT_LZMA)
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Can only use one of -l, -b, -g, -z or -n\n");
|
2011-02-21 02:03:08 +01:00
|
|
|
control.flags |= FLAG_BZIP2_COMPRESS;
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'c':
|
|
|
|
|
control.flags |= FLAG_CHECK;
|
|
|
|
|
control.flags |= FLAG_HASH;
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
|
|
|
|
case 'd':
|
|
|
|
|
control.flags |= FLAG_DECOMPRESS;
|
|
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'D':
|
|
|
|
|
control.flags &= ~FLAG_KEEP_FILES;
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
|
|
|
|
case 'f':
|
|
|
|
|
control.flags |= FLAG_FORCE_REPLACE;
|
|
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'g':
|
|
|
|
|
if (control.flags & FLAG_NOT_LZMA)
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Can only use one of -l, -b, -g, -z or -n\n");
|
2011-02-21 02:03:08 +01:00
|
|
|
control.flags |= FLAG_ZLIB_COMPRESS;
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'h':
|
|
|
|
|
case '?':
|
|
|
|
|
usage();
|
|
|
|
|
return -1;
|
|
|
|
|
case 'H':
|
|
|
|
|
control.flags |= FLAG_HASH;
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'i':
|
|
|
|
|
control.flags |= FLAG_INFO;
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'k':
|
|
|
|
|
control.flags |= FLAG_KEEP_BROKEN;
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
|
|
|
|
case 'l':
|
|
|
|
|
if (control.flags & FLAG_NOT_LZMA)
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Can only use one of -l, -b, -g, -z or -n\n");
|
2010-03-29 01:07:08 +02:00
|
|
|
control.flags |= FLAG_LZO_COMPRESS;
|
|
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'L':
|
|
|
|
|
control.compression_level = atoi(optarg);
|
|
|
|
|
if (control.compression_level < 1 || control.compression_level > 9)
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Invalid compression level (must be 1-9)\n");
|
2011-02-21 02:03:08 +01:00
|
|
|
break;
|
2010-03-29 01:07:08 +02:00
|
|
|
case 'n':
|
|
|
|
|
if (control.flags & FLAG_NOT_LZMA)
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Can only use one of -l, -b, -g, -z or -n\n");
|
2010-03-29 01:07:08 +02:00
|
|
|
control.flags |= FLAG_NO_COMPRESS;
|
|
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'N':
|
|
|
|
|
control.nice_val = atoi(optarg);
|
|
|
|
|
if (control.nice_val < -20 || control.nice_val > 19)
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Invalid nice value (must be -20..19)\n");
|
2010-11-04 11:14:55 +01:00
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'o':
|
|
|
|
|
if (control.outdir)
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Cannot have -o and -O together\n");
|
2011-02-21 02:03:08 +01:00
|
|
|
control.outname = optarg;
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
|
|
|
|
case 'O':
|
|
|
|
|
if (control.outname) /* can't mix -o and -O */
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Cannot have options -o and -O together\n");
|
2010-03-29 01:07:08 +02:00
|
|
|
control.outdir = malloc(strlen(optarg) + 2);
|
|
|
|
|
if (control.outdir == NULL)
|
|
|
|
|
fatal("Failed to allocate for outdir\n");
|
|
|
|
|
strcpy(control.outdir,optarg);
|
|
|
|
|
if (strcmp(optarg+strlen(optarg) - 1, "/")) /* need a trailing slash */
|
|
|
|
|
strcat(control.outdir, "/");
|
|
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'p':
|
|
|
|
|
control.threads = atoi(optarg);
|
|
|
|
|
if (control.threads < 1)
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Must have at least one thread\n");
|
2011-02-21 02:03:08 +01:00
|
|
|
break;
|
|
|
|
|
case 'q':
|
|
|
|
|
control.flags &= ~FLAG_SHOW_PROGRESS;
|
|
|
|
|
break;
|
|
|
|
|
case 'S':
|
|
|
|
|
control.suffix = optarg;
|
|
|
|
|
break;
|
|
|
|
|
case 't':
|
|
|
|
|
if (control.outname)
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Cannot specify an output file name when just testing.\n");
|
2011-02-21 02:03:08 +01:00
|
|
|
if (!KEEP_FILES)
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Doubt that you want to delete a file when just testing.\n");
|
2011-02-21 02:03:08 +01:00
|
|
|
control.flags |= FLAG_TEST_ONLY;
|
|
|
|
|
break;
|
2010-03-29 01:07:08 +02:00
|
|
|
case 'T':
|
2011-02-22 15:15:18 +01:00
|
|
|
control.flags &= ~FLAG_THRESHOLD;
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'U':
|
|
|
|
|
control.flags |= FLAG_UNLIMITED;
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'v':
|
|
|
|
|
/* set verbosity flag */
|
|
|
|
|
if (!(control.flags & FLAG_VERBOSITY) && !(control.flags & FLAG_VERBOSITY_MAX))
|
|
|
|
|
control.flags |= FLAG_VERBOSITY;
|
|
|
|
|
else if ((control.flags & FLAG_VERBOSITY)) {
|
|
|
|
|
control.flags &= ~FLAG_VERBOSITY;
|
|
|
|
|
control.flags |= FLAG_VERBOSITY_MAX;
|
|
|
|
|
}
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
2011-02-21 02:03:08 +01:00
|
|
|
case 'V':
|
|
|
|
|
print_output("lrzip version %d.%d%d\n",
|
|
|
|
|
LRZIP_MAJOR_VERSION, LRZIP_MINOR_VERSION, LRZIP_MINOR_SUBVERSION);
|
|
|
|
|
exit(0);
|
|
|
|
|
break;
|
|
|
|
|
case 'w':
|
|
|
|
|
control.window = atol(optarg);
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
|
|
|
|
case 'z':
|
|
|
|
|
if (control.flags & FLAG_NOT_LZMA)
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Can only use one of -l, -b, -g, -z or -n\n");
|
2010-03-29 01:07:08 +02:00
|
|
|
control.flags |= FLAG_ZPAQ_COMPRESS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
argc -= optind;
|
|
|
|
|
argv += optind;
|
|
|
|
|
|
|
|
|
|
if (control.outname && argc > 1)
|
2011-02-21 04:51:20 +01:00
|
|
|
failure("Cannot specify output filename with more than 1 file\n");
|
2010-03-29 01:07:08 +02:00
|
|
|
|
2010-10-31 18:53:53 +01:00
|
|
|
if (VERBOSE && !SHOW_PROGRESS) {
|
|
|
|
|
print_err("Cannot have -v and -q options. -v wins.\n");
|
2010-03-29 01:07:08 +02:00
|
|
|
control.flags |= FLAG_SHOW_PROGRESS;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-22 10:38:39 +01:00
|
|
|
if (UNLIMITED && control.window) {
|
|
|
|
|
print_err("If -U used, cannot specify a window size with -w.\n");
|
2011-02-21 02:03:08 +01:00
|
|
|
control.window = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-06 08:17:33 +01:00
|
|
|
if (argc < 1)
|
|
|
|
|
control.flags |= FLAG_STDIN;
|
|
|
|
|
|
2010-11-05 13:02:58 +01:00
|
|
|
if (UNLIMITED && STDIN) {
|
|
|
|
|
print_err("Cannot have -U and stdin, unlimited mode disabled.\n");
|
2011-03-01 07:25:50 +01:00
|
|
|
control.flags &= ~FLAG_UNLIMITED;
|
2010-11-05 13:02:58 +01:00
|
|
|
}
|
|
|
|
|
|
2011-02-22 15:22:54 +01:00
|
|
|
/* Work out the compression overhead per compression thread for the
|
|
|
|
|
* compression back-ends that need a lot of ram */
|
2011-02-22 05:19:31 +01:00
|
|
|
if (LZMA_COMPRESS) {
|
|
|
|
|
int level = control.compression_level * 7 / 9 ? : 1;
|
|
|
|
|
i64 dictsize = (level <= 5 ? (1 << (level * 2 + 14)) :
|
|
|
|
|
(level == 6 ? (1 << 25) : (1 << 26)));
|
|
|
|
|
|
2011-02-22 15:22:54 +01:00
|
|
|
control.overhead = (dictsize * 23 / 2) + (4 * 1024 * 1024);
|
2011-02-22 05:19:31 +01:00
|
|
|
} else if (ZPAQ_COMPRESS)
|
|
|
|
|
control.overhead = 112 * 1024 * 1024;
|
|
|
|
|
|
2011-02-23 13:58:50 +01:00
|
|
|
/* Decrease usable ram size on 32 bits due to kernel/userspace split */
|
|
|
|
|
if (BITS32)
|
|
|
|
|
control.ramsize = MAX(control.ramsize - 900000000ll, 900000000ll);
|
2011-03-07 03:23:14 +01:00
|
|
|
control.maxram = control.ramsize / 3;
|
2010-12-03 09:30:27 +01:00
|
|
|
|
2010-11-24 10:12:19 +01:00
|
|
|
/* Set the main nice value to half that of the backend threads since
|
|
|
|
|
* the rzip stage is usually the rate limiting step */
|
2011-02-22 15:26:51 +01:00
|
|
|
if (control.nice_val > 0 && !NO_COMPRESS) {
|
2010-11-24 10:12:19 +01:00
|
|
|
if (unlikely(setpriority(PRIO_PROCESS, 0, control.nice_val / 2) == -1))
|
|
|
|
|
print_err("Warning, unable to set nice value\n");
|
|
|
|
|
} else {
|
|
|
|
|
if (unlikely(setpriority(PRIO_PROCESS, 0, control.nice_val) == -1))
|
|
|
|
|
print_err("Warning, unable to set nice value\n");
|
|
|
|
|
}
|
2010-03-29 01:07:08 +02:00
|
|
|
|
|
|
|
|
/* One extra iteration for the case of no parameters means we will default to stdin/out */
|
|
|
|
|
for (i = 0; i <= argc; i++) {
|
|
|
|
|
if (i < argc)
|
|
|
|
|
control.infile = argv[i];
|
2010-10-31 18:53:53 +01:00
|
|
|
else if (!(i == 0 && STDIN))
|
2010-03-29 01:07:08 +02:00
|
|
|
break;
|
|
|
|
|
if (control.infile && (strcmp(control.infile, "-") == 0))
|
|
|
|
|
control.flags |= FLAG_STDIN;
|
|
|
|
|
|
2010-04-25 08:26:00 +02:00
|
|
|
if (control.outname && (strcmp(control.outname, "-") == 0)) {
|
2010-03-29 01:07:08 +02:00
|
|
|
control.flags |= FLAG_STDOUT;
|
2010-04-25 08:26:00 +02:00
|
|
|
control.msgout = stderr;
|
2011-03-08 22:32:14 +01:00
|
|
|
register_outputfile(control.msgout);
|
2010-04-25 08:26:00 +02:00
|
|
|
}
|
2010-03-29 01:07:08 +02:00
|
|
|
|
|
|
|
|
/* If we're using stdin and no output filename, use stdout */
|
2010-10-31 18:53:53 +01:00
|
|
|
if (STDIN && !control.outname) {
|
2010-03-29 01:07:08 +02:00
|
|
|
control.flags |= FLAG_STDOUT;
|
2010-04-25 08:26:00 +02:00
|
|
|
control.msgout = stderr;
|
2011-03-08 22:32:14 +01:00
|
|
|
register_outputfile(control.msgout);
|
2010-04-25 08:26:00 +02:00
|
|
|
}
|
2010-03-29 01:07:08 +02:00
|
|
|
|
2011-03-08 22:32:14 +01:00
|
|
|
if (!STDOUT) {
|
2010-04-25 08:26:00 +02:00
|
|
|
control.msgout = stdout;
|
2011-03-08 22:32:14 +01:00
|
|
|
register_outputfile(control.msgout);
|
|
|
|
|
}
|
2010-03-29 01:07:08 +02:00
|
|
|
/* Implement signal handler only once flags are set */
|
|
|
|
|
handler.sa_handler = &sighandler;
|
|
|
|
|
sigaction(SIGTERM, &handler, 0);
|
|
|
|
|
sigaction(SIGINT, &handler, 0);
|
|
|
|
|
|
2011-02-21 03:26:51 +01:00
|
|
|
if (!FORCE_REPLACE) {
|
|
|
|
|
if (STDIN && isatty(fileno((FILE *)stdin))) {
|
|
|
|
|
print_err("Will not read stdin from a terminal. Use -f to override.\n");
|
2011-02-21 03:29:45 +01:00
|
|
|
usage();
|
2011-02-21 03:26:51 +01:00
|
|
|
exit (1);
|
|
|
|
|
}
|
2011-02-28 11:25:16 +01:00
|
|
|
if (!TEST_ONLY && STDOUT && isatty(fileno((FILE *)stdout))) {
|
2011-02-21 03:26:51 +01:00
|
|
|
print_err("Will not write stdout to a terminal. Use -f to override.\n");
|
2011-02-21 03:29:45 +01:00
|
|
|
usage();
|
2011-02-21 03:26:51 +01:00
|
|
|
exit (1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-01 07:25:50 +01:00
|
|
|
if (CHECK_FILE) {
|
|
|
|
|
if (!DECOMPRESS) {
|
|
|
|
|
print_err("Can only check file written on decompression.\n");
|
|
|
|
|
control.flags &= ~FLAG_CHECK;
|
|
|
|
|
} else if (STDOUT) {
|
|
|
|
|
print_err("Can't check file written when writing to stdout. Checking disabled.\n");
|
|
|
|
|
control.flags &= ~FLAG_CHECK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-01 04:21:10 +01:00
|
|
|
show_summary();
|
|
|
|
|
|
2010-03-29 01:07:08 +02:00
|
|
|
gettimeofday(&start_time, NULL);
|
|
|
|
|
|
|
|
|
|
if (control.flags & (FLAG_DECOMPRESS | FLAG_TEST_ONLY))
|
2011-03-08 22:32:14 +01:00
|
|
|
decompress_file(&control);
|
2010-10-31 18:53:53 +01:00
|
|
|
else if (INFO)
|
2011-03-08 22:32:14 +01:00
|
|
|
get_fileinfo(&control);
|
2010-03-29 01:07:08 +02:00
|
|
|
else
|
2011-03-08 22:32:14 +01:00
|
|
|
compress_file(&control);
|
2010-03-29 01:07:08 +02:00
|
|
|
|
|
|
|
|
/* compute total time */
|
|
|
|
|
gettimeofday(&end_time, NULL);
|
|
|
|
|
total_time = (end_time.tv_sec + (double)end_time.tv_usec / 1000000) -
|
|
|
|
|
(start_time.tv_sec + (double)start_time.tv_usec / 1000000);
|
|
|
|
|
hours = (int)total_time / 3600;
|
2011-03-02 04:16:57 +01:00
|
|
|
minutes = (int)(total_time / 60) % 60;
|
|
|
|
|
seconds = total_time - hours * 3600 - minutes * 60;
|
2010-10-31 18:53:53 +01:00
|
|
|
if (!INFO)
|
2011-03-02 04:16:57 +01:00
|
|
|
print_progress("Total time: %02d:%02d:%05.2f\n", hours, minutes, seconds);
|
2010-03-29 01:07:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|