#! /bin/ksh
#
PREF=${PREF:-nosuchfilenameprefix}
ARCNAM=${ARCNAM:-nosucharchivename}
#
cclargs 0$                         "[Transfert des fichiers dans une archive sur une machine cible]"\
      -pref    "${PREF}"    ",,,," "[Prefixe commun aux fichiers de donnees]"\
      -rep     "."          ",,,," "[Repertoire contenant ces donnees]"\
      -arcnam  "${ARCNAM}"  ",,,," "[Nom du fichier archive sur la machine cible]"\
      -mach_   "cfs"        ",,,," "[Nom de la machine cible]"\
      -clean+  "NON"        "OUI"  "[Faire le menage apres la creation de l'archive]"\
      -travail "${BIG_TMPDIR}" "." "[Repertoire de travail (BIG_TMPDIR)]"\
      -info+   "NON"        "OUI"  "[Informations supplementaires sur l'archive produite]"\
      -help+   "NON"        "OUI"  "[Information sur la sequence d'appel]"\
      -debut   "0000"       ",,,," "[Premier pas de temps considere]"\
      -fin     "0000"       ",,,," "[Dernier pas de temps considere]"\
      -delta   "0000"       ",,,," "[Interval de pas de temps considere]"\
      -turboc+ "NON"        "OUI"  "[Faire appel aux compresseurs turbos (16 bits)]"\
      -repack+ "NON"        "OUI"  "[Recompacter les donnees utilisant $npg bits]"\
      -npg     "16"         "32"   "[Nombre de bits a utiliser dans la compaction]"\
      -debug+  "NON"        "OUI"  "[Activer le mode DEBUG]"\
      ++ $* > ${BIG_TMPDIR}/cclargs_mv2cfs.out$$
#
. ${BIG_TMPDIR}/cclargs_mv2cfs.out$$ && /bin/rm -f ${BIG_TMPDIR}/cclargs_mv2cfs.out$$
#
######################################################################
#
# Description...
#    Cette script transfert des fichiers dans une archive sur une machine cible
#
######################################################################
#
# Auteur...
#    Bernard Dugas
#
######################################################################
#
# Revisions...
#    001  - decembre  1998: version initiale
#    002  - janvier   1999: ajouter les cles "-clean", "-info" et "-travail"
#    003  - fevrier   2001: ajouter les cles "-debut", "-fin",  "-delta" et
#                           les cles "-repack" et "-npg"
#    004  - mars      2001: verifier l'existence des fichiers avant de tenter
#                           de les re-compacter et arreter le travail apres
#                           toute autre erreur de compaction
#    005  - mai       2001: 1) Passer a ksh
#                           2) Ajouter le parametre "-n" aux rsh
#                              qui ne lisent pas de pipe stdin
#                           3) Tenir compte du "echo" de Linux
#                           4) Correction lorsqu'on ne fait pas de recompaction
#    006  - mars      2002: 1) modifier la valeur par defaut de -travail
#                           2) verifier que -pref pointe a des fichiers
#                           3) ajouter la cle -debug
#    007  - aout      2002: utiliser r.diag2000 par defaut
#    008  - decembre  2002: 1) implementer restore_list et save_list
#                           2) comportement modifie si ${mach} = `hostname`
#    009  - janvier   2003: 1) corriger le mode clean lorsque ${mach} != `hostname`
#                           quand l'archive est en plusieurs parties
#                           2) ne pas definir $grand lorsque fin=debut ou debut=0
#    010  - mai       2003: modifier l'appel a cclargs
#    011  - mai       2004: 1) Remplacer `hostname` par ${TRUE_HOST} (KW)
#                           2) Remplacer r.smcp par rsync (KW)
#    012  - septembre 2004: modifier la definition de ${list_all} (KW)
#    013  - juillet   2005: ajouter la cle -turboc (BD)
#    014  - janvier   2006: utiliser Climat_functions (BD)
#    015  - fevrier   2006: changer la compression de "FAST" a "best"
#
######################################################################
#
# Imprimer la sequence d'appel
#
if [ ${help}_moi = OUI_moi ]; then
  r.echo " "
  r.echo " Syntaxe..."
  r.echo " "
  r.echo " Climat_mv2cfs -pref VAL1 -rep VAL2 -arcnam VAL3 \\"
  r.echo "        -mach VAL4 -clean VAL5 -travail VAL6 \\"
  r.echo "        -info VAL7 -repack VAL8 -npg VAL9"
  r.echo " "
  r.echo " ou pref    = Prefixe commun aux fichiers de donnees"
  r.echo '    rep     = Repertoire contenant ces donnees (Defaut ".")'
  r.echo "    arcnam  = Nom du fichier, possiblement avec informations de"
  r.echo "              repertoires, de l'archive sur la machine cible."
  r.echo "    mach    = Nom de la machine cible (Defaut = cfs)"
  r.echo "    clean   = Faire le menage apres la creation de l'archive"
  r.echo '    travail = Repertoire de travail (${BIG_TMPDIR} ou bien .)'
  r.echo "              utilise seulement si clean = OUI"
  r.echo "    info    = Produire des informations supplementaires"
  r.echo "              sur l'archive produite (Defaut NON)"
  r.echo "    debut   = Premier pas de temps considere"
  r.echo "    fin     = Dernier pas de temps considere"
  r.echo "    delta   = Interval de pas de temps considere"
  r.echo "    turboc  = Faire appel aux compresseurs turbos (16 bits)"
  r.echo "    repack  = Recompacter les donnees (defaut NON)"
  r.echo "    npg     = Nombre de bits a utiliser dans la compaction"
  r.echo "    debug   = Activer le mode DEBUG"
  r.echo " "
  r.echo " Notez que les parametres pref et arcnam peuvent egalement"
  r.echo " etre specifies en utilisant les variables d'environnement"
  r.echo ' ${PREF} et ${ACRNAM}, respectivement'
  r.echo " "
  r.echo ' Le resultat est un fichier cmcarc ${mach}:${arcnam}.ca'
  r.echo " "
  exit 1
fi
#
if [[ ${ARCH:-none} = Linux* ]]; then
  ECHOARG=-e
else
  ECHOARG=""
fi
#
if [ ! -d ${travail} ]; then
  echo "Le repertoire de travail ${travail} doit exister a l'entree..."
  exit 2
fi
#
travail=`true_path ${travail}` 
#
# Definir certaines variables d'environnement de R.DIAG
#
export BIG_TMPDIR=${travail}
#
. Climat_functions
#
if [ ! -d ${rep} ]; then
  echo "Le repertoire de donnees initiale ${rep} n'existe pas"
  exit 3
fi
#
rep=`true_path ${rep}`
#
if [ ${rep} = ${travail} ]; then
  echo "Les repertoires rep et travail doivent etre differents..."
  echo "  rep = travail = ${travail}"
  exit 4
fi
#
if [ ${mach} = ${TRUE_HOST} ]; then
  clean=OUI
  arc_name=`basename ${arcnam}`
  dest_rep=`dirname ${arcnam}`
  dest_rep=`true_path ${dest_rep}`
  arcnam=${dest_rep}/${arc_name}
fi
#  
if [ ${debut} -ne ${fin} -a ${delta} -gt 000000 ]; then
  longueur=`echo ${debut} | wc -c`
  set $longueur ; longueur=$1
  if [ ${longueur} -ge 3 -a \
       ${longueur} -le 12 ]; then
    case ${longueur} in
      3)  grand=100;;
      4)  grand=1000;;
      5)  grand=10000;;
      6)  grand=100000;;
      7)  grand=1000000;;
      8)  grand=10000000;;
      9)  grand=100000000;;
      10) grand=1000000000;;
      11) grand=10000000000;;
      12) grand=100000000000;;
    esac
  else
    echo "Format debut=${debut} non reconnu"
    exit 5
  fi
fi
#
# Definir deux fonctions qui sont utilisees pour sauver les
# listes partielles des fichiers a sauver dans des archives
#
restore_list()
{
case "${part}" in
  1)
    list_all=${list_part1}
    count_part=${count_part2}
    ext="_part1"
    if [ ${count_part} -eq 0 ]; then ext="" ; fi
    ;;
  2)
    list_all=${list_part2}
    count_part=${count_part3}
    ext="_part2"
    ;;
  3)
    list_all=${list_part3}
    count_part=${count_part4}
    ext="_part3"
    ;;
  4)
    list_all=${list_part4}
    count_part=${count_part5}
    ext="_part4"
    ;;
  5)
    list_all=${list_part5}
    count_part=${count_part6}
    ext="_part5"
    ;;
  6)
    list_all=${list_part6}
    count_part=0
    ext="_part6"
    ;;
esac
part=$(( ${part} + 1 ))
}
#
save_list()
{
case "${part}" in
  1)
    list_part1=${list_part}
    count_part1=${count_part}
    ;;
  2)
    list_part2=${list_part}
    count_part2=${count_part}
    ;;
  3)
    list_part3=${list_part}
    count_part3=${count_part}
    ;;
  4)
    list_part4=${list_part}
    count_part4=${count_part}
    ;;
  5)
    list_part5=${list_part}
    count_part5=${count_part}
    ;;
  6)
    list_part6=${list_part}
    count_part6=${count_part}
    ;;
esac
list_part=""
count_part=0
part=$(( ${part} + 1 ))
}
#
# Conversions de l'anglais au francais
#
if [ ${clean} = YES ]; then
  clean=OUI
elif [ ${clean} = NO ]; then
  clean=NON
fi
#
if [ ${debug} = YES ]; then
  debug=OUI
elif [ ${debug} = NO ]; then
  debug=NON
fi
#
if [ ${help} = YES ]; then
  help=OUI
elif [ ${help} = NO ]; then
  help=NON
fi
#
if [ ${info} = YES ]; then
  info=OUI
elif [ ${info} = NO ]; then
  info=NON
fi
#
if [ ${repack} = YES ]; then
  repack=OUI
elif [ ${repack} = NO ]; then
  repack=NON
fi
#
if [ ${turboc} = YES ]; then
  turboc=OUI
elif [ ${turboc} = NO ]; then
  turboc=NON
fi
#
r.echo " "
r.echo " Climat_mv2cfs: BIG_TMPDIR     =${BIG_TMPDIR}"
r.echo " Climat_mv2cfs: DIAGNOSTIC_EXIT=${DIAGNOSTIC_EXIT}"
r.echo " Climat_mv2cfs: Starting at `date`"
r.echo " "
if [ ${info} = OUI ]; then
  r.echo " Climat_mv2cfs: prefix =${pref}"
  r.echo " Climat_mv2cfs: rep    =${rep}"
  r.echo " Climat_mv2cfs: arcnam =${arcnam}"
  r.echo " Climat_mv2cfs: mach   =${mach}"
  r.echo " Climat_mv2cfs: travail=${travail}"
  r.echo " Climat_mv2cfs: debut  =${debut}"
  r.echo " Climat_mv2cfs: fin    =${fin}"
  r.echo " Climat_mv2cfs: delta  =${delta}"
  r.echo " Climat_mv2cfs: turboc =${turboc}"
  r.echo " Climat_mv2cfs: repack =${repack}"
  r.echo " Climat_mv2cfs: npg    =${npg}"
  r.echo " "
fi
#
if [ ${debug} = OUI ]; then set -x ; fi
#
# Aller dans le repertoire ou sont les fichiers
#
cd ${rep}
#
# Construire une liste de fichiers a utiliser
#
if [ "${pref}" != nosuchfilenameprefix ]; then
  if [ ${debut} -ne ${fin} -a \
       ${delta} -gt 000000 ]; then
    pas=${debut}
    list_all=''
    while [ ${pas} -le ${fin} ]
    do
      label=`echo $(( ${grand} + 1${pas} )) | cut -c 2- `
      list_all="${list_all} ${pref}_${label}*"
      pas=`echo $(( 1${pas} + ${delta} )) | cut -c 2- `
    done
  else
    list_all=`ls -x ${pref}* `
    if [ $? -ne 0 ]; then
      echo " "
      echo " mauvais prefixe de fichiers de donnees"
      echo " "
      exit 6
    fi
  fi
else
  echo " "
  echo " S.V.P. specifier un prefixe de fichiers de donnees"
  echo " "
  exit 7
fi
#
if [ ${repack} = OUI -o ${turboc} = OUI ]; then
  #
  # Re-compacter les fichiers avant de les archiver
  #
  cd ${travail} ; /bin/rm -f ${pref}*
  cd ${rep}
  #
  for fichier in ${list_all} ; do
    if [ -s ${fichier} ]; then
      if [ ${repack} = OUI ]; then
        ${RDIAG} repack ${fichier} ${travail}/${fichier} -npg =-${npg}
      fi
      if [ ${turboc} = OUI ]; then
        if [ -s ${travail}/${fichier} -a ${repack} = OUI ]; then
          rfstcompress -fstin  ${travail}/${fichier} -level best \
                       -fstout ${travail}/${fichier}$$ 1> /dev/null
          r.catf ${travail}/${fichier}$$ ${travail}/${fichier} -d
        else
          /bin/rm -f ${travail}/${fichier} 
          rfstcompress -fstin             ${fichier} -level best \
                       -fstout ${travail}/${fichier}   1> /dev/null
          r.delf -dn ${rep}/${fichier}
        fi
      fi
    else
      r.echo " "
      r.echo "${fichier} manquant dans Climat_mv2cfs"
      r.echo " "
    fi
  done
  #
  if [ -s ${DIAGNOSTIC_EXIT} ]; then
    echo ${ECHOARG} "\n Detection de probleme lors de la compaction \n"
    exit 8
  fi
  #
  cd ${travail}
  #
  list_all=`ls -x ${pref}* `
  #
fi
#
totalMB=`ls -l ${list_all} | awk 'BEGIN{s=0}{s = s + $5}END{printf "%.10g",  s / 1048576.}'`
totalMB=${totalMB%%.*}
#
if [ ${totalMB} -lt 1999 ]; then
  limit1=1999
elif [ ${totalMB} -lt 3999 ]; then
  limit1=$(( ${totalMB} / 2 + 1 ))
elif [ ${totalMB} -lt 5999 ]; then
  limit1=$(( ${totalMB} / 3 + 1 ))
elif [ ${totalMB} -lt 7999 ]; then
  limit1=$(( ${totalMB} / 4 + 1 ))
elif [ ${totalMB} -lt 9999 ]; then
  limit1=$(( ${totalMB} / 5 + 1 ))
elif [ ${totalMB} -lt 11999 ]; then
  limit1=$(( ${totalMB} / 6 + 1 ))
else
  echo "Too many files to be archived"
  exit 9
fi
#
# Verifier la taille de tout ca et construire
# des listes partielles en consequence
#
list_part1="" ; list_part2="" ; list_part3=""
list_part4="" ; list_part5="" ; list_part6=""
#
count_part1=0 ; count_part2=0 ; count_part3=0
count_part4=0 ; count_part5=0 ; count_part6=0
#
list_part=""  ; count_part=0  ; part=1 ; nMB=0
#
if [ ${totalMB} -ge 1999 ]; then
  #
  for fichier in ${list_all} ; do
    #
    taille=`ls -l ${fichier} | awk '{s=$5}{printf "%.10g",  s / 1048576.}'`
    taille=${taille%%.*}
    #
    if [ ${taille} -gt 1999 ]; then
      echo "File ${fichier} too large to fit in cmcarc archive"
      exit 10
    fi
    #
    old_list=${list_part}
    list_part=${list_part}" "${fichier}
    count_part=$(( ${count_part} + 1 ))
    #
    old_nMB=${nMB}
    nMB=`ls -l ${list_part} | awk 'BEGIN{s=0}{s = s + $5}END{printf "%.10g",  s / 1048576.}'`
    nMB=${nMB%%.*}
    #
    if [ ${nMB} -gt ${limit1} -a ${nMB} -lt 2000 ]; then
      #
      save_list
      #
      if [ ${part} -gt 6 ]; then
        echo "Too many files to be archived"
        exit 9
      fi
      #
    elif [ ${nMB} -ge 2000 ]; then
      #
      list_part=${old_list}
      count_part=$(( ${count_part} - 1 ))
      #
      save_list
      #
      list_part=${fichier}
      count_part=1
      #
    fi
    #
  done
  #
else
  #
  count_part1=`ls ${list_all} | wc -w`
  list_part1=${list_all}
  #
fi
#
if [ ${count_part} -gt 0 ]; then save_list ; fi
#
# Creer et transferer les archives (maximum de 6 ayant moins de 2GB chacune)
#
count_part=${count_part1} ; part=1
#
while [ ${count_part} -gt 0 ]; do
  #
  restore_list
  #
  if [ ${mach} = ${TRUE_HOST} ]; then
    if [ -s ${arcnam}${ext}.ca ]; then
      echo "on efface le ${arcnam}${ext}.ca precedent"
      /bin/rm -f ${arcnam}${ext}.ca
    fi
    cmcarc -p -a ${list_all} -f ${arcnam}${ext}.ca
    status_cmcarc=$?
    status_rsync=0
  elif [ ${clean} = NON ]; then
    cmcarc -p -o -a ${list_all} | rsh ${mach} dd ibs=64k obs=128k of=${arcnam}${ext}.ca
    status_cmcarc=$?
    status_rsync=0
  else
    arcbase=`basename ${arcnam}${ext}`.ca
    if [ -s ${travail}/${arcbase} ]; then
      echo "on efface le ${travail}/${arcbase} precedent"
      /bin/rm -f ${travail}/${arcbase}
    fi
    cmcarc -p -a ${list_all} -f ${travail}/${arcbase}
    status_cmcarc=$?
    rsync -a -r -u -v ${travail}/${arcbase} ${mach}:${arcnam}${ext}.ca 
    status_rsync=$? 
    if [ ${status_rsync} = 0 ] ; then /bin/rm -f ${travail}/${arcbase} ; fi
  fi
  #
  # Verifier le resultat
  #
  if [ ${status_cmcarc} != 0 -o ${status_rsync} != 0 ]; then
    echo " "
    echo "Probleme avec CMCARC ou bien avec le transfert vers ${mach}:${arcnam}${ext}.ca"
    echo "Code d'erreur cmcarc = ${status_cmcarc}"
    echo "Code d'erreur rsync  = ${status_rsync}"
    echo " "
    exit 11
  fi
  #
  # Faire le menage
  #
  if [ ${clean} = OUI ]; then
    if [ ${repack} = OUI ]; then
      cd ${rep} ; /bin/rm -f ${list_all} ; cd ${travail}
    fi      
    /bin/rm -f ${list_all}
  fi
  #
  if [ ${info} = OUI ]; then
    #
    # Decrire la nouvelle archive. Remarquons que la commande CMCARC
    # est ici declaree de facon absolue puisque celle-ci pourrait ne
    # pas faire partie de l'environnement restreint sur ${mach}...
    #
    if [ ${mach}ine = cfsine ]; then
      CMCARC=cmcarc
    else
      CMCARC=/software/pub/bin/cmcarc
    fi
    #
    if [ ${mach} = ${TRUE_HOST} ]; then
      echo ; ls -al ${arcnam}${ext}.ca ; echo ; echo et son contenu
      cmcarc -t -v -f ${arcnam}${ext}.ca
    else
      rsh ${mach} -n "echo ; ls -al ${arcnam}${ext}.ca ; echo ; echo et son contenu ; \
      echo ; ${CMCARC} -t -v -f ${arcnam}${ext}.ca"
    fi
  fi
  #
done
#
echo ${ECHOARG} "\n Climat_mv2cfs: Ending at `date` \n"
exit 0
