diff options
author | Yen-Ming Lee <leeym@FreeBSD.org> | 2003-09-30 14:19:27 +0000 |
---|---|---|
committer | Yen-Ming Lee <leeym@FreeBSD.org> | 2003-09-30 14:19:27 +0000 |
commit | d85f8f76c8571ac9c6f2f08f1c7c33d95f560ff0 (patch) | |
tree | 22bc05c1961112e3a760c4ac32cee250c4cc4bf1 /ports-mgmt/pkg_cutleaves | |
parent | Update vertion to 1.2.1 (diff) |
add pkg_cutleaves-20030727
pkg_cutleaves finds installed 'leaf' packages, i.e. packages that
are not referenced by any other installed package, and lets you
decide for each one if you want to keep or deinstall it via pkg_deinstall(1).
PR: 54912
Submitted by: Stefan Walter <sw@gegenunendlich.de>
Notes
Notes:
svn path=/head/; revision=89898
Diffstat (limited to 'ports-mgmt/pkg_cutleaves')
-rw-r--r-- | ports-mgmt/pkg_cutleaves/Makefile | 56 | ||||
-rw-r--r-- | ports-mgmt/pkg_cutleaves/pkg-descr | 10 | ||||
-rw-r--r-- | ports-mgmt/pkg_cutleaves/pkg-plist | 1 | ||||
-rw-r--r-- | ports-mgmt/pkg_cutleaves/src/pkg_cutleaves | 186 | ||||
-rw-r--r-- | ports-mgmt/pkg_cutleaves/src/pkg_cutleaves.1 | 40 |
5 files changed, 293 insertions, 0 deletions
diff --git a/ports-mgmt/pkg_cutleaves/Makefile b/ports-mgmt/pkg_cutleaves/Makefile new file mode 100644 index 000000000000..14b066efa08b --- /dev/null +++ b/ports-mgmt/pkg_cutleaves/Makefile @@ -0,0 +1,56 @@ +# New ports collection makefile for: pkg_cutleaves +# Date created: 27 July 2003 +# Whom: Stefan Walter <sw@gegenunendlich.de> +# +# $FreeBSD$ +# +# This port is self contained in the src directory. +# + +PORTNAME= pkg_cutleaves +PORTVERSION= 20030727 +CATEGORIES= sysutils +MASTER_SITES= # none +DISTFILES= # none + +MAINTAINER= sw@gegenunendlich.de +COMMENT= Interactive script for deinstalling 'leaf' packages + +RUN_DEPENDS= ${LOCALBASE}/sbin/pkg_deinstall:${PORTSDIR}/sysutils/portupgrade + +NO_BUILD= yes +USE_PERL5= yes +USE_REINPLACE= yes + +SRC= ${.CURDIR}/src + +MAN1= pkg_cutleaves.1 + +do-fetch: + @${DO_NADA} + +pre-patch: + @${CP} ${SRC}/pkg_cutleaves ${WRKDIR}/pkg_cutleaves + @${CP} ${SRC}/pkg_cutleaves.1 ${WRKDIR}/pkg_cutleaves.1 + +post-patch: + @${REINPLACE_CMD} -e \ + 's,/usr/local/etc/pkg_leaves.exclude,${PREFIX}/etc/pkg_leaves.exclude,' \ + ${WRKDIR}/pkg_cutleaves.1 + @${REINPLACE_CMD} -e \ + 's,/usr/local/etc/pkg_leaves.exclude,${PREFIX}/etc/pkg_leaves.exclude,' \ + ${WRKDIR}/pkg_cutleaves + @${REINPLACE_CMD} -e \ + 's,/usr/local/sbin/pkg_deinstall,${LOCALBASE}/sbin/pkg_deinstall,' \ + ${WRKDIR}/pkg_cutleaves + @${REINPLACE_CMD} -e \ + 's,/var/db/pkg,${PKG_DBDIR},' \ + ${WRKDIR}/pkg_cutleaves + @${REINPLACE_CMD} -e 's,/usr/bin/perl,${PERL},' \ + ${WRKDIR}/pkg_cutleaves + +do-install: + ${INSTALL_SCRIPT} ${WRKDIR}/pkg_cutleaves ${PREFIX}/sbin/pkg_cutleaves + ${INSTALL_MAN} ${WRKDIR}/pkg_cutleaves.1 ${MAN1PREFIX}/man/man1 + +.include <bsd.port.mk> diff --git a/ports-mgmt/pkg_cutleaves/pkg-descr b/ports-mgmt/pkg_cutleaves/pkg-descr new file mode 100644 index 000000000000..02d99d329a1b --- /dev/null +++ b/ports-mgmt/pkg_cutleaves/pkg-descr @@ -0,0 +1,10 @@ +pkg_cutleaves finds installed 'leaf' packages, i.e. packages that are +not referenced by any other installed package, and lets you decide for +each one if you want to keep or deinstall it (via pkg_deinstall(1)). + +Usage: pkg_cutleaves [-l] [-x] [-R] + -l: List leaf packages only, one per line, and don't ask for anything + to be deinstalled. + -x: Exclude packages matching expressions given in the exclude file. + -R: Run 'pkg_deinstall -R' instead of plain 'pkg_deinstall', so packages + the removed leaf packages depend(ed) on will be deinstalled, too. diff --git a/ports-mgmt/pkg_cutleaves/pkg-plist b/ports-mgmt/pkg_cutleaves/pkg-plist new file mode 100644 index 000000000000..eb45d358eeda --- /dev/null +++ b/ports-mgmt/pkg_cutleaves/pkg-plist @@ -0,0 +1 @@ +sbin/pkg_cutleaves diff --git a/ports-mgmt/pkg_cutleaves/src/pkg_cutleaves b/ports-mgmt/pkg_cutleaves/src/pkg_cutleaves new file mode 100644 index 000000000000..355c4093d48d --- /dev/null +++ b/ports-mgmt/pkg_cutleaves/src/pkg_cutleaves @@ -0,0 +1,186 @@ +#!/usr/bin/perl +# +# Copyright (c) 2003 Stefan Walter <sw@gegenunendlich.de> +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ + +# Interactive script for deinstalling "leaf" packages; +# requires the portupgrade tools +# +# Syntax: pkg_cutleaves [-l] [-x] [-R] +# Options: +# -l: List leaf packages only, don't ask if they should be deinstalled +# -x: Honor exclude list in $excludefile +# -R: Run 'pkg_deinstall -R' instead of plain 'pkg_deinstall' + +use strict; + +my $dbdir = "/var/db/pkg"; +my $excludefile = "/usr/local/etc/pkg_leaves.exclude"; +my $pkgdeinstall = "/usr/local/sbin/pkg_deinstall"; +my ($opt_listonly, $opt_excludelist, $opt_recursive); +my $exclpattern; + +# Read the exclude list if the file exists +sub get_excl_pattern { + my $excl_file = $_[0]; + my $excl_pattern; + # Does the exclude file exist? + if (($excl_file) && (-f $excl_file) && (-T $excl_file)) { + # Read the patterns to be excluded + my @excludes; + open(EXCLFILE, $excl_file) + or die "Couldn't open $excl_file!"; + while(my $exclude = <EXCLFILE>) { + chomp($exclude); + # Ignore comments and empty lines, add others as regular expressions + unless (($exclude =~ m/(^ *#)|(^ *$)/)) { + $exclude = "^" . $exclude . ".*"; + @excludes = (@excludes, $exclude); + } + } + close(EXCLFILE); + $excl_pattern = join("|", @excludes); + } else { + # Dummy exclusion pattern -> doesn't exclude anything + $excl_pattern = " "; + } + return $excl_pattern; +} + +# Get a list of all leaves +sub get_leaves { + my $db_dir = $_[0]; + my $excl_pattern = $_[1]; + my @pkgdirs; + opendir(DBDIR, $db_dir) + or die "Can't open package db directory $db_dir!"; + while(defined(my $file = readdir(DBDIR))) { + my $path = $db_dir . '/' . $file; + my $reqlist = $path . '/+REQUIRED_BY'; + # Exclude non-directories, "." and ".." + if (($file ne ".") && ($file ne "..") && (-d $path) && (!-s $reqlist)) { + # Exclude packages matching exclude pattern, if requested + unless ($file =~ m/$excl_pattern/) { + @pkgdirs = (@pkgdirs, $file); + } + } + } + closedir(DBDIR); + return @pkgdirs; +} + +# Examine command line arguments +while(@ARGV) { + my $arg = shift(@ARGV); + if ($arg eq "-x") { + $opt_excludelist = 1; + } + elsif ($arg eq "-l") { + $opt_listonly = 1; + } + elsif ($arg eq "-R") { + $opt_recursive = 1; + } +} + +# Exclusion requested? +if ($opt_excludelist) { + # Get exclusion pattern + $exclpattern = get_excl_pattern($excludefile); +} else { + # Spaces don't appear in package names -> this doesn't exclude anything + $exclpattern = " "; +} + +if ($opt_listonly) { + # Just print out the list of leaves, one per line + my @leaveslist = get_leaves($dbdir, $exclpattern); + foreach my $leaf (sort @leaveslist) { + print "$leaf\n"; + } +} else { + my %leavestokeep; + my %leavestocut; + my @cutleaves; + # Loop while the user wants to + my $again = "y"; + ROUND: while($again eq "y") { + # Get list of packages and put them into an array + my @leaves = get_leaves($dbdir, $exclpattern); + LEAVESLOOP: foreach my $leaf (sort @leaves) { + if (!$leavestokeep{$leaf}) { + print "$leaf - [keep]/(d)elete/(f)lush marked pkgs/(a)bort? "; + my $answer = substr(lc(<STDIN>), 0, 1); + + if ($answer eq "d") { + print "** Marking $leaf for removal.\n\n"; + $leavestocut{$leaf} = 1; + } + elsif ($answer eq "f") { + print "\n"; + last LEAVESLOOP; + } + elsif ($answer eq "a") { + print "\n"; + last ROUND; + } + else { + print "** Keeping $leaf.\n\n"; + $leavestokeep{$leaf} = 1; + } + } + } # LEAVESLOOP + + # loop through packages marked for removal and pkg_deinstall them + foreach my $leaf (sort keys %leavestocut) { + print "Deleting $leaf.\n"; + my @deinstall_args; + if ($opt_recursive) { + @deinstall_args = ($pkgdeinstall, '-R', $leaf); + } else { + @deinstall_args = ($pkgdeinstall, $leaf); + } + if ((my $status = system(@deinstall_args) >> 8) != 0) { + print "\nError: pkg_deinstall returned $status - exiting, fix this first.\n\n"; + last ROUND; + } + @cutleaves = (@cutleaves, $leaf); + delete $leavestocut{$leaf}; + } + + print "Once more ((y)es/[no])? "; + $again = substr(lc(<STDIN>), 0, 1); + print "\n"; + } # ROUND + + # print list of removed packages + print "** Deinstalled packages:\n"; + foreach my $cutleaf (@cutleaves) { + print "$cutleaf\n"; + } +} + diff --git a/ports-mgmt/pkg_cutleaves/src/pkg_cutleaves.1 b/ports-mgmt/pkg_cutleaves/src/pkg_cutleaves.1 new file mode 100644 index 000000000000..52b3b3231287 --- /dev/null +++ b/ports-mgmt/pkg_cutleaves/src/pkg_cutleaves.1 @@ -0,0 +1,40 @@ +.TH PKG_CUTLEAVES 1 "Jul 2003" FreeBSD +.SH NAME +pkg_cutleaves \- deinstall 'leaf' packages +.SH SYNOPSIS +.B pkg_cutleaves [-l] [-x] [-R] +.SH DESCRIPTION +.B pkg_cutleaves +finds installed 'leaf' packages, i.e. packages that are not referenced +by any other installed package, and lets you decide for each one if you +want to keep or deinstall it (via pkg_deinstall(1)). +Once the packages marked for removal have been flushed/deinstalled, +you'll be asked if you want to do another run (to see packages that have +become 'leaves' now because you've deinstalled the package(s) that +depended on them). In every run you will be shown only packages that you +haven't marked for keeping, yet. + +Note that your package registry database should be up to date for this +to work properly, so it might be a good idea to run pkgdb(1) before +running pkg_cutleaves. +.SH OPTIONS +.IP -l +List leaf packages only, one per line, and don't ask for anything to be +deinstalled. +.IP -x +Exclude packages matching expressions given in the exclude file. +.IP -R +Run 'pkg_deinstall -R' instead of plain 'pkg_deinstall', so packages the +removed leaf packages depend(ed) on will be deinstalled, too. +.SH FILES +.I /usr/local/etc/pkg_leaves.exclude +.RS +An optional list for excluding packages when the '-x' option is given. +If the beginning of a package's name matches any line (except comment or +empty lines) in this file, the package will not be listed/offered for +removal (e.g., a line saying just 'XFree86' (without the 's) will +exclude all packages with names starting with 'XFree86'). +.SH AUTHOR +Stefan Walter <sw@gegenunendlich.de> +.SH SEE ALSO +pkg_deinstall(1), portsclean(1) |