X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=checks%2Fdeb-format;fp=checks%2Fdeb-format;h=bb337dee0aeb855a0f373bb29ca8ec0dc052ab4b;hb=1960326d487467271f731ff6a62830404a4947af;hp=0000000000000000000000000000000000000000;hpb=ce31209d7230201c69f8f234032a774fbbbc43cd;p=maemian diff --git a/checks/deb-format b/checks/deb-format new file mode 100644 index 0000000..bb337de --- /dev/null +++ b/checks/deb-format @@ -0,0 +1,134 @@ +# deb-format -- lintian check script -*- perl -*- + +# Copyright (C) 2009 Russ Allbery +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see . + +package Maemian::deb_format; +use strict; +use Tags; + +use Maemian::Command qw(spawn); + +# The files that contain error messages from tar, which we'll check and issue +# tags for if they contain something unexpected, and their corresponding tags. +our %ERRORS = ('control-errors' => 'tar-errors-from-control', + 'control-index-errors' => 'tar-errors-from-control', + 'index-errors' => 'tar-errors-from-data', + 'unpacked-errors' => 'tar-errors-from-data'); + +# Used to match Ubuntu distribution names in target distributions. +our $UBUNTU_REGEX; +{ + my $dists = Maemian::Data->new('changelog-file/ubuntu-dists'); + my $string = join ('|', 'ubuntu', $dists->all); + $UBUNTU_REGEX = qr/$string/o; +} + +sub run { + +my $pkg = shift; +my $type = shift; +my $info = shift; + +# Run ar t on the *.deb file. deb will be a symlink to it. +my $okay = 0; +my $opts = {}; +my $success = spawn($opts, ['ar', 't', 'deb']); +if ($success) { + my @members = split("\n", ${ $opts->{out} }); + if (@members != 3) { + my $count = scalar(@members); + tag 'malformed-deb-archive', + "found $count members instead of 3"; + } elsif ($members[0] ne 'debian-binary') { + tag 'malformed-deb-archive', + "first member $members[0] not debian-binary"; + } elsif ($members[1] ne 'control.tar.gz') { + tag 'malformed-deb-archive', + "second member $members[1] not control.tar.gz"; + } elsif ($members[2] eq 'data.tar.lzma') { + # Ubuntu's archive allows lzma packages. + my ($entry) = $info->changelog->data; + my $distribution = $entry->Distribution; + if ($distribution =~ /$UBUNTU_REGEX/) { + $okay = 1; + } else { + tag 'lzma-deb-archive'; + } + } elsif ($members[2] !~ /^data\.tar\.(gz|bz2)\z/) { + tag 'malformed-deb-archive', + "third member $members[2] not data.tar.(gz|bz2)"; + } else { + $okay = 1; + } +} else { + # unpack will probably fail so we'll never get here, but may as well be + # complete just in case. + my $error = ${ $opts->{err} }; + $error =~ s/\n.*//s; + $error =~ s/^ar:\s*//; + $error =~ s/^deb:\s*//; + tag 'malformed-deb-archive', "ar error: $error"; +} + +# Check the debian-binary version number. We probably won't get here because +# dpkg-deb will decline to unpack the deb, but be thorough just in case. We +# may eventually have a case where dpkg supports a newer format but it's not +# permitted in the archive yet. +if ($okay) { + my $opts = {}; + my $success = spawn($opts, ['ar', 'p', 'deb', 'debian-binary']); + if (not $success) { + tag 'malformed-deb-archive', "can't read debian-binary member"; + } elsif (${ $opts->{out} } !~ /^2\.\d+\n/) { + my ($version) = split("\n", ${ $opts->{out} }); + tag 'malformed-deb-archive', "version $version not 2.0"; + } +} + +# If either control-errors or index-errors exist, tar produced error output +# when processing the package. We want to report those as tags unless they're +# just tar noise that doesn't represent an actual problem. +for my $file (keys %ERRORS) { + my $tag = $ERRORS{$file}; + if (-s $file) { + open(ERRORS, '<', $file) or fail("cannot open $file: $!"); + local $_; + while () { + chomp; + s,^(?:[/\w]+/)?tar: ,,; + + # Record size errors are harmless. Ignore implausibly old + # timestamps in the data section since we already check for that + # elsewhere, but still warn for control. + next if /^Record size =/; + if ($tag eq 'tar-errors-from-data') { + next if /implausibly old time stamp/; + } + tag $tag, $_; + } + close ERRORS; + } +} + +} + +1; + +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 ts=4 et shiftround