Documentation/scripts/oldfiles.pl

165 lines
4.7 KiB
Perl
Executable File

#!/usr/bin/env perl
#
# oldfiles - show outdated packages, sources, build logs for a CRUX system
#
# by Simone Rota <sip at varlock dot com>,
# Mark Rosenstand <mark at borkware dot net>,
# John McQuah <jmcquah at disroot dot org>
# 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 (<CONFIG>) {
$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;
# 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 (<PGCONF>) {
$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 (<SIGNATURES>) {
m/^SHA256\s\((.+)\)\s.+\n/;
if ($1 && !($1 =~ "Pkgfile") && !($1 =~ ".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 $keep;
open KEEPME, "/etc/oldfiles.conf" or die "Could not open /etc/oldfiles.conf";
while ($keep = <KEEPME>) {
chomp($keep);
$keepme{$keep} = 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";
}