From 9f2bfaa01144170b0183ab03bd49da633d4776b8 Mon Sep 17 00:00:00 2001 From: John McQuah Date: Wed, 6 Sep 2023 09:56:07 -0400 Subject: [PATCH] oldfiles: initial import --- man1/oldfiles.1 | 68 ++++++++++++++++++ scripts/oldfiles.pl | 164 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 232 insertions(+) create mode 100644 man1/oldfiles.1 create mode 100755 scripts/oldfiles.pl diff --git a/man1/oldfiles.1 b/man1/oldfiles.1 new file mode 100644 index 0000000..02cbb3c --- /dev/null +++ b/man1/oldfiles.1 @@ -0,0 +1,68 @@ +." Text automatically generated by txt2man-1.4.7 +.TH oldfiles 1 "April 23, 2006" "" "" +.SH NAME +\fBoldfiles\fP - display old packages and sources + +.SH SYNOPSIS +.nf +.fam C +.B oldfiles [\-p|\-s|\-l] +.fam T +.fi +.SH DESCRIPTION +Oldfiles is a script to list outdated packages, sources, and build logs on a +CRUX system with central directories for those \fBpkgmk\fP(8) and +\fBprt\-get\fP(8) artifacts. +The global config /etc/pkgmk.conf must define PKGMK_SOURCE_DIR and +PKGMK_PACKAGE_DIR (if using \fB\-s\fP or \fB\-p\fP), and /etc/prt-get.conf must +define \fIwritelog enabled\fP and a template for \fIlogfile\fP (if using +\fB\-l\fP). See \fBpkgmk.conf\fP(5) and \fBprt\-get.conf\fP(5) for details. +.PP +Without any options, \fBoldfiles\fP will default to showing only sources and +packages. The list of ports is built using \fBprt\-get\fP(8), so deactivating +a repository in /etc/prt-get.conf will result in all its ports' sources and +packages being flagged as old. +.SH OPTIONS +.TP +.B \-p +list only outdated packages + +.TP +.B \-s +list only outdated sources + +.TP +.B \-l +list only outdated build logs (those from packages that have since been +uninstalled, or from building a previous version) + +.SH EXAMPLES +.TP +.B +\fBoldfiles\fP \fB-p\fP +will list all outdated packages. +.TP +.B +\fBoldfiles\fP | xargs rm +will remove all outdated packages and sources. +.SH CONFIGURATION +\fBoldfiles\fP looks for the file /etc/oldfiles.conf (if present) that contains +a list of files that should be kept. The format is a simple list of filenames +(full path required), e.g.: +.PP +.nf +.fam C + /usr/sources/someport-1.3.tar.gz + /usr/packages/someport#1.3.pkg.tar.gz + /usr/packages/index.html + +.fam T +.fi +.SH AUTHORS +Simone Rota +.PP +Mark Rosenstand +.PP +John McQuah +.SH SEE ALSO +\fBpkgmk\fP(8), \fBprt-get\fP(8) diff --git a/scripts/oldfiles.pl b/scripts/oldfiles.pl new file mode 100755 index 0000000..71e741c --- /dev/null +++ b/scripts/oldfiles.pl @@ -0,0 +1,164 @@ +#!/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; + +# 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 =~ "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 = ) { + 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"; +}