1
0
Fork 0

Adding upstream version 1.10.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-23 19:24:32 +01:00
parent d2ef351ac9
commit 187580aeb9
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
12 changed files with 276 additions and 193 deletions

View file

@ -1,3 +1,13 @@
2019-01-01 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.10 released.
* File_* renamed to Lzip_*.
* main.c: Document option -0 and make it use a 64 KiB dict size.
* main.c (main): Check return value of close( infd ).
* main.c: Compile on DOS with DJGPP.
* configure: Accept appending to CFLAGS, 'CFLAGS+=OPTIONS'.
* INSTALL: Document use of CFLAGS+='-D __USE_MINGW_ANSI_STDIO'.
2018-02-04 Antonio Diaz Diaz <antonio@gnu.org> 2018-02-04 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.9 released. * Version 1.9 released.
@ -84,7 +94,7 @@
* Using LZMA SDK 9.10 (public domain) from Igor Pavlov. * Using LZMA SDK 9.10 (public domain) from Igor Pavlov.
Copyright (C) 2010-2018 Antonio Diaz Diaz. Copyright (C) 2010-2019 Antonio Diaz Diaz.
This file is a collection of facts, and thus it is not copyrightable, This file is a collection of facts, and thus it is not copyrightable,
but just in case, you have unlimited permission to copy, distribute and but just in case, you have unlimited permission to copy, distribute and

14
INSTALL
View file

@ -1,10 +1,14 @@
Requirements Requirements
------------ ------------
You will need a C compiler. You will need a C compiler.
I use gcc 5.3.0 and 4.1.2, but the code should compile with any I use gcc 5.3.0 and 4.1.2, but the code should compile with any standards
standards compliant compiler. compliant compiler.
Gcc is available at http://gcc.gnu.org. Gcc is available at http://gcc.gnu.org.
The operating system must allow signal handlers read access to objects with
static storage duration so that the cleanup handler for Control-C can delete
the partial output file.
Procedure Procedure
--------- ---------
@ -23,6 +27,10 @@ the main archive.
cd pdlzip[version] cd pdlzip[version]
./configure ./configure
If you are compiling on MinGW, use:
./configure CFLAGS+='-D __USE_MINGW_ANSI_STDIO'
3. Run make. 3. Run make.
make make
@ -61,7 +69,7 @@ After running 'configure', you can run 'make' and 'make install' as
explained above. explained above.
Copyright (C) 2010-2018 Antonio Diaz Diaz. Copyright (C) 2010-2019 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy, This file is free documentation: you have unlimited permission to copy,
distribute and modify it. distribute and modify it.

View file

@ -1352,7 +1352,7 @@ static uint32_t GetOptimumFast(CLzmaEnc *p, uint32_t *backRes)
static void LZe_full_flush(CLzmaEnc *p, uint32_t posState) static void LZe_full_flush(CLzmaEnc *p, uint32_t posState)
{ {
const uint32_t len = LZMA_MATCH_LEN_MIN; const uint32_t len = LZMA_MATCH_LEN_MIN;
File_trailer trailer; Lzip_trailer trailer;
RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
p->state = kMatchNextStates[p->state]; p->state = kMatchNextStates[p->state];
@ -1362,15 +1362,15 @@ static void LZe_full_flush(CLzmaEnc *p, uint32_t posState)
RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
RangeEnc_FlushData(&p->rc); RangeEnc_FlushData(&p->rc);
RangeEnc_FlushStream(&p->rc); RangeEnc_FlushStream(&p->rc);
Ft_set_data_crc( trailer, p->matchFinderBase.crc ^ 0xFFFFFFFFU ); Lt_set_data_crc( trailer, p->matchFinderBase.crc ^ 0xFFFFFFFFU );
Ft_set_data_size( trailer, p->nowPos64 ); Lt_set_data_size( trailer, p->nowPos64 );
Ft_set_member_size( trailer, p->rc.processed + Fh_size + Ft_size ); Lt_set_member_size( trailer, p->rc.processed + Lh_size + Lt_size );
if( writeblock( p->rc.outfd, trailer, Ft_size ) != Ft_size ) if( writeblock( p->rc.outfd, trailer, Lt_size ) != Lt_size )
p->rc.res = SZ_ERROR_WRITE; p->rc.res = SZ_ERROR_WRITE;
if( verbosity >= 1 ) if( verbosity >= 1 )
{ {
unsigned long long in_size = p->nowPos64; unsigned long long in_size = p->nowPos64;
unsigned long long out_size = p->rc.processed + Fh_size + Ft_size; unsigned long long out_size = p->rc.processed + Lh_size + Lt_size;
if( in_size == 0 || out_size == 0 ) if( in_size == 0 || out_size == 0 )
fputs( " no data compressed.\n", stderr ); fputs( " no data compressed.\n", stderr );
else else

30
NEWS
View file

@ -1,26 +1,14 @@
Changes in version 1.9: Changes in version 1.10:
The option '--loose-trailing', has been added. Compression level '-0' now uses a dictionary size of 64 KiB instead of
1 MiB.
The test used by pdlzip to discriminate trailing data from a corrupt Errors are now also checked when closing the input file.
header in multimember or concatenated files has been improved to a
Hamming distance (HD) of 3, and the 3 bit flips must happen in different
magic bytes for the test to fail. As a consequence some kinds of files
no longer can be appended to a lzip file as trailing data unless the
'--loose-trailing' option is used when decompressing.
Lziprecover can be used to remove conflicting trailing data from a file.
The 'bits/byte' ratio has been replaced with the inverse compression Pdlzip now compiles on DOS with DJGPP. (Patch from Robert Riebisch).
ratio in the output.
A final diagnostic is now shown at verbosity level 1 (-v) or higher if The configure script now accepts appending options to CFLAGS using the
any file fails the test when testing multiple files. syntax 'CFLAGS+=OPTIONS'.
A second '.lz' extension is no longer added to the argument of '-o' if It has been documented in INSTALL the use of
it already ends in '.lz' or '.tlz'. CFLAGS+='-D __USE_MINGW_ANSI_STDIO' when compiling on MinGW.
In case of (de)compressed size mismatch, the stored size is now also
shown in hexadecimal to ease visual comparison.
The dictionary size is now shown at verbosity level 4 (-vvvv) when
decompressing or testing.

38
README
View file

@ -1,17 +1,21 @@
Description Description
Pdlzip is a lossless data compressor with a user interface similar to Pdlzip is a permissively licensed implementation of the lzip data
the one of lzip, bzip2 or gzip. compressor, intended for those who can't distribute (or even use) GPL
licensed Free Software. (The name of pdlzip comes from 'public domain
lzip'). Pdlzip is written in C and is (hope)fully compatible with lzip 1.4
or newer.
Pdlzip uses the lzip file format; the files produced by pdlzip are Lzip is a lossless data compressor with a user interface similar to the
(hope)fully compatible with lzip-1.4 or newer. Pdlzip is in fact a one of gzip or bzip2. Lzip can compress about as fast as gzip (lzip -0)
permissively licensed implementation of the lzip data compressor, or compress most files more than bzip2 (lzip -9). Decompression speed is
intended for those who can't distribute (or even use) GPL licensed Free intermediate between gzip and bzip2. Lzip is better than gzip and bzip2
Software. (The name of pdlzip comes from "public domain lzip"). from a data recovery perspective. Lzip has been designed, written and
tested with great care to replace gzip and bzip2 as the standard
general-purpose compressed format for unix-like systems.
The lzip file format is designed for data sharing and long-term The lzip file format is designed for data sharing and long-term archiving,
archiving, taking into account both data integrity and decoder taking into account both data integrity and decoder availability:
availability:
* The lzip format provides very safe integrity checking and some data * The lzip format provides very safe integrity checking and some data
recovery means. The lziprecover program can repair bit flip errors recovery means. The lziprecover program can repair bit flip errors
@ -20,11 +24,11 @@ availability:
merging of damaged copies of a file. merging of damaged copies of a file.
* The lzip format is as simple as possible (but not simpler). The * The lzip format is as simple as possible (but not simpler). The
lzip manual provides the source code of a simple decompressor along lzip manual provides the source code of a simple decompressor
with a detailed explanation of how it works, so that with the only along with a detailed explanation of how it works, so that with
help of the lzip manual it would be possible for a digital the only help of the lzip manual it would be possible for a
archaeologist to extract the data from a lzip file long after digital archaeologist to extract the data from a lzip file long
quantum computers eventually render LZMA obsolete. after quantum computers eventually render LZMA obsolete.
* Additionally the lzip reference implementation is copylefted, which * Additionally the lzip reference implementation is copylefted, which
guarantees that it will remain free forever. guarantees that it will remain free forever.
@ -40,8 +44,6 @@ If you keep any lzma-alone files, it is advisable to recompress them to
lzip format. Lziprecover can convert some lzma-alone files to lzip format lzip format. Lziprecover can convert some lzma-alone files to lzip format
without recompressing. without recompressing.
Pdlzip is written in C.
Pdlzip includes public domain (de)compression code from the LZMA SDK Pdlzip includes public domain (de)compression code from the LZMA SDK
(Software Development Kit) written by Igor Pavlov. (Software Development Kit) written by Igor Pavlov.
@ -52,7 +54,7 @@ users of the most non-free platforms can share lzip files with everybody
else. else.
Copyright (C) 2010-2018 Antonio Diaz Diaz. Copyright (C) 2010-2019 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy, This file is free documentation: you have unlimited permission to copy,
distribute and modify it. distribute and modify it.

View file

@ -1,5 +1,5 @@
/* Arg_parser - POSIX/GNU command line argument parser. (C version) /* Arg_parser - POSIX/GNU command line argument parser. (C version)
Copyright (C) 2006-2018 Antonio Diaz Diaz. Copyright (C) 2006-2019 Antonio Diaz Diaz.
This library is free software. Redistribution and use in source and This library is free software. Redistribution and use in source and
binary forms, with or without modification, are permitted provided binary forms, with or without modification, are permitted provided

View file

@ -1,5 +1,5 @@
/* Arg_parser - POSIX/GNU command line argument parser. (C version) /* Arg_parser - POSIX/GNU command line argument parser. (C version)
Copyright (C) 2006-2018 Antonio Diaz Diaz. Copyright (C) 2006-2019 Antonio Diaz Diaz.
This library is free software. Redistribution and use in source and This library is free software. Redistribution and use in source and
binary forms, with or without modification, are permitted provided binary forms, with or without modification, are permitted provided

8
configure vendored
View file

@ -1,12 +1,12 @@
#! /bin/sh #! /bin/sh
# configure script for Pdlzip - LZMA lossless data compressor # configure script for Pdlzip - LZMA lossless data compressor
# Copyright (C) 2010-2018 Antonio Diaz Diaz. # Copyright (C) 2010-2019 Antonio Diaz Diaz.
# #
# This configure script is free software: you have unlimited permission # This configure script is free software: you have unlimited permission
# to copy, distribute and modify it. # to copy, distribute and modify it.
pkgname=pdlzip pkgname=pdlzip
pkgversion=1.9 pkgversion=1.10
progname=pdlzip progname=pdlzip
srctrigger=doc/${progname}.1 srctrigger=doc/${progname}.1
@ -70,6 +70,7 @@ while [ $# != 0 ] ; do
echo " CC=COMPILER C compiler to use [${CC}]" echo " CC=COMPILER C compiler to use [${CC}]"
echo " CPPFLAGS=OPTIONS command line options for the preprocessor [${CPPFLAGS}]" echo " CPPFLAGS=OPTIONS command line options for the preprocessor [${CPPFLAGS}]"
echo " CFLAGS=OPTIONS command line options for the C compiler [${CFLAGS}]" echo " CFLAGS=OPTIONS command line options for the C compiler [${CFLAGS}]"
echo " CFLAGS+=OPTIONS append options to the current value of CFLAGS"
echo " LDFLAGS=OPTIONS command line options for the linker [${LDFLAGS}]" echo " LDFLAGS=OPTIONS command line options for the linker [${LDFLAGS}]"
echo echo
exit 0 ;; exit 0 ;;
@ -96,6 +97,7 @@ while [ $# != 0 ] ; do
CC=*) CC=${optarg} ;; CC=*) CC=${optarg} ;;
CPPFLAGS=*) CPPFLAGS=${optarg} ;; CPPFLAGS=*) CPPFLAGS=${optarg} ;;
CFLAGS=*) CFLAGS=${optarg} ;; CFLAGS=*) CFLAGS=${optarg} ;;
CFLAGS+=*) CFLAGS="${CFLAGS} ${optarg}" ;;
LDFLAGS=*) LDFLAGS=${optarg} ;; LDFLAGS=*) LDFLAGS=${optarg} ;;
--*) --*)
@ -168,7 +170,7 @@ echo "LDFLAGS = ${LDFLAGS}"
rm -f Makefile rm -f Makefile
cat > Makefile << EOF cat > Makefile << EOF
# Makefile for Pdlzip - LZMA lossless data compressor # Makefile for Pdlzip - LZMA lossless data compressor
# Copyright (C) 2010-2018 Antonio Diaz Diaz. # Copyright (C) 2010-2019 Antonio Diaz Diaz.
# This file was generated automatically by configure. Don't edit. # This file was generated automatically by configure. Don't edit.
# #
# This Makefile is free software: you have unlimited permission # This Makefile is free software: you have unlimited permission

View file

@ -1,14 +1,26 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
.TH PDLZIP "1" "February 2018" "pdlzip 1.9" "User Commands" .TH PDLZIP "1" "January 2019" "pdlzip 1.10" "User Commands"
.SH NAME .SH NAME
pdlzip \- reduces the size of files pdlzip \- reduces the size of files
.SH SYNOPSIS .SH SYNOPSIS
.B pdlzip .B pdlzip
[\fI\,options\/\fR] [\fI\,files\/\fR] [\fI\,options\/\fR] [\fI\,files\/\fR]
.SH DESCRIPTION .SH DESCRIPTION
Pdlzip \- A permissively licensed implementation of the lzip data Pdlzip is a permissively licensed implementation of the lzip data
compressor also able to decompress legacy lzma\-alone (.lzma) files. compressor, intended for those who can't distribute (or even use) GPL
licensed Free Software. (The name of pdlzip comes from 'public domain
lzip'). Pdlzip is written in C and is (hope)fully compatible with lzip 1.4
or newer.
.PP .PP
Lzip is a lossless data compressor with a user interface similar to the
one of gzip or bzip2. Lzip can compress about as fast as gzip (lzip \fB\-0\fR)
or compress most files more than bzip2 (lzip \fB\-9\fR). Decompression speed is
intermediate between gzip and bzip2. Lzip is better than gzip and bzip2
from a data recovery perspective. Lzip has been designed, written and
tested with great care to replace gzip and bzip2 as the standard
general\-purpose compressed format for unix\-like systems.
.PP
Pdlzip is also able to decompress legacy lzma\-alone (.lzma) files.
Lzma\-alone is a very bad format; it is essentially a raw LZMA stream. Lzma\-alone is a very bad format; it is essentially a raw LZMA stream.
If you keep any lzma\-alone files, it is advisable to recompress them to If you keep any lzma\-alone files, it is advisable to recompress them to
lzip format. Lziprecover can convert some lzma\-alone files to lzip format lzip format. Lziprecover can convert some lzma\-alone files to lzip format
@ -57,11 +69,11 @@ test compressed file integrity
\fB\-v\fR, \fB\-\-verbose\fR \fB\-v\fR, \fB\-\-verbose\fR
be verbose (a 2nd \fB\-v\fR gives more) be verbose (a 2nd \fB\-v\fR gives more)
.TP .TP
\fB\-1\fR .. \fB\-9\fR \fB\-0\fR .. \fB\-9\fR
set compression level [default 6] set compression level [default 6]
.TP .TP
\fB\-\-fast\fR \fB\-\-fast\fR
alias for \fB\-1\fR alias for \fB\-0\fR
.TP .TP
\fB\-\-best\fR \fB\-\-best\fR
alias for \fB\-9\fR alias for \fB\-9\fR
@ -91,7 +103,7 @@ Report bugs to lzip\-bug@nongnu.org
.br .br
Pdlzip home page: http://www.nongnu.org/lzip/pdlzip.html Pdlzip home page: http://www.nongnu.org/lzip/pdlzip.html
.SH COPYRIGHT .SH COPYRIGHT
Copyright \(co 2018 Antonio Diaz Diaz. Copyright \(co 2019 Antonio Diaz Diaz.
Public Domain 2009 Igor Pavlov. Public Domain 2009 Igor Pavlov.
License 2\-clause BSD. License 2\-clause BSD.
.br .br

53
lzip.h
View file

@ -1,5 +1,5 @@
/* Pdlzip - LZMA lossless data compressor /* Pdlzip - LZMA lossless data compressor
Copyright (C) 2010-2018 Antonio Diaz Diaz. Copyright (C) 2010-2019 Antonio Diaz Diaz.
This program is free software. Redistribution and use in source and This program is free software. Redistribution and use in source and
binary forms, with or without modification, are permitted provided binary forms, with or without modification, are permitted provided
@ -55,7 +55,7 @@ enum {
/* defined in main.c */ /* defined in main.c */
extern int verbosity; extern int verbosity;
struct Pretty_print struct Pretty_print /* requires global var 'int verbosity' */
{ {
const char * name; const char * name;
char * padded_name; char * padded_name;
@ -82,7 +82,7 @@ static inline void Pp_init( struct Pretty_print * const pp,
{ {
const char * const s = filenames[i]; const char * const s = filenames[i];
const unsigned len = (strcmp( s, "-" ) == 0) ? stdin_name_len : strlen( s ); const unsigned len = (strcmp( s, "-" ) == 0) ? stdin_name_len : strlen( s );
if( len > pp->longest_name ) pp->longest_name = len; if( pp->longest_name < len ) pp->longest_name = len;
} }
if( pp->longest_name == 0 ) pp->longest_name = stdin_name_len; if( pp->longest_name == 0 ) pp->longest_name = stdin_name_len;
} }
@ -153,43 +153,43 @@ static inline int real_bits( unsigned value )
} }
static const uint8_t magic_string[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */ static const uint8_t lzip_magic[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */
typedef uint8_t File_header[6]; /* 0-3 magic bytes */ typedef uint8_t Lzip_header[6]; /* 0-3 magic bytes */
/* 4 version */ /* 4 version */
/* 5 coded_dict_size */ /* 5 coded_dict_size */
enum { Fh_size = 6 }; enum { Lh_size = 6 };
static inline void Fh_set_magic( File_header data ) static inline void Lh_set_magic( Lzip_header data )
{ memcpy( data, magic_string, 4 ); data[4] = 1; } { memcpy( data, lzip_magic, 4 ); data[4] = 1; }
static inline bool Fh_verify_magic( const File_header data ) static inline bool Lh_verify_magic( const Lzip_header data )
{ return ( memcmp( data, magic_string, 4 ) == 0 ); } { return ( memcmp( data, lzip_magic, 4 ) == 0 ); }
/* detect (truncated) header */ /* detect (truncated) header */
static inline bool Fh_verify_prefix( const File_header data, const int sz ) static inline bool Lh_verify_prefix( const Lzip_header data, const int sz )
{ {
int i; for( i = 0; i < sz && i < 4; ++i ) int i; for( i = 0; i < sz && i < 4; ++i )
if( data[i] != magic_string[i] ) return false; if( data[i] != lzip_magic[i] ) return false;
return ( sz > 0 ); return ( sz > 0 );
} }
/* detect corrupt header */ /* detect corrupt header */
static inline bool Fh_verify_corrupt( const File_header data ) static inline bool Lh_verify_corrupt( const Lzip_header data )
{ {
int matches = 0; int matches = 0;
int i; for( i = 0; i < 4; ++i ) int i; for( i = 0; i < 4; ++i )
if( data[i] == magic_string[i] ) ++matches; if( data[i] == lzip_magic[i] ) ++matches;
return ( matches > 1 && matches < 4 ); return ( matches > 1 && matches < 4 );
} }
static inline uint8_t Fh_version( const File_header data ) static inline uint8_t Lh_version( const Lzip_header data )
{ return data[4]; } { return data[4]; }
static inline bool Fh_verify_version( const File_header data ) static inline bool Lh_verify_version( const Lzip_header data )
{ return ( data[4] == 1 ); } { return ( data[4] == 1 ); }
static inline unsigned Fh_get_dictionary_size( const File_header data ) static inline unsigned Lh_get_dictionary_size( const Lzip_header data )
{ {
unsigned sz = ( 1 << ( data[5] & 0x1F ) ); unsigned sz = ( 1 << ( data[5] & 0x1F ) );
if( sz > min_dictionary_size ) if( sz > min_dictionary_size )
@ -197,7 +197,7 @@ static inline unsigned Fh_get_dictionary_size( const File_header data )
return sz; return sz;
} }
static inline bool Fh_set_dictionary_size( File_header data, const unsigned sz ) static inline bool Lh_set_dictionary_size( Lzip_header data, const unsigned sz )
{ {
if( !isvalid_ds( sz ) ) return false; if( !isvalid_ds( sz ) ) return false;
data[5] = real_bits( sz - 1 ); data[5] = real_bits( sz - 1 );
@ -214,41 +214,40 @@ static inline bool Fh_set_dictionary_size( File_header data, const unsigned sz )
} }
typedef uint8_t File_trailer[20]; typedef uint8_t Lzip_trailer[20];
/* 0-3 CRC32 of the uncompressed data */ /* 0-3 CRC32 of the uncompressed data */
/* 4-11 size of the uncompressed data */ /* 4-11 size of the uncompressed data */
/* 12-19 member size including header and trailer */ /* 12-19 member size including header and trailer */
enum { Lt_size = 20 };
enum { Ft_size = 20 }; static inline unsigned Lt_get_data_crc( const Lzip_trailer data )
static inline unsigned Ft_get_data_crc( const File_trailer data )
{ {
unsigned tmp = 0; unsigned tmp = 0;
int i; for( i = 3; i >= 0; --i ) { tmp <<= 8; tmp += data[i]; } int i; for( i = 3; i >= 0; --i ) { tmp <<= 8; tmp += data[i]; }
return tmp; return tmp;
} }
static inline void Ft_set_data_crc( File_trailer data, unsigned crc ) static inline void Lt_set_data_crc( Lzip_trailer data, unsigned crc )
{ int i; for( i = 0; i <= 3; ++i ) { data[i] = (uint8_t)crc; crc >>= 8; } } { int i; for( i = 0; i <= 3; ++i ) { data[i] = (uint8_t)crc; crc >>= 8; } }
static inline unsigned long long Ft_get_data_size( const File_trailer data ) static inline unsigned long long Lt_get_data_size( const Lzip_trailer data )
{ {
unsigned long long tmp = 0; unsigned long long tmp = 0;
int i; for( i = 11; i >= 4; --i ) { tmp <<= 8; tmp += data[i]; } int i; for( i = 11; i >= 4; --i ) { tmp <<= 8; tmp += data[i]; }
return tmp; return tmp;
} }
static inline void Ft_set_data_size( File_trailer data, unsigned long long sz ) static inline void Lt_set_data_size( Lzip_trailer data, unsigned long long sz )
{ int i; for( i = 4; i <= 11; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; } } { int i; for( i = 4; i <= 11; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; } }
static inline unsigned long long Ft_get_member_size( const File_trailer data ) static inline unsigned long long Lt_get_member_size( const Lzip_trailer data )
{ {
unsigned long long tmp = 0; unsigned long long tmp = 0;
int i; for( i = 19; i >= 12; --i ) { tmp <<= 8; tmp += data[i]; } int i; for( i = 19; i >= 12; --i ) { tmp <<= 8; tmp += data[i]; }
return tmp; return tmp;
} }
static inline void Ft_set_member_size( File_trailer data, unsigned long long sz ) static inline void Lt_set_member_size( Lzip_trailer data, unsigned long long sz )
{ int i; for( i = 12; i <= 19; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; } } { int i; for( i = 12; i <= 19; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; } }

153
main.c
View file

@ -1,6 +1,6 @@
/* Pdlzip - LZMA lossless data compressor /* Pdlzip - LZMA lossless data compressor
2009-08-14 : Igor Pavlov : Public domain 2009-08-14 : Igor Pavlov : Public domain
Copyright (C) 2010-2018 Antonio Diaz Diaz. Copyright (C) 2010-2019 Antonio Diaz Diaz.
This program is free software. Redistribution and use in source and This program is free software. Redistribution and use in source and
binary forms, with or without modification, are permitted provided binary forms, with or without modification, are permitted provided
@ -38,19 +38,24 @@
#include <unistd.h> #include <unistd.h>
#include <utime.h> #include <utime.h>
#include <sys/stat.h> #include <sys/stat.h>
#if defined(__MSVCRT__) #if defined(__MSVCRT__) || defined(__OS2__) || defined(__DJGPP__)
#include <io.h> #include <io.h>
#if defined(__MSVCRT__)
#define fchmod(x,y) 0 #define fchmod(x,y) 0
#define fchown(x,y,z) 0 #define fchown(x,y,z) 0
#define SIGHUP SIGTERM #define SIGHUP SIGTERM
#define S_ISSOCK(x) 0 #define S_ISSOCK(x) 0
#ifndef S_IRGRP
#define S_IRGRP 0 #define S_IRGRP 0
#define S_IWGRP 0 #define S_IWGRP 0
#define S_IROTH 0 #define S_IROTH 0
#define S_IWOTH 0 #define S_IWOTH 0
#endif #endif
#if defined(__OS2__) #endif
#include <io.h> #if defined(__DJGPP__)
#define S_ISSOCK(x) 0
#define S_ISVTX 0
#endif
#endif #endif
#include "carg_parser.h" #include "carg_parser.h"
@ -68,9 +73,8 @@
int verbosity = 0; int verbosity = 0;
const char * const Program_name = "Pdlzip";
const char * const program_name = "pdlzip"; const char * const program_name = "pdlzip";
const char * const program_year = "2018"; const char * const program_year = "2019";
const char * invocation_name = 0; const char * invocation_name = 0;
const struct { const char * from; const char * to; } known_extensions[] = { const struct { const char * from; const char * to; } known_extensions[] = {
@ -87,6 +91,8 @@ struct Lzma_options
enum Mode { m_compress, m_decompress, m_test }; enum Mode { m_compress, m_decompress, m_test };
/* Variables used in signal handler context.
They are not declared volatile because the handler never returns. */
char * output_filename = 0; char * output_filename = 0;
int outfd = -1; int outfd = -1;
bool delete_output_on_interrupt = false; bool delete_output_on_interrupt = false;
@ -94,9 +100,20 @@ bool delete_output_on_interrupt = false;
static void show_help( void ) static void show_help( void )
{ {
printf( "%s - A permissively licensed implementation of the lzip data\n", Program_name ); printf( "Pdlzip is a permissively licensed implementation of the lzip data\n"
printf( "compressor also able to decompress legacy lzma-alone (.lzma) files.\n" "compressor, intended for those who can't distribute (or even use) GPL\n"
"\nLzma-alone is a very bad format; it is essentially a raw LZMA stream.\n" "licensed Free Software. (The name of pdlzip comes from 'public domain\n"
"lzip'). Pdlzip is written in C and is (hope)fully compatible with lzip 1.4\n"
"or newer.\n"
"\nLzip is a lossless data compressor with a user interface similar to the\n"
"one of gzip or bzip2. Lzip can compress about as fast as gzip (lzip -0)\n"
"or compress most files more than bzip2 (lzip -9). Decompression speed is\n"
"intermediate between gzip and bzip2. Lzip is better than gzip and bzip2\n"
"from a data recovery perspective. Lzip has been designed, written and\n"
"tested with great care to replace gzip and bzip2 as the standard\n"
"general-purpose compressed format for unix-like systems.\n"
"\nPdlzip is also able to decompress legacy lzma-alone (.lzma) files.\n"
"Lzma-alone is a very bad format; it is essentially a raw LZMA stream.\n"
"If you keep any lzma-alone files, it is advisable to recompress them to\n" "If you keep any lzma-alone files, it is advisable to recompress them to\n"
"lzip format. Lziprecover can convert some lzma-alone files to lzip format\n" "lzip format. Lziprecover can convert some lzma-alone files to lzip format\n"
"without recompressing.\n" "without recompressing.\n"
@ -116,8 +133,8 @@ static void show_help( void )
" -s, --dictionary-size=<bytes> set dictionary size limit in bytes [8 MiB]\n" " -s, --dictionary-size=<bytes> set dictionary size limit in bytes [8 MiB]\n"
" -t, --test test compressed file integrity\n" " -t, --test test compressed file integrity\n"
" -v, --verbose be verbose (a 2nd -v gives more)\n" " -v, --verbose be verbose (a 2nd -v gives more)\n"
" -1 .. -9 set compression level [default 6]\n" " -0 .. -9 set compression level [default 6]\n"
" --fast alias for -1\n" " --fast alias for -0\n"
" --best alias for -9\n" " --best alias for -9\n"
" --loose-trailing allow trailing data seeming corrupt header\n" " --loose-trailing allow trailing data seeming corrupt header\n"
"If no file names are given, or if a file is '-', pdlzip compresses or\n" "If no file names are given, or if a file is '-', pdlzip compresses or\n"
@ -255,7 +272,7 @@ static int get_dict_size( const char * const arg )
const long bits = strtol( arg, &tail, 0 ); const long bits = strtol( arg, &tail, 0 );
if( bits >= min_dictionary_bits && if( bits >= min_dictionary_bits &&
bits <= max_dictionary_bits_c && *tail == 0 ) bits <= max_dictionary_bits_c && *tail == 0 )
return ( 1 << bits ); return 1 << bits;
return getnum( arg, min_dictionary_size, max_dictionary_size_c ); return getnum( arg, min_dictionary_size, max_dictionary_size_c );
} }
@ -393,8 +410,17 @@ static bool check_tty( const char * const input_filename, const int infd,
} }
static void set_signals( void (*action)(int) )
{
signal( SIGHUP, action );
signal( SIGINT, action );
signal( SIGTERM, action );
}
void cleanup_and_fail( const int retval ) void cleanup_and_fail( const int retval )
{ {
set_signals( SIG_IGN ); /* ignore signals */
if( delete_output_on_interrupt ) if( delete_output_on_interrupt )
{ {
delete_output_on_interrupt = false; delete_output_on_interrupt = false;
@ -409,6 +435,14 @@ void cleanup_and_fail( const int retval )
} }
void signal_handler( int sig )
{
if( sig ) {} /* keep compiler happy */
show_error( "Control-C or similar caught, quitting.", 0, false );
cleanup_and_fail( 1 );
}
/* Set permissions, owner and times. */ /* Set permissions, owner and times. */
static void close_and_set_permissions( const struct stat * const in_statsp ) static void close_and_set_permissions( const struct stat * const in_statsp )
{ {
@ -448,14 +482,14 @@ static int compress( const struct Lzma_options * const encoder_options,
{ {
int retval = 0; int retval = 0;
CLzmaEncHandle encoder = 0; CLzmaEncHandle encoder = 0;
File_header header; Lzip_header header;
Fh_set_magic( header ); Lh_set_magic( header );
if( verbosity >= 1 ) Pp_show_msg( pp, 0 ); if( verbosity >= 1 ) Pp_show_msg( pp, 0 );
if( Fh_set_dictionary_size( header, encoder_options->dictionary_size ) && if( Lh_set_dictionary_size( header, encoder_options->dictionary_size ) &&
encoder_options->match_len_limit >= min_match_len_limit && encoder_options->match_len_limit >= min_match_len_limit &&
encoder_options->match_len_limit <= max_match_len ) encoder_options->match_len_limit <= max_match_len )
encoder = LzmaEnc_Init( Fh_get_dictionary_size( header ), encoder = LzmaEnc_Init( Lh_get_dictionary_size( header ),
encoder_options->match_len_limit, infd, outfd ); encoder_options->match_len_limit, infd, outfd );
else internal_error( "invalid argument to encoder." ); else internal_error( "invalid argument to encoder." );
@ -465,7 +499,7 @@ static int compress( const struct Lzma_options * const encoder_options,
return 1; return 1;
} }
if( writeblock( outfd, header, Fh_size ) != Fh_size ) if( writeblock( outfd, header, Lh_size ) != Lh_size )
{ show_error( "Can't write output file", errno, false ); retval = 1; } { show_error( "Can't write output file", errno, false ); retval = 1; }
else else
if( LzmaEnc_Encode( encoder ) != 0 ) if( LzmaEnc_Encode( encoder ) != 0 )
@ -578,7 +612,7 @@ static int lzip_decode( CLzmaDec *decoder, const int infd,
int * const inPos, int * const inSize, int * const inPos, int * const inSize,
const unsigned dictionary_size ) const unsigned dictionary_size )
{ {
unsigned long long member_size = Fh_size, data_size = 0; unsigned long long member_size = Lh_size, data_size = 0;
uint8_t outBuf[OUT_BUF_SIZE]; uint8_t outBuf[OUT_BUF_SIZE];
int outPos = 0; int outPos = 0;
uint32_t crc = 0xFFFFFFFFU; uint32_t crc = 0xFFFFFFFFU;
@ -612,7 +646,7 @@ static int lzip_decode( CLzmaDec *decoder, const int infd,
if (inProcessed == 0 && outProcessed == 0) if (inProcessed == 0 && outProcessed == 0)
{ {
File_trailer trailer; Lzip_trailer trailer;
int i; int i;
unsigned td_crc; unsigned td_crc;
unsigned long long td_size, tm_size; unsigned long long td_size, tm_size;
@ -620,9 +654,9 @@ static int lzip_decode( CLzmaDec *decoder, const int infd,
if( status != LZMA_STATUS_FINISHED_WITH_MARK ) if( status != LZMA_STATUS_FINISHED_WITH_MARK )
{ Pp_show_msg( pp, "Data error." ); return 2; } { Pp_show_msg( pp, "Data error." ); return 2; }
if( *inSize - *inPos < Ft_size && if( *inSize - *inPos < Lt_size &&
!read_inbuf( infd, inBuf, inPos, inSize ) ) return 1; !read_inbuf( infd, inBuf, inPos, inSize ) ) return 1;
if( *inSize - *inPos < Ft_size ) if( *inSize - *inPos < Lt_size )
{ {
error = true; error = true;
if( verbosity >= 0 ) if( verbosity >= 0 )
@ -632,12 +666,12 @@ static int lzip_decode( CLzmaDec *decoder, const int infd,
" some checks may fail.\n", *inSize - *inPos ); " some checks may fail.\n", *inSize - *inPos );
} }
} }
for( i = 0; i < Ft_size && *inPos < *inSize; ++i ) for( i = 0; i < Lt_size && *inPos < *inSize; ++i )
trailer[i] = inBuf[(*inPos)++]; trailer[i] = inBuf[(*inPos)++];
member_size += i; member_size += i;
while( i < Ft_size ) trailer[i++] = 0; while( i < Lt_size ) trailer[i++] = 0;
crc ^= 0xFFFFFFFFU; crc ^= 0xFFFFFFFFU;
td_crc = Ft_get_data_crc( trailer ); td_crc = Lt_get_data_crc( trailer );
if( td_crc != crc ) if( td_crc != crc )
{ {
error = true; error = true;
@ -648,7 +682,7 @@ static int lzip_decode( CLzmaDec *decoder, const int infd,
td_crc, crc ); td_crc, crc );
} }
} }
td_size = Ft_get_data_size( trailer ); td_size = Lt_get_data_size( trailer );
if( td_size != data_size ) if( td_size != data_size )
{ {
error = true; error = true;
@ -659,7 +693,7 @@ static int lzip_decode( CLzmaDec *decoder, const int infd,
td_size, td_size, data_size, data_size ); td_size, td_size, data_size, data_size );
} }
} }
tm_size = Ft_get_member_size( trailer ); tm_size = Lt_get_member_size( trailer );
if( tm_size != member_size ) if( tm_size != member_size )
{ {
error = true; error = true;
@ -709,38 +743,38 @@ static int decompress( const int infd, struct Pretty_print * const pp,
{ {
int i, size; int i, size;
unsigned dictionary_size; unsigned dictionary_size;
File_header header; Lzip_header header;
if( inSize - inPos < lzma_header_size && if( inSize - inPos < lzma_header_size &&
!read_inbuf( infd, inBuf, &inPos, &inSize ) ) return 1; !read_inbuf( infd, inBuf, &inPos, &inSize ) ) return 1;
size = inSize - inPos; size = inSize - inPos;
for( i = 0; i < size && i < Fh_size; ++i ) for( i = 0; i < size && i < Lh_size; ++i )
raw_props[i] = header[i] = inBuf[inPos++]; raw_props[i] = header[i] = inBuf[inPos++];
if( size <= Fh_size ) /* End Of File */ if( size <= Lh_size ) /* End Of File */
{ {
if( first_member ) if( first_member )
{ show_file_error( pp->name, "File ends unexpectedly at member header.", 0 ); { show_file_error( pp->name, "File ends unexpectedly at member header.", 0 );
retval = 2; } retval = 2; }
else if( Fh_verify_prefix( header, size ) ) else if( Lh_verify_prefix( header, size ) )
{ Pp_show_msg( pp, "Truncated header in multimember file." ); { Pp_show_msg( pp, "Truncated header in multimember file." );
retval = 2; } retval = 2; }
else if( size > 0 && !ignore_trailing ) else if( size > 0 && !ignore_trailing )
{ Pp_show_msg( pp, trailing_msg ); retval = 2; } { Pp_show_msg( pp, trailing_msg ); retval = 2; }
break; break;
} }
if( !Fh_verify_magic( header ) ) if( !Lh_verify_magic( header ) )
{ {
if( !first_member ) if( !first_member )
{ {
if( !loose_trailing && Fh_verify_corrupt( header ) ) if( !loose_trailing && Lh_verify_corrupt( header ) )
{ Pp_show_msg( pp, "Corrupt header in multimember file." ); { Pp_show_msg( pp, "Corrupt header in multimember file." );
retval = 2; } retval = 2; }
else if( !ignore_trailing ) else if( !ignore_trailing )
{ Pp_show_msg( pp, trailing_msg ); retval = 2; } { Pp_show_msg( pp, trailing_msg ); retval = 2; }
break; break;
} }
if( inSize - inPos >= lzma_header_size - Fh_size ) /* try lzma-alone */ if( inSize - inPos >= lzma_header_size - Lh_size ) /* try lzma-alone */
{ {
for( i = Fh_size; i < lzma_header_size; ++i ) for( i = Lh_size; i < lzma_header_size; ++i )
raw_props[i] = inBuf[inPos++]; raw_props[i] = inBuf[inPos++];
if( ( raw_props[12] == 0 || raw_props[12] == 0xFF ) && if( ( raw_props[12] == 0 || raw_props[12] == 0xFF ) &&
raw_props[12] == raw_props[11] && raw_props[0] < (9 * 5 * 5) ) raw_props[12] == raw_props[11] && raw_props[0] < (9 * 5 * 5) )
@ -763,15 +797,15 @@ static int decompress( const int infd, struct Pretty_print * const pp,
if( lzip_mode ) if( lzip_mode )
{ {
int ds, i; int ds, i;
if( !Fh_verify_version( header ) ) if( !Lh_verify_version( header ) )
{ {
if( verbosity >= 0 ) if( verbosity >= 0 )
{ Pp_show_msg( pp, 0 ); { Pp_show_msg( pp, 0 );
fprintf( stderr, "Version %d member format not supported.\n", fprintf( stderr, "Version %d member format not supported.\n",
Fh_version( header ) ); } Lh_version( header ) ); }
retval = 2; break; retval = 2; break;
} }
dictionary_size = Fh_get_dictionary_size( header ); dictionary_size = Lh_get_dictionary_size( header );
if( !isvalid_ds( dictionary_size ) ) if( !isvalid_ds( dictionary_size ) )
{ Pp_show_msg( pp, "Invalid dictionary size in member header." ); { Pp_show_msg( pp, "Invalid dictionary size in member header." );
retval = 2; break; } retval = 2; break; }
@ -803,22 +837,6 @@ static int decompress( const int infd, struct Pretty_print * const pp,
} }
void signal_handler( int sig )
{
if( sig ) {} /* keep compiler happy */
show_error( "Control-C or similar caught, quitting.", 0, false );
cleanup_and_fail( 1 );
}
static void set_signals( void )
{
signal( SIGHUP, signal_handler );
signal( SIGINT, signal_handler );
signal( SIGTERM, signal_handler );
}
CRC32 crc32; CRC32 crc32;
@ -863,11 +881,9 @@ void show_error( const char * const msg, const int errcode, const bool help )
{ {
if( verbosity < 0 ) return; if( verbosity < 0 ) return;
if( msg && msg[0] ) if( msg && msg[0] )
{ fprintf( stderr, "%s: %s%s%s\n", program_name, msg,
fprintf( stderr, "%s: %s", program_name, msg ); ( errcode > 0 ) ? ": " : "",
if( errcode > 0 ) fprintf( stderr, ": %s", strerror( errcode ) ); ( errcode > 0 ) ? strerror( errcode ) : "" );
fputc( '\n', stderr );
}
if( help ) if( help )
fprintf( stderr, "Try '%s --help' for more information.\n", fprintf( stderr, "Try '%s --help' for more information.\n",
invocation_name ); invocation_name );
@ -877,10 +893,10 @@ void show_error( const char * const msg, const int errcode, const bool help )
void show_file_error( const char * const filename, const char * const msg, void show_file_error( const char * const filename, const char * const msg,
const int errcode ) const int errcode )
{ {
if( verbosity < 0 ) return; if( verbosity >= 0 )
fprintf( stderr, "%s: %s: %s", program_name, filename, msg ); fprintf( stderr, "%s: %s: %s%s%s\n", program_name, filename, msg,
if( errcode > 0 ) fprintf( stderr, ": %s", strerror( errcode ) ); ( errcode > 0 ) ? ": " : "",
fputc( '\n', stderr ); ( errcode > 0 ) ? strerror( errcode ) : "" );
} }
@ -898,7 +914,7 @@ int main( const int argc, const char * const argv[] )
to the corresponding LZMA compression modes. */ to the corresponding LZMA compression modes. */
const struct Lzma_options option_mapping[] = const struct Lzma_options option_mapping[] =
{ {
{ 1 << 20, 5 }, /* -0 */ { 1 << 16, 5 }, /* -0 */
{ 1 << 20, 5 }, /* -1 */ { 1 << 20, 5 }, /* -1 */
{ 3 << 19, 6 }, /* -2 */ { 3 << 19, 6 }, /* -2 */
{ 1 << 21, 8 }, /* -3 */ { 1 << 21, 8 }, /* -3 */
@ -1004,7 +1020,7 @@ int main( const int argc, const char * const argv[] )
} }
} /* end process options */ } /* end process options */
#if defined(__MSVCRT__) || defined(__OS2__) #if defined(__MSVCRT__) || defined(__OS2__) || defined(__DJGPP__)
setmode( STDIN_FILENO, O_BINARY ); setmode( STDIN_FILENO, O_BINARY );
setmode( STDOUT_FILENO, O_BINARY ); setmode( STDOUT_FILENO, O_BINARY );
#endif #endif
@ -1024,7 +1040,7 @@ int main( const int argc, const char * const argv[] )
if( !to_stdout && program_mode != m_test && if( !to_stdout && program_mode != m_test &&
( filenames_given || default_output_filename[0] ) ) ( filenames_given || default_output_filename[0] ) )
set_signals(); set_signals( signal_handler );
Pp_init( &pp, filenames, num_filenames ); Pp_init( &pp, filenames, num_filenames );
@ -1103,6 +1119,12 @@ int main( const int argc, const char * const argv[] )
else else
tmp = decompress( infd, &pp, ignore_trailing, tmp = decompress( infd, &pp, ignore_trailing,
loose_trailing, program_mode == m_test ); loose_trailing, program_mode == m_test );
if( close( infd ) != 0 )
{
show_error( input_filename[0] ? "Error closing input file" :
"Error closing stdin", errno, false );
if( tmp < 1 ) tmp = 1;
}
if( tmp > retval ) retval = tmp; if( tmp > retval ) retval = tmp;
if( tmp ) if( tmp )
{ if( program_mode != m_test ) cleanup_and_fail( retval ); { if( program_mode != m_test ) cleanup_and_fail( retval );
@ -1112,7 +1134,6 @@ int main( const int argc, const char * const argv[] )
close_and_set_permissions( in_statsp ); close_and_set_permissions( in_statsp );
if( input_filename[0] ) if( input_filename[0] )
{ {
close( infd );
if( !keep_input_files && !to_stdout && program_mode != m_test ) if( !keep_input_files && !to_stdout && program_mode != m_test )
remove( input_filename ); remove( input_filename );
} }

View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# check script for Pdlzip - LZMA lossless data compressor # check script for Pdlzip - LZMA lossless data compressor
# Copyright (C) 2010-2018 Antonio Diaz Diaz. # Copyright (C) 2010-2019 Antonio Diaz Diaz.
# #
# This script is free software: you have unlimited permission # This script is free software: you have unlimited permission
# to copy, distribute and modify it. # to copy, distribute and modify it.
@ -36,12 +36,15 @@ test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; }
printf "testing pdlzip-%s..." "$2" printf "testing pdlzip-%s..." "$2"
"${LZIP}" -fkqm4 in "${LZIP}" -fkqm4 in
{ [ $? = 1 ] && [ ! -e in.lz ] ; } || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
[ ! -e in.lz ] || test_failed $LINENO
"${LZIP}" -fkqm274 in "${LZIP}" -fkqm274 in
{ [ $? = 1 ] && [ ! -e in.lz ] ; } || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
[ ! -e in.lz ] || test_failed $LINENO
for i in bad_size -1 0 4095 513MiB 1G 1T 1P 1E 1Z 1Y 10KB ; do for i in bad_size -1 0 4095 513MiB 1G 1T 1P 1E 1Z 1Y 10KB ; do
"${LZIP}" -fkqs $i in "${LZIP}" -fkqs $i in
{ [ $? = 1 ] && [ ! -e in.lz ] ; } || test_failed $LINENO $i [ $? = 1 ] || test_failed $LINENO $i
[ ! -e in.lz ] || test_failed $LINENO $i
done done
"${LZIP}" -tq in "${LZIP}" -tq in
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
@ -86,36 +89,46 @@ cmp in copy || test_failed $LINENO
"${LZIP}" -cd "${testdir}"/test.txt.lzma > copy || test_failed $LINENO "${LZIP}" -cd "${testdir}"/test.txt.lzma > copy || test_failed $LINENO
cmp in copy || test_failed $LINENO cmp in copy || test_failed $LINENO
rm -f copy rm -f copy || framework_failure
cat "${in_lz}" > copy.lz || framework_failure cat "${in_lz}" > copy.lz || framework_failure
"${LZIP}" -dk copy.lz || test_failed $LINENO "${LZIP}" -dk copy.lz || test_failed $LINENO
cmp in copy || test_failed $LINENO cmp in copy || test_failed $LINENO
printf "to be overwritten" > copy || framework_failure printf "to be overwritten" > copy || framework_failure
"${LZIP}" -d copy.lz 2> /dev/null "${LZIP}" -d copy.lz 2> /dev/null
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
"${LZIP}" -df copy.lz "${LZIP}" -df copy.lz || test_failed $LINENO
{ [ $? = 0 ] && [ ! -e copy.lz ] && cmp in copy ; } || test_failed $LINENO [ ! -e copy.lz ] || test_failed $LINENO
cmp in copy || test_failed $LINENO
rm -f copy || framework_failure
cat "${in_lz}" > copy.lz || framework_failure
"${LZIP}" -d -S100k copy.lz || test_failed $LINENO # ignore -S
[ ! -e copy.lz ] || test_failed $LINENO
cmp in copy || test_failed $LINENO
printf "to be overwritten" > copy || framework_failure printf "to be overwritten" > copy || framework_failure
"${LZIP}" -df -o copy < "${in_lz}" || test_failed $LINENO "${LZIP}" -df -o copy < "${in_lz}" || test_failed $LINENO
cmp in copy || test_failed $LINENO cmp in copy || test_failed $LINENO
rm -f copy rm -f copy || framework_failure
"${LZIP}" -s16 < in > anyothername || test_failed $LINENO "${LZIP}" -s16 < in > anyothername || test_failed $LINENO
"${LZIP}" -dv --output copy - anyothername - < "${in_lz}" 2> /dev/null "${LZIP}" -dv --output copy - anyothername - < "${in_lz}" 2> /dev/null ||
{ [ $? = 0 ] && cmp in copy && cmp in anyothername.out ; } ||
test_failed $LINENO test_failed $LINENO
rm -f copy anyothername.out cmp in copy || test_failed $LINENO
cmp in anyothername.out || test_failed $LINENO
rm -f copy anyothername.out || framework_failure
"${LZIP}" -tq in "${in_lz}" "${LZIP}" -tq in "${in_lz}"
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${LZIP}" -tq nx_file.lz "${in_lz}" "${LZIP}" -tq nx_file.lz "${in_lz}"
[ $? = 1 ] || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
"${LZIP}" -cdq in "${in_lz}" > copy "${LZIP}" -cdq in "${in_lz}" > copy
{ [ $? = 2 ] && cat copy in | cmp in - ; } || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
cat copy in | cmp in - || test_failed $LINENO
"${LZIP}" -cdq nx_file.lz "${in_lz}" > copy "${LZIP}" -cdq nx_file.lz "${in_lz}" > copy
{ [ $? = 1 ] && cmp in copy ; } || test_failed $LINENO [ $? = 1 ] || test_failed $LINENO
rm -f copy cmp in copy || test_failed $LINENO
rm -f copy || framework_failure
cat "${in_lz}" > copy.lz || framework_failure cat "${in_lz}" > copy.lz || framework_failure
for i in 1 2 3 4 5 6 7 ; do for i in 1 2 3 4 5 6 7 ; do
printf "g" >> copy.lz || framework_failure printf "g" >> copy.lz || framework_failure
@ -123,11 +136,15 @@ for i in 1 2 3 4 5 6 7 ; do
[ $? = 2 ] || test_failed $LINENO $i [ $? = 2 ] || test_failed $LINENO $i
done done
"${LZIP}" -dq in copy.lz "${LZIP}" -dq in copy.lz
{ [ $? = 2 ] && [ -e copy.lz ] && [ ! -e copy ] && [ ! -e in.out ] ; } || [ $? = 2 ] || test_failed $LINENO
test_failed $LINENO [ -e copy.lz ] || test_failed $LINENO
[ ! -e copy ] || test_failed $LINENO
[ ! -e in.out ] || test_failed $LINENO
"${LZIP}" -dq nx_file.lz copy.lz "${LZIP}" -dq nx_file.lz copy.lz
{ [ $? = 1 ] && [ ! -e copy.lz ] && [ ! -e nx_file ] && cmp in copy ; } || [ $? = 1 ] || test_failed $LINENO
test_failed $LINENO [ ! -e copy.lz ] || test_failed $LINENO
[ ! -e nx_file ] || test_failed $LINENO
cmp in copy || test_failed $LINENO
cat in in > in2 || framework_failure cat in in > in2 || framework_failure
cat "${in_lz}" "${in_lz}" > in2.lz || framework_failure cat "${in_lz}" "${in_lz}" > in2.lz || framework_failure
@ -142,18 +159,21 @@ cmp in2 copy2 || test_failed $LINENO
printf "\ngarbage" >> copy2.lz || framework_failure printf "\ngarbage" >> copy2.lz || framework_failure
"${LZIP}" -tvvvv copy2.lz 2> /dev/null || test_failed $LINENO "${LZIP}" -tvvvv copy2.lz 2> /dev/null || test_failed $LINENO
rm -f copy2 rm -f copy2 || framework_failure
"${LZIP}" -atq copy2.lz "${LZIP}" -atq copy2.lz
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${LZIP}" -atq < copy2.lz "${LZIP}" -atq < copy2.lz
[ $? = 2 ] || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
"${LZIP}" -adkq copy2.lz "${LZIP}" -adkq copy2.lz
{ [ $? = 2 ] && [ ! -e copy2 ] ; } || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
[ ! -e copy2 ] || test_failed $LINENO
"${LZIP}" -adkq -o copy2 < copy2.lz "${LZIP}" -adkq -o copy2 < copy2.lz
{ [ $? = 2 ] && [ ! -e copy2 ] ; } || test_failed $LINENO [ $? = 2 ] || test_failed $LINENO
[ ! -e copy2 ] || test_failed $LINENO
printf "to be overwritten" > copy2 || framework_failure printf "to be overwritten" > copy2 || framework_failure
"${LZIP}" -df copy2.lz || test_failed $LINENO "${LZIP}" -df copy2.lz || test_failed $LINENO
cmp in2 copy2 || test_failed $LINENO cmp in2 copy2 || test_failed $LINENO
rm -f in2 copy2 || framework_failure
printf "\ntesting compression..." printf "\ntesting compression..."
@ -189,33 +209,54 @@ for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
"${LZIP}" -df -o copy < out.lz || test_failed $LINENO $i "${LZIP}" -df -o copy < out.lz || test_failed $LINENO $i
cmp in copy || test_failed $LINENO $i cmp in copy || test_failed $LINENO $i
done done
rm -f out.lz || framework_failure
printf "\ntesting bad input..." printf "\ntesting bad input..."
headers='LZIp LZiP LZip LzIP LzIp LziP lZIP lZIp lZiP lzIP' headers='LZIp LZiP LZip LzIP LzIp LziP lZIP lZIp lZiP lzIP'
body='\001\014\000\203\377\373\377\377\300\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\000\000\000\000\000\000' body='\001\014\000\203\377\373\377\377\300\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000$\000\000\000\000\000\000\000'
cat "${in_lz}" > in0.lz cat "${in_lz}" > int.lz
printf "LZIP${body}" >> in0.lz printf "LZIP${body}" >> int.lz
if "${LZIP}" -tq in0.lz ; then if "${LZIP}" -tq int.lz ; then
for header in ${headers} ; do for header in ${headers} ; do
printf "${header}${body}" > in0.lz # first member printf "${header}${body}" > int.lz # first member
"${LZIP}" -tq in0.lz "${LZIP}" -tq int.lz
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -tq --loose-trailing in0.lz "${LZIP}" -tq < int.lz
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
cat "${in_lz}" > in0.lz "${LZIP}" -cdq int.lz > /dev/null
printf "${header}${body}" >> in0.lz # trailing data
"${LZIP}" -tq in0.lz
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -t --loose-trailing in0.lz "${LZIP}" -tq --loose-trailing int.lz
[ $? = 0 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -tq --loose-trailing --trailing-error in0.lz "${LZIP}" -tq --loose-trailing < int.lz
[ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -cdq --loose-trailing int.lz > /dev/null
[ $? = 2 ] || test_failed $LINENO ${header}
cat "${in_lz}" > int.lz
printf "${header}${body}" >> int.lz # trailing data
"${LZIP}" -tq int.lz
[ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -tq < int.lz
[ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -cdq int.lz > /dev/null
[ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -t --loose-trailing int.lz ||
test_failed $LINENO ${header}
"${LZIP}" -t --loose-trailing < int.lz ||
test_failed $LINENO ${header}
"${LZIP}" -cd --loose-trailing int.lz > /dev/null ||
test_failed $LINENO ${header}
"${LZIP}" -tq --loose-trailing --trailing-error int.lz
[ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -tq --loose-trailing --trailing-error < int.lz
[ $? = 2 ] || test_failed $LINENO ${header}
"${LZIP}" -cdq --loose-trailing --trailing-error int.lz > /dev/null
[ $? = 2 ] || test_failed $LINENO ${header} [ $? = 2 ] || test_failed $LINENO ${header}
done done
else else
printf "\nwarning: skipping header test: 'printf' does not work on your system." printf "\nwarning: skipping header test: 'printf' does not work on your system."
fi fi
rm -f in0.lz rm -f int.lz || framework_failure
cat "${in_lz}" "${in_lz}" "${in_lz}" > in3.lz || framework_failure cat "${in_lz}" "${in_lz}" "${in_lz}" > in3.lz || framework_failure
if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null && if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null &&
@ -234,7 +275,7 @@ if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null &&
else else
printf "\nwarning: skipping truncation test: 'dd' does not work on your system." printf "\nwarning: skipping truncation test: 'dd' does not work on your system."
fi fi
rm -f in3.lz trunc.lz rm -f in2.lz in3.lz trunc.lz out || framework_failure
cat "${in_lz}" > ingin.lz || framework_failure cat "${in_lz}" > ingin.lz || framework_failure
printf "g" >> ingin.lz || framework_failure printf "g" >> ingin.lz || framework_failure
@ -245,7 +286,7 @@ cmp in copy || test_failed $LINENO
"${LZIP}" -t < ingin.lz || test_failed $LINENO "${LZIP}" -t < ingin.lz || test_failed $LINENO
"${LZIP}" -d < ingin.lz > copy || test_failed $LINENO "${LZIP}" -d < ingin.lz > copy || test_failed $LINENO
cmp in copy || test_failed $LINENO cmp in copy || test_failed $LINENO
rm -f ingin.lz rm -f copy ingin.lz || framework_failure
echo echo
if [ ${fail} = 0 ] ; then if [ ${fail} = 0 ] ; then