I managed to fix almost half the failures in knownproblems by making --gnu always be tried rather than only when GZIP_OS_UNIX is found. Doing the same for --rsyncable and --new-rsyncable probably makes sense too.
The --new-rsyncable was written for gzip 1.4, while gzip 1.6 does things a bit different (it's a bit of a hybrid between the original rsyncable and the 1.4 rsyncable). I have added a new --16-rsyncable option to zgz that matches the new behaviour, which fixes this bug. I have tested both gzip 1.4 and gzip 1.6 with --rsyncable and pristine-tar now handles both. -- Len Sorensen
>From dd0d04fa27d77c1a808e43a313788b63200e54b5 Mon Sep 17 00:00:00 2001 From: Len Sorensen <lsore...@mythtv64.local.lan> Date: Thu, 6 Jul 2017 16:52:41 -0400 Subject: [PATCH] Try --gnu all the time and fix current rsyncable The rsyncable code was not quite in sync with what gzip --rsyncable actually does on debian. Resolving this fixes bug 805488. Only trying --gnu when GZIP_OS_UNIX is found causes a lot of possible matches to be missed. Making --gnu always be attemped no matter what fixes the following knownproblem cases: abind_1.1.0.orig.tar.gz arj_3.10.22.orig.tar.gz commons-configuration_1.6.orig.tar.gz dot2tex_2.8.5.orig.tar.gz evolver_2.30c.orig.tar.gz faad2_2.6.1.orig.tar.gz intercal_0.28.orig.tar.gz libapache-session-perl_1.87.orig.tar.gz libdatetime-event-sunrise-perl_0.0501.orig.tar.gz libfreezethaw-perl_0.45.orig.tar.gz libhtml-linkextractor-perl_0.130.orig.tar.gz libhtml-prototype-perl_1.48.orig.tar.gz libhttp-browserdetect-perl_0.98.orig.tar.gz libinline-perl_0.45.orig.tar.gz libmail-sendeasy-perl_1.2.orig.tar.gz libmail-sender-perl_0.8.13.orig.tar.gz libmail-sender-perl_0.8.16.orig.tar.gz libmarc-lint-perl_1.43.orig.tar.gz libmp3-tag-perl_0.9714.orig.tar.gz libnet-daemon-perl_0.43.orig.tar.gz libnet-ifconfig-wrapper-perl_0.09.orig.tar.gz libpdf-api2-perl_0.72.003.orig.tar.gz libpdf-api2-perl_0.73.orig.tar.gz libpdf-reuse-perl_0.35.orig.tar.gz libphp-adodb_5.07.orig.tar.gz libplrpc-perl_0.2020.orig.tar.gz libpod-simple-wiki-perl_0.08.orig.tar.gz libreadonly-perl_1.03.orig.tar.gz libspreadsheet-writeexcel-perl_2.25.orig.tar.gz libterm-readline-perl-perl_1.0302.orig.tar.gz libxml-smart-perl_1.6.9.orig.tar.gz pyparsing_1.5.1.orig.tar.gz python-kinterbasdb_3.2.orig.tar.gz rmetrics_260.72.orig.tar.gz scalpel_1.60.orig.tar.gz ttf-umefont_401.orig.tar.gz ttf-umefont_402.orig.tar.gz unace_1.2b.orig.tar.gz unrar-nonfree_3.8.5.orig.tar.gz --- pristine-gz | 13 +++++-------- zgz/gzip/deflate.c | 27 ++++++++++++++++++++------- zgz/gzip/gzip.c | 4 ++-- zgz/gzip/gzip.h | 2 +- zgz/zgz.c | 15 ++++++++++----- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/pristine-gz b/pristine-gz index 2f67160..d110eaf 100755 --- a/pristine-gz +++ b/pristine-gz @@ -188,13 +188,10 @@ sub reproducegz { my @try; - if ($os == $fconstants{GZIP_OS_UNIX}) { - # for 98% of the cases the simple heuristic above works - # and it was produced by gnu gzip. - push @try, [ '--gnu', @args ]; - push @try, [ '--gnu', @args, '--rsyncable' ]; - push @try, [ '--gnu', @args, '--new-rsyncable' ]; - } + push @try, [ '--gnu', @args ]; + push @try, [ '--gnu', @args, '--rsyncable' ]; + push @try, [ '--gnu', @args, '--new-rsyncable' ]; + push @try, [ '--gnu', @args, '--16-rsyncable' ]; if ($name =~ /\//) { push @args, "--original-name", $name; @@ -301,7 +298,7 @@ sub gengz { my @params = split(' ', $delta->{params}); while (@params) { $_ = shift @params; - next if /^(--gnu|--rsyncable|--new-rsyncable|-[nmM1-9])$/; + next if /^(--gnu|--rsyncable|--new-rsyncable|--16-rsyncable|-[nmM1-9])$/; if (/^(--original-name|--quirk|--osflag)$/) { shift @params; next; diff --git a/zgz/gzip/deflate.c b/zgz/gzip/deflate.c index 780e500..016b757 100644 --- a/zgz/gzip/deflate.c +++ b/zgz/gzip/deflate.c @@ -107,11 +107,19 @@ int RSYNC_WIN = 4096; /* Whether to enable compatability with Debian's old rsyncable patch. */ int debian_rsyncable = 1; -void disable_debian_rsyncable () { +void set_14_rsyncable () { debian_rsyncable = 0; RSYNC_WIN = 8192; } +/* gzip 1.6 uses a different rsyncable that is a hybrid between the + * original and the gzip 1.4 version + */ +void set_16_rsyncable () { + debian_rsyncable = 2; + 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 */ @@ -532,9 +540,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 (debian_rsyncable && rsync_chunk_end == 0xFFFFFFFFUL && RSYNC_SUM_MATCH_DEBIAN(rsync_sum)) + if (debian_rsyncable == 1 && 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)) + if (debian_rsyncable != 1 && rsync_chunk_end == 0xFFFFFFFFUL && RSYNC_SUM_MATCH(rsync_sum)) rsync_chunk_end = i; } } @@ -650,7 +658,7 @@ 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, int newrsync) +void gnu_deflate(int pack_level, int rsync, int rsync14, int rsync16) { IPos hash_head; /* head of hash chain */ IPos prev_match; /* previous match */ @@ -658,11 +666,16 @@ void gnu_deflate(int pack_level, int rsync, int newrsync) 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 + /* The rsync14 mode superscedes Debian's old, somewhat broken * rsync patch. */ - if (newrsync) { + if (rsync14) { + rsync=1; + set_14_rsyncable(); + } + /* The rsync16 mode superscedes the others yet again */ + if (rsync16) { rsync=1; - disable_debian_rsyncable(); + set_16_rsyncable(); } if (pack_level <= 3) { diff --git a/zgz/gzip/gzip.c b/zgz/gzip/gzip.c index a9a39dc..41d2175 100644 --- a/zgz/gzip/gzip.c +++ b/zgz/gzip/gzip.c @@ -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, int newrsync) +void gnuzip(int in, int out, char *origname, ulg timestamp, int level, int osflag, int rsync, int rsync14, int rsync16) { uch flags = 0; /* general purpose bit flags */ ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ @@ -76,7 +76,7 @@ void gnuzip(int in, int out, char *origname, ulg timestamp, int level, int osfla } while (*p++); } - gnu_deflate(level, rsync, newrsync); + gnu_deflate(level, rsync, rsync14, rsync16); /* Write the crc and uncompressed size */ put_long(crc); diff --git a/zgz/gzip/gzip.h b/zgz/gzip/gzip.h index 267a2ec..170bfa4 100644 --- a/zgz/gzip/gzip.h +++ b/zgz/gzip/gzip.h @@ -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, int newrsync); +void gnu_deflate(int pack_level, int rsync, int rsync14, int rsync16); /* in trees.c */ void ct_init(void); diff --git a/zgz/zgz.c b/zgz/zgz.c index a4e3a97..e916873 100644 --- a/zgz/zgz.c +++ b/zgz/zgz.c @@ -71,7 +71,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, int newrsync); +extern void gnuzip(int in, int out, char *origname, unsigned long timestamp, int level, int osflag, int rsync, int rsync14, int rsync16); extern void old_bzip2(int level); #define BUFLEN (64 * 1024) @@ -157,6 +157,7 @@ static const struct option longopts[] = { { "zlib", no_argument, 0, 'Z' }, { "rsyncable", no_argument, 0, 'R' }, { "new-rsyncable", no_argument, 0, 'r' }, + { "16-rsyncable", no_argument, 0, 'D' }, { "no-timestamp", no_argument, 0, 'm' }, { "force-timestamp", no_argument, 0, 'M' }, { "timestamp", required_argument, 0, 'T' }, @@ -190,7 +191,8 @@ main(int argc, char **argv) int level = 6; int osflag = GZIP_OS_UNIX; int rsync = 0; - int new_rsync = 0; + int rsync14 = 0; + int rsync16 = 0; int ch; if (strcmp(progname, "gunzip") == 0 || @@ -292,7 +294,10 @@ main(int argc, char **argv) rsync = 1; break; case 'r': - new_rsync = 1; + rsync14 = 1; + break; + case 'D': + rsync16 = 1; break; case 'd': fprintf(stderr, "%s: decompression is not supported on this version\n", progname); @@ -333,7 +338,7 @@ 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, new_rsync); + gnuzip(STDIN_FILENO, STDOUT_FILENO, origname, timestamp, level, osflag, rsync, rsync14, rsync16); } else if (bzold) { if (quirks) { fprintf(stderr, "%s: quirks not supported with --old-bzip2\n", progname); @@ -345,7 +350,7 @@ main(int argc, char **argv) } else if (pbzsuse) { rebrain("suse-bzip2", "pbzip2", level); } else { - if (rsync || new_rsync) { + if (rsync || rsync14 || rsync16) { fprintf(stderr, "%s: --rsyncable not supported with --zlib\n", progname); return 1; } -- 2.13.2