#!/usr/bin/perl # # $Id: prtcheckmissing,v 1.1 2003/10/27 15:26:50 opel Exp $ # prtcheckmissing,v 1.2 2022/05/31 18:41:19 jmq Exp $ # prtcheckmissing,v 1.3 2023/03/25 15:55:20 jmq Exp $ use strict; use warnings; my @installed; my @regfiles; my @symlinks; my @missingReg; my @missingSym; my @mask = parse_pkgadd_conf(); open(PORTLIST,"-|","prt-get printf '%i:%p/%n\n'"); while () { push(@installed,$1) if m/^yes:(.+)/; } foreach (@installed) { local $/ = ""; # read files paragraph-wise; see ``perldoc perlvar'' my $pf = "$_/.footprint"; my $pkg_name = (split /\//)[-1]; open (my $dbh, $pf) or die "Could not read $pf !\n"; while(<$dbh>) { my @pkg_file = split /\n/; # erase the annotations that appear in the footprint foreach (@pkg_file) { s/ \(EMPTY\)//; s/ \([0-9]+, [0-9]+\)//; } # extract the paths, ignoring fields for mode and uid/gid @symlinks = map {(split /[\t ]/, $_)[2]} grep {m/ -> /} @pkg_file; @regfiles = map {(split /\t/, $_)[2]} grep { !m/ -> / } @pkg_file; # apply the pkgadd rules to eliminate false positives @missingSym = grep { (! -e "/$_") && wanted($_, @mask) } @symlinks; @missingReg = grep { (! -e "/$_") && wanted($_, @mask) } @regfiles; # final report for this package next if ((not @missingSym) and (not @missingReg)); print map "/$_ $pkg_name\n", @missingReg if (@missingReg); print map "/$_ $pkg_name\n", @missingSym if (@missingSym); } close($dbh); } sub parse_pkgadd_conf { my @unwanted; local $/ = "\n"; open my $pah, "< /etc/pkgadd.conf" or die "Couldn't open pkgadd install rules!\n"; while(<$pah>) { next if /^\s*#/ or /^$/; my ($event, $pattern, $choice) = split; push (@unwanted, qr/$pattern/s) if ($event eq "INSTALL" and $choice eq "NO"); } close ($pah); return @unwanted; } sub wanted { my $testfile = shift; my $retval = 1; while (my $regexp=shift) { $retval = 0 if $testfile =~ $regexp; last if $retval==0; } return $retval; }