From: joeyh Date: Wed, 3 Oct 2007 01:20:27 +0000 (+0000) Subject: * Fix a bug related to tar's handling of unicode filenames. X-Git-Tag: 0.2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=529d1be1ec5f0e6572bc0d299b8b97dac5deefea;p=tools%2Fpristine-tar.git * Fix a bug related to tar's handling of unicode filenames. * Work around a strange tar behavior: When run with --mode 644, tar preserves the sgid bit on subdirectories. --- diff --git a/debian/changelog b/debian/changelog index 9d51fe1..be4f65b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,9 @@ pristine-tar (0.2) UNRELEASED; urgency=low more likely file mode than the previous 0000 and thus makes the delta smaller. * File format version is up to 2.0 due to misc incompatible changes. + * Fix a bug related to tar's handling of unicode filenames. + * Work around a strange tar behavior: When run with --mode 644, tar + preserves the sgid bit on subdirectories. -- Joey Hess Tue, 02 Oct 2007 19:36:26 -0400 diff --git a/pristine-tar b/pristine-tar index 929733c..2245cd9 100755 --- a/pristine-tar +++ b/pristine-tar @@ -68,6 +68,10 @@ use constant GZIP_METHOD_DEFLATE => 0x08; my $verbose=0; my $debug=0; my $keep=0; + +# Force locale to C since tar may output utf-8 filenames differently +# depending on the locale. +$ENV{LANG}='C'; sub usage { print STDERR "Usage: pristine-tar [-vdk] gentar delta tarball\n"; @@ -143,6 +147,28 @@ sub gentarball { # for a given set of input files. So don't include file metadata # in the tarball, since it can easily vary. foreach my $file (@manifest) { + if (! -e "$tempdir/workdir/$file" && + ! -l "$tempdir/workdir/$file") { + my $try=$file; + # XXX this is a stupid approach. Should just + # convert tar's encoding to utf-8. + $try=~s/\\(\d+)/*/g; + if ($try ne $file) { + debug("$file not found, seems to be encoded by tar, trying to glob: $try"); + my @result=glob("$tempdir/workdir/$try"); + if (@result == 1) { + $try=shift @result; + if (-e $try || -l $try) { + $try=~s/^\Q$tempdir\/workdir\/\E//; + $file=$try; + debug("found it: $file"); + } + } + else { + debug("multiple results :-("); + } + } + } if (-l "$tempdir/workdir/$file") { # Can't set timestamp of a symlink, so # replace the symlink with an empty file. @@ -151,13 +177,22 @@ sub gentarball { close OUT; } elsif (! -e "$tempdir/workdir/$file") { - die "$file is listed in the manifest but not present in the source directory.\n"; + die "$file is listed in the manifest but may not be present in the source directory.\n"; + } + + if (-d "$tempdir/workdir/$file" && (-u _ || -g _ || -k _)) { + # tar behaves weirdly for some special modes + # and ignores --mode, so clear them. + debug("chmod $file"); + chmod(0755, "$tempdir/workdir/$file") || + die "chmod: $!"; } - utime 0, 0, "$tempdir/workdir/$file"; + utime 0, 0, "$tempdir/workdir/$file" || die "utime: $!"; } doit("tar", "cf", "$tempdir/gentarball", "--owner", 0, "--group", 0, - "--numeric-owner", "--mode", "0644", "-C", "$tempdir/workdir", - "--no-recursion", "--files-from", "$tempdir/manifest"); + "--numeric-owner", "-C", "$tempdir/workdir", + "--no-recursion", "--mode", "0644", + "--files-from", "$tempdir/manifest"); } sub gentar {