#!/bin/sh

# dpkg-missing-files.sh - Find missing files owned by packages in Debian
# Copyright (C) 2008  Dominik George
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

if [ $1 = --quiet ]; then
 QUIET=1
else
 QUIET=0
fi

echo ">>> Dpkg missing files lister"
echo ">>> Copyright (c) 2008 by Dominik George"
echo ">>> USE AT YOUR OWN RISK !!!"
echo ""

echo "Checking software dependencies:"
echo ""
CMD_DPKG=`which dpkg`
CMD_AWK=`which awk`
CMD_CAT=`which cat`
CMD_LESS=`which less`
CMD_APT=`which aptitude`
CMD_TR=`which tr`
CMD_SED=`which sed`
CMD_CUT=`which cut`
CMD_GREP=`which grep`

missing=""

if [ "$CMD_DPKG" = "" ]; then
 echo "Can not find dpkg, please install package dpkg!"
 missing=" $missing dpkg"
fi

if [ "$CMD_AWK" = "" ]; then
 echo "Can not find awk, please install package gawk!"
 missing=" $missing gawk"
fi

if [ "$CMD_CAT" = "" ]; then
 echo "Can not find cat, please install package coreutils!"
 missing=" $missing coreutils"
fi

if [ "$CMD_LESS" = "" ]; then
 echo "Can not find less, please install package less!"
 missing=" $missing less"
fi

if [ "$CMD_APT" = "" ]; then
 echo "Can not find aptitude, please install package aptitude!"
 missing=" $missing aptitude"
fi

if [ "$CMD_TR" = "" ]; then
 echo "Can not find tr, please install package coreutils!"
 missing=" $missing coreutils"
fi

if [ "$CMD_SED" = "" ]; then
 echo "Can not find sed, please install package sed!"
 missing=" $missing sed"
fi

if [ "$CMD_CUT" = "" ]; then
 echo "Can not find cut, please install package coreutils!"
 missing=" $missing coreutils"
fi

if [ "$CMD_GREP" = "" ]; then
 echo "Can not find grep, please install package grep!"
 missing=" $missing grep"
fi

echo ""
if [ "$missing" != "" ]; then
 echo -n "Some required tools sem to be mising. Type YES to install them: "
 read CONFIRMATION
 if [ $CONFIRMATION = YES ]; then
  aptitude install $missing
 else
  echo "Install the following packages to make this script work: $missing"
  exit 1
 fi
fi

echo "All required tools seem to be available."
echo ""

echo -n "Removing possible old files ... "
rm .dmf-*
echo "done."

echo -n "Creating list of installed packages ... "
dpkg --get-selections | grep install | cut -f1 >.dmf-pkgs
echo "done."

echo -n "Creating list of expected files ... "
for pkg in `cat .dmf-pkgs`; do
 dpkg -L $pkg | grep "^\\/\\w" | grep -v \\* >>.dmf-files-pre
 if [ ! $QUIET ]; then echo -n "."; fi
done
echo " done."

echo -n "Removing duplicate entries ... "
awk '!x[$0]++' .dmf-files-pre >.dmf-files
echo "done."

echo -n "Checking each file and listing missing ones ... "
missing=0
for file in `cat .dmf-files`; do
 if [ -e $file ]; then
  if [ ! $QUIET ]; then echo -n "."; fi
 else
  if [ ! $QUIET ]; then echo -n "X"; fi
  echo $file >>.dmf-missing-files-pre
  echo `dpkg-query -S $file` | cut -d":" -f1 | sed "s/,/\\n/" >>.dmf-broken-pkgs-pre
  let missing=$missing+1
 fi
done
echo " done."

echo -n "Removing duplicate entries ... "
awk '!x[$0]++' .dmf-missing-files-pre >.dmf-missing-files
awk '!x[$0]++' .dmf-broken-pkgs-pre >.dmf-broken-pkgs
echo "done."

echo ""
if [ $missing -gt 0 ]; then
 echo "*** Found $missing missing files! ***"
 echo -n "Press enter to view list ..."
 read
 less .dmf-missing-files
 echo "Press enter to show list of packages to be reinstalled."
 echo -n "Feel free to edit the list at will ..."
 read
 less .dmf-broken-pkgs
 echo -n "If you want to reinstall the packages in question, type YES: "
 read CONFIRMATION

 if [ $CONFIRMATION = YES ]; then
  pkgs="`cat .dmf-broken-pkgs | tr '\n' ' '`"
  aptitude reinstall $pkgs
 fi
else
 echo "*** No missing files found! ***"
fi

echo "*** Finished! ***"
exit 0

