About a year ago I started this
topic
in the forum already but didn't seem to arise too much attention. Since
about a month ago somebody picked the topic up again and another suggested
to discuss it in the mailing list, here I am to give it another try.
So whats all this about?
Coming from a debian system I knew about
possibilities to identify orphaned packages (via deborphan) and
uninstalling
them. Being fascinated of SliTaz and the perfect mixture of enough eyecandy
and usability with tinyness I saw the necessity of exactly this
feature.
What is meant by "orphaned packages"?
If you install a package, others may be installed with it as dependencies,
enabling the program to work as intended (libraries, additional binaries
or whatever). If you uninstall the wanted package, the dependencies remain
on your system (losing the "parent" package and therefore becoming
an "orphane"), if you don't have any function which identifies
and deletes them. So your systems gets crammed up by files you actually
don't need.
What are the criteria of orphancy?
1.) No other package depends on the
orphan (there is no "parent" package)
2.) The package has not been installed
deliberately, e.g. on choice of the user/admin
3.) The package is not a part of the
basic system, therefore not essential (which equals 2. to some
degree)
As first step I tried to find the packages
that matched criteria 1). Using "tazpkg (r)depends" was awfully
slow though, especially when I went through the uninstallation of orphaned
packages recursively (since uninstallation of a package may bring up new
orphancies, freeing your system even more...).
Realizing that all information I was
searching for was available in the receipts of the installed packages I
figured out a script, that sped the search up to some degree:
============================================================================
#!/bin/sh
#
# tazorphan
#
# script to identify packages that ARE
no dependency
# indicating possible orphancy
#
# Nils Christiansen, 2011
#
# cleaning up list of collected
dependencies
#
echo > /tmp/Deps.txt
# collecting dependencies of all installed
packages
# from package receipts
#
for DIRECTRY in
/var/lib/tazpkg/installed/*
do
.
$DIRECTRY/receipt
for
PKG in $DEPENDS
do
echo "$PKG" >> /tmp/Deps.txt
done
done
# check each package if it is mentioned
in the list;
# if not, then the package might be
orphaned.
#
for DIRECTRY in
/var/lib/tazpkg/installed/*
do
PKG=$(basename
$DIRECTRY)
if
[ -z "`sed -n "s/^${PKG}$/&/p" /tmp/Deps.txt`"
]; then
echo
$PKG
fi
done
============================================================================
So now I had a list of all files, that
WERE no dependency for any package (fulfilling criteria 1), therefore MIGHT
be orphans.
In order to identify those packages
of the list, that additionally fulfill criteria 2, I had to check against a
list of
all those packages I had CHOSEN to install.
This lead to patching the tazpkg script:
everytime I installed a package from the shell, the name of the chosen
package was added to a text file /var/lib/tazpkg/chosenpkg.lst. Since
tazpkg
invokes itself recursively to install dependencies, a check against the
number of running tazpkg processes delivers the possibility of
discrimination.
As "tazpkg unorphan" is invoked,
the script performs the same action as in tazorphan, checks the resulting
packages agains chosenpkgs.lst as well as against another list of files
that are system-relevant in /var/lib/tazpkg/systempkg.lst and offers
remaining
packages (one by one) for uninstallation. If you deny uninstallation, then
the package is added to chosenpkg.lst. If you acknowledge uninstallation,
then the package is uninstalled and unorphan starts over again, since new
orphancies might have arisen.
Pros and Cons up to now:
- Since the patch has not been installed
from scratch, you need one initial run in order to build up chosenpkg.lst
(you might as well create a list using an editor)
- the patch seems not to work in tazpanel,
since interactivity is not supported; so you can't accept or deny
uninstallation
- I am not sure, which packages should
be in systempkg.lst so they never will be proposed for uninstallation.
I started with:
enchant
clearlooks
curl
desktop-file-utils
hicolor-icon-theme
kbd-busybox
linux
linux-video
linux-wireless
locale-de
obconf
pangomm
slim
slitaz-configs
slitaz-menus
slitaz-polar-cursors
wpa_supplicant
wv
xorg-base-fonts
xorg-setxkbmap
xorg-xauth
xorg-xf86-video-intel
xterm
which keeps my system up and running,
but which might contain unnecessities or I might have forgotten
something.
So, I'd be happy about some discussion
and constructive critics about this...
Cheers,
nils
Patch for tazpkg v4.9.2:
============================================================================
--- /usr/bin/tazpkg
+++ tazpkg
@@ -102,6 +102,7 @@
install|-i
`gettext \"Install a local (*.tazpkg) package (--forced to
force).\"`
install-list
`gettext \"Install all packages from a list of packages.\"`
remove|-r
`gettext \"Remove the specified package and all installed
files.\"`
+ unorphan
`gettext \"Search for orphaned packages and
remove them interactively.\"`
extract
`gettext \"Extract a (*.tazpkg) package into a
directory.\"`
pack
`gettext \"Pack an unpacked or prepared package
tree.\"`
recharge
`gettext \"Recharge your packages.list from the
mirror.\"`
@@ -635,6 +636,9 @@
separator
eval_gettext
"\$PACKAGE (\$VERSION\$EXTRAVERSION) is installed."; echo
echo
""
+ if
[ `pidof tazpkg | wc -w` = "2" ]; then
+
echo $PACKAGE >> $LOCALSTATE/chosenpkg.lst
+ fi
#
Log this activity
[
-n "$ROOT" ] || log Installed
}
@@ -765,6 +769,66 @@
fi
}
+# Check for orphaned packages and
uninstall
them
+unorphan()
+{
+ #
prepare temporary files
+ if
[ -f /tmp/orph ]; then
+
rm /tmp/orph
+ fi
+ if
[ -f /tmp/chkpkgs ]; then
+
rm /tmp/chkpkgs
+ fi
+ touch
$LOCALSTATE/systempkg.lst
+ touch
$LOCALSTATE/chosenpkg.lst
+
+ #
collect all existing dependencies in one temporary file, one in a
line
+ for
verz in /var/lib/tazpkg/installed/*
+
do
+ .
$verz/receipt
+ for
pack in $DEPENDS
+
do
+
echo "$pack" >> /tmp/chkpkgs
+
done
+
done
+
+ #
check each package for system or chosen case and - if none - for
orphancy
+
separator
+ eval_gettext
"Checking:";echo
+ for
prog in `ls /var/lib/tazpkg/installed`
+
do
+
echo -en "\\033[0G
"
+
echo -en "\\033[0G$prog
"
+
if [ -z "`sed -n "s/^${prog}$/&/p" $LOCALSTATE/systempkg.lst`"
]; then
+
if [ -z "`sed -n "s/^${prog}$/&/p" $LOCALSTATE/chosenpkg.lst`"
]; then
+
if [ -z "`sed -n "s/^${prog}$/&/p" /tmp/chkpkgs`"
]; then
+
tazpkg remove ${prog}
+
if [ ! -d $LOCALSTATE/installed/${prog}
]; then
+
echo orphaned > /tmp/orph
+
break
+
fi
+
fi
+
fi
+
fi
+
done
+
+ if
[ -f /tmp/orph ]; then
+
echo -en "\n\n"
+
eval_gettext "Removed orphaned packages... taking another recursive
turn...";echo
+
unorphan
+ fi
+
echo;eval_gettext
"...finished.";echo
+
separator
+
+ #
clear temporary files
+ if
[ -f /tmp/orph ]; then
+
rm /tmp/orph
+ fi
+ rm /tmp/chkpkgs
+exit 0
+}
+
+
# xHTML packages list header.
xhtml_header()
{
@@ -1857,6 +1921,7 @@
do
grep
-qs ^$pkg$ $2-processed && continue
tazpkg
$COMMAND $pkg --list=$2 "$3" "$4" "$5"
+
echo
$pkg >> $LOCALSTATE/chosenpkg.lst
done
rm -f $2-processed ;;
add-flavor)
@@ -1968,6 +2033,7 @@
status
sed
-i "/ $PACKAGE-$VERSION$EXTRAVERSION$/d" \
$LOCALSTATE/installed.md5 2> /dev/null
+
sed
-i "/^$PACKAGE$/d" $LOCALSTATE/chosenpkg.lst
#
Log this activity
log
Removed
if
[ "$ALTERED" ]; then
@@ -2005,11 +2071,23 @@
done
fi
fi
+
if
[ `pidof tazpkg | wc -w` = "2" ]; then
+
eval_gettext "Check for orphaned
packages and delete them?"
+
echo -n " (`translate_querry
y`/`translate_querry
N`) ? "
+
read answer
+
if [ "$answer" = "$(translate_querry
y)" ]; then
+
unorphan
+
fi
+
fi
else
echo
""
eval_gettext
"Uninstallation of \$PACKAGE cancelled."; echo
+
eval_gettext
"Adding $PACKAGE to $LOCALSTATE/chosenpkg.lst."
+
echo
$PACKAGE >> $LOCALSTATE/chosenpkg.lst
fi
echo "" ;;
+
unorphan)
+
unorphan;;
extract)
# Extract .tazpkg cpio archive into
a directory.
check_for_package_on_cmdline
============================================================================

