2 # Lintian::Collect::Binary -- interface to binary package data collection
4 # Copyright (C) 2008 Russ Allbery
5 # Copyright (C) 2008 Frank Lichtenheld
7 # This program is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by the Free
9 # Software Foundation; either version 2 of the License, or (at your option)
12 # This program is distributed in the hope that it will be useful, but WITHOUT
13 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 # You should have received a copy of the GNU General Public License along with
18 # this program. If not, see <http://www.gnu.org/licenses/>.
20 package Lintian::Collect::Binary;
26 our @ISA = qw(Lintian::Collect);
28 # Initialize a new binary package collect object. Takes the package name,
29 # which is currently unused.
31 my ($class, $pkg) = @_;
37 # Returns whether the package is a native package according to
41 return $self->{native} if exists $self->{native};
42 my $version = $self->field('version');
43 $self->{native} = ($version !~ m/-/);
46 # Returns the information from the indices
47 # FIXME: should maybe return an object
50 return $self->{index} if exists $self->{index};
52 my (@idx, %dir_counts);
53 open my $idx, '<', "index"
54 or fail("cannot open index file index: $!");
55 open my $num_idx, '<', "index-owner-id"
56 or fail("cannot open index file index-owner-id: $!");
60 my (%file, $perm, $owner, $name);
61 ($perm,$owner,$file{size},$file{date},$file{time},$name) =
63 $file{operm} = perm2oct($perm);
64 $file{type} = substr $perm, 0, 1;
66 my $numeric = <$num_idx>;
68 fail("cannot read index file index-owner-id") unless defined $numeric;
69 my ($owner_id, $name_chk) = (split(' ', $numeric, 6))[1, 5];
70 fail("mismatching contents of index files: $name $name_chk")
71 if $name ne $name_chk;
73 ($file{owner}, $file{group}) = split '/', $owner, 2;
74 ($file{uid}, $file{gid}) = split '/', $owner_id, 2;
77 if ($name =~ s/ link to (.*)//) {
80 $file{link} =~ s,^\./,,;
81 } elsif ($file{type} eq 'l') {
82 ($name, $file{link}) = split ' -> ', $name, 2;
86 # count directory contents:
87 $dir_counts{$name} ||= 0 if $file{type} eq 'd';
88 $dir_counts{$1} = ($dir_counts{$1} || 0) + 1
89 if $name =~ m,^(.+/)[^/]+/?$,;
93 foreach my $file (@idx) {
94 if ($dir_counts{$file->{name}}) {
95 $file->{count} = $dir_counts{$file->{name}};
98 $self->{index} = \@idx;
100 return $self->{index};
103 # Returns the information from collect/file-info
106 return $self->{file_info} if exists $self->{file_info};
109 open(my $idx, '<', "file-info")
110 or fail("cannot open file-info: $!");
115 or fail("an error in the file pkg is preventing lintian from checking this package: $_");
116 my ($file, $info) = ($1,$2);
121 $file_info{$file} = $info;
124 $self->{file_info} = \%file_info;
126 return $self->{file_info};
129 # Returns the information from collect/objdump-info
132 return $self->{objdump_info} if exists $self->{objdump_info};
135 my ($dynsyms, $file);
136 open(my $idx, '<', "objdump-info")
137 or fail("cannot open objdump-info: $!");
143 if (m,^-- \./(\S+)\s*$,o) {
145 $objdump_info{$file->{name}} = $file;
147 $file = { name => $1 };
150 # The .*? near the end is added because a number of optional fields
151 # might be printed. The symbol name should be the last word.
152 if (m/^[0-9a-fA-F]+.{6}\w\w?\s+(\S+)\s+[0-9a-zA-Z]+\s+(\S+)\s+(\S+)$/){
153 my ($foo, $sec, $sym) = ($1, $2, $3);
154 push @{$file->{SYMBOLS}}, [ $foo, $sec, $sym ];
157 if (m/^\s*NEEDED\s*(\S+)/o) {
158 push @{$file->{NEEDED}}, $1;
159 } elsif (m/^\s*RPATH\s*(\S+)/o) {
160 foreach (split m/:/, $1) {
161 $file->{RPATH}{$_}++;
163 } elsif (m/^\s*SONAME\s*(\S+)/o) {
164 push @{$file->{SONAME}}, $1;
165 } elsif (m/^\s*\d+\s+\.comment\s+/o) {
166 $file->{COMMENT_SECTION} = 1;
167 } elsif (m/^\s*\d+\s+\.note\s+/o) {
168 $file->{NOTE_SECTION} = 1;
169 } elsif (m/^DYNAMIC SYMBOL TABLE:/) {
171 } elsif (m/^objdump: (.*?): File format not recognized$/) {
172 push @{$file->{NOTES}}, "File format not recognized";
173 } elsif (m/^objdump: \.(.*?): Packed with UPX$/) {
174 push @{$file->{NOTES}}, "Packed with UPX";
175 } elsif (m/objdump: \.(.*?): Invalid operation$/) {
176 # Don't anchor this regex since it can be interspersed with other
177 # output and hence not on the beginning of a line.
178 push @{$file->{NOTES}}, "Invalid operation";
179 } elsif (m/CXXABI/) {
181 } elsif (m%Requesting program interpreter:\s+/lib/klibc-\S+\.so%) {
187 $objdump_info{$file->{name}} = $file;
189 $self->{objdump_info} = \%objdump_info;
191 return $self->{objdump_info};
196 Lintian::Collect::Binary - Lintian interface to binary package data collection
200 my $collect = Lintian::Collect->new($name, $type);
201 if ($collect->native) {
202 print "Package is native\n";
207 Lintian::Collect::Binary provides an interface to package data for binary
208 packages. It implements data collection methods specific to binary
211 This module is in its infancy. Most of Lintian still reads all data from
212 files in the laboratory whenever that data is needed and generates that
213 data via collect scripts. The goal is to eventually access all data about
214 source packages via this module so that the module can cache data where
215 appropriate and possibly retire collect scripts in favor of caching that
222 Creates a new Lintian::Collect::Binary object. Currently, PACKAGE is
223 ignored. Normally, this method should not be called directly, only via
224 the Lintian::Collect constructor.
228 =head1 INSTANCE METHODS
230 In addition to the instance methods listed below, all instance methods
231 documented in the Lintian::Collect module are also available.
237 Returns true if the binary package is native and false otherwise.
238 Nativeness will be judged by its version number.
242 Returns a reference to an array of hash references with content
243 information about the binary package. Each hash may have the
250 Name of the index entry without leading slash.
260 The former two are in string form and may depend on the local system,
261 the latter two are the original numerical values as saved by tar.
273 Entry type as one character.
277 Entry permissions as octal number.
281 Entry size in bytes. Note that tar(1) lists the size of directories as
282 0 (so this is what you will get) contrary to what ls(1) does.
286 If the entry is either a hardlink or symlink, contains the target of the
291 If the entry is a directory, contains the number of other entries this
298 Originally written by Frank Lichtenheld <djpig@debian.org> for Lintian.
302 lintian(1), Lintian::Collect(3)
309 # indent-tabs-mode: nil
310 # cperl-indent-level: 4
312 # vim: syntax=perl sw=4 sts=4 ts=4 et shiftround