Initial import from FreeBSD RELENG_4:
[dragonfly.git] / release / scripts / checkindex.pl
1 #!/usr/bin/perl
2 # -----------------------------------------------------------------
3 #  FreeBSD Release Checking Utility - Package Index Check
4 #
5 #  This program checks the packages/INDEX file to verify that
6 #  the index is in the correct format and that every package
7 #  needed by a release is included on the CD.
8 #
9 #  Copyright(c) 2000 BSDi
10 #  Murray Stokely
11 # -----------------------------------------------------------------
12 # 08 Apr 2000
13 #
14 # $FreeBSD: src/release/scripts/checkindex.pl,v 1.1.2.1 2003/03/03 09:49:13 murray Exp $
15 #
16
17 use Getopt::Long;
18
19 #
20 # Display the usage instructions
21 #
22
23 sub printHelp {
24     print<<end;
25 usage : checkindex -s <sysinstall src dir> <INDEX>
26
27   This program checks the packages INDEX file to verify that the 
28 index is correct and that every package needed by sysinstall is
29 included in the index.
30
31   Options
32
33      -help                Display usage instructions
34      -s <src dir>         Specify the sysinstall source directory.  Use
35                           this so to make sure every package referenced
36                           in the code is in your INDEX
37      -newindex            Generate a new index consisting of only those
38                           packages that actually exist in pkgdir/All
39      -depends <pkg>       Lists all packages in the index that depend
40                           on <pkg>.
41
42 end
43 }
44
45 ##
46 ## Attempts to find the value of a variable in C code by backtracking
47 ## up the source looking for a previous declaration.
48 ## 
49 ## This is a bit overkill for the purpose of this script,
50 ## stick with grepping for likely packages for now.
51
52 sub findAssignment($$) {
53             ## This code deals with the small (5%) number of matches
54             ## in which package_add refers to a variable rather than
55             ## a inline string, so we have to find the value of that
56             ## variable so that we can push it onto the list
57 #           my($fileName,$code) = split(/:/,$match);
58 #           open(FILE,$fileName) || die "Could not open $fileName : $!\n";
59 #           my(@lines) = <FILE>;
60 #           my($cnt)  = 1;
61 #           my($lineMatch) = 0;
62 #           chomp(@lines);
63 #           foreach $line (@lines) {
64 #               $lineMatch = $cnt if ($line eq $code);
65 #               $cnt++;
66 #           }
67 #           $code =~ /package_add\((\S+)\)/;
68 #           my($varName) = $1;
69 #           print STDERR "$lineMatch of $fileName is wierd\n";
70 #           print STDERR "Trying to find '$varName'\n";
71 #           while ($cnt > 0) {
72 #               $cnt--;
73 #           }
74
75
76 }
77
78 ##
79 ## Returns a list of all the packages referenced in the sysinstall source
80 ## code
81 ##
82
83 sub getPackages($) {
84     my($srcDir) = $_[0];
85     my(@matches) = `grep package_add $opt_s/*.c`;
86     my(@packages);
87     foreach $match (@matches) {
88         chomp $match;
89         next if ($match =~ m|$opt_s/package.c|);
90         if ($match =~ /package_add\(\"(\S+)\"\)/) {
91             push(@packages,$1);
92         } elsif ($match =~ /package_add\(char/) {
93             # function definition or prototype
94             next;
95         } else {
96             # package_add(variable or DEFINE)
97             my(@varMatches) = `grep variable_set2 $opt_s/*.c`;
98             chomp @varMatches;
99             foreach $varMatch (@varMatches) {
100                 if ($varMatch =~ /variable_set2\(\S+_PACKAGE,\s+\"(\S+)\"/) {
101                     push(@packages,$1);
102                 }
103             }
104         }
105     }
106     @packages;
107 }
108
109
110 &GetOptions("help","s=s","newindex","depends=s");
111 if ($opt_help) {
112     &printHelp;
113 } else{
114     my ($indexName) = $ARGV[0];
115     my ($mistakes) = 0;
116     my ($counter)  = 0;
117     print STDERR "Packages Referenced :\n---------------------\n";
118     open(INDEX,$indexName) || die "Could not open $indexName : $!";
119     @index = <INDEX>;
120     close(INDEX);
121
122     ## Check to ensure that every file in the index exists physically.
123     print STDERR "Check to ensure that every file in the index exists physically\n";
124     foreach $line (@index) {
125         chomp $line;
126         ($file,$pathto,$prefix,$comment,$descr,$maint,$cats,$junk,$rdeps,$junk) = split(/\|/,$line,10);
127         $DEPENDS{$file} = $rdeps if (-e "All/$file.tgz");
128     }
129
130     if ($opt_newindex) {
131         foreach $pkg (keys %DEPENDS) {
132             $new = quotemeta $pkg;
133             @lines = grep(/^$new\|/,@index);
134             chomp $lines;
135             ($#lines == 0) || die "Multiple lines for '$pkg' in index!";
136             printf "%s\n",$lines[0];
137         }
138     } elsif ($opt_depends) {
139         foreach $key (keys %DEPENDS) {
140             foreach $dependency (split ' ',$DEPENDS{$key}) {
141                 if ($opt_depends eq $dependency) {
142                     print "$opt_depends is needed by $key\n";
143                     $counter++;
144                 }
145             }
146         }
147         print "$opt_depends is not needed by any packages in the index!\n"
148             unless ($counter);
149     } else {
150
151     ## Check to ensure that all the dependencies are there.
152     print "Check to make sure that every dependency of every file exists\n",
153         "in the Index and physically.\n";
154     foreach $file (keys %DEPENDS) {
155 #       print "Checking $file\n";
156         foreach $depend (split(' ',$DEPENDS{$file})) {
157             unless (-e "All/$depend.tgz") {
158                 # instead of a hash counter, make it a hash of arrays
159                 # where the arrays are the files depended on.
160                 push @{ $MISSING{$depend} }, $file;
161                 $mistakes++;
162             }
163         }
164     }
165
166     ## This makes sure that the index file contains everything
167     ## that sysinstall uses.
168     if ($opt_s) {
169         @packages = getPackages($opt_s);
170         foreach $pkg (@packages) {
171             unless (grep(/^$pkg/,@index)) {
172                 push @{ $MISSING{$pkg} }, "sysinstall";
173                 $mistakes++;
174             }
175         }
176     }
177
178
179     ## If there were mistakes, print out the missing packages.
180     if ($mistakes) {
181         print "--------------------------------------------------------\n",
182               " Packages Missing : \n",
183               "--------------------------------------------------------\n";
184         foreach $pkg (keys %MISSING) {
185             @files = @{ $MISSING{$pkg} };
186             print "$pkg (@files)\n";
187         }
188     } else {
189         print "Everything looks good!\n";
190     }
191 }
192 }