Added some code to peer into a data structure in Maemian/Schedule.pm. Also added the
[maemian] / nokia-lintian / unpack / list-binpkg
1 #!/usr/bin/perl -w
2 # list-binpkg -- lintian helper script
3
4 # Copyright (C) 1998 Christian Schwarz
5
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program.  If not, you can find it on the World Wide
18 # Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
19 # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
20 # MA 02110-1301, USA.
21
22 use strict;
23
24 # turn file buffering off:
25 $| = 1;
26
27 # parse command line options
28 if ($#ARGV == -1) {
29     print "list-binpkg [-v] <output-list-file>\n";
30     print "options:\n";
31     print "   -v  verbose\n";
32     exit 0;
33 }
34
35 my $verbose = 0;
36 my $output_file = undef;
37 my $pkgdata = undef; # WTF?
38
39 while (my $arg = shift) {
40     if ($arg =~ s,^-,,o) {
41         if ($arg eq 'v') {
42             $verbose = 1;
43         } else {
44             print STDERR "error: unknown command line argument: $arg\n";
45             exit 1;
46         }
47     } else {
48         if ($output_file) {
49             print STDERR "error: too many command line arguments: $arg\n";
50             exit 1;
51         }
52         $output_file = $arg;
53     }
54 }
55
56 unless ($output_file) {
57     print STDERR "error: no output file specified\n";
58     exit 1;
59 }
60
61 # import perl libraries
62 use lib "$ENV{'LINTIAN_ROOT'}/lib";
63 use Read_pkglists;
64 use vars qw(%binary_info $BINLIST_FORMAT); # from the above
65 use Pipeline;
66 use Util;
67
68 # get variables out of environment
69 my $LINTIAN_ARCHIVEDIR = $ENV{'LINTIAN_ARCHIVEDIR'};
70 my $LINTIAN_DIST = $ENV{'LINTIAN_DIST'};
71 my $LINTIAN_ARCH = $ENV{'LINTIAN_ARCH'};
72 my $LINTIAN_SECTION = $ENV{'LINTIAN_SECTION'};
73 my $LINTIAN_LAB = $ENV{'LINTIAN_LAB'};
74
75 # read old list file (this command does nothing if the file does not exist)
76 read_bin_list($output_file,1);
77
78 my %pkgfile;
79 # map filenames to package names
80 for my $pkg (keys %binary_info) {
81     $pkgfile{$binary_info{$pkg}->{'file'}} = $pkg;
82 }
83
84 # open output file
85 open(OUT, '>', $output_file)
86     or fail("cannot open list file $output_file for writing: $!");
87 print OUT "$BINLIST_FORMAT\n";
88
89 # parse Packages file to get list of packages
90 my $packages = "$LINTIAN_ARCHIVEDIR/dists/$LINTIAN_DIST/$LINTIAN_SECTION/".
91                "binary-$LINTIAN_ARCH/Packages";
92 if (-e $packages) {
93         print "N: Parsing $packages ...\n" if $verbose;
94         open(IN, '<', $packages) or fail("cannot open Packages file $packages: $!");
95 } elsif (-e "$packages.gz") {
96         print "N: Parsing $packages.gz ...\n" if $verbose;
97         open (IN, '-|', 'gzip', '-dc', "$packages.gz")
98             or fail("cannot open Packages file $packages.gz: $!");
99 } else {
100         fail("No packages file $packages");
101 }
102
103 my $line;
104 my %packages;
105 my $total = 0;
106
107 while (!eof(IN)) {
108     do { $line = <IN> } until ($line =~ m/^Architecture: (.*)$/m);
109     my $arch = $1;
110     do { $line = <IN> } until ($line =~ m/^Filename: (.*)$/m);
111     my $deb_file = $1;
112     do { $line = <IN> } until ($line =~ m/^\s*$/m);
113
114     my @stat;
115     # get timestamp...
116     unless (@stat = stat "$LINTIAN_ARCHIVEDIR/$deb_file") {
117         print "E: general: cannot stat $LINTIAN_ARCHIVEDIR/$deb_file\n";
118         next;
119     }
120     my $timestamp = $stat[9];
121     my ($status, $pkg, $data);
122
123     # was package already included in last list?
124     if (exists $pkgfile{$deb_file}) {
125         # yes!
126         $pkg = $pkgfile{$deb_file};
127         $data = $binary_info{$pkg};
128
129         # file changed since last run?
130         if ($timestamp == $data->{'timestamp'}) {
131             # no.
132             $status = 'unchanged';
133         } else {
134             $status = 'changed';
135             delete $binary_info{$pkg};
136         }
137     } else {
138         # new package, get info
139         $status = 'new';
140     }
141
142     if (($status eq 'new') or ($status eq 'changed')) {
143         if (defined $pkgdata) {
144             # avoid collecting the info twice
145             $data = $pkgdata;
146         } else {
147             $data = &safe_get_deb_info($deb_file);
148         }
149         next if not defined $data;
150         $pkg = $data->{'package'};
151     }
152
153     # check for duplicates
154     if (exists $packages{$pkg}) {
155         print "E: general: duplicate-binary-package $pkg\n";
156         next;
157     }
158
159     # write entry to output file
160     print OUT join(';',
161                    $pkg,
162                    $data->{'version'},
163                    $data->{'source'},
164                    $deb_file,
165                    $timestamp,
166                    ),"\n";
167     printf "N: Listed %s binary package %s %s\n",$status,$pkg,$data->{'version'} if $verbose;
168
169     # remove record from hash
170     delete $binary_info{$pkg} if $status eq 'unchanged';
171     $packages{$pkg} = 1;
172     $total++;
173 }
174 close(IN) or fail("cannot close input pipe: $!");
175 close(OUT) or fail("cannot close output pipe: $!");
176
177 if ($verbose) {
178     # all packages that are still included in %binary_info have disappeared from the archive...
179     for my $pkg (sort keys %binary_info) {
180         print "N: Removed binary package $pkg from list\n";
181     }
182     printf "N: Listed %d binary packages\n",$total;
183 }
184
185 exit 0;
186
187 sub safe_get_deb_info {
188     # use eval when calling get_deb_info, since we don't want to `die' just
189     # because of a single broken package
190     my $data;
191     eval { $data = get_deb_info("$LINTIAN_ARCHIVEDIR/$_[0]"); };
192     if ($@) {
193         # error!
194         print STDERR "$@\n";
195         print "E: general: bad-binary-package $_[0]\n";
196         return undef;
197     }
198     $data->{'source'} or ($data->{'source'} = $data->{'package'});
199     return $data;
200 }