"Fossies" - the Fresh Open Source Software Archive

Member "ext3undel-0.1.6/ralf" (20 Jul 2008, 18192 Bytes) of package /linux/misc/old/ext3undel-0.1.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Bash source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #!/bin/bash
    2 #==============================================================================
    3 # R.A.L.F. (Recover A Lost File)         (c) 2008 by Itzchak Rehberg & IzzySoft
    4 # Syntax: $0 <filename>
    5 #------------------------------------------------------------------------------
    6 # Ralf is just a shell script that automates the manual steps required to
    7 # restore a (accidentally) deleted file from a modern ext2/ext3 file system.
    8 # For other *nix file systems there may be easier solutions - though Rolf
    9 # should also be able to handle them, as long as they work with iNodes.
   10 #------------------------------------------------------------------------------
   11 # Requires: photorec OR foremost
   12 # Requires: sleuthkit (at least fsstat, dls and fls from that package)
   13 #==============================================================================
   14 # $Id: ralf 41 2008-07-20 17:35:30Z izzy $
   15 
   16 #==========================================================[ Configuration ]===
   17 # for explanation of the options, see ext3undelrc
   18 #-------------------------------------------------[ File Systems and Paths ]---
   19 TMPDIR=/tmp
   20 MNTFILE=${TMPDIR}/undel_FIFO
   21 TMP=$TMPDIR/undel_FIFO2$$
   22 RESTDIR=recover
   23 
   24 #--------------------------------------------------------[ runtime options ]---
   25 SILENT=0
   26 DEBUG=0
   27 
   28 #-------------------------------------------------------[ foremost options ]---
   29 FILESPEC="everything"
   30 USETS=0
   31 USEQUICK=1
   32 USEQUIET=1
   33 READONLY=0
   34 VERBOSE=1
   35 ALLHEAD=1
   36 
   37 #-------------------------------------------------------[ photorec options ]---
   38 WHOLESPACE=0
   39 
   40 RECOPROG=photorec
   41 
   42 #-----------------------------------------------[ Read configuration files ]---
   43 [ -e /etc/ext3undel/ext3undelrc ] && . /etc/ext3undel/ext3undelrc
   44 [ -e $HOME/.ext3undel/ext3undelrc ] && . $HOME/.ext3undel/ext3undelrc
   45 
   46 #===================================================[ Helper / SubRoutines ]===
   47 shopt -s extglob
   48 trap "cleanUp ; exit 2" 2 3 15
   49 #-----------------------------------[ Check whether we are running as root ]---
   50 function checkRoot() {
   51   local uid=`id -u`
   52   [ $uid -gt 0 ] && {
   53     echo "This script must be run as root (or at least with sudo)."
   54     exit 1
   55   }
   56 }
   57 
   58 #-------------------------------[ Make sure needed binaries exist in $PATH ]---
   59 function checkBins() {
   60   local fm=1
   61   [ "$RECOPROG" = "photorec" -a -z "`which photorec`" ] && RECOPROG=foremost
   62   [ "$RECOPROG" = "foremost" -a -z "`which foremost`" ] && {
   63     echo
   64     echo "Neither the 'photorec' nor the 'foremost' executable could be found"
   65     echo "in your \$PATH - but we need one of them. They usually ship in a"
   66     echo "package with the same name (i.e. 'photorec' or 'foremost')."
   67     echo
   68     fm=0
   69   }
   70   [ -z "`which fls`" ] && {
   71     echo
   72     echo "Could not find the 'fls' executable in your \$PATH. This is part of the"
   73     echo "sleuthkit package."
   74     echo
   75     fm=0
   76   }
   77   [ -z "`which fsstat`" ] && {
   78     echo
   79     echo "Could not find the 'fsstat' executable in your \$PATH. This is part of the"
   80     echo "sleuthkit package."
   81     echo
   82     fm=0
   83   }
   84   [ -z "`which dls`" ] && {
   85     echo
   86     echo "Could not find the 'dls' executable in your \$PATH. This is part of the"
   87     echo "sleuthkit package."
   88     echo
   89     fm=0
   90   }
   91   [ $fm -ne 1 ] && {
   92     echo
   93     echo "One or more of the essential tools required to recover your file cannot"
   94     echo "be found. Please make sure you have them installed, and they can be found"
   95     echo "in your \$PATH."
   96     echo
   97     exit 2
   98   }
   99 }
  100 
  101 #--------------------------------------------------[ Display help and exit ]---
  102 function syntax() {
  103   echo
  104   echo "Syntax:"
  105   echo "  ralf <filename> [options]"
  106   echo "where <filename> specifies the name of the file to restore - either"
  107   echo "relative to the current working directory, or with full (absolute) path."
  108   echo
  109   echo "Available options:"
  110   echo "+d / --debug    Enable Debug Output"
  111   echo "-d / --nodebug  Disable Debug Output"
  112   echo "+s / --silent   Make output less verbose"
  113   echo "-s / --nosilent Display progress messages"
  114   echo "--freespace Recover from free space only"
  115   echo "--wholespace    Recover from whole space"
  116   echo
  117   exit 0
  118 }
  119 
  120 #-------------------------------[ Remove leading and trailing white spaces ]---
  121 function trim() {
  122   echo "$1"|sed 's/^\s*//;s/\s*$//'
  123 }
  124 
  125 #---------------------------------------------[ Read a number (user input) ]---
  126 # $1: Prompt message
  127 # opt $2: Min
  128 # opt $3: Max
  129 function readnum() {
  130   read -p "$1" rd
  131   local tn=`echo $rd|sed 's/[0-9]//g'`
  132   local min=$2
  133   local max=$3
  134   [ -n "$tn" ] && {
  135     echo "Please enter only digits!"
  136     readnum "$1" "$2" "$3"
  137   }
  138   [ -z "$min" ] && min=0
  139   [ -z "$max" ] && max=99999999
  140   [ $rd -lt $min -o $rd -gt $max ] && {
  141     echo "Please enter a number between $2 and $3!"
  142     readnum "$1" "$2" "$3"
  143   }
  144 }
  145 
  146 #---------------------------------------------------------[ Read Y/N input ]---
  147 function readyn() {
  148   read -n 1 rd
  149   echo
  150   rd=`echo $rd|tr [:upper:] [:lower:]`
  151   if [ "$rd" = "y" -o "$rd" = "j" ]; then
  152     rd=1
  153   elif [ "$rd" = "n" ]; then
  154     rd=0
  155   else
  156     echo -n "Please enter 'y' for 'yes', 'n' for 'no' - or press Ctrl-C to abort: "
  157     readyn
  158   fi
  159 }
  160 
  161 #-------------------------------------------[ Select Destination directory ]---
  162 function selDest() {
  163   local rd
  164   echo
  165   echo "Please select the file system to store the recovered files to."
  166   echo "(This must be on a different device than you restore from)"
  167   echo
  168   printf "%2s| %-7s| %-15s| %-32s| %-16s\n" "ID" "Type" "Device" "MountPoint" "Size"
  169   echo "--+--------+----------------+---------------------------------+----------------"
  170   typeset -i i=0
  171   local uLINE=""
  172   local SKIP=1
  173   mkfifo $MNTFILE
  174   df -h -l -T >$MNTFILE &
  175   while read line; do
  176     [ $SKIP -eq 1 ] && { # skip the header
  177       SKIP=0
  178       continue
  179     }
  180     if [ -n "$(trim "$uLINE")" ]; then # wrapped line continued
  181       line="${uLINE} $line"
  182     else
  183       [ -z "$(trim "`echo $line|awk '{print $7}'`" )" ] && { # line wrapped?
  184         uLINE="$line"
  185     continue
  186       }
  187     fi
  188     uLINE=""
  189     if [[ "$line" == /dev* ]]; then # skip pseudo filesystems
  190       i+=1
  191       devs[$i]=`echo $line|awk '{print $1}'`
  192       [ "${devs[$i]}" != "$DEV" ] && echo "$i $line"|awk '{printf "%2d| %-7s| %-15s| %-32s| %-16s\n", $1, $3, $2, $8, $4 }'
  193       stores[$i]=`echo $line|awk '{print $7}'`
  194     fi
  195   done<$MNTFILE
  196   rm -f $MNTFILE
  197   readnum "Destination ID: " 1 $i
  198   if [ "${devs[$rd]}" = "$DEV" ]; then
  199     echo
  200     echo "Invalid selection: Source and Target file systems must not be identical!"
  201     echo "This way you may destroy your lost data permanently. Are you sure to"
  202     echo -n "proceed (y/n)? "
  203     readyn
  204     echo
  205     if [ $rd -eq 1 ]; then
  206       recoTo=${stores[$rd]}/$RESTDIR
  207     else
  208       li1 "Aborting on user request."
  209       cleanUp
  210       exit 0
  211     fi
  212   else
  213     STORETO=${stores[$rd]}
  214   fi
  215   echo
  216 }
  217 
  218 #--------------------------------------------------------[ Output progress ]---
  219 function li1() {
  220   [ $SILENT -eq 0 ] && echo "* $1"
  221 }
  222 
  223 #-----------------------------------------------[ Output debug information ]---
  224 function debugMsg() {
  225   [ $DEBUG -gt 0 ] && echo "# debug: $1"
  226 }
  227 
  228 #--------------------------------------------------------[ Verify filename ]---
  229 function fileName() {
  230   if [[ "$1" == /* ]]; then
  231     uFILE=$1
  232   else
  233     uFILE="`pwd`/$1"
  234   fi
  235   li1 "FileName set to '$uFILE'"
  236 }
  237 
  238 #-----------------------------------------------[ Select Source MountPoint ]---
  239 function selSrc() {
  240   local mid
  241   typeset -i i=0
  242   mounts[0]=""
  243   local uLINE=""
  244   local SKIP=1
  245   mkfifo $TMP
  246   mkfifo $MNTFILE
  247   df -h -l -T >$MNTFILE &
  248   while read line; do
  249     [ $SKIP -eq 1 ] && { # skip the header
  250       SKIP=0
  251       continue
  252     }
  253     if [ -n "$(trim "$uLINE")" ]; then # wrapped line continued
  254       line="${uLINE} $line"
  255     else
  256       [ -z "$(trim "`echo $line|awk '{print $7}'`" )" ] && { # line wrapped?
  257         uLINE="$line"
  258     continue
  259       }
  260     fi
  261     uLINE=""
  262     if [[ "$line" == /dev* ]]; then # skip pseudo filesystems
  263       echo $line|awk '{print $7}'>>$TMP &
  264       uDEV[$i]=`echo $line|awk '{print $1}'`
  265       uMOUNT[$i]=`echo $line|awk '{print $7}'`
  266       uFSTYPE[$i]=`echo $line|awk '{print $2}'`
  267       i+=1
  268     fi
  269   done<$MNTFILE
  270   sort -n -r <$TMP>$MNTFILE &
  271   while read line; do
  272     if [[ "$uFILE" == $line* ]]; then
  273       i=0
  274       while (( i < ${#uMOUNT[*]} )); do
  275         if [[ "$line" = "${uMOUNT[$i]}" ]]; then
  276           li1 "Selected file should be on device ${uDEV[$i]}, mounted to ${uMOUNT[$i]} (${uFSTYPE[$i]})."
  277       DEV=${uDEV[$i]}
  278       MNT=${uMOUNT[$i]}
  279       FSTYPE=${uFSTYPE[$i]}
  280       break 2
  281         fi
  282         i+=1
  283       done
  284     fi
  285   done <$MNTFILE
  286   rm -f $TMP
  287   rm -f $MNTFILE
  288   li1 "Evaluated '$MNT' as corresponding mount point, using '$FSTYPE' file system."
  289   [ "$FSTYPE" != "ext2" -a "$FSTYPE" != "ext3" ] && echo "! WARNING: This is not an ext2/ext3 file system, so our algorithm may fail!"
  290 }
  291 
  292 #--------------------------------------------[ Splitup filename for search ]---
  293 function splitFileName() {
  294   if [ "$MNT" = "/" ]; then
  295     SEARCH=${uFILE:1}
  296   else
  297     SEARCH=${uFILE#$MNT/*}
  298   fi
  299   li1 "Setting SearchString relative to mountpoint ('$SEARCH')"
  300   SEARCH=`echo "$SEARCH"|awk {'gsub("*",".*");gsub("?",".{1}");gsub("/","\\\/");print $0}'`
  301   li1 "Translating wildcards to RegExp ('$SEARCH')"
  302 }
  303 
  304 #-----------------------------------------------------[ Check for Symlinks ]---
  305 function symlinkCheck() {
  306   local left="$uFILE"
  307   local check=""
  308   while [ -n "$left" ]; do
  309     if [ -n "$right" ]; then
  310       right="${left##*/}/${right}"
  311     else
  312       right="${left##*/}"
  313     fi
  314     left="${left%/*}"
  315     [ -n "$left" ] && check=`readlink $left`
  316     [ -n "$check" ] && {
  317       uFILE="${check}/${right}"
  318       left="$uFILE"
  319       right=""
  320     }
  321   done
  322   li1 "Real filename: '$uFILE'"
  323 }
  324 
  325 #---------------------------------------------------[ Get PhotoRec Version ]---
  326 function photoRecVer() {
  327   local TMP="${TMPDIR}/undel_xFIFO.$$"
  328   mkfifo $TMP
  329   photorec --help>$TMP &
  330   while read line; do
  331     local ver=`echo $line|awk '{print $2}'`
  332     break
  333   done<$TMP
  334   pr_maj=${ver%.*}
  335   pr_min=${ver#*.}
  336   pr_min=${pr_min%,*}
  337   [ "$pr_min" != "${pr_min%-*}" ] && let pr_min=${pr_min%-*}-1
  338   rm -f $TMP
  339 }
  340 
  341 #--------------------------------------------------[ Restore with PhotoRec ]---
  342 function recoPhotoRec() {
  343   photoRecVer
  344   li1 "Extracting file with PhotoRec v${pr_maj}.${pr_min}"
  345   cmd="photorec /d ${STORETO}/${RESTDIR} /cmd $DUMPFILE partition_i386"
  346   [ "$FSTYPE" = "ext3" -o "$FSTYPE" = "ext2" ] && cmd="${cmd},options,mode_ext2"
  347   if [ $pr_maj -gt 6 -o $pr_maj -eq 6 -a $pr_min -ge 9 ]; then
  348     if [ "$FILESPEC" = "everything" ]; then
  349       cmd="${cmd},fileopt,everything,enable,search"
  350     else
  351       cmd="${cmd},fileopt,everything,disable,$FILESPEC,enable,search"
  352     fi
  353     if [ $WHOLESPACE -eq 0 ]; then
  354       cmd="${cmd},freespace"
  355     else
  356       cmd="${cmd},wholespace"
  357     fi
  358   else
  359     if [ "$FILESPEC" = "everything" ]; then
  360       cmd="${cmd},search"
  361     else
  362       cmd="${cmd},fileopt,$FILESPEC,enable,search"
  363     fi
  364   fi
  365   debugMsg "Executing '$cmd'"
  366   eval $cmd
  367   rc=$?
  368 }
  369 
  370 #--------------------------------------------------[ Restore with foremost ]---
  371 function recoForemost() {
  372   li1 "Extracting file with foremost..."
  373   cmd="foremost "
  374   [ $USEQUICK -eq 1 ] && cmd="$cmd -q"
  375   [ $USETS -eq 1 ] && cmd="$cmd -T"
  376   [ $USEQUIET -eq 1 ] && cmd="$cmd -Q"
  377   [ $READONLY -eq 1 ] && cmd="$cmd -w"
  378   [ $VERBOSE -eq 1 ] && cmd="$cmd -v"
  379   [ $ALLHEAD -eq 1 ] && cmd="$cmd -a"
  380   local FILEXT
  381   if [ -z "$FILESPEC" -o "$FILESPEC" = "everything" ]; then
  382     FILEXT="all";
  383   else
  384     FILEXT="$FILESPEC"
  385   fi
  386   cmd="$cmd -t $FILEXT -o ${STORETO}/$RESTDIR ${DUMPFILE} >/dev/null"
  387   debugMsg "Executing '$cmd'"
  388   eval $cmd
  389   rc=$?
  390 }
  391 
  392 #----------------------------------------------------[ Obtain the FileType ]---
  393 function getFileType() {
  394   local FEXT=`echo ${1##*.}|tr [:upper:] [:lower:]`
  395   local EXT
  396   local DESC
  397   local FTLIST="filetypes.${RECOPROG}"
  398   if [ -f /etc/ext3undel/$FTLIST ]; then
  399     FTLIST="/etc/ext3undel/$FTLIST"
  400   elif [ -f $HOME/.ext3undel/$FTLIST ]; then
  401     FTLIST="$HOME/.ext3undel/$FTLIST"
  402   elif [ -f ${0%/*}/$FTLIST ]; then
  403     FTLIST="${0%/*}/$FTLIST"
  404   fi
  405   while read line; do
  406     EXT=${line%%;*}
  407     [ "$FEXT" != "$EXT" ] && continue
  408     DESC=${line##*;}
  409     break
  410   done<$FTLIST
  411   if [ -z "$DESC" ]; then
  412     li1 "FileType '$FEXT' is unknown to $RECOPROG - so we let it check all it knows."
  413     FILESPEC="everything"
  414   else
  415     echo "File has the extension '$EXT'. According to the list of known file types, it"
  416     echo "probably is a '$DESC' file."
  417     echo "Shall we handle it as such (y), or better check all other file types"
  418     echo -n "as well (y/n)? "
  419     readyn
  420     echo
  421     if [ $rd -eq 1 ]; then
  422       FILESPEC="$EXT"
  423       li1 "FileType set to '$EXT' ('$DESC')"
  424     else
  425       FILESPEC="everything"
  426       li1 "FileType set to 'everything' (all that's supported)"
  427     fi
  428   fi
  429 }
  430 
  431 #-------------------------------------------------[ Find iNode information ]---
  432 # $1: what to search (-d for deleted, -u for undeleted, "all" for all)
  433 # $2: "all" for no "r/r" restriction
  434 function getINode() {
  435   case "$1" in
  436     "all") FLS="fls -r -p $DEV|grep -v '(realloc)'|egrep '$SEARCH'";;
  437     "-d"|"-u") FLS="fls -r $1 -p $DEV|grep -v '(realloc)'|grep 'r/r'|egrep '$SEARCH'";;
  438   esac
  439   mkfifo $TMP
  440   debugMsg "$FLS"
  441   eval $FLS>$TMP &
  442   typeset -i i=0
  443   while read line; do
  444     if [ "$(echo $line|awk '{print $2}')" = "*" ]; then
  445       iFILE[$i]=`echo "'$line '"|awk '{print $4}'`
  446       iNODE[$i]=`echo "'$line'"|awk '{print $3}'`
  447     else
  448       iFILE[$i]=`echo "'$line '"|awk '{print $3}'`
  449       iNODE[$i]=`echo "'$line'"|awk '{print $2}'`
  450     fi
  451     iNODE[$i]=${iNODE%*:}
  452     i+=1
  453   done <$TMP
  454   debugMsg "Found ${#iNODE[*]} entries"
  455   rm -f $TMP
  456 }
  457 
  458 #------------------------------------------------[ Restore a file (or not) ]---
  459 # $1: filename (relative to mountpoint)
  460 # $2: iNode#
  461 # $3: directory iNode substituted
  462 function fileRestore() {
  463   if [ -n "$3" ]; then
  464     local SUBST=$3
  465   else
  466     local SUBST=0
  467   fi
  468   if [ $SUBST -eq 0 ]; then
  469     local NAM="file"
  470   else
  471     local NAM="substituted directory"
  472   fi
  473   echo
  474   echo -n "Found $NAM '$MNT/$1' on iNode '$2'. Restore (y/n)? "
  475   readyn
  476   if [ $rd -eq 1 ]; then
  477     echo
  478     if [ $SUBST -eq 0 ]; then
  479       getFileType "$1"
  480     else
  481       getFileType "$uFILE"
  482     fi
  483     mkfifo $TMP
  484     fsstat $DEV > $TMP &
  485     typeset -i min
  486     typeset -i max
  487     typeset -i nod=$2
  488     local range=0
  489     local start=0
  490     while read line; do
  491       if [ $start -eq 0 ]; then
  492         [[ "$line" == Group:* ]] && start=1
  493       else
  494         if [[ "$line" == Inode?Range:* ]]; then
  495           min=`echo $line|awk '{print $3}'`
  496       max=`echo $line|awk '{print $5}'`
  497       if [ $nod -gt $min -a $nod -lt $max ]; then
  498         li1 "iNode $2 found in range '$min - $max'"
  499         range=1
  500         continue
  501       fi
  502         elif [ $range -eq 1 ]; then
  503           if [[ "$line" == Block?Range:* ]]; then
  504             min=`echo $line|awk '{print $3}'`
  505             max=`echo $line|awk '{print $5}'`
  506         li1 "Creating image of matching block range ($min - $max)"
  507         dls $DEV $min-$max >${DUMPFILE}
  508         case "$RECOPROG" in
  509           "photorec") recoPhotoRec;;
  510           "foremost") recoForemost;;
  511           *) echo "Ooops - no recovery tool specified???"
  512              echo "You normally should not see this message - there seems to be some bug in the script..."
  513          ;;
  514         esac
  515         if [ $rc -eq 0 ]; then
  516           echo
  517           echo "All recoverable files from the data block range where the requested"
  518           echo "file had been stored in have been reconstructed and stored into"
  519           echo "  ${STORETO}/$RESTDIR"
  520           echo "(if you used PhotoRec, you have to add '.#' to this path, where '#'"
  521           echo "is a number). You still have to check these files manually, and"
  522           echo "to rename/copy those you want to where you want them."
  523         else
  524           echo "Ooops! It looks like $RECOPROG failed to recover your file. So we will"
  525           echo "exit as well now - with the exit code $RECPROG gave us..."
  526           cleanUp
  527           exit $rc
  528         fi
  529         break
  530       fi
  531         fi
  532       fi
  533     done<$TMP
  534     [ $range -eq 0 ] && echo "Could not determine data block range - so no restore, sorry..."
  535   fi
  536 }
  537 
  538 #------------------------------------------------[ cleanUp temporary stuff ]---
  539 function cleanUp() {
  540   li1 "Cleaning up..."
  541   echo
  542   rm -f $TMP $MNTFILE $DUMPFILE
  543   echo
  544 }
  545 
  546 #============================================================[ Do the job! ]===
  547 #---------------------------------------------------[ check pre-requisites ]---
  548 DIRECTHIT=1 # Hopefully we find the files iNode
  549 checkRoot
  550 checkBins
  551 #-----------------------------------------------------[ parse command line ]---
  552 [ -z "$1" ] && syntax
  553 case "$1" in
  554   "-h"|"--help"|"-?") syntax;;
  555   *)
  556      set -f
  557      echo
  558      fileName "$1"
  559      set +f
  560   ;;
  561 esac
  562 shift
  563 while [ -n "$1" ]; do
  564   case "$1" in
  565     "+d"|"--debug") DEBUG=1;;
  566     "-d"|"--nodebug")   DEBUG=0;;
  567     "+s"|"--silent")    SILENT=1;;
  568     "-s"|"--nosilent")  SILENT=0;;
  569     "--freespace")  WHOLESPACE=0;;
  570     "--wholespace") WHOLESPACE=1;;
  571   esac
  572   shift
  573 done
  574 debugMsg "SILENT=${SILENT}"
  575 debugMsg "DEBUG=${DEBUG}"
  576 
  577 #----------------------------------------------------------[ check sources ]---
  578 symlinkCheck
  579 selSrc
  580 [ -z "$DEV" ] && {
  581   echo
  582   echo "Sorry - something went wrong, could not determine the source device."
  583   echo
  584   cleanUp
  585   exit 19
  586 }
  587 selDest
  588 if [ -n "$STORETO" ]; then
  589   DUMPFILE=${STORETO}/dump.$$
  590 else
  591   echo
  592   echo "Sorry - something went wrong, we do not have a destination to store to."
  593   echo
  594   cleanUp
  595   exit 2
  596 fi
  597 splitFileName
  598 li1 "Searching for iNode on '$DEV'..."
  599 getINode "-d"
  600 if [ ${#iNODE[*]} -eq 0 ]; then
  601   DIRECTHIT=0
  602   echo "No matching iNode found. Shall we try to substitute with the iNode of the"
  603   echo -n "parent directory (y/n)? "
  604   readyn
  605   echo
  606   if [ $rd -eq 1 ]; then
  607     SEARCH=${SEARCH%\\*}
  608     getINode "all"
  609   fi
  610 fi
  611 if [ ${#iNODE[*]} -eq 0 ]; then
  612   echo "No matching iNode found. Looks like G.A.B.I. is your last chance."
  613 else
  614   typeset -i i=0
  615   if [ $DIRECTHIT -eq 1 ]; then
  616     while (( i < ${#iNODE[*]} )); do
  617       fileRestore "${iFILE[$i]}" ${iNODE[$i]} 0
  618       i+=1
  619     done
  620   else # we substitute the directories iNode - so first hit only
  621     fileRestore "${iFILE[0]}" ${iNODE[0]} 1
  622   fi
  623 fi
  624 cleanUp
  625 exit 0