#!/bin/bash
# upkg-check
#
# compare contents of the digests with the really existing files
#
# Copyright (C) 2004-2005 Raffaele Sandrini, Jürg Billeter
#
# This file is part of Upkg (http://www.upkg.org).
#
# Upkg is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# Upkg is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Upkg; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# Authors:
#   Raffaele Sandrini <rasa at paldo dot org>
#   Jürg Billeter <juerg at paldo dot org>


function upkgcat ()
{
	for f in "$@"; do
		if [ -e "$f.zst" ]; then
			zstdcat "$f.zst"
		elif [ -e "$f.xz" ]; then
			xzcat "$f.xz"
		elif [ -e "$f.bz2" ]; then
			bzcat "$f.bz2"
		elif [ -e "$f.gz" ]; then
			zcat "$f.gz"
		elif [ -e "$f" ]; then
			cat "$f"
		fi
	done
}

set -- $(getopt -u --longoptions unreferenced "" $@)

unreferenced=0
pkg=system

for arg in $*
do
	case $arg in
		--unreferenced)
			unreferenced=1
			shift
			;;
		--)
			shift
			break
			;;
	esac
done

if [ $# -ge 1 ]
then
	pkg=$1
	shift
fi

if [ $# -gt 0 ] || ( [ $unreferenced = 1 ] && [ "$pkg" != "system" ] )
then
	echo "Usage: $0 [--unreferenced] [PACKAGE]"
	exit 1
fi

if [ "$pkg" = "system" ] ; then
	PACKAGES="/var/lib/upkg/packages/*.info"
elif [ -L /var/lib/upkg/packages/$pkg ] ; then
	PACKAGES=/var/lib/upkg/packages/$(readlink /var/lib/upkg/packages/$pkg).info
else
	echo "Package $pkg could not be found" >&2
	exit 1
fi

for package_file in $PACKAGES ; do
	package=$(basename ${package_file/.info/})
	[ ! -e /var/lib/upkg/files/$package.digest.* ] || upkgcat /var/lib/upkg/files/$package.digest | md5sum --check 2>&1 | grep -v OK > /tmp/upkg-files-$package
	upkgcat /var/lib/upkg/files/$package.dirs | xargs -i -n 1 sh -c "[ -d {} ] || echo {}: No such directory" >> /tmp/upkg-files-$package
	upkgcat /var/lib/upkg/files/$package.links | (
		while read target link
		do
			if [ -L "$link" ]
			then
				[ "$(readlink $link)" = "$target" ] || echo "bad link $link"
			else
				echo "missing link $link"
			fi
		done
	) >> /tmp/upkg-files-$package
	if [ "$pkg" != "system" ] || [ "$(cat /tmp/upkg-files-$package)" != "" ]
	then
		echo $package
		echo ----
		cat /tmp/upkg-files-$package
		echo
	fi
	rm /tmp/upkg-files-$package
done

if [ $unreferenced = 1 ]
then
	# Check for not recorded files and directories
	echo "Unreferenced files"
	echo "------------------"
	zcat /var/lib/upkg/files/*.{digest,links,config}.gz 2>/dev/null | sed -e 's/  / /' | ( zcat /var/lib/upkg/files/*.dirs.gz 2>/dev/null ; cut -d ' ' -f 2 ) > /tmp/upkg-files-gz
	bzcat /var/lib/upkg/files/*.{digest,links,config}.bz2 2>/dev/null | sed -e 's/  / /' | ( bzcat /var/lib/upkg/files/*.dirs.bz2 2>/dev/null ; cut -d ' ' -f 2 ) > /tmp/upkg-files-bz2
	xzcat /var/lib/upkg/files/*.{digest,links,config}.xz 2>/dev/null | sed -e 's/  / /' | ( xzcat /var/lib/upkg/files/*.dirs.xz 2>/dev/null ; cut -d ' ' -f 2 ) > /tmp/upkg-files-xz
	zstdcat /var/lib/upkg/files/*.{digest,links,config}.zst 2>/dev/null | sed -e 's/  / /' | ( zstdcat /var/lib/upkg/files/*.dirs.zst 2>/dev/null ; cut -d ' ' -f 2 ) | > /tmp/upkg-files-zst
	sort /tmp/upkg-files-{gz,bz2,xz,zstd} > /tmp/upkg-files
	find /bin /boot /lib /sbin /usr -xdev | sort | diff /tmp/upkg-files - | grep ^\> | cut -b 3- | sed -e 's/^/unreferenced file /'
	rm /tmp/upkg-files-{gz,bz2,xz,zstd}
fi
