# control-file -- lintian check script -*- perl -*- # # Copyright (C) 2004 Marc Brockschmidt # # 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, you can find it on the World Wide # Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, # MA 02110-1301, USA. package Lintian::control_file; use strict; use lib "$ENV{'LINTIAN_ROOT'}/checks/"; use common_data; use Dep; use Util; use Tags; sub run { my $pkg = shift; my $type = shift; if (-l "debfiles/control") { tag "debian-control-file-is-a-symlink", ""; } # check that control is UTF-8 encoded my $line = file_is_encoded_in_non_utf8("debfiles/control", $type, $pkg); if ($line) { tag "debian-control-file-uses-obsolete-national-encoding", "at line $line" } # Check that each field is only used once: my $seen_fields = {}; open (CONTROL, '<', "debfiles/control") or fail "Couldn't read debfiles/control: $!"; while () { s/\s*\n$//; next if /^\#/; #Reset seen_fields if we enter a new section: $seen_fields = {} if /^$/; #line with field: if (/^(\S+):/) { my $field = lc ($1); if ($seen_fields->{$field}) { tag "debian-control-with-duplicate-fields", "$field: $$seen_fields{$field}, $."; } $seen_fields->{$field} = $.; if ($field =~ /^xs-vcs-/) { my $base = $field; $base =~ s/^xs-//; tag "xs-vcs-header-in-debian-control", "$field" if $known_source_fields{$base}; } } } close CONTROL; my ($header, @binary_controls) = read_dpkg_control("debfiles/control"); for my $binary_control (@binary_controls) { tag "build-info-in-binary-control-file-section", "Package ".$binary_control->{"package"} if ($binary_control->{"build-depends"} || $binary_control->{"build-depends-indep"} || $binary_control->{"build-conflicts"} || $binary_control->{"build-conflicts-indep"}); } # Make sure that a stronger dependency field doesn't imply any of the elements # of a weaker dependency field. dpkg-gencontrol will fix this up for us, but # we want to check the source package since dpkg-gencontrol may silently "fix" # something that's a more subtle bug. # # Also check if a package declares a simple dependency on itself, since # similarly dpkg-gencontrol will clean this up for us but it may be a sign of # another problem. my @dep_fields = qw(pre-depends depends recommends suggests); for my $control (@binary_controls) { for my $strong (0 .. ($#dep_fields - 1)) { next unless $control->{$dep_fields[$strong]}; my $parsed = Dep::parse ($control->{$dep_fields[$strong]}); tag "package-depends-on-itself", $control->{package}, $dep_fields[$strong] if Dep::implies($parsed, Dep::parse($control->{package})); for my $weak (($strong + 1) .. $#dep_fields) { next unless $control->{$dep_fields[$weak]}; for my $dependency (split /\s*,\s*/, $control->{$dep_fields[$weak]}) { next unless $dependency; tag "stronger-dependency-implies-weaker", $control->{package}, "$dep_fields[$strong] -> $dep_fields[$weak]", $dependency if Dep::implies($parsed, Dep::parse($dependency)); } } } } # Check that every package is in the same archive category, except that # sources in main can deliver both main and contrib packages. The source # package may or may not have a section specified; if it doesn't, derive the # expected archive category from the first binary package by leaving $category # undefined until parsing the first binary section. Missing sections will be # caught by other checks. my $category; if ($header->{'section'}) { if ($header->{'section'} =~ m%^([^/]+)/%) { $category = $1; } else { $category = ''; } } else { tag "no-section-field-for-source", ""; } for my $binary_control (@binary_controls) { next unless $binary_control->{'section'}; if (!defined ($category)) { if ($binary_control->{'section'} =~ m%^([^/]+)/%) { $category = ($1 eq 'contrib') ? '' : $1; } else { $category = ''; } next; } tag "section-category-mismatch", "Package " . $binary_control->{'package'} if ($category && $binary_control->{'section'} !~ m%^$category/%); tag "section-category-mismatch", "Package " . $binary_control->{'package'} if (!$category && $binary_control->{'section'} =~ m%^([^/]+)/% && $1 ne 'contrib'); } } 1; # Local Variables: # indent-tabs-mode: t # cperl-indent-level: 8 # End: # vim: syntax=perl sw=4 ts=4 noet shiftround