#!/usr/bin/env perl # # oldfiles - show outdated packages, sources, build logs for a CRUX system # # by Simone Rota , # Mark Rosenstand , # John McQuah # License: GNU GPL v2 # # Requires prt-get by Johannes Winkelmann # # User beware: # - Ports not using signatures for their manifests will have all their # source files listed. Contact those port maintainers and get them to # abandon the deprecated md5sums. # - Deactivating a repository in prt-get.conf will allow all its packages # and source files to be reported by this script. use warnings; use strict; my %options = %{getoptions(@ARGV)}; my $pkgdir = ""; my $srcdir = ""; my $logdir = ""; my $logtemplate = ""; my $writelog = "disabled"; my $compress = "gz"; my %wanted; my %keepme; # Assume packages and sources if no options specified (historical behaviour). # Users who want to search for build logs (feature added in Sep 2023) # must pass the -l flag explicitly if ( $options{"-p"} + $options{"-s"} + $options{"-l"} == 0 ) { $options{"-p"} = 1; $options{"-s"} = 1; $options{"-l"} = 0; } # Read pkgmk.conf open CONFIG, "/etc/pkgmk.conf" or die "Could not open /etc/pkgmk.conf"; while () { $srcdir = $1 if m/^PKGMK_SOURCE_DIR=(.*)\n/; $pkgdir = $1 if m/^PKGMK_PACKAGE_DIR=(.*)\n/; $compress = $1 if m/^PKGMK_COMPRESSION_MODE=(.*)\n/; } close CONFIG; $srcdir =~ s/"//g; $pkgdir =~ s/"//g; $compress =~ s/"//g; # Check if dirs are specified / exists if ( $options{"-p"} ) { if ($pkgdir eq ""){ print STDERR "error: no PKGMK_PACKAGE_DIR specified in /etc/pkgmk.conf\n"; print STDERR " skipping the search for old packages.\n"; $options{"-p"} = 0; } elsif (! -d $pkgdir) { print STDERR "error: $pkgdir is not a directory\n"; print STDERR " skipping the search for old packages.\n"; $options{"-p"} = 0; } } if ( $options{"-s"} ) { if ($srcdir eq ""){ print STDERR "error: no PKGMK_SOURCE_DIR specified in /etc/pkgmk.conf\n"; print STDERR " skipping the search for old sources.\n"; $options{"-s"} = 0; } elsif (! -d $srcdir) { print STDERR "error: $srcdir is not a directory\n"; print STDERR " skipping the search for old sources.\n"; $options{"-s"} = 0; } } if ( $options{"-l"} ) { open PGCONF, "/etc/prt-get.conf" or die "cannot open prt-get.conf"; while () { $writelog = $1 if m/^\s*writelog\s+(enabled|disabled)/; $logtemplate = $1 if m/^\s*logfile\s+([^\s]+)(#|\n)/; } close PGCONF; if ($logtemplate ne "") { $logdir = $logtemplate; $logdir =~ s/[^\/]+$//; $logdir =~ s/\/$//; } if (($writelog eq "disabled") or ($logdir =~ m/(%p|%n|%v|%r)/)) { print STDERR "warning: $logdir does not resolve to a shared directory,\n"; print STDERR " skipping the search for old logs.\n"; $options{"-l"} = 0; } } # Early exit if no valid dirs are found if ($options{"-s"}+$options{"-p"}+$options{"-l"}==0) { exit 1; } # Collect current sources / packages / log files foreach (split('\n', `prt-get printf "%p:%n:%v:%r:%i\n"`)) { my ($path, $name, $version, $release, $isinst) = split(':', $_, 5); if ( $options{"-p"} ) { $wanted{$pkgdir}{"$name\#$version-$release.pkg.tar.$compress"} = 1; } if ( $options{"-s"} ) { open SIGNATURES, "$path/$name/.signature" or next; while () { m/^SHA256\s\((.+)\)\s.+\n/; if ($1 && ($1 ne "Pkgfile") && ($1 ne ".footprint")) { $wanted{$srcdir}{$1} = 1; } } close SIGNATURES; } if ( $options{"-l"} and ($isinst ne "no") ) { my $logfile = $logtemplate; my %subs = ( $logdir => "", "%p" => $path, "%n" => $name, "%v" => $version, "%r" => $release ); $logfile =~ s/($logdir|%p|%n|%v|%r)/$subs{$1}/g; $logfile =~ s/^\///; $wanted{$logdir}{$logfile} = 1; } } # Keep user-specified files if ( -f "/etc/oldfiles.conf") { my $k; open KEEPME, "/etc/oldfiles.conf" or die "Could not open /etc/oldfiles.conf"; while ($k = ) { chomp($k); $keepme{$k} = 1; } } close KEEPME; # Display unwanted files foreach my $dir (keys %wanted) { opendir DIR, $dir; foreach (readdir DIR) { next if ($_ eq '.' or $_ eq '..'); print "$dir/$_\n" unless ($wanted{$dir}{$_} or $keepme{"$dir/$_"}); } closedir DIR; } ######################## subroutines ######################## # Adapted from Martin Opel's prtorphan script sub getoptions { my @args = reverse @_; my %options = ("-p" => 0, "-s" => 0, "-l" => 0); while (my $argument = pop @args) { if ( $argument eq "-p" ) { $options{"-p"} = 1; } elsif ( $argument eq "-s" ) { $options{"-s"} = 1; } elsif ( $argument eq "-l" ) { $options{"-l"} = 1; } else { usage(); exit 1; } } return \%options; } # Show usage sub usage { print "usage: oldfiles [-p|-s|-l]\n"; }