123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- #! /usr/bin/perl
- # ex:ts=8 sw=4:
- # $OpenBSD: clean-old-distfiles,v 1.7 2016/01/24 20:26:56 espie Exp $
- #
- # Copyright (c) 2012 Marc Espie <espie@openbsd.org>
- #
- # Permission to use, copy, modify, and distribute this software for any
- # purpose with or without fee is hereby granted, provided that the above
- # copyright notice and this permission notice appear in all copies.
- #
- # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- use strict;
- use warnings;
- use feature qw(say);
- use OpenBSD::Getopt;
- use OpenBSD::md5;
- use File::Basename;
- sub usage
- {
- my $err = shift;
- my $prog = $0;
- $prog =~ s/.*\///;
- $err =~ s/\sat.*//s;
- say STDERR "$prog: $err";
- say STDERR "Usage: $prog [-nv] [-e except] [-h history] [cutdate]";
- exit 1;
- }
- our ($opt_v, $opt_n, $opt_e, $opt_h);
- eval { getopts('e:h:vn'); };
- if ($@) {
- usage($@);
- }
- if (@ARGV > 1) {
- usage("too many arguments");
- }
- if ($opt_h) {
- $opt_n = 1;
- $opt_v = 1;
- }
- sub really_remove
- {
- my $file = shift;
- say "rm $file" if $opt_v;
- return if $opt_n;
- if (unlink $file) {
- my $dirname = $file;
- do {
- $dirname = File::Basename::dirname $dirname;
- } while (rmdir $dirname);
- } else {
- say STDERR "Couldn't remove $file: $!";
- }
- }
- sub remove_file
- {
- my ($file, $sha) = @_;
- # let's do i-node caching to avoid doing the same file twice.
- my $basename = $file;
- my $inode;
- $basename =~ s/^.*\///; # remove directory
- $sha =~ m/(..)/;
- my $link = "by_cipher/sha256/$1/$sha/$basename";
- if (-f $link) {
- $inode = (stat _)[1];
- really_remove($link);
- }
- if (-f $file) {
- my $inode2 = (stat _)[1];
- if (defined $inode && $inode2 == $inode) {
- really_remove($file);
- } else {
- my $ck = OpenBSD::sha->new($file);
- if ($ck->stringize eq $sha) {
- really_remove($file);
- } else {
- say STDERR "SHA256 mismatch on $file: ",
- $ck->stringize, " vs $sha";
- }
- }
- }
- }
- my $cutdate = $ARGV[0];
- my $PORTSDIR = $ENV{PORTSDIR} // '/usr/ports';
- my $DISTDIR = $ENV{DISTDIR} // "$PORTSDIR/distfiles";
- chdir($DISTDIR) or die "Can't chdir to $DISTDIR";
- my $history = $opt_h ? $opt_h : 'history';
- open my $fh, '<', $history or die "No $history to prune";
- my $fh2;
- unless ($opt_n) {
- open $fh2, '>', "history.new" or die "Can't write new history";
- }
- my $except = {};
- if ($opt_e) {
- open(my $e, '<', $opt_e) or die "Can't read exception file $opt_e: $!";
- while (<$e>) {
- chomp;
- $except->{$_} = 1;
- }
- close $e;
- }
- while (<$fh>) {
- my ($ts, $file, $sha);
- if (m/^(\d+)\s+SHA256\s*\((.*)\) \= (.*)$/) {
- ($ts, $file, $sha) = ($1, $2, $3);
- } else {
- die "Bad history line $_";
- }
- if ($except->{$file} || (defined $cutdate && $ts > $cutdate)) {
- if ($fh2) {
- print $fh2 $_;
- }
- } else {
- remove_file($file, $sha);
- }
- }
- close $fh;
- if ($fh2) {
- close $fh2;
- unlink('history');
- rename('history.new', 'history');
- }
|