#!/bin/bash

## Shell script getrsync/putrsync
## HDM 01/01 ;  last update 02/06
#############################################################################
## This script is called "getrsync". "putrsync" is a link.                 ##
## Set "ln -s getrsync putrsync".                                          ##
##                                                                         ##
## Edit the following lines #################################################

remote_dir=  # remote dir which contains the MCTDH dir
host=        # remote host internet-address, including username

##         EXAMPLE          #################################################
## remote_dir=/home/dieter/MCTDH                                           ##
## host=dieter@tc-gate2.pci.uni-heidelberg.de                              ##
#############################################################################

minus40='----------------------------------------'
prog=`basename $0 | cut -c 1-8 `
exitl=0
exith=0
sdate=`date '+%b_%d_%H.%M.%S' `

# --- Check $MCTDH_DIR
if [ -z "$MCTDH_DIR" ] ; then
   help=1
   echo " You must first set the environment variable MCTDH_DIR"
   echo " Run install/install_mctdh "
fi

mdir=`basename $MCTDH_DIR`
local=$MCTDH_DIR
remote=$remote_dir/$mdir
n2=`echo -n "$mdir" | wc -c `
n1=$(($n2-5))
nn=`echo $n1$n2 | tr ' ' '-' `
ver=`echo -n "$mdir" | cut -c $nn | tr -d [:alpha:] `

# u=ignore newer-files, z=compress, a=-rlptgoD=archive
# c=checksum, slow but transfers only files which differ
opt='--safe-links --stats -c -avvvzu -e ssh'

if [ "$1" = "-addsurf" ] ; then
   local=${MCTDH_DIR%/*}/addsurf
   remote=$remote_dir/addsurf
fi

#############################################################################
## Set exclude

excl='--exclude mctdhform.ps          --exclude python/*/*.pyc
      --include doc/guide/guide.tex   --include doc/guide/figures/*.ps
      --include doc/examples/*        --include doc/guide/guide.bbl
      --include doc/guide-dev/guide-dev.bbl   --include bin/python/
      --include vcham_inputs/*.log    --include inputs/optcntrl/*.inp.0
      --exclude mctdhform.ps          --exclude python/*.pyc
      --exclude *.flc                 --exclude install/*.inc.bak
      --exclude mctdhall.prj          --exclude .mctdhall.prcs_aux
      --exclude *mctdhall*            --exclude mctdhall.log
      --exclude .addsurf*             --exclude addsurf.log
      --exclude [a-zA-Z]*.[0-9][0-9]  --exclude [a-zA-Z]*.[0-9]
      --exclude *_bk[0-9]*            --exclude *_md[0-9]*
      --exclude .[a-zA-Z]*            --exclude *.pdf
      --exclude *.ps                  --exclude *.dvi
      --exclude *.pyc
      --exclude *.log                 --exclude *.aux
      --exclude *.toc                 --exclude *.bbl
      --exclude *.blg                 --exclude *~
      --exclude #*#                   --exclude .#*
      --exclude source/*.orig/        --exclude save-*
      --exclude source_*/             --exclude source.*/
      --exclude doc/guide/guid*       --exclude guide.b*
      --exclude guide.lo*             --exclude guide.i*
      --exclude guide-dev.lo*         --exclude guide-dev.i*
      --exclude bin/*/                --exclude CompDir*/
      --exclude object/               --exclude obsolete/
      --exclude source/SFILES         --exclude source/SUBR
      --exclude install/depend*       --exclude paths.inc
      --exclude source/TAGS           --exclude source/tags
      --exclude source/TYPE_DATABASE* --exclude source/**/*.orig
      --exclude install/compile.cnf   --exclude install/platform.cnf
      --exclude install/platform.cnf.csh   --exclude addsurf.prj
      --exclude tags  --exclude Doxyfile   --exclude mctdh83.kde*
      --exclude install/MCTDH_client  --exclude *_mbk[0-9]*
      --exclude doc/guide/figures/mctdhform.ps
      --exclude doc/examples/.svn/*   --exclude /.svn/*
      --exclude /.svn/                --exclude install/MCTDH_IFORT_*
      --exclude elk_comp/             --exclude install/Makefile_*'

#############################################################################
## Read options. Re-define: opt, excl, local and remote.

for i in $@ ; do
    if [ "$i" = "-addsurf" ] ; then
        echo "Synchronizing addsurf"
        ladd=1
    elif [ "$i" = "-all" ] ; then
        opt='--safe-links --stats -c -avvvz -e ssh'
    elif [ -n "$lver" ] && [ -z "$ladd" ] ; then
       ver="$i"
       local=${local%%[0123456789.]*}$ver
       remote=${remote%%[0123456789.]*}$ver
       unset lver
    elif [ -n "$ex" ] ; then
      nexcl="$nexcl --exclude $i"
      unset ex
    elif [ -n "$in" ] ; then
      nexcl="$nexcl --include $i"
      unset in
    elif [ -n "$rm" ] ; then
      remote="${i%/}"
      host=localhost
      remote_dir=$remote
      if [ -z "${i##*:*}" ] ; then unset host ; fi
      unset rm
    elif [ -n "$loc" ] ; then
      local="${i%/}"
      unset loc
    elif [ $i = "-ver" ] ; then
      lver=1
    elif [ $i = "-ex" ] ; then
      ex=1
    elif [ $i = "-in" ] ; then
      in=1
    elif [ $i = "-exclude" ] ; then
      showexclude=1
    elif [ $i = "-remote" ] ; then
      rm=1
    elif [ $i = "-local" ] ; then
      loc=1
    elif [ $i = "-results" ] ; then
      cd $local
      cd ..
      pwd=`pwd`
      if [ ! -d rsynclog ] ; then mkdir rsynclog ; fi
      li1=$pwd/rsynclog/${prog%rsync}_L1_$sdate
      if [ ! -f $li1 ] ; then
         string=`ls -t ${li1%%1_*}1* | tr '\n' ' ' | cut -d' ' -f1`
         newdate=${string##*_L1_}
         li1=${li1%%1_*}1_$newdate
         echo $li1
      fi
      if [ ! -f "$li1" ] ; then
           echo "The file li1 = $li1 does not exist!"
           exit
      fi
      echo "$minus40$minus40"
      tail -n 30 $li1
      echo "$minus40$minus40"
      echo $li1
      echo "$minus40$minus40"
      egrep '[0-9]:[0-9][0-9]:[0-9][0-9] CE'  $li1
      echo ' '
      echo 'These are the files excluded because destination files are newer:'
      fgrep 'is newer' $li1 | cut -d' ' -f1 | sort
      echo ' '
      echo 'These are the files explicitely included:'
      egrep '^including file ' $li1 | cut -d' ' -f3 | sort
      echo ' '
      echo 'These are the files excluded:'
      egrep '^excluding file ' $li1 | cut -d' ' -f3 | sort
      echo ' '
      echo 'These are the directories excluded:'
      egrep '^excluding directory ' $li1 | cut -d' ' -f3 | sort
      echo ' '
      echo 'These are the files deleted:'
      egrep '^deleting' $li1 | cut -c 9- | grep -v in | sort
      echo ' '
      echo 'These are the files sent:'
#      egrep '^send_files\(' $li1 | cut -d, -f2 | tr ')' ' '
#      egrep '^recv mapped ' $li1 | cut -d' ' -f3
      egrep '^send_files mapped ' $li1 | cut -d' ' -f3
      echo ' '
      tail -n 20 $li1 | egrep '(Number of files|Total)'
      egrep '[0-9]:[0-9][0-9]:[0-9][0-9] CE'  $li1
      echo "$minus40$minus40"
      tail $li1 | fgrep terminated
      tail $li1 | fgrep EOF
      exit
    elif [ $i = "+results" ] ; then
      cd $local
      cd ..
      pwd=`pwd`
      if [ ! -d rsynclog ] ; then mkdir rsynclog ; fi
      li1=$pwd/rsynclog/${prog%rsync}_L1_$sdate
      ls -ltr ${li1%%1_*}1* | cut -c 1-11,31-
      echo "Please give date (e.g. Jul_07). RETURN=last date."
      read newdate
      if [ -z "$newdate" ] ; then
         string=`ls -t ${li1%%1_*}* | tr '\n' ' ' | cut -d' ' -f1`
         newdate=${string##*_L1_}
      fi
      li1=${li1%%1_*}1_$newdate
      unset string
      string=`ls ${li1}* `
      string=`echo $string' ' | cut -d' ' -f2 `
      if [ ! -f $li1 ] ; then
         if [ -n "$string" ]; then
            echo "Non-unique name. Add the time to the date string."
            ls ${li1}*
            exit 1
         fi
         li1=`ls ${li1}*`
      fi

      echo "$minus40$minus40"
      tail -n 30 $li1
      echo "$minus40$minus40"
      echo $li1
      echo "$minus40$minus40"
      egrep '[0-9]:[0-9][0-9]:[0-9][0-9] CE'  $li1
      echo ' '
      echo 'These are the files excluded because destination files are newer:'
      fgrep 'is newer' $li1 | cut -d' ' -f1 | sort
      echo ' '
      echo 'These are the files explicitely included:'
      egrep '^including file ' $li1 | cut -d' ' -f3 | sort
      echo ' '
      echo 'These are the files excluded:'
      egrep '^excluding file ' $li1 | cut -d' ' -f3 | sort
      echo ' '
      echo 'These are the directories excluded:'
      egrep '^excluding directory ' $li1 | cut -d' ' -f3 | sort
      echo ' '
      echo 'These are the files sent:'
#      egrep '^send_files\(' $li1 | cut -d, -f2 | tr ')' ' '
#      egrep '^recv mapped ' $li1 | cut -d' ' -f3
      egrep '^send_files mapped ' $li1 | cut -d' ' -f3
      echo ' '
      tail -n 20 $li1 | egrep '(Number of files|Total)'
      egrep '[0-9]:[0-9][0-9]:[0-9][0-9] CE'  $li1
      echo "$minus40$minus40"
      tail $li1 | fgrep terminated
      tail $li1 | fgrep EOF
      exit
    elif [ $i = "-h" ] ; then
	help=1
    elif [ $i = "--help" ] ; then
	rsync --help
      exit
    elif [ -z "${i##-*}" ] ; then
	nopt="$nopt $i"
    else
	rdir=${i#/}
    fi
done

if [ -z "$remote_dir" ] && [ "$1" != "-h" ]; then
      echo ==================================================================
      echo "Running: $0"
      echo 'ERROR: "remote_dir" is not set. Edit lines 11 and 12 of this'
      echo '        script, or use the option -remote.'
      echo ==================================================================
      exit 1
fi



dlocal=$local
dremote=$remote

# If a directory $rdir is specified (given as argument) then
# complete the name and change $local and $remote appropriately.
if [ -n "$rdir" ] && [ -z "$ladd" ]; then
    rdir=${rdir%/}
    rdir=${rdir#./}
    excl=`echo "$excl" | sed "s?$rdir/??g" `
    if [ ! -d $local/$rdir ] ; then
      cd $local
      alld=`find .  -type d`          # Find all dirs under MCTDH.
      alls=`echo "$alld" | grep  source`        # Source Dirs only.
      allr=`echo "$alld" | grep -v source`      # Except source dirs.
      alld=`echo -e "${alls}\n$allr"` # Putting source-files before all others.
      set -f  # Do not expand shell wildcards *?[]
      unset aa
      bb=$rdir
      aa=`echo "$alld" | egrep .*/$bb$`
      aa=`echo $aa  | cut -d" " -f1`
      set +f
      if [ -z "$aa" ] ; then
         aa=`echo "$alld" | egrep .*/$bb`
         aa=`echo $aa  | cut -d" " -f1`
         if [ -n "$aa" ] ; then
            rdir=${aa#./}
         else
            echo "No such directory under $MCTDH_DIR : $bb"
            exit
         fi
      else
         rdir=${aa#./}
      fi
    fi

    echo "Synchronizing only:  rdir = $rdir"
    remote=$remote/$rdir
    local=$local/$rdir
fi
if [ -n "$nexcl" ] ; then
    excl="$nexcl $excl"
fi

if [ -n "$host" ] ; then remote=${host}:$remote ; fi

#############################################################################
## Set paths and default options

dloc=`basename $dlocal`
drem=`basename $dremote`
if [ "$drem" != "$dloc" ] ; then
      echo
      echo "$minus40$minus40"
      echo '*******************************************************'
      echo "WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
      echo " The names of the MCTDH-directories differ."
      echo " local = $dloc ; remote = $drem "
      echo " This may lead to problems."
      echo '*******************************************************'
      echo "$minus40$minus40"
      echo
fi

cd $dlocal
cd ..
pwd=`pwd`
if [ ! -d rsynclog ] ; then mkdir rsynclog ; fi
li1=$pwd/rsynclog/${prog%rsync}_L1_$sdate
day=`date '+%d' `
bak="-b --suffix=_bk$day"
opt="$opt $nopt $bak"


#############################################################################
## HELP option

if [ -n "$help" ] ; then
  echo "$minus40$minus40"
  echo "Purpose: $prog synchronizes two MCTDH directories."
  echo "Usage  : $prog [ rsync-options ] [ -ex excide-file ]" \
       " [ -in include-file ]"
  echo "           [ -remote dir ] [ -h | -results | -exclude ]" \
       " [ start-directory ]."
  echo "Options, except '-ex -in -h -results -exclude -remote',"\
       "will be passed to rsync."
  echo "E.G.: with the option -n, rsync will list the files but performs"\
       "no copying."
  echo "      and with the option --help, rsync will list help information."
  echo " "
  echo " -h       : print this help text."
  echo " -addsurf : Synchronize addsurf rather than mctdh."
  echo "            If -addsurf is given, it must be the first option!"
  echo " -all     : Update files even if destination files are newer."
  echo " -results : Show the results of the previous $prog run."
  echo " +results : Show the results of some older $prog run"\
         " (prompting for date)."
  echo " -exclude : Show the exclude list."
  echo " -remote dir : Synchronize with remote directory dir."
  echo " -local  dir : Synchronize with local  directory dir."
  echo " -ver ver : Set version numbers of both mctdh dirs to ver."
  echo " -ex file : Add file to exclude list."
  echo " -in file : Add file to include list."
  echo " others   : Option passed through to rsync. (See: man rsync)."
  echo " Some useful rsync options are:"
  echo " -n       : This tells rsync to  not  do  any  file  transfers,"
  echo "            instead  it  will  just report the actions it would"
  echo "            have taken. (Inspect log-file or run -results)."
  echo " --delete : This tells rsync to delete any files on the"
  echo "            receiving side that aren't on the sending side."

  echo " "
  echo "The argument 'start-directory' specifies a directory form" \
       "which rsync starts."
  echo ' '
  echo "Examples: '$prog'         : Synchronize the whole MCTDH directory."
  echo "          '$prog source'  : Synchronize only the source files."
  echo "          '$prog -ex doc/': Ignore all doc-files."
  echo ' '
  echo "The log-file is : $li1"
  echo ' '
    if   [ $prog = "getrsync" ] ; then
       echo 'From: '$remote
       echo 'To  : '$local
    elif [ $prog = "putrsync" ] ; then
       echo 'From: '$local
       echo 'To  : '$remote
    else
       echo "What ? $prog  $0"
       exit 2
    fi
    echo ' '
    echo "These are the rsync options: $opt"
    echo ' '
    echo "You may need to edit line 10-13 of this script"\
         "to set the paths correctly!"
    echo "$minus40$minus40"
    exith=1
fi
if [ -n "$showexclude" ] ; then
    set -f   # Do not expand shell wildcards *?[]
    echo "$minus40$minus40"
    echo -n "These are the rsync excludes:"
    echo $excl | sed 's/--/\
/g'
    echo "$minus40$minus40"
    exit
fi

#############################################################################
### Check

if [ ! -d "$local" ] ; then
      echo ==================================================================
      echo "Running: $0"
      echo "ERROR: The directory $local does not exist."
      echo ==================================================================
      exith=1
fi
if [ -z "$remote_dir" ]; then
      echo ==================================================================
      echo "Running: $0"
      echo 'ERROR: "remote_dir" is not set. Edit lines 11 and 12 of this'
      echo '        script, or use the option -remote.'
      echo ==================================================================
      exith=1
fi

if [ $exith = 1 ] ; then exit ; fi  # exit from help


#############################################################################
## Run rsync

echo "--- Running $prog --- Synchronizing MCTDH directories"
date

if   [ $prog = "getrsync" ] ; then
  echo 'From: '$remote
  echo 'To  : '$local
elif [ $prog = "putrsync" ] ; then
  echo 'From: '$local
  echo 'To  : '$remote
else
  echo "What ? $prog  $0"
  exit 2
fi
echo "Options : $opt"

unset ians
until [ $ians ] ; do
    echo -n 'OK ? (y/n) '
    read ans
    if  [ "$ans" = "y" ] || [ "$ans" = '"y"' ] || [ "$ans" = "yes" ]; then
       ians=0
    elif [ "$ans" = "n" ] || [ "$ans" = '"n"' ] || [ "$ans" = "no" ]; then
       ians=1
       exit
    else
       echo ' What? '$ans' ?  Please answer "y" or "n"'
    fi
done

if [ -f $li1.old ] ; then mv $li1.old $li1.old2 ; mv $li1 $li1.old
elif [ -f $li1 ] ; then mv $li1 $li1.old ; fi

date
date > $li1
set -f  # Do not expand shell wildcards *?[]
if   [ $prog = "getrsync" ] ; then
    rsync $opt $excl $remote/ $local/  \
      | fgrep -v recv_  | fgrep -v make_  >> $li1  2>&1
elif [ $prog = "putrsync" ] ; then
    rsync $opt $excl $local/ $remote/  \
      | fgrep -v recv_  | fgrep -v make_  >> $li1  2>&1
else
    echo "What ? $prog  $0"
    exit 2
fi
date >> $li1

date
echo "--- Done $prog --- Synchronizing MCTDH directories"
echo "$minus40$minus40"
echo ' '
echo " ------  Log File Information (see also $prog -results)  ----- "
echo "The log-file is : $li1"
egrep '[0-9]:[0-9][0-9]:[0-9][0-9] CE'  $li1
echo ' '
echo 'These are the files sent:'
#egrep '^send_files\(' $li1 | cut -d, -f2 | tr ')' ' '
#egrep '^recv mapped ' $li1 | cut -d' ' -f3
egrep '^send_files mapped ' $li1 | cut -d' ' -f3
fgrep 'is newer' $li1 &> /dev/null
if [ $? = 0 ]; then
   echo ' '
   echo 'Files excluded because destination files are newer:'
   fgrep 'is newer' $li1 | cut -d' ' -f1 | sort
fi
echo ' '
tail -n 20 $li1 | fgrep 'Number of files'
echo "$minus40$minus40"

tail -n 30 $li1 | fgrep terminated
tail -n 30 $li1 | fgrep EOF

exit
#############################################################################

