#!/bin/sh
#
# Copyright (C) 2012 Colomban Wendling <ban@herbesfolles.org>
#
# 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/>.
#

# drop-in replacement and wrapper script for sfill to work around its lack of
# support for file size limits.

. gettext.sh

export TEXTDOMAIN="libgsecuredelete"
export TEXTDOMAINDIR="/usr/share/locale"


SRM="/usr/bin/srm"
SFILL="/usr/bin/sfill"

OPT_f=
OPT_i=
OPT_I=
OPT_l=
OPT_v=
OPT_z=

MISSING_ROOT=0


# die [MESSAGE]
die() {
  echo "$@" >&2
  exit 1
}


# check we have the required tools
which "$SRM" >/dev/null || \
  die "$(eval_gettext '$SRM: command not found. ')" \
      "$(gettext "Please make sure secure-delete is correctly installed.")"
which "$SFILL" >/dev/null || \
  die "$(eval_gettext '$SFILL: command not found. ')" \
      "$(gettext "Please make sure secure-delete is correctly installed.")"


# parse arguments
while getopts 'fiIlvz' o; do
  case "$o" in
    f) OPT_f=-f;;
    i) OPT_i=-i;;
    I) OPT_I=-I;;
    l) OPT_l="$OPT_l -l";;
    v) OPT_v=-v;;
    z) OPT_z=-z;;
  esac
done
shift $(expr $OPTIND - 1)
[ $# -eq 1 ] || die "wrong arguments"


# do our work in a temp directory so in the worst case if we fail to cleanup we
# don't leave the user with tons of temp files but a single directory
dir=$(mktemp -d --tmpdir="$1") || die "$(gettext "failed to create temporary directory")"

cleanup() {
  echo "$(gettext 'Terminated by signal. Clean exit.')" >&2
  rm -rf '$dir'
  
  exit 1
}

# progress_step
progress_step_STEP=0
progress_step() {
  if [ -n $OPT_v ]; then
    case "$(echo $OPT_l | wc -w)" in
      0)
        echo '*******************';;
      1)
        echo '*';;
      *)
        [ "$progress_step_STEP" -gt 0 ] && echo '*'
        ;;
    esac
    progress_step_STEP=1
  fi
}


trap "rm -rf '$dir'" EXIT
trap cleanup INT QUIT TERM


if [ `whoami` != root ]; then
  # before trying to become root, check whether the FS on which we will work
  # actually requires root privileges
  fstype=$(df -T "$dir" | tail -n1 | tr -s ' ' | cut -d' ' -f 2)
  case $fstype in
    msdos|umsdos|vfat) # no need to be root for those FS
      [ -n $OPT_v ] || echo "$(eval_gettext 'File system type is $fstype, no need to be root')"
      ;;
    
    *) # guess we better be root for all other FS types, so try to become root!
      if which pkexec >/dev/null; then
        pkexec --user root "$0" $OPT_f $OPT_i $OPT_I $OPT_l $OPT_v $OPT_z "$dir"
        code=$?
        if [ $code -ne 126 -a $code -ne 127 ]; then
          # if becoming root succeeded, abort this instance
          exit $code
        fi
      fi
      
      echo "$(gettext "Continuing without root privileges, wipe may be incomplete")" >&2
      MISSING_ROOT=1
      ;;
  esac
fi


# fill disk space, workaround for file size limit
if [ -z "$OPT_i" ]; then
  input=/dev/zero
  [ -r "$input" ] || die "$input is not readable"
  
  while [ 1 ]; do
    file=$(mktemp --tmpdir="$dir") || die "failed to create temp file"
    
    dd if="$input" of="$file" bs=8M conv=fdatasync 2>&1
    
    # if the file we tried to create has size 0, guess there's actually no
    # space left on device
    size=$(stat -c '%s' "$file") || die "failed to stat file '$f'"
    [ "$size" = 0 ] && break
  done
  sync
  progress_step
fi

# launch sfill as wanted, now there is not much free space
sfill_v=$OPT_v
# don't report progress if we're also filling disk space
[ -z "$OPT_i" ] && sfill_v=
"$SFILL" $OPT_f $OPT_i $OPT_I $OPT_l $sfill_v $OPT_z "$dir"

# and finally securely remove temporary files created earlier
if [ -z "$OPT_i" ]; then
  "$SRM" -r $OPT_f $OPT_l $OPT_z "$dir"
  
  progress_step
fi


# if we missed root permissions, report this as a special failure (42)
if [ $MISSING_ROOT -ne 0 ]; then
  echo "$(gettext "Wipe succeeded but may have been incomplete due to missing root privileges.")">&2
  exit 42
fi
