Skip to content

Commit

Permalink
Add support for gzip --rsyncable output produced by gzip 1.4.
Browse files Browse the repository at this point in the history
This differs from prior --rsyncable output, which was made by a debian
specific patch and used a different rsync window size, and reset huffman
encodings less often.
  • Loading branch information
joeyh committed Aug 7, 2011
1 parent 2caae4f commit 9698832
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 21 deletions.
4 changes: 4 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
pristine-tar (1.14) UNRELEASED; urgency=low

* Add support for gzip --rsyncable output produced by gzip 1.4.
This differs from prior --rsyncable output, which was made by a debian
specific patch and used a different rsync window size, and reset
huffman encodings less often.
* Clarify man page.

-- Joey Hess <joeyh@debian.org> Thu, 07 Jul 2011 12:17:00 -0400
Expand Down
3 changes: 2 additions & 1 deletion pristine-gz
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ sub reproducegz {
# and it was produced by gnu gzip.
push @try, ['--gnu', @args];
push @try, ['--gnu', @args, '--rsyncable'];
push @try, ['--gnu', @args, '--new-rsyncable'];
}

if ($name =~ /\//) {
Expand Down Expand Up @@ -285,7 +286,7 @@ sub gengz {
my @params=split(' ', $delta->{params});
while (@params) {
$_=shift @params;
next if /^(--gnu|--rsyncable|-[nmM1-9])$/;
next if /^(--gnu|--rsyncable|--new-rsyncable|-[nmM1-9])$/;
if (/^(--original-name|--quirk|--osflag)$/) {
shift @params;
next;
Expand Down
2 changes: 1 addition & 1 deletion pristine-tar.spec
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: pristine-tar
Version: 1.13
Version: 1.14
Release: 2%{?dist}
Summary: regenerate pristine tarballs

Expand Down
57 changes: 47 additions & 10 deletions zgz/gzip/deflate.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,19 @@
#endif
/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */

#ifndef RSYNC_WIN
# define RSYNC_WIN 4096
#endif
int RSYNC_WIN = 4096;
/* Size of rsync window, must be < MAX_DIST */

#define RSYNC_SUM_MATCH(sum) ((sum) % RSYNC_WIN == 0)
/* Whether to enable compatability with Debian's old rsyncable patch. */
int debian_rsyncable = 1;

void disable_debian_rsyncable () {
debian_rsyncable = 0;
RSYNC_WIN = 8192;
}

#define RSYNC_SUM_MATCH_DEBIAN(sum) ((sum) % RSYNC_WIN == 0)
#define RSYNC_SUM_MATCH(sum) (((sum) & (RSYNC_WIN - 1)) == 0)
/* Whether window sum matches magic value */

/* ===========================================================================
Expand Down Expand Up @@ -525,7 +532,9 @@ static void rsync_roll(unsigned start, unsigned num)
rsync_sum += (ulg)window[i];
/* Old character out */
rsync_sum -= (ulg)window[i - RSYNC_WIN];
if (rsync_chunk_end == 0xFFFFFFFFUL && RSYNC_SUM_MATCH(rsync_sum))
if (debian_rsyncable && rsync_chunk_end == 0xFFFFFFFFUL && RSYNC_SUM_MATCH_DEBIAN(rsync_sum))
rsync_chunk_end = i;
if (! debian_rsyncable && rsync_chunk_end == 0xFFFFFFFFUL && RSYNC_SUM_MATCH(rsync_sum))
rsync_chunk_end = i;
}
}
Expand Down Expand Up @@ -614,10 +623,15 @@ static void deflate_fast(int pack_level, int rsync)
lookahead--;
strstart++;
}
if (rsync && strstart > rsync_chunk_end) {
if (rsync && debian_rsyncable && strstart > rsync_chunk_end) {
rsync_chunk_end = 0xFFFFFFFFUL;
flush = 2;
}
if (rsync && ! debian_rsyncable && strstart > rsync_chunk_end) {
flush = 1;
ct_init();
rsync_chunk_end = 0xFFFFFFFFUL;
}
if (flush) FLUSH_BLOCK(0), block_start = strstart;

/* Make sure that we always have enough lookahead, except
Expand All @@ -636,14 +650,21 @@ static void deflate_fast(int pack_level, int rsync)
* evaluation for matches: a match is finally adopted only if there is
* no better match at the next window position.
*/
void gnu_deflate(int pack_level, int rsync)
void gnu_deflate(int pack_level, int rsync, int newrsync)
{
IPos hash_head; /* head of hash chain */
IPos prev_match; /* previous match */
int flush = 0; /* set if current block must be flushed */
int match_available = 0; /* set if previous match exists */
register unsigned match_length = MIN_MATCH-1; /* length of best match */

/* The newrsync mode superscedes Debian's old, somewhat broken
* rsync patch. */
if (newrsync) {
rsync=1;
disable_debian_rsyncable();
}

if (pack_level <= 3) {
deflate_fast(pack_level, rsync); /* optimized for speed */
return;
Expand Down Expand Up @@ -705,10 +726,15 @@ void gnu_deflate(int pack_level, int rsync)
match_length = MIN_MATCH-1;
strstart++;

if (rsync && strstart > rsync_chunk_end) {
if (rsync && debian_rsyncable && strstart > rsync_chunk_end) {
rsync_chunk_end = 0xFFFFFFFFUL;
flush = 2;
}
if (rsync && ! debian_rsyncable && strstart > rsync_chunk_end) {
ct_init();
rsync_chunk_end = 0xFFFFFFFFUL;
flush = 1;
}
if (flush) FLUSH_BLOCK(0), block_start = strstart;
} else if (match_available) {
/* If there was no match at the previous position, output a
Expand All @@ -717,10 +743,15 @@ void gnu_deflate(int pack_level, int rsync)
*/
Tracevv((stderr,"%c",window[strstart-1]));
flush = ct_tally (pack_level, 0, window[strstart-1]);
if (rsync && strstart > rsync_chunk_end) {
if (rsync && debian_rsyncable && strstart > rsync_chunk_end) {
rsync_chunk_end = 0xFFFFFFFFUL;
flush = 2;
}
if (rsync && ! debian_rsyncable && strstart > rsync_chunk_end) {
ct_init();
rsync_chunk_end = 0xFFFFFFFFUL;
flush = 1;
}
if (flush) FLUSH_BLOCK(0), block_start = strstart;
RSYNC_ROLL(strstart, 1);
strstart++;
Expand All @@ -729,12 +760,18 @@ void gnu_deflate(int pack_level, int rsync)
/* There is no previous match to compare with, wait for
* the next step to decide.
*/
if (rsync && strstart > rsync_chunk_end) {
if (rsync && debian_rsyncable && strstart > rsync_chunk_end) {
/* Reset huffman tree */
rsync_chunk_end = 0xFFFFFFFFUL;
flush = 2;
FLUSH_BLOCK(0), block_start = strstart;
}
if (rsync && ! debian_rsyncable && strstart > rsync_chunk_end) {
ct_init();
/* Reset huffman tree */
rsync_chunk_end = 0xFFFFFFFFUL;
FLUSH_BLOCK(0), block_start = strstart;
}
match_available = 1;
RSYNC_ROLL(strstart, 1);
strstart++;
Expand Down
4 changes: 2 additions & 2 deletions zgz/gzip/gzip.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static off_t bytes_in; /* number of input bytes */
* Deflate in to out.
* IN assertions: the input and output buffers are cleared.
*/
void gnuzip(int in, int out, char *origname, ulg timestamp, int level, int osflag, int rsync)
void gnuzip(int in, int out, char *origname, ulg timestamp, int level, int osflag, int rsync, int newrsync)
{
uch flags = 0; /* general purpose bit flags */
ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */
Expand Down Expand Up @@ -76,7 +76,7 @@ void gnuzip(int in, int out, char *origname, ulg timestamp, int level, int osfla
} while (*p++);
}

gnu_deflate(level, rsync);
gnu_deflate(level, rsync, newrsync);

/* Write the crc and uncompressed size */
put_long(crc);
Expand Down
2 changes: 1 addition & 1 deletion zgz/gzip/gzip.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ extern int file_read(char *buf, unsigned size);

/* in deflate.c */
void lm_init(int pack_level, ush *flags);
void gnu_deflate(int pack_level, int rsync);
void gnu_deflate(int pack_level, int rsync, int newrsync);

/* in trees.c */
void ct_init(void);
Expand Down
13 changes: 7 additions & 6 deletions zgz/zgz.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
#include <getopt.h>
#include <time.h>

extern void gnuzip(int in, int out, char *origname, unsigned long timestamp, int level, int osflag, int rsync);
extern void gnuzip(int in, int out, char *origname, unsigned long timestamp, int level, int osflag, int rsync, int newrsync);
extern void old_bzip2(int level);

#define BUFLEN (64 * 1024)
Expand Down Expand Up @@ -145,7 +145,6 @@ static const struct option longopts[] = {
{ "no-name", no_argument, 0, 'n' },
{ "name", no_argument, 0, 'N' },
{ "quiet", no_argument, 0, 'q' },
{ "recursive", no_argument, 0, 'r' },
{ "fast", no_argument, 0, '1' },
{ "best", no_argument, 0, '9' },
{ "ascii", no_argument, 0, 'a' },
Expand All @@ -154,6 +153,7 @@ static const struct option longopts[] = {
{ "old-bzip2", no_argument, 0, 'O' },
{ "zlib", no_argument, 0, 'Z' },
{ "rsyncable", no_argument, 0, 'R' },
{ "new-rsyncable", no_argument, 0, 'r' },
{ "no-timestamp", no_argument, 0, 'm' },
{ "force-timestamp", no_argument, 0, 'M' },
{ "timestamp", required_argument, 0, 'T' },
Expand Down Expand Up @@ -185,6 +185,7 @@ main(int argc, char **argv)
int level = 6;
int osflag = GZIP_OS_UNIX;
int rsync = 0;
int new_rsync = 0;
int ch;

if (strcmp(progname, "gunzip") == 0 ||
Expand Down Expand Up @@ -280,8 +281,7 @@ main(int argc, char **argv)
rsync = 1;
break;
case 'r':
fprintf(stderr, "%s: recursive is not supported on this version\n", progname);
usage();
new_rsync = 1;
break;
case 'd':
fprintf(stderr, "%s: decompression is not supported on this version\n", progname);
Expand Down Expand Up @@ -322,15 +322,15 @@ main(int argc, char **argv)
fprintf(stderr, "%s: quirks not supported with --gnu\n", progname);
return 1;
}
gnuzip(STDIN_FILENO, STDOUT_FILENO, origname, timestamp, level, osflag, rsync);
gnuzip(STDIN_FILENO, STDOUT_FILENO, origname, timestamp, level, osflag, rsync, new_rsync);
} else if (bzold) {
if (quirks) {
fprintf(stderr, "%s: quirks not supported with --old-bzip\n", progname);
return 1;
}
old_bzip2(level);
} else {
if (rsync) {
if (rsync || new_rsync) {
fprintf(stderr, "%s: --rsyncable not supported with --zlib\n", progname);
return 1;
}
Expand Down Expand Up @@ -528,6 +528,7 @@ usage(void)
" -T --timestamp SECONDS set the timestamp to the specified number of seconds\n"
" \ngnu-specific options:\n"
" -R --rsyncable make rsync-friendly archive\n"
" -r --new-rsyncable make rsync-friendly archive (new version)\n"
" \nzlib-specific options:\n"
" -k --quirk QUIRK enable a format quirk (buggy-bsd, ntfs, perl)\n");
exit(0);
Expand Down

0 comments on commit 9698832

Please sign in to comment.