Home About BC DR HA Support Training Download
You are here: Home/ Downloads/ Scripts/ Korn/ Please Login or Register

-
Current Location
-

js
  Downloads
    Scripts
      Korn



-
 Mt Xia Inc.
-
BOOK:Advanced Shell Scripting



 Join our LinkedIn Group
AIX Advanced Technical Experts
Contract Opportunities

www.LinkedIn.com
-
 Train By Tweet
Training courses Tweet By Tweet
Various Subjects and Products
TrainByTweet.com


AIX Admin Methodology
Global Consolidation Project
All AIX admins should join
www.aixexpert.com
-

digg Digg this page
del.icio.us Post to del.icio.us
Slashdot Slashdot it!
The script "dodwipe_k93" will perform a DoD style disk wipe of a file, logical volume, or disk partition. It performs 3 passes, first pass fills the space with zero's using an octal 0 character, second pass fills the space with one's using an octal 377 character, and the third pass fills the space with random bits.


#!/usr/bin/ksh93
################################################################
function usagemsg_dodwipe_k93 {
  print "
Program: dodwipe_k93

This script will perform a DoD style disk wipe of a file, logical
volume, or disk partition. It performs 3 passes, first pass fills the
space with zero's using an octal 0 character, second pass fills the
space with one's using an octal 377 character, and the third pass fills
the space with random bits.

Usage: ${1##*/} [-?vV] [-w] [-1|-2|-3] -f fileName | -l lvName | -p pvName

  Where:
    -f fileName = full path file name of a file to wipe clean (/home/username/filename)
    -l lvName   = full path file name of a logical volume to wipe clean (/dev/vgName/lvName)
    -p pvName   = full path file name of a physical volume to wipe clean (/dev/rdsk/sdx#)
    -w          = turn off warning message and confirmation prompt
    -1          = Do NOT perform Pass 1: Do NOT overwrite space with zero's (0)
    -2          = Do NOT perform Pass 2: Do NOT overwrite space with one's  (1)
    -3          = Do NOT perform Pass 3: Do NOT overwrite space with random bits
    -v = Verbose mode - displays dodwipe_k93 function info
    -V = Very Verbose Mode - debug output displayed
    -? = Help - display this message

Author: Dana French (dfrench@mtxia.com)
Copyright 2014, All Rights Reserved

\"AutoContent\" enabled
"
}
################################################################
#### 
#### Description:
#### 
#### This script will perform a DoD style disk wipe of a file, logical
#### volume, or disk partition. It performs 3 passes, first pass fills the
#### space with zero's using an octal 0 character, second pass fills the
#### space with one's using an octal 377 character, and the third pass fills
#### the space with random bits.
#### 
#### Assumptions:
#### 
#### This script assumes the existance of /dev/zero to generate continuous
#### stream of 0's. If /dev/zero does not exist, this script will generate
#### it's own continuous stream of zero's or one's, but it takes much longer
#### to run.
#### 
#### Dependencies:
#### 
#### This script is dependent upon the Unix utility "dd" and uses it to
#### overwrite logical volumes and physical volumes.
#### 
#### Products:
#### 
#### The product of this shell script are wiped clean and overwritten files,
#### logical volumes and physical volumes. The result is NOT a newly
#### initialize file, logical volume, or physical volume. The result is a
#### file, LV, or PV where every bit has been overwritten multiple times,
#### then every byte is overwritten with a random set of bits.
#### 
#### Configured Usage:
#### 
#### This shell script can be executed as a standalone script, or included in
#### a function library to be referenced and used by other shell scripts.
#### 
#### Details:
#### 
################################################################
configure_dodwipe_k93()
{
#### 
#### Notice this function is a POSIX function so that it can see local
#### and global variables from calling functions and scripts.
#### 
#### Configuration parameters can be stored in a file and
#### this script can be dynamically reconfigured by sending
#### the running script a HUP signal using the kill command.
#### 
#### Configuration variables can be defined in the configuration file using
#### the same syntax as defining a shell variable, e.g.: VARIABLE="value"

  CFILE=~/.dodwipe_k93.conf

  (( VERBOSE == TRUE )) && print -- "# Configuration File: ${CFILE}"

  if [[ -f ${CFILE} ]]
  then
      (( VERBOSE == TRUE )) && cat ${CFILE}
      . ${CFILE}
  fi

  return 0
}  
################################################################
function dodwipe_k93 {
  typeset VERSION="1.0"
  typeset TRUE="1"
  typeset FALSE="0"
  typeset VERBOSE="${FALSE}"
  typeset VERYVERB="${FALSE}"
  typeset FILETOGGLE="${FALSE}"
  typeset FINAME=""
  typeset LVTOGGLE="${FALSE}"
  typeset LVNAME=""
  typeset PVTOGGLE="${FALSE}"
  typeset PVNAME=""
  typeset WARNTOGGLE="${TRUE}"
  typeset P1TOGGLE="${TRUE}"
  typeset P2TOGGLE="${TRUE}"
  typeset P3TOGGLE="${TRUE}"
  typeset BSIZE="1024"
  typeset CFILE
  typeset TFILE
  typeset BLOCK
  typeset SKIP
  typeset BCNT
  typeset ANS
  typeset LV
  typeset PV
  typeset OF
  typeset R
  typeset i

#### 
#### Set up a trap of the HUP signal to cause this script
#### to dynamically configure or reconfigure itself upon
#### receipt of the HUP signal.

  trap "configure_dodwipe_k93 ${0}" HUP

#### Read the configuration file and initialize variables by
#### sending this script a HUP signal

  kill -HUP ${$}

#### Process the command line options and arguments.

  while getopts ":vVw123f:l:p:" OPTION
  do
      case "${OPTION}" in
          'f') FITOGGLE="${TRUE}"
               FINAME="${OPTARG}";;

          'l') LVTOGGLE="${TRUE}"
               LVNAME="${OPTARG}";;

          'p') PVTOGGLE="${TRUE}"
               PVNAME="${OPTARG}";;

          'w') WARNTOGGLE="${FALSE}";;

          '1') P1TOGGLE="${FALSE}"
               P2TOGGLE="${FALSE}"
               P3TOGGLE="${FALSE}";;

          '2') P2TOGGLE="${FALSE}"
               P3TOGGLE="${FALSE}";;

          '3') P3TOGGLE="${FALSE}";;

          'v') VERBOSE="${TRUE}";;
          'V') VERYVERB="${TRUE}";;
          '?') usagemsg_dodwipe_k93 "${0}" && return 1 ;;
          ':') usagemsg_dodwipe_k93 "${0}" && return 1 ;;
          '#') usagemsg_dodwipe_k93 "${0}" && return 1 ;;
      esac
  done
   
  shift $(( ${OPTIND} - 1 ))
  
  (( VERYVERB == TRUE )) && set -x
  (( VERYVERB == TRUE )) && VERBOSE="${TRUE}"
  (( VERBOSE  == TRUE )) && print -u 2 "# Program Name...: ${0}"
  (( VERBOSE  == TRUE )) && print -u 2 "# Version........: ${VERSION}"
  (( VERBOSE  == TRUE )) && print -u 2 "# Block Size.....: ${BSIZE}"

  (( VERBOSE  == TRUE )) && (( P1TOGGLE == TRUE  )) && print -u 2 "# PASS 1 Request.: TRUE"
  (( VERBOSE  == TRUE )) && (( P2TOGGLE == TRUE  )) && print -u 2 "# PASS 2 Request.: TRUE"
  (( VERBOSE  == TRUE )) && (( P3TOGGLE == TRUE  )) && print -u 2 "# PASS 3 Request.: TRUE"

  (( VERBOSE  == TRUE )) && (( P1TOGGLE == FALSE )) && print -u 2 "# PASS 1 Request.: FALSE"
  (( VERBOSE  == TRUE )) && (( P2TOGGLE == FALSE )) && print -u 2 "# PASS 2 Request.: FALSE"
  (( VERBOSE  == TRUE )) && (( P3TOGGLE == FALSE )) && print -u 2 "# PASS 3 Request.: FALSE"

################################################################

#### 
#### Check the command line options and arguments and verify that required
#### information has been provided, and that it is of the correct type, and
#### that it makes sense. If anything is incorrect, then return from this
#### function and display the usage message by trapping the exit.

  trap "usagemsg_dodwipe_k93 ${0}" EXIT

#### 
#### Check the file name, logical volume, and physical volume toggle
#### variables. If they are all set to FALSE, issue an error message and
#### return from the script. Tell the user they must specify at least one of
#### these.

    if (( FITOGGLE == FALSE )) &&
       (( LVTOGGLE == FALSE )) &&
       (( PVTOGGLE == FALSE ))
    then
        print -u 2 -- "# SYNTAX ERROR: You must specify a file, logical volume, or physical partition."
        return 10
    fi

#### 
#### If the user specified a filename to wipe on the command line, check to see if
#### it is a regular file. If not, issue an error message and return from the script.

    if (( FITOGGLE == TRUE ))
    then
        OF="${FINAME}"
        if [[ ! -f "${FINAME}" ]]
        then
            print -u 2 -- "# $( ls -l ${FINAME} )"
            print -u 2 -- "# ERROR: The file name specified \"${FINAME}\" is not a regular file."
            return 11
        fi
        (( VERBOSE  == TRUE )) && print -u 2 "# File Name......: ${FINAME}"
    fi

#### 
#### If the user specified a logical volume to wipe on the command line, check to see if
#### it is a block device file. If not, issue an error message and return from the script.

    if (( LVTOGGLE == TRUE )) && OF="${LVNAME}"
    then
        OF="${LVNAME}"
        if [[ ! -b "${LVNAME}" ]]
        then
            print -u 2 -- "# $( ls -l ${LVNAME} )"
            print -u 2 -- "# ERROR: The Logical Volume name specified \"${LVNAME}\" is not a block device."
            return 12
        fi
        (( VERBOSE  == TRUE )) && print -u 2 "# Logical Volume.: ${LVNAME}"
    fi

#### 
#### If the user specified a logical volume to wipe on the command line, check to see if
#### it is a block device file. If not, issue an error message and return from the script.

    if (( PVTOGGLE == TRUE )) && OF="${PVNAME}"
    then
        OF="${PVNAME}"
        if [[ ! -c "${PVNAME}" ]]
        then
            print -u 2 -- "# $( ls -l ${PVNAME} )"
            print -u 2 -- "# ERROR: The Physical Volume name specified \"${PVNAME}\" is not a character device."
            return 13
        fi
        (( VERBOSE  == TRUE )) && print -u 2 "# Physical Volume: ${PVNAME}"
    fi

#### 
#### Check the data wipe PASS toggles selected on the command line. If the
#### first data wipe pass is turned off, then return from the function and
#### inform the user that all data wipe passes are disabled. The first pass
#### is a requirement before other passes can be executed.

    if (( P1TOGGLE == FALSE ))
    then
        print -u 2 -- "# All data wipe passes are disabled."
        return 10
    fi

#### 
#### Check the data wipe PASS toggles selected on the command line. If the
#### second data wipe pass is false, but the third is true, then some sort of
#### error has occurred. Each pass must be executed in order, so it is not
#### allowed to run pass 1, and pass 3, but NOT pass 2.

    if (( P2TOGGLE == FALSE )) &&
       (( P3TOGGLE == TRUE  ))
    then
        print -u 2 -- "# ERROR: You must first execute PASS 2 before you can execute PASS 3"
        return 10
    fi

    if [[ ! -c /dev/zero ]]
    then
        print -u 2 -- "# ERROR: The ZERO device /dev/zero must exist as a character device"
        return 15
    fi

  trap "-" EXIT
  
################################################################

#### 
#### Warn the user that they are about to wipe clean whatever storage device
#### they specified, ask them to verify they really want to do this.  If the
#### user specified the "-w" command line option, do not ask, just do it.

  if (( WARNTOGGLE == TRUE ))
  then
      print    -- "# The storage area \"${OF}\" is about to be wiped clean and overwritten."
      print -n -- "# Are you sure you want to wipe clean/overwrite \"${OF}\" (y/N)? "
      read ANS

      if [[ "_${ANS}" != _[Yy] ]]
      then
          print "# You did not answer \"Y\" or \"y\", exiting program."
          return 99
      fi
  fi

################################################################
#### Pass 1: fill the space with zero's (\0)

if (( P1TOGGLE == TRUE ))
then

  if (( FITOGGLE == TRUE ))
  then
      (( VERBOSE  == TRUE )) && print -u 2 -- "# $( ls -l ${FINAME} )"
      (( VERBOSE  == TRUE )) && print -u 2 -- "# Pass 1 (0's)...: Overwritting every bit with zero's"
      TFILE="/tmp/tmp${$}.out"
      if cp "${FINAME}" "${TFILE}"
      then
          tr '[[:print:][:cntrl:][:xdigit:][:space:]]' '\0' < "${TFILE}" > "${FINAME}"
      fi
      [[ -f "${TFILE}" ]] && rm -f "${TFILE}"
  fi

#### 
#### Check to see if the /dev/zero device exists, if so use it to generate a
#### continuous stream of zeros to overwrite all the bits of the targeted
#### storage space.

  if [[ -c /dev/zero ]]
  then

      if (( LVTOGGLE == TRUE ))
      then
          (( VERBOSE  == TRUE )) && print -u 2 "# Pass 1 (0's)...: /dev/zero"
          dd bs=${BSIZE} of="${LVNAME}" if=/dev/zero
      fi

      if (( PVTOGGLE == TRUE ))
      then
          (( VERBOSE  == TRUE )) && print -u 2 "# Pass 1 (0's)...: /dev/zero"
          dd bs=${BSIZE} of="${PVNAME}" if=/dev/zero
      fi

  else

#### 
#### This "else" code is not currently active because /dev/zero is required to exist

      (( VERBOSE  == TRUE )) && print -u 2 "# ZERO Device....: none"

      if (( LVTOGGLE == TRUE )) ||
         (( PVTOGGLE == TRUE ))
      then

          (( VERBOSE  == TRUE )) && print -u 2 "# Pass 1 (0's)...: while looping"

          BLOCK=""
          for (( i=0; i<${BSIZE}; ++i ))
          do
              R=$'\0'
              BLOCK="${BLOCK}${R}"
          done

#           SKIP=0
#           while print -- "${BLOCK}" | dd bs=${BSIZE} of="${OF}" count=1 skip=${SKIP}
#           do
#               (( ++SKIP ))
#           done
      fi

  fi

fi

################################################################
#### Pass 2: fill the space with one's (\377)

if (( P2TOGGLE == TRUE ))
then

  if (( FITOGGLE == TRUE ))
  then
      (( VERBOSE  == TRUE )) && print -u 2 -- "# Pass 2 (1's)...: Overwritting every bit with one's"
      TFILE="/tmp/tmp${$}.out"
      if cp "${FINAME}" "${TFILE}"
      then
          tr '\0' '\377' < "${TFILE}" > "${FINAME}"
      fi
      [[ -f "${TFILE}" ]] && rm -f "${TFILE}"
  fi

#### 
#### Check to see if the /dev/zero device exists, if so use it to generate a
#### continuous stream of zeros, then translate those zeros to one's and
#### overwrite all the bits of the targeted storage space.

  if [[ -c /dev/zero ]]
  then

      if (( LVTOGGLE == TRUE ))
      then
          (( VERBOSE  == TRUE )) && print -u 2 "# Pass 2 (1's)...: tr conv < /dev/zero"
          tr '\0' '\377' < /dev/zero | dd bs=${BSIZE} of="${LV}"
      fi

      if (( PVTOGGLE == TRUE ))
      then
          (( VERBOSE  == TRUE )) && print -u 2 "# Pass 2 (1's)...: tr conv < /dev/zero"
          tr '\0' '\377' < /dev/zero | dd bs=${BSIZE} of="${PV}"
      fi

  else

#### 
#### This "else" code is not currently active because /dev/zero is required to exist

      (( VERBOSE  == TRUE )) && print -u 2 "# ZERO Device....: none"

      if (( LVTOGGLE == TRUE )) ||
         (( PVTOGGLE == TRUE ))
      then

          (( VERBOSE  == TRUE )) && print -u 2 "# Pass 2 (1's)...: while looping"

          BLOCK=""
          for (( i=0; i<${BSIZE}; ++i ))
          do
              R=$'\377'
              BLOCK="${BLOCK}${R}"
          done

#           SKIP=0
#           while print -- "${BLOCK}" | dd bs=${BSIZE} of="${OF}" count=1 skip=${SKIP}
#           do
#               (( ++SKIP ))
#           done
      fi
  fi

fi

################################################################
#### Pass 3: fill the space with random bits (( RANDOM % 377 ))

if (( P3TOGGLE == TRUE ))
then

  if (( FITOGGLE == TRUE ))
  then
      (( VERBOSE  == TRUE )) && print -u 2 "# Pass 3 (random): Overwritting every byte with random bits"
      TFILE="/tmp/tmp${$}.out"
      if cp "${FINAME}" "${TFILE}"
      then
          BCNT=0
          > "${FINAME}"
          tr '\377' '\n' < "${TFILE}" | while read -- C
          do
              R=$( printf "%o" $((  ${RANDOM} % 377 )) )
              print -n -- "\\0${R}" >> "${FINAME}"

              (( ++BCNT ))
              if (( VERBOSE  == TRUE ))
              then
                  if (( BCNT >= BSIZE ))
                  then
                      print -u 2 -n -- "."
                      BCNT=0
                  fi
              fi

          done
          (( VERBOSE  == TRUE )) && print -u 2 -- "."
      fi
      [[ -f "${TFILE}" ]] && rm -f "${TFILE}"
      (( VERBOSE  == TRUE )) && print -u 2 -- "# $( ls -l ${FINAME} )"
  fi

  if (( LVTOGGLE == TRUE )) ||
     (( PVTOGGLE == TRUE ))
  then
      (( VERBOSE  == TRUE )) && print -u 2 "# Pass 3 (random): while looping"

      SKIP=0  
      while :;
      do
          BLOCK=""
          for (( i=0; i<${BSIZE}; ++i ))
          do
              R=$( printf "%o" $((  ${RANDOM} % 377 )) )
              BLOCK="${BLOCK}\\0${R}"
          done
          if ! print -- "${BLOCK}" | dd bs=${BSIZE} of="${OF}" count=1 skip=${SKIP}
          then
              break
          fi
          (( ++SKIP ))
      done
  fi

fi

  trap "-" HUP

  return 0
}
################################################################

dodwipe_k93 "${@}"

-
DoD style storage wipe
-