#!/bin/sh
# This script overwrites a target file/directory alternately
#+ with random bytes, then zeros before finally deleting it.
# After that, even examining the raw disk sectors
#+ will make it hard to reveal the original file data.
STARTPATH=$(pwd)
E_BADARGS=70 # Wrong Arguments
E_NOT_FOUND=71 # File not found
if [ -z "${1}" ] # No filename/path specified.
then
echo "Usage: `basename $0` path/filename"
exit $E_BADARGS
fi
file="${1}"
if [ ! -e "${file}" ]
then
echo "File \"${file}\" not found."
exit $E_NOT_FOUND
fi
if [ -n "$2" ] # Number of passes specified.
then
PASSES=$(echo $2 | sed -e 's/[^0-9]//g')
fi
if [ "$PASSES" -eq "" ]
then
PASSES=1 # Set default number of file-shredding passes.
fi
# If there's no /dev/zero, create one in /var/tmp.
if [ ! -e "/var/tmp/zero" ]
then
mknod /var/tmp/zero c 1 5
fi
# Wipe File
wipe_file () {
# restore filename
fn=$(echo "${1}" | sed -e s/":"/" "/g)
BLOCKSIZE=1 # I/O with /dev/urandom requires unit block size,
#+ otherwise you get weird results.
dirname=$(echo "${fn}" | sed 's,[^/]*$,,') # extract the dirname from a path
filename=$(echo "${fn}" | sed 's,.*/,,') # extract the filename from a path
cd "${dirname}"
flength=$(ls -l "${filename}" | tr -s ' ' '\n' | sed -n 5p) # Field 5 is file length.
pass_count=1
rpass_count=$2
echo -n "$2-Pass Wipe of File \"${filename}\": "
while [ "$pass_count" -le "$2" ]
do
if [ $pass_count -gt 1 -a $pass_count -le $2 ]
then
echo -n \>
fi
echo -n $rpass_count
busybox dd if=/dev/urandom of="${filename}" bs=$BLOCKSIZE count=$flength 2> /dev/null
# Fill with random bytes.
busybox dd if=/var/tmp/zero of="${filename}" bs=$BLOCKSIZE count=$flength 2> /dev/null
# Fill with zeros.
let "pass_count += 1"
let "rpass_count -= 1"
done
# Scramble Filename with pseudo random string
fnlength=$(echo ${#filename})
new_fn=$(echo $(busybox dd if=/dev/urandom count=500 bs=1 2>/dev/null | sed -e s/[^0-9A-Za-z]//g) | sed -e s/[^0-9A-Za-z]//g | sed -e "s/.*\(.\{$fnlength\}\)/\1/")
mv "${filename}" $new_fn
rm -f $new_fn # Finally, delete scrambled and wiped file.
cd "${STARTPATH}"
echo " Done!";
}
if [ -d "${file}" ]
then
echo Wiping, scrambling and removing files:
# wipe files in whole directory including subdirs
# find files and mask spaces
for ff in `find "${file}" -type f | sed -e s/" "/":"/g 2>/dev/null`
do
wipe_file $ff $PASSES "${STARTPATH}"
done
echo
echo Scrambling and removing directories:
i=0
#find files, mask spaces and reverse find output
for ff in `find "${file}" -type d | sed -e s/" "/":"/g | sed '1!G;h;$!d' 2>/dev/null`
do
# restore filename
fn=$(echo "${ff}" | sed -e s/":"/" "/g)
echo -n "${fn}"
let "i=i+1"
dirname=$(echo "${fn}" | sed 's,[^/]*$,,') # extract the dirname from a path
filename=$(echo "${fn}" | sed 's,.*/,,') # extract the filename from a path
if [ ! "${dirname}" == "" ]
then
cd "${dirname}"
fi
# Scramble Dirname with pseudo random string
fnlength=$(echo ${#filename})
new_fn=$(echo $(busybox dd if=/dev/urandom count=500 bs=1 2>/dev/null | sed -e s/[^0-9A-Za-z]//g) | sed -e s/[^0-9A-Za-z]//g | sed -e "s/.*\(.\{$fnlength\}\)/\1/")
mv "${filename}" $new_fn
rm -r $new_fn
cd "${STARTPATH}"
echo " "\> Done.
done
else
# wipe single file
wipe_file "${file}" $PASSES "${STARTPATH}"
fi
exit 0