summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin H. Johnson <robbat2@gentoo.org>2019-12-06 23:55:32 -0800
committerRobin H. Johnson <robbat2@gentoo.org>2019-12-06 23:55:32 -0800
commit91a082c6fcdb26319fb9ed8d915d70c1573b6234 (patch)
treee0d8648748a05328c65a7241b2005aea1b2e9902
parentsnapshots-create: refactor (diff)
downloadmastermirror-scripts-91a082c6fcdb26319fb9ed8d915d70c1573b6234.tar.gz
mastermirror-scripts-91a082c6fcdb26319fb9ed8d915d70c1573b6234.tar.bz2
mastermirror-scripts-91a082c6fcdb26319fb9ed8d915d70c1573b6234.zip
tar-transform-names.pl: new tool to do stream modification of tarball
Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
-rwxr-xr-xtar-transform-names.pl80
1 files changed, 80 insertions, 0 deletions
diff --git a/tar-transform-names.pl b/tar-transform-names.pl
new file mode 100755
index 0000000..9bc0fd6
--- /dev/null
+++ b/tar-transform-names.pl
@@ -0,0 +1,80 @@
+#!/usr/bin/perl -w
+# Copyright 2019 Gentoo Authors; Distributed under the GPL v2
+# Trivial tool to modify the path strings of files in a tarball, WITHOUT
+# unpacking the tarball.
+use strict;
+use warnings;
+#use re 'strict'; # This fails if the modifiers are empty
+use Getopt::Long;
+use File::Temp qw/tempfile/;
+use File::Basename;
+use Archive::Tar::Stream;
+
+my $input_filename;
+my $output_filename;
+my $regex;
+my $verbose = 0;
+#my ($t, $t2, $r);
+
+GetOptions(
+ "i|input-filename=s" => \$input_filename,
+ "o|output-filename=s" => \$output_filename,
+ "r|regex-replacement=s" => \$regex,
+ "v|verbose" => \$verbose,
+ #"t|test-string=s" => \$t,
+) or die("Error in args");
+
+die("--input-filename=... is required") unless -e $input_filename;
+die("--output-filename=... is required") unless defined $output_filename;
+die("--regex=... is required") unless defined $regex;
+$regex =~ /^(?<op>s)(?<sep>.)(?<match>.*)\g{sep}(?<replacement>.*)\g{sep}(?<mod>[a-zA-Z0-9]*)$/;
+my $regex_op = $+{op};
+my $regex_match = $+{match};
+my $regex_replacement = $+{replacement};
+my $regex_mod = $+{mod};
+die("--regex=$regex is not valid") unless defined $regex_op and defined $regex_match and defined $regex_replacement and defined $regex_mod;
+die "Refusing unsafe/unknown regex modifiers" unless $regex_mod=~/^[msixpodualng]*$/;
+
+die("Refusing to overwrite") if $input_filename eq $output_filename;
+
+#printf "op %s\n", $regex_op;
+#printf "match %s\n", $regex_match;
+#printf "replacement %s\n", $regex_replacement;
+#printf "mod %s\n", $regex_mod;
+
+#my $infh = IO::File->new("zcat $infile |") || die "oops";
+#my $outfh = IO::File->new("| gzip > $outfile") || die "double oops";
+open(my $infh, '<', $input_filename);
+my ($outfh, $temp_filename) = tempfile(
+ sprintf('.%s.XXXXXXXX', basename($output_filename)),
+ DIR => dirname($output_filename),
+ UNLINK => 1,
+);
+
+
+my $ts = Archive::Tar::Stream->new(infh => $infh, outfh => $outfh);
+my $success = 0;
+$Archive::Tar::Stream::VERBOSE = $verbose;
+$ts->StreamCopy(sub {
+ my ($header, $outpos, $fh) = @_;
+
+ $header->{name} =~ s/(?${regex_mod})${regex_match}/${regex_replacement}/;
+ #printf "%s => %s\n", $header->{name}, $newheader->{name};
+
+ return 'KEEP', $header;
+});
+$success = 1;
+
+close($infh);
+
+END {
+ if($success == 1) {
+ rename $temp_filename, $output_filename or do {
+ unlink $temp_filename;
+ die("Failed to rename temporary file to destination name");
+ }
+ }
+ # Cleanup in other case
+ unlink $temp_filename if -e $temp_filename;
+ close $outfh;
+}