#!/usr/bin/perl -w use strict; if (@ARGV != 1) { print STDERR "Usage: freebsd-cleanup.pl \n"; exit 1; } my $workdir = $ARGV[0]; mkdir $workdir unless -d($workdir); build_fullworld(); build_customworld(); install_fullworld(); install_customworld(); compare_worlds(); edit_list(); cleanup(); sub build_fullworld { return if -f("$workdir/done-full_obj"); print STDERR "==> Building full world...\n"; system "rm -rf $workdir/full_obj"; mkdir "$workdir/full_obj"; $ENV{MAKEOBJDIRPREFIX} = "$workdir/full_obj"; $ENV{__MAKE_CONF} = "/nonexistant"; chdir "/usr/src"; unless (system "make buildworld") { touch("$workdir/done-full_obj"); } else { die "Failed to build full world"; } } sub build_customworld { return if -f("$workdir/done-custom_obj"); print STDERR "==> Building custom world...\n"; system "rm -rf $workdir/custom_obj"; mkdir "$workdir/custom_obj"; $ENV{MAKEOBJDIRPREFIX} = "$workdir/custom_obj"; delete $ENV{__MAKE_CONF}; chdir "/usr/src"; unless (system "make buildworld") { touch("$workdir/done-custom_obj"); } else { die "Failed to build custom world"; } } sub install_fullworld { return if -f("$workdir/done-full_inst"); print STDERR "==> Installing full world...\n"; system "rm -rf $workdir/full_inst"; mkdir "$workdir/full_inst"; $ENV{MAKEOBJDIRPREFIX} = "$workdir/full_obj"; $ENV{__MAKE_CONF} = "/nonexistant"; chdir "/usr/src"; unless (system "make installworld DESTDIR=$workdir/full_inst") { touch("$workdir/done-full_inst"); } else { die "Failed to install full world"; } } sub install_customworld { return if -f("$workdir/done-custom_inst"); print STDERR "==> Installing custom world...\n"; system "rm -rf $workdir/custom_inst"; mkdir "$workdir/custom_inst"; $ENV{MAKEOBJDIRPREFIX} = "$workdir/custom_obj"; delete $ENV{__MAKE_CONF}; chdir "/usr/src"; unless (system "make installworld DESTDIR=$workdir/custom_inst") { touch("$workdir/done-custom_inst"); } else { die "Failed to install custom world"; } } sub compare_worlds { print "==> Comparing worlds\n"; my @full_files = map {substr($_, length("$workdir/full_inst"))} `find $workdir/full_inst -type f`; my %custom_files = map {substr($_, length("$workdir/custom_inst")) => 1} `find $workdir/custom_inst -type f`; my @bad_files = (); for my $full (@full_files) { push @bad_files, $full unless exists $custom_files{$full}; } open (FILE, ">$workdir/badfiles.txt") or die "Couldn't open $workdir/badfiles.txt for writing: $!"; print FILE @bad_files; close FILE; } sub edit_list { system "vi $workdir/badfiles.txt"; } sub cleanup { print STDERR "Should I delete the selected files now? "; my $answer = ; if ($answer =~ /^y/i) { print STDERR "==> Deleting files...\n"; open (FILE, "$workdir/badfiles.txt") or die "Couldn't open $workdir/badfiles.txt for reading: $!"; my @files = ; close FILE; chomp @files; my $count = 0; for my $file (@files) { if (-f($file)) { $count++; system "chflags noschg '$file'"; unlink $file; } } print STDERR "$count files deleted\n"; } } sub touch { my ($file) = @_; open (FILE, ">$file") or die "Couldn't open $file for writing: $!"; close FILE; }