#!/bin/sh

# Options are passed on to deborphan
# 
# Orphaner is a neat frontend for deborphan displaying a list
# of orphaned packages with dialog or whiptail. Packages may be
# selected for removal with apt-get which is then called to do the
# work. After removal a new list of orphaned packages is gathered
# from deborphan. The program ends when either `Cancel' is pressed
# or no package is marked for removal.
#
# (c) 2000 Goswin Brederlow <goswin.brederlow@student.uni-tuebingen.de>
# (c) 2000 Peter Palfrader <peter@palfrader.org>
#
# This program is dual licensed either unter the GNU GPL as published
# by the Free Software Foundation; either version 2, or (at your option)
# any later version,
# _OR_ (at your opinion)
# the Artistic license (under which deborphan itself is distributed).
#
# The full text of both can be found in /usr/share/common-licenses on
# Debian systems. If you have problems obtaining the files please
# write to the authors.

set -e

OPTIONS=$@
VALIDOPTIONS='^-([aDHns]|-fake-dev|-nice-mode|-all-packages|-priority(.+)|p(.+)|-show-section|-force-hold)[[:space:]]$'
VALIDKEEPOPTIONS='^-([aDHns]|-guess-(dev|perl|section|debug|all)|-nice-mode|-all-packages|-priority(.+)|p(.+)|-show-section|-force-hold)[[:space:]]$'

if [ -x /usr/bin/dialog ]; then
  DIALOG=/usr/bin/dialog
elif [ -x /usr/local/bin/dialog ]; then
  DIALOG=/usr/local/bin/dialog
elif [ -x /usr/bin/whiptail ]; then
  DIALOG=/usr/bin/whiptail
elif [ -x /usr/local/bin/whiptail ]; then
  DIALOG=/usr/local/bin/whiptail
else
  echo "$0: You need dialog or whiptail to run this frontend." >&2
  exit 1
fi

if echo `deborphan -h` | grep 'Do not read debfoster' >/dev/null 2>&1; then
  nodf="--df-keep"
else
  nodf=""
fi

printhelp(){
  echo "Usage: $0 [OPTIONS]"
  echo
  echo "See orphaner(8) and deborphan(1) for a list of valid options."
  exit 0
}

editkeepers() {
  for each in $OPTIONS; do
    if [ "$SKIPONE" = "1" ]; then
      SKIPONE=0;
    elif [ " $each" = " --keep-file" -o " $each" = " -k" ]; then
      SKIPONE=1;
    elif [ " $each" = " --status-file" -o " $each" = " -f" ]; then
      SKIPONE=1;
    elif ! echo "$each " | egrep $VALIDKEEPOPTIONS >/dev/null; then
      case "$each" in
        --status-file* | -f* | --keep-file* | -k*)
          ;;
        *)
          echo "$0: Invalid option: $each." >&2
          exit 1
          ;;
      esac;
    fi
  done

    ORPHANED=`keeping_list $OPTIONS | sort`;
    # insert clever error handling

    if [ "$ORPHANED" != "" ]; then
      PACKAGES=`$DIALOG \
	--backtitle "Orphaner V1.1" \
	--separate-output \
	--title "Orphaner V1.1" \
	--checklist "Select Packages that should never be recommended for removal in deborphan:" \
	18 70 11 \
	$ORPHANED \
	2>&1 >/dev/tty` || true
  
      if [ ! -z "`deborphan ${nodf} -L $@`" ]; then
        deborphan ${nodf} -L $@ | xargs deborphan -R $@
      fi
      if [ ! -z "$PACKAGES" ]; then
        deborphan -A $@ $PACKAGES
      fi
    fi
  exit 0;
}

keeping_list() {
 (
  (deborphan -a $@ || echo "ERROR" ) \
   | while read SECTION PACKAGE; do 
       echo $PACKAGE $SECTION off
     done;
  (deborphan -L $@ 2>/dev/null|| echo "ERROR" ) \
   | while read PACKAGE; do 
       echo $PACKAGE "." on
     done;
 ) | sort;
};

deborphan_list() {
  (deborphan -s $@ || echo "ERROR") \
   | while read SECTION PACKAGE; do 
       echo $PACKAGE $SECTION off
     done
}

doorphans() {
  # Check options
  for each in $OPTIONS; do
    if [ "$SKIPONE" = "1" ]; then
      SKIPONE=0;
    elif [ " $each" = " --status-file" -o " $each" = " -f" ]; then
      SKIPONE=1;
    elif ! echo "$each " | egrep $VALIDOPTIONS >/dev/null; then
      case "$each" in
        --status-file* | -f*)
          ;;
        *)
          echo "$0: Invalid option: $each." >&2
          exit 1
          ;;
      esac;
    fi
  done

  while [ 1 ]; do
    ORPHANED=`deborphan_list $OPTIONS | sort`;
    if [ "$ORPHANED" = "ERROR off" ] ; then
      exit 1
    fi

    if [ "$ORPHANED" != "" ]; then
      PACKAGES=`$DIALOG \
	--backtitle "Orphaner V1.1" \
	--separate-output \
	--title "Orphaner V1.1" \
	--checklist "Select Packages for removal or cancel to quit:" \
	18 70 11 \
	$ORPHANED \
	2>&1 >/dev/tty` || true
  
      ERROR=$?

      if [ $ERROR = 0 -a "$PACKAGES" != "" ]; then
        clear;
        echo "Removing $PACKAGES..."
        apt-get -u remove $PACKAGES
      else
        exit 0;
      fi
    else
      $DIALOG \
	--backtitle "Orphaner V1.1" \
	--title "Orphaner V1.1" \
    	--msgbox "No orphaned packages found." \
	18 70
      exit 0;
    fi
  done
  exit 0;
}



# Plea for help?
for each in $OPTIONS; do
  if [ " $each" = " --help" -o " $each" = " -h" ]; then
    printhelp;
  fi
done

case $0 in
  *orphaner)
    doorphans;
    ;;
  *editkeep)
    editkeepers;
    ;;
  *)
    printhelp;
    ;;
esac
