#!/usr/bin/perl -w # # # Copywrite 2005 - Steven Rostedt # # This code has no restrictions and NO WARRANTY. # Use it at your own risk, do what you want with it, # Just don't blame me. # # This program is used to clean up the /boot and /lib/modules # directories. It searches all the config-*, vmlinuz-*, # System.map-* and initrd.img-* found in /boot as well all # the directories that start with a digit in /lib/modules. # Then after displaying the versions found, it goes through # each one asking if you would like to remove all the files # found. # require 'sys/ioctl.ph'; my $VERSION = "0.2"; chomp(my $pwd = `pwd`); my $bootdir = "/boot"; my $moduledir = "/lib/modules"; while ($#ARGV >= 0) { if ($ARGV[0] eq "-b") { shift; usage(-1) if ($#ARGV < 0); $bootdir = $ARGV[0]; } elsif ($ARGV[0] eq "-m") { shift; usage(-1) if ($#ARGV < 0); $moduledir = $ARGV[0]; } else { usage(0); } shift; } my %configs; my %vmlinux; my %initrd; my %maps; my %modules; my %versions; my $colsize = 80; my $winsize; if (ioctl(STDOUT, &TIOCGWINSZ, $winsize='')) { my ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize); $colsize = $col; } chdir $bootdir || die "Can't entering $bootdir"; open(IN, "ls|") || die "Error listing $bootdir\n"; while () { chomp; if (/(vmlinuz|config|initrd\.img|System\.map)-(.*)/) { my $type = $1; my $name = $2; $versions{$name} = 1; $configs{$name} = $_ if ($type eq "config"); $vmlinux{$name} = $_ if ($type eq "vmlinuz"); $initrd{$name} = $_ if ($type eq "initrd.img"); $maps{$name} = $_ if ($type eq "System.map"); } } close IN; chdir $pwd; # may be a relative path chdir $moduledir || die "Error entering $moduledir\n"; open(IN, "ls|") || die "Error listing $bootdir\n"; while () { chomp; if (/(\d.*)/) { my $name = $1; $versions{$name} = 1; $modules{$name} = $_; } } close IN; my $maxsize = 0; foreach my $key (sort keys %versions) { my $len = length $key; $maxsize = $len if ($len > $maxsize); } my $cols = int ($colsize / ($maxsize + 3)); my $pad = 0; if (!$cols) { $cols = 1; } elsif ($cols > 1) { $pad = int (($colsize - ($maxsize * $cols)) / $cols); $pad = 3 if ($pad < 3); } $pad += $maxsize; list_versions(); foreach my $key (sort keys %versions) { next if ($key =~ /\.old$/); repeat: print "Remove files for version $key [y/N/l/q/?]: "; goto repeat if (process_answer($key)); $key .= ".old"; if (defined($versions{$key})) { repeat2: print "Remove files for older version $key [y/N/l/q/?]: "; goto repeat2 if (process_answer($key)); } } exit 0; sub usage { my ($err) = @_; print "\n"; print "usage: clean-boot.pl [-b boot_dir] [-m module_dir]\n"; print " (version $VERSION)\n"; print " default boot_dir = /boot\n"; print " default module_dir = /lib/modules\n"; print "\n"; exit $err; } sub list_versions { print "List of versions found: \n"; my $cnt = 1; foreach my $key (sort keys %versions) { print (" ") if ($cnt == 1); if ($cnt < $cols) { printf "%-*s",$pad,$key; $cnt++; } else { print "$key\n"; $cnt = 1; } } print "\n" if ($cnt != 1); } sub process_answer { my ($ver) = @_; chomp(my $answer = ); $answer =~ tr/A-Z/a-z/; if ($answer =~ /^y(e(s)?)?$/) { remove_files($ver); } exit 0 if ($answer eq "q"); if ($answer eq "l") { list_versions(); return 1; } if ($answer eq "?") { print " y - remove files from boot and modules\n"; print " n [default] - skip this version\n"; print " l - list the found versions again\n"; print " q - quit\n"; print " ? - display this message\n"; return 1; } return 0; } sub remove_files { local ($ver) = @_; chdir $pwd; unlink "$bootdir/config-$ver" if (defined($configs{$ver})); unlink "$bootdir/vmlinuz-$ver" if (defined($vmlinux{$ver})); unlink "$bootdir/initrd.img-$ver" if (defined($initrd{$ver})); unlink "$bootdir/System.map-$ver" if (defined($maps{$ver})); if (defined($modules{$ver})) { `rm -rf "$moduledir/$ver"` if ( -d "$moduledir/$ver"); } }