use Dpkg::Version;
use POSIX;
use IPC::Open2;
+use Digest::SHA;
+use Config;
our $our_version = 'UNRELEASED'; ###substituted###
}
};
+our @signames = split / /, $Config{sig_name};
+
+sub waitstatusmsg () {
+ if (!$?) {
+ return "terminated, reporting successful completion";
+ } elsif (!($? & 255)) {
+ return "failed with error exit status ".WEXITSTATUS($?);
+ } elsif (WIFSIGNALED($?)) {
+ my $signum=WTERMSIG($?);
+ return "died due to fatal signal ".
+ ($signames[$signum] // "number $signum").
+ ($? & 128 ? " (core dumped)" : ""); # POSIX(3pm) has no WCOREDUMP
+ } else {
+ return "failed with unknown wait status ".$?;
+ }
+}
+
sub printdebug { print DEBUG $debugprefix, @_ or die $!; }
sub fail {
my $r = $ua->get(@_) or die $!;
return undef if $r->code == 404;
$r->is_success or fail "failed to fetch $what: ".$r->status_line;
- return $r->decoded_content();
+ return $r->decoded_content(charset => 'none');
}
-our ($dscdata,$dscurl,$dsc,$skew_warning_vsn);
+our ($dscdata,$dscurl,$dsc,$dsc_checked,$skew_warning_vsn);
sub shellquote {
my @out;
{ local ($!); printcmd \*STDERR, "$us: failed command:", @_ or die $!; };
if ($!) {
fail "failed to fork/exec: $!";
- } elsif (!($? & 0xff)) {
- fail "subprocess failed with error exit status ".($?>>8);
} elsif ($?) {
- fail "subprocess crashed (wait status $?)";
+ fail "subprocess ".waitstatusmsg();
} else {
fail "subprocess produced invalid output";
}
return "$url/$package.git";
}
-sub parsecontrolfh ($$@) {
- my ($fh, $desc, @opts) = @_;
- my %opts = ('name' => $desc, @opts);
- my $c = Dpkg::Control::Hash->new(%opts);
- $c->parse($fh) or die "parsing of $desc failed";
+sub parsecontrolfh ($$;$) {
+ my ($fh, $desc, $allowsigned) = @_;
+ our $dpkgcontrolhash_noissigned;
+ my $c;
+ for (;;) {
+ my %opts = ('name' => $desc);
+ $opts{allow_pgp}= $allowsigned || !$dpkgcontrolhash_noissigned;
+print STDERR Dumper(\%opts);
+ $c = Dpkg::Control::Hash->new(%opts);
+ $c->parse($fh,$desc) or die "parsing of $desc failed";
+ last if $allowsigned;
+ last if $dpkgcontrolhash_noissigned;
+ my $issigned= $c->get_option('is_pgp_signed');
+ if (!defined $issigned) {
+ $dpkgcontrolhash_noissigned= 1;
+ seek $fh, 0,0 or die "seek $desc: $!";
+ } elsif ($issigned) {
+ fail "control file $desc is (already) PGP-signed. ".
+ " Note that dgit push needs to modify the .dsc and then".
+ " do the signature itself";
+ } else {
+ last;
+ }
+ }
return $c;
}
my ($proto,$data) = @_;
sql_injection_check $isuite, $package;
my @rows = sshpsql($data, <<END);
- SELECT source.version, component.name, files.filename
+ SELECT source.version, component.name, files.filename, files.sha256sum
FROM source
JOIN src_associations ON source.id = src_associations.source
JOIN suite ON suite.id = src_associations.suite
AND files.filename LIKE '%.dsc';
END
@rows = sort { -version_compare_string($a->[0],$b->[0]) } @rows;
+ my $digester = Digest::SHA->new(256);
@rows = map {
- my ($vsn,$component,$filename) = @$_;
- [ $vsn, "/pool/$component/$filename" ];
+ my ($vsn,$component,$filename,$sha256sum) = @$_;
+ [ $vsn, "/pool/$component/$filename",$digester,$sha256sum ];
} @rows;
return @rows;
}
canonicalise_suite();
my @vsns = archive_query('archive_query');
foreach my $vinfo (@vsns) {
- my ($vsn,$subpath) = @$vinfo;
+ my ($vsn,$subpath,$digester,$digest) = @$vinfo;
$dscurl = access_cfg('mirror').$subpath;
$dscdata = url_get($dscurl);
if (!$dscdata) {
$skew_warning_vsn = $vsn if !defined $skew_warning_vsn;
next;
}
+ if ($digester) {
+ $digester->reset();
+ $digester->add($dscdata);
+ my $got = $digester->hexdigest();
+ $got eq $digest or
+ fail "$dscurl has hash $got but".
+ " archive told us to expect $digest";
+ }
my $dscfh = new IO::File \$dscdata, '<' or die $!;
printdebug Dumper($dscdata) if $debug>1;
- $dsc = parsecontrolfh($dscfh,$dscurl, allow_pgp=>1);
+ $dsc = parsecontrolfh($dscfh,$dscurl,1);
printdebug Dumper($dsc) if $debug>1;
my $fmt = getfield $dsc, 'Format';
fail "unsupported source format $fmt, sorry" unless $format_ok{$fmt};
+ $dsc_checked = !!$digester;
return;
}
$dsc = undef;
print D $dscdata or die "$dscfn: $!";
close D or die "$dscfn: $!";
my @cmd = qw(dpkg-source);
+ push @cmd, '--no-check' if $dsc_checked;
push @cmd, qw(-x --), $dscfn;
runcmd @cmd;
progress "starting new git history";
}
fetch_from_archive() or no_such_package;
+ my $vcsgiturl = $dsc->{'Vcs-Git'};
+ if (length $vcsgiturl) {
+ runcmd @git, qw(remote add vcs-git), $vcsgiturl;
+ }
runcmd @git, qw(reset --hard), lrref();
printdone "ready for work in $dstdir";
}
}
}
+sub cmd_clean () {
+ badusage "clean takes no additional arguments" if @ARGV;
+ clean_tree();
+}
+
sub build_prep () {
badusage "-p is not allowed when building" if defined $package;
check_not_dirty();
}
my $cmd = shift @ARGV;
$cmd =~ y/-/_/;
-{ no strict qw(refs); &{"cmd_$cmd"}(); }
+
+my $fn = ${*::}{"cmd_$cmd"};
+$fn or badusage "unknown operation $cmd";
+$fn->();