#!/bin/bash
########################################################################
#                  mdircp                                              #
# This shell script copies a MCTDH-directory to another file.          #
# Ignored are executable,object,*.dvi,*.ps,*_bk*, *_md*, and *~ files. #
# The script uses cpio.                                                #
# HDM 12/03                                                            #
########################################################################

#-----------------------------------------------------------------------
#  Definitions :
#-----------------------------------------------------------------------
minus40='----------------------------------------'
minus60=$minus40'--------------------'
minus80=$minus40$minus40
 star40='****************************************'
# set locale, so that date etc will be in uniform format.
export LC_ALL=C

purp1="Purpose : Copy the MCTDH-directory dir1 to dir2."
purp2="Ignored are binary, object, *.dvi, *.ps, *~ files (etc)."
purp3="I.e., copied will be those files, which are on the MCTDH package"
purp4="before installation."
usage="Usage   : mdircp [ -A -a -b -r -R -e -i -p -h ] [dir1] dir2."
help0='-h     : print this help text.'
help1='-A     : Copy all files.'
hlp1a='-a     : Copy all files except object/, bin/.+/ and obsolete/ ones.'
hlp1b='-s     : Show all files which are excluded by default but would be'
hlp1c='         copied by -a. No other options allowed when -s is set.'
help2='-b     : Backup. Copy $MCTDH_DIR to $MCTDH_BACKUP/.'
hlp2a='-f     : force. Copy without asking.'
hlp2A='-n dir : Restore to a new directory dir. Only in combination'
hlp2B=' with -r|R option.'
hlp2C='         NB: There must be at most one agrument when using -r|R.'
hlp2D='         But with option -n one may set another ouput directory.'
hlp2b='-r nun : Restore backup number num. Copy to $MCTDH_DIR .'
hlp2c='-R num : Restore backup counting number from the end.'
help3='-e pat : Exclude file the names of which match pattern pat. '
help4='-i pat : Include only file the names of which match pattern pat. '
hlp4a='-t     : "touch" files copied, i.e. set new access and modifcation time.'
help5='-p     : Print file list (and do nothing else).'
hlp5a='-T     : Produce a gziped tar file. dir2 is the name of this file'
hlp5b='         and should have the extension .tgz.'
hlp5c='-N host: Use ssh to send the tar file over a network (-N sets -T).'
hlp5d='host is the network address, e.g dieter@tc-gate1.pci.uni-heidelberg.de.'
hlp5e='Note: "tc"  is mapped to "tc-gate1.pci.uni-heidelberg.de".'
hlp5f='Note: "urz" is mapped to "aixterm6.urz.uni-heidelberg.de".'
help6=' Copy dir1 to dir2. dir2 must not exist.'
help7=' If dir1 is not given, $MCTDH_DIR is assumed.'
help8=' If dir2 is not given or dir2=., then ./basename($MCTDH_DIR) is assumed.'
help9=' The pattern pat is an egrep regular expression.'

echo "$minus80"
oldpwd=`pwd`

# --- Find the argument dir (last argument).
it=1
for i in "$@" ; do
   i1=$i
   if [ -z "${it#-[eirRN]}" ]; then unset i1  # all options with arguments
   elif [ -z "${i##-*}" ];     then unset i1 ; fi
   if [ -z "${i#-[TNn]}" ]; then break ; fi   # do not set dir for -T,-N or -n
   it=$i
done
dir=${i1:-$MCTDH_DIR}

# --- Set file names and determine the total number of backups.

if [ -z "$dir" ]; then
   echo " MCTDH_DIR is empty!"
   exit
elif [  -d "$dir" ]; then
   cd $dir
   dir=`pwd`
   mdir=`basename $dir`
   bdir=$MCTDH_BACKUP/$mdir
   last=${bdir}_last
   log=${bdir}_log
else
   unset dir
fi
nrtot=0
all=0
if [ -f "$last" ]; then
   nrtot=`wc -l $last`
   nrtot=`echo $nrtot | cut -d' ' -f1 `
fi

# --- This is to check that -r -R have arguments (e.g. -R1).
echo " $@" | grep -i ' -r'  > /dev/null && restore=1

#-----------------------------------------------------------------------
#  Read the options (if any).
#-----------------------------------------------------------------------

while getopts ":AThabfstpn:e:i:r:R:N:" opt; do
    case $opt in
    h  ) help=1 ;;
    A  ) all=2  ;;
    a  ) all=1  ;;
    b  ) bck=1  ;;
    f  ) frc=1  ;;
    n  ) new=$OPTARG  ;;
    s  ) show=1 ;;
    r  ) rst=1
         unset ok
         echo $OPTARG | egrep '^[0-9]*$' &> /dev/null && ok=1
         if [ -z "$OPTARG" ] || [ -z "$ok" ] ; then
            echo " A positive integer must follow -r, not: $OPTARG "
            exit
         fi
         if [ -n "$nrst" ] ; then
            echo " No more than one -r or -R option allowed."
            exit
         else
            nrst=$OPTARG
         fi ;;
    R  ) rst=1
         unset ok
         echo $OPTARG | egrep '^[0-9]*$' &> /dev/null && ok=1
         if [ -z "$OPTARG" ] || [ -z "$ok" ] ; then
            echo " A positive integer must follow -R, not: $OPTARG "
            exit
         fi
         if [ -n "$nrst" ] ; then
            echo " No more than one -r or -R option allowed."
            exit
         else
            nrst=$(($nrtot+1-$OPTARG))
         fi ;;
    t  ) touch=1 ;;
    T  ) tar=1 ;;
    N  ) tar=1; host="$OPTARG" ;;
    e  ) excl=$OPTARG ;;
    i  ) incl=$OPTARG ;;
    p  ) pr=1   ;;
    \? ) echo ' Unkown option!'
         echo $usage
         echo ' -h provides a help text.'
         exit 1 ;;
  esac
done
shift $(($OPTIND - 1))
cd $oldpwd

if [ -n "$show" ];then
   unset all
   unset bck
   unset rst
   unset tar
   unset excl
   unset incl
   unset pr
fi

if [ -n "$rst$bck" ] && [ -n "$tar" ]; then
   echo "-T or -N cannot be set when -b, -r, or -R is given."
   exit
fi
if [ "$host" = "tc" ] || [ "$host" = "TC" ];then
   host='dieter@tc-gate1.pci.uni-heidelberg.de'
elif [ "$host" = "urz" ] || [ "$host" = "URZ" ];then
   host='i77@aixterm6.urz.uni-heidelberg.de'
elif [ "${host#*@}" = "tc" ];then
   host="${host%@urz}@tc-gate1.pci.uni-heidelberg.de"
elif [ "${host#*@}" = "urz" ];then
   host="${host%@urz}@aixterm6.urz.uni-heidelberg.de"
fi

if   [ -z "$1" ] || [ "$1" = "." ] ; then
   dir1="$MCTDH_DIR"
   dir2="$oldpwd"/`basename $MCTDH_DIR `
elif [ -z "$2" ] ; then
   dir2="$1"
   dir1="$MCTDH_DIR"
else
   dir1=$1
   dir2=$2
fi
if [ -n "${dir1%%/*}" ] ; then
    if [ -d $dir1 ]; then cd $dir1; dir1=`pwd`; cd $oldpwd; fi
fi
if [ -n "${dir2%%/*}" ] ; then
    if [ -d $dir2 ]; then cd $dir2; dir2=`pwd`; cd $oldpwd; fi
fi


if [ -n "$bck" ]; then
   if [ -n "$2" ]; then
      echo " No second directory must be given when option -b is set."
      echo "$minus80"
      exit
   fi
   if [ -z "$dir" ]; then
      echo "The directory dir = $dir does not exist!"
      echo "$minus80"
      exit
   fi
   dir1=$dir
   dir2=$bdir
   if [ -n "$rst" ] || [ -n "$tar" ]; then
      echo " One must not give -r, -R, -T or -N option for a Backup run."
      echo "$minus80"
      exit
   fi
   if [ -d $bdir ]; then
      echo " The directory $bdir already exist."
      echo " Cannot do initial backup. Exit."
      echo "$minus80"
      exit
   fi
elif [ -n "$rst" ]; then
   if [ -n "$2" ]; then
      echo " No second directory must be given when option -r or -R is set."
      exit
   elif [ $nrst -lt 1 ] || [ $nrst -gt $nrtot ]; then
      echo " There is no such backup (-r -R option) on:"
      echo ' '$bdir
      echo " nrst=$nrst, nrtot=$nrtot"
      echo "$minus80"
      exit
   elif [ -n "$tar" ]; then
      echo " One must not give -T or -N option for a Restore run."
      echo "$minus80"
      exit
   fi
   dir1=$MCTDH_BACKUP/`cat $last | tr '\n' ' ' | cut -d' ' -f$nrst `
   dir2=$dir
   if [ -n "$new" ]; then dir2=$new ; fi
fi

if [ "$1" = "-h" ] || [ "$2" = "-h" ] || [ "$3" = "-h" ]; then help=1; fi

if [ -n "$help" ] ; then
    echo "$purp1"
    echo "          $purp2"
    echo "          $purp3"
    echo "          $purp4"
    echo ' '
    echo "$usage"
    echo ' '
    echo " $help0"
    echo " $help1"
    echo " $hlp1a"
    echo " $hlp1b"
    echo " $hlp1c"
    echo " $help2"
    echo " $hlp2a"
    echo " $hlp2A$hlp2B"
    echo " $hlp2b"
    echo " $hlp2c"
    echo " $hlp2C"
    echo " $hlp2D"
    echo " $help3"
    echo " $help4"
    echo " $hlp4a"
    echo " $help5"
    echo " $hlp5a"
    echo " $hlp5b"
    echo " $hlp5c"
    echo "          $hlp5d"
    echo "          $hlp5e"
    echo "          $hlp5f"
    echo ' '
    echo " $help6"
    echo " $help7"
    echo " $help8"
    echo " $help9"
    echo ' '
    echo '  If option -T or -N is given, a tar file (*.tgz) will be produced.'
    echo ' '
    blnk20='                    '
    echo 'EXAMPLES:'
    echo 'mdircp -b         : A new initial backup is produced'
    echo 'mdircp -b dir     : As above, but copying from dir rather'\
         'than from $MCTDH_DIR'
    echo 'mdircp -R1 -i doc : Copying the doc files from the'\
         'last backup to $MCTDH_DIR'
    echo 'mdircp -R3 dir    : Copying all files from the third'\
         'last backup of dir to dir'
    echo 'mdircp -r3 -n dir : Copying all files from the third'\
         'backup of $MCTDH_DIR to dir'
    echo 'mdircp -R1 -n dir dir1 : Copying the last backup'\
         'of dir1 to dir'
    echo "mdircp -i source -e '(/fd_.*/|potfit)' dir2 : Copying all source"\
      'files of the'
    echo "$blnk20 current MCTDH directory, but excluding the directories"
    echo "$blnk20 fd_cmplx, fd_real, and potfit, to dir2"
    echo ' '
    echo ' '
    echo '  Copy from Directory: '$dir1
    if [ -z "$tar" ]; then
       echo '  Copy to   Directory: '$dir2
    else
       echo '  Copy to tar-File   : '$dir2
       if [ -n "$host" ];then
          echo "  Using remote host  : $host"
       fi
    fi
    echo "$minus80"
    exit
fi

#-- Check for correct input.

if [ -n "$restore" ] && [ -z "$rst" ]; then
   echo " A number must follow -r or -R option!"
   exit
fi


#-- Check if dir2 already exist.

if [ -z "$pr$rst$tar" ] || [ -n "$new" ]; then
# normal; i.e. not tar, not print, not restore; or -n (new) option
   if [ -n "$show" ] ; then
      :
   elif [ -f $dir2 ] ; then
      echo " There exist already a (regular) file with name $dir2"
      echo " exit"
      echo $minus80
      exit
   elif [ -d $dir2 ] ; then
      echo " Copy from $dir1  to  $dir2"
      echo " The directory $dir2 already exist!"
      echo " What shall I do?"
      echo "   rm) Remove this directory."
      echo "   wr) Overwrite existing files on this directory."
      echo "   x ) Do nothing. Exit."
      unset answ
      echo -n " Type (rm|wr|x) : "
      read answ
      if [ "$answ" = rm ]; then
         rm -rf   $dir2
         mkdir -p $dir2
         echo " Removed!"
         echo " "
      elif [ "$answ" = wr ]; then
         echo " Overwite!"
         echo " "
      else
         echo " No copy! Exit."
         echo "$minus80"
         exit
      fi
   elif [ -e $dir2 ] ; then
      echo " The file $dir2 already exist!"
      echo " exit"
      echo $minus80
      exit
   else
      mkdir -p $dir2      # make the destination directory.
   fi
fi

if [ -n "$tar" ]; then        # tar (-T or -N option)
   file2=`basename $dir2`
   dir2=${dir2%/*}
   if [ "$dir2" = "$file2" ]; then dir2='.' ; fi
# Make $dir2 if not exist and not -N option.
   if [ -z "$host" ] && [ ! -e $dir2 ]; then
      mkdir -p $dir2 && echo "###  Made directory : $dir2"
   fi
#  Add extension .tgz.
   if [ -z ${file2##*.tgz} ] || [ -z ${file2##*.tar.gz} ] ;then
      :
   elif [ -n ${file2##*.tar} ];then
      file2=${file2}.gz
   elif [ -n ${file2##*.t*} ];then
      file2=${file2}.tgz
   fi
fi


#  Make file-name absolute if not already absolute and if not -N option.
if [ -n "${dir2%%/*}" ] && [ -z "$host" ] ; then
    cd $dir2
    dir2=`pwd`
    cd $oldpwd
fi

if [ ! -d $dir1 ]; then
   echo " The directory dir1 = $dir1 does not exist!"
   exit
fi
cd $dir1
dir1=`pwd`

echo ' Copy from Directory: '$dir1
if [ -n "$show" ]; then
   :
elif [ -z "$tar" ]; then
   echo ' Copy to   Directory: '$dir2
else
   echo ' Copy to tar-File   : '$dir2/$file2
   if [ -n "$host" ];then
      echo " Using remote host  : $host"
   fi
fi
echo ' '

if [ ! -d $dir1 ] ; then
   echo "There is no directory $dir1"
   exit
fi
if [ ! -d $dir2 ] && [ -z "$pr$host$show" ]; then
   echo "There is no directory $dir2"
   exit
fi


#-----------------------------------------------------------------------
#  Exclude list.
#-----------------------------------------------------------------------

EXCLUDE='(/obsolete/|/\.svn/|mctdhall|.*_bk[0-9].*|.*_md[0-9].*|\./bin/binary/|\./object/|.*\.pyc|.*\.pdf|.*\.ps|.*\.dvi|.*\.aux|/install/Makefile_.*|\./doc/.*\.log$|\./doc/guide/guide\.i.*|\./doc/guide/guide\.l.*|\./doc/guide/guide\.blg|\./doc/guide/guide\.toc|.*\.swp$|.*~$|\./source/SUBR|\./source/SFILES|\./install/save-.*|\./install/dependencies|#.*#|\./install/MCTDH_client|MCTDH_IFORT_.*|\./install/MCTDH_IFORT.*|\./source/.*\.F.personal|\./source/.*\.F.original|\./source/include/.*\.inc\.original|\./source/include/.*\.inc\.private|\./source/.*\.F\.new|\./source/.*\.F\.save|Makefile\.new|Makefile\.save|Makefile\.original|include/.*\.inc\.old|include/.*\.inc\.new|include/.*\.inc\.bak|\.nfs.*|cleaned_.*)'

EXEX='(/obsolete/|/\.svn/|\./bin/binary/|\./object/|.*\.swp$|.*~$|#.*#|.*_bk[0-9].*|.*_md[0-9].*)'
EXIN='(/doc/guide/figures|doc/guide/guide\.bbl|/vcham_inputs/.*\.log|/doc/vcham/example/.*\.log|/doc/examples|/doc/filter/exampl.*)'

#-----------------------------------------------------------------------
#  Generate the flists.
#-----------------------------------------------------------------------

cd $dir1
if [ -n "$show" ]; then
   echo '######  SHOW EXCLUDED FILES ########'
   set -f  # Do not expand shell wildcards
   flist1=`find . -type f -print | egrep -v "$EXEX" |\
           egrep -v "$EXIN" | egrep  "$EXCLUDE" `
   set +f
   n1=`echo "$flist1" | wc -l `
   n1=`echo $n1 `
   echo " ---  There are $n1 excluded files.  ---"
   echo "$flist1" | sort
   echo '-----------------------------------------------------------------'
   exit
fi

if [ $all = 0 ]; then
   flist=`find . -type f -print `
   set -f  # Do not expand shell wildcards
   flist1=`echo "$flist" | egrep -v "$EXCLUDE" `
   flist2=`echo "$flist" | egrep  "$EXIN" |\
           egrep -v '(/obsolete/|/\.svn/|.*\.swp$|.*~$|#.*#)'`
   set +f
   flist=`echo "$flist1"; echo "$flist2" `
   flist=`echo "$flist" | sort -u `
elif [ $all = 1 ];then
   flist=`find . -type f -print `
   set -f
   flist1=`echo "$flist" | egrep -v "$EXEX" `
   flist2=`echo "$flist" | egrep  "$EXIN" |\
           egrep -v '(/obsolete/|/\.svn/|.*\.swp$|.*~$|#.*#)'`
   set +f
   flist=`echo "$flist1"; echo "$flist2" `
   flist=`echo "$flist" | sort -u `
else
   flist=`find . -type f -print | sort `
fi

if [ -n "$excl" ]; then
   flist=`echo "$flist" | egrep -v "$excl" `
fi

if [ -n "$incl" ]; then
   flist=`echo "$flist" | egrep  "$incl" `
fi


n1=`echo "$flist" | wc -l `
n1=`echo $n1 `
if [ -z "$tar" ]; then
   if [ ${#dir1} -lt 25 ]; then
      echo " There are $n1 files on $dir1 to be copied (cpio)."
   else
      echo " There are $n1 files on "
      echo " $dir1"
      echo " to be copied (cpio)."
   fi
   if [ $n1 -lt 9 ]; then echo "$flist" ; fi
else
   echo " There are $n1 files on:   $dir1"
   if [ -z "$host" ]; then
      echo " to be tared to the file: $dir2/$file2"
   else
      echo " to be tared to the file:"
      echo " ${host}:$dir2/$file2"
   fi
fi

unset answ
if [ -n "$tar" ] && [ -z "$host" ];then
   if [ -d $dir2/$file2 ]; then
      echo " The file $dir2/$file2 is a directory! exit."
      exit
   elif [ -e $dir2/$file2 ]; then
      echo " "
      echo " The file $dir2/$file2 already exist!"
      echo -n " Shall I overwite it? Type (y|n) :"
      read answ
      if [ "$answ" != y ]; then
         echo " No copy! Exit."
         echo "$minus80"
         exit
      fi
   fi
fi

if [ -n "$pr" ]; then
   echo "$flist"
   echo "$minus80"
   echo "There are $n1 files on $dir1"
   exit
fi

if [ -n "$frc" ]; then answ=y ; fi
if [ -z "$answ" ]; then
   echo -n ' OK? Type (y|n): '
   read answ
fi
if [ "$answ" = y ]; then

   if [ -n "$tar" ];then
      mflist=`echo "$flist" | sed -e "s%^\./%$mdir/%" `
      cd ..
      if [ -z "$host" ]; then
         tar czf $dir2/$file2 $mflist
      else
         tar czf - $mflist | ssh ${host} \
         "mkdir -p $dir2; cat > $dir2/$file2; ls -l $dir2/$file2"
      fi
      echo "$star40$star40"
      exit
   fi

   if [ -z "$touch" ]; then
      echo "$flist" | cpio  -padum $dir2     # cpio
      echo "access and modification time preserved"
   else
      echo "$flist" | cpio  -pdu $dir2      # cpio
      echo "new access and modification time"
   fi

   if [ -n "$bck" ]; then
      echo $mdir > $last
      dt=`date`
      echo "$minus60"     > $log
      echo "1)(#)  $dt"  >> $log
      echo "$mdir"       >> $log
      echo "Full backup. (First copy)." >> $log
      echo "$minus60"    >> $log
   fi
elif [ -z "$rst$tar" ]; then    # if answ is no
   rmdir $dir2
   echo "No copy performed. Directory $dir2 is removed."
else
   echo "No copy performed."
fi

echo "$star40$star40"

exit
