#
#
# Copyright (C) 2000-2022 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
# A set of useful functions to be sourced in each test
#

. ./config

if [ "$TestName" ]; then
   export TestName
fi

check_encoding()
{
   if ${bin}/bacula-dir -d50 -t -c ${conf}/bacula-dir.conf 2>&1 | grep 'Wanted SQL_ASCII, got UTF8' >/dev/null ; then
       echo "Found database encoding problem, please modify the database encoding (SQL_ASCII)"
       exit 1
   fi
}

update_cloud()
{
   make -C build/src/stored install-cloud install-s3-cloud install-s3-glacier-cloud install-oci-cloud install-gs-cloud install-swift-cloud install-generic-cloud install-bcloud > /dev/null 2>&1
   make -C build/scripts install-regress-drivers > /dev/null 2>&1
   $bperl -e 'add_attribute("$conf/bacula-sd.conf", "Plugin Directory", "$plugins", "Storage")'

   CLOUD_NAME=${CLOUD_NAME:-RegressCloud}
   # try to launch the emulators
   if [ x$CLOUD_NAME = xFakeS3Cloud ]; then   #S3 Emulator
      mkdir -p $tmp/cloud
      fakes3 --root=$tmp/cloud --port=4567 &
      aws s3api --endpoint-url='http://localhost:4567' create-bucket --bucket ${1:-regressbucket}
      CLOUD_MAXIMUM_PART_SIZE=50MB
   fi

   if [ x$CLOUD_NAME = xScalabilityCloud ]; then   # like S3
      aws s3api --endpoint-url='http://localhost:8000' create-bucket --bucket ${1:-regressbucket}
   fi

   if [ x$CLOUD_NAME = xAzuriteCloud ]; then  #WAS Emulator
      azurite &
   fi

   if [ x$CLOUD_NAME = xFakeAzureCloud ]; then  #WAS Emulator
      make -C build/scripts install-generic-cloud-as-was > /dev/null 2>&1
   fi

   #FIXME : if we find an existing Cloud, might be worth it to remove it here
   grep $CLOUD_NAME $conf/bacula-sd.conf > /dev/null
   if [ $? != 0 ]; then
      cfile="$cwd/cloud.conf.sample"
      if [ -f "$cwd/cloud.conf" ]; then
          cfile="$cwd/cloud.conf"
      fi
      if grep $CLOUD_NAME $cfile > /dev/null; then
         $bperl -e "extract_resource('$cfile', 'Cloud', '$CLOUD_NAME')" >> $conf/bacula-sd.conf
      else
          echo "Missing cloud $CLOUD_NAME in $cfile. Contact R@D manager for more info."
          exit 1
      fi
   fi

   if [ x$CLOUD_NAME = xOracleCloud -a -f $HOME/.oci/config ]; then
       oci  os bucket create --name ${1:-regressbucket}
       $bperl -e "add_attribute('$conf/bacula-sd.conf', 'HostName', '$HOME/.oci/config', 'Cloud', 'OracleCloud')"
   fi

   if [ x$CLOUD_NAME = xGoogleCloud -a -d $HOME/.gsutil ]; then
       # Command line buckets are not working correctly, permissions are not set
       gsutil list | grep ${1:-regressbucket}
       $bperl -e "add_attribute('$conf/bacula-sd.conf', 'HostName', '$HOME', 'Cloud', 'GoogleCloud')"
   fi

   #File driver
   if [ x$CLOUD_NAME = xRegressCloud ]; then
       $bperl -e "add_attribute('$conf/bacula-sd.conf', 'HostName', '$tmp/cloud', 'Cloud', 'RegressCloud')"
       mkdir -p $tmp/cloud
   fi

   # update Devices to use this Cloud
   $bperl -e 'add_attribute("$conf/bacula-sd.conf", "Device Type", "Cloud", "Device")'
   $bperl -e 'add_attribute("$conf/bacula-sd.conf", "Cloud", "'$CLOUD_NAME'", "Device")'

   # overwrites from the config file (for personnal account use)
   if [ "$CLOUD_HOSTNAME" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'HostName', '\"$CLOUD_HOSTNAME\"', 'Cloud')"
   fi
   if [ "$CLOUD_BUCKETNAME" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'BucketName', '\"$CLOUD_BUCKETNAME\"', 'Cloud')"
   fi
   if [ "$CLOUD_ACCESSKEY" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'AccessKey', '\"$CLOUD_ACCESSKEY\"', 'Cloud')"
   fi
   if [ "$CLOUD_SECRETKEY" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'SecretKey', '\"$CLOUD_SECRETKEY\"', 'Cloud')"
   fi
   if [ "$CLOUD_REGION" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'Region', '\"$CLOUD_REGION\"', 'Cloud')"
   fi
   if [ "$CLOUD_PROTOCOL" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'Protocol', '$CLOUD_PROTOCOL', 'Cloud')"
   fi
   if [ "$CLOUD_URISTYLE" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'UriStyle', '$CLOUD_URISTYLE', 'Cloud')"
   fi
   if [ "$CLOUD_BLOBENDPOINT" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'BlobEndpoint', '\"$CLOUD_BLOBENDPOINT\"', 'Cloud')"
   fi
   if [ "$CLOUD_FILEENDPOINT" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'FileEndpoint', '\"$CLOUD_FILEENDPOINT\"', 'Cloud')"
   fi
   if [ "$CLOUD_QUEUEENDPOINT" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'QueueEndpoint', '\"$CLOUD_QUEUEENDPOINT\"', 'Cloud')"
   fi
   if [ "$CLOUD_TABLEENDPOINT" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'TableEndpoint', '\"$CLOUD_TABLEENDPOINT\"', 'Cloud')"
   fi
   if [ "$CLOUD_ENDPOINTSUFFIX" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'EndpointSuffix', '\"$CLOUD_ENDPOINTSUFFIX\"', 'Cloud')"
   fi
   if [ "$CLOUD_DRIVER" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'Driver', '\"$CLOUD_DRIVER\"', 'Cloud')"
   fi
   if [ "$CLOUD_MAXIMUM_PART_SIZE" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'MaximumPartSize', '$CLOUD_MAXIMUM_PART_SIZE', 'Device')"
   fi
   if [ "$CLOUD_TRUNCATE_CACHE" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'TruncateCache', '$CLOUD_TRUNCATE_CACHE', 'Cloud')"
   fi
   if [ "$CLOUD_DRIVER_COMMAND" ]; then
         $bperl -e "add_attribute('$conf/bacula-sd.conf', 'DriverCommand', '$CLOUD_DRIVER_COMMAND', 'Cloud')"
   fi
}

start_test()
{
   check_encoding
   rm -rf ${working}/@*
   variant_name=""
   devicetype=0
   # If no or dummy smtp_host, use dummy email handler
   if [ x${SMTP_HOST} = x -o x${SMTP_HOST} = xdummy ]; then
      cp scripts/dummy_bsmtp bin/bsmtp
      chmod 755 bin/bsmtp
   else
      # Deactivate all email
      outf="tmp/sed_tmp2"
      echo "s%  mail =%# mail = %g" >${outf}
      echo "s%  operator =%# operator =%g" >>${outf}
      cp ${conf}/bacula-dir.conf ${tmp}/1
      sed -f ${outf} ${tmp}/1 > ${conf}/bacula-dir.conf
   fi
   if [ x$FORCE_DOT_STATUS = xyes ]; then
      $bperl -e "check_dot_status()" 2> /dev/null > $tmp/check_dot_status.out &
   fi
   echo $TestName | grep aligned > /dev/null
   if [ $? -eq 0 -o x$FORCE_ALIGNED = xyes ]; then
      make -C build/src/stored install-aligned > /dev/null 2>&1
      $bperl -e 'add_attribute("$conf/bacula-sd.conf", "Device Type", "Aligned", "Device")'
      $bperl -e 'add_attribute("$conf/bacula-sd.conf", "Plugin Directory", "$plugins", "Storage")'
      variant_name="Aligned"
      devicetype=`expr $devicetype + 1`
   fi
   if [ x$FORCE_CLOUD = xyes ]; then
      update_cloud
      variant_name="$CLOUD_NAME"
      devicetype=`expr $devicetype + 1`
   fi
   if [ x$FORCE_DEDUP = xyes ]; then
      make -C build/src/stored install-dedup > /dev/null 2>&1
      make -C build/src/plugins/fd install-test-dedup >/dev/null 2>&1
      make -C build/scripts install-btools >/dev/null 2>&1
      DEDUP_DRIVER=${DEDUP_DRIVER:-Legacy}
      if [ "$DEDUP_DRIVER" = "Legacy" ] ; then
         default_dedup_config_fmt="1"
      else
         default_dedup_config_fmt="2"
      fi
      DEDUP_CONFIG_FMT=${DEDUP_CONFIG_FMT:-$default_config_dedup_fmt}
      DEDUP_FS_OPTION=${DEDUP_FS_OPTION:-bothsides}
      mkdir -p ${working}/dde
      DEDUP_MAXIMUM_CONTAINER_SIZE=${DEDUP_MAXIMUM_CONTAINER_SIZE:-10MB}
      touch ${working}/dde/dde.conf # When dde.conf exists, DDE create a smaller Index
      $bperl -e 'add_attribute("$conf/bacula-sd.conf", "Plugin Directory", "$plugins", "Storage")'
      $bperl -e 'add_attribute("$conf/bacula-sd.conf", "Device Type", "Dedup", "Device")'
      if [ "$DEDUP_CONFIG_FMT" = "1" ] ; then
         $bperl -e 'add_attribute("$conf/bacula-sd.conf", "DedupDirectory", "${working}/dde", "Storage")'
         $bperl -e 'add_attribute("$conf/bacula-sd.conf", "MaximumContainerSize", "'$DEDUP_MAXIMUM_CONTAINER_SIZE'", "Storage")'
      else
#         $bperl -e 'add_attribute("$conf/bacula-sd.conf", "Dedupengine", "Dedupengine1", "Device")'
         $bperl -e 'add_attribute("$conf/bacula-sd.conf", "MaximumContainerSize", "'$DEDUP_MAXIMUM_CONTAINER_SIZE'", "Dedup")'
         cat >> $conf/bacula-sd.conf <<EOF

Dedupengine {
  Name = Dedupengine1
  DedupDirectory = "${working}/dde"
  Driver = Legacy
}

EOF
      fi
      $bperl -e 'add_attribute("$conf/bacula-dir.conf", "Dedup", "'$DEDUP_FS_OPTION'", "Options")'
      DEDUP_FD_CACHE=${DEDUP_FD_CACHE:-no}
      if [ x$DEDUP_FD_CACHE = xyes ]; then
            $bperl -e 'add_attribute("$conf/bacula-fd.conf", "DedupIndexDirectory", "$working/ddefd", "FileDaemon")'
      fi
      variant_name="Dedup($DEDUP_DRIVER,$DEDUP_FS_OPTION,fdcache=$DEDUP_FD_CACHE)"
      devicetype=`expr $devicetype + 1`
   fi
   if [ x$FORCE_SDCALLS = xyes ]; then
      $bperl -e 'add_attribute("$conf/bacula-dir.conf", "SD Calls Client", "yes", "Client")'
      variant_name="${variant_name} SDcall"
   fi
   if [ $devicetype -gt 1 ]; then
       echo "ERROR: Found multiple FORCE_XXX switches"
       set | awk '/^FORCE_/ { print $0 }'
       exit 1
   fi
   if [ x$FORCE_SPOOL_ATTRIBUTES = xyes ]; then
       $bperl -e 'add_attribute("$conf/bacula-dir.conf", "SpoolAttributes", "No", "Job")'
       variant_name="${variant_name} NoSpoolAttributes"
   fi
   if [ x$FORCE_SDPACKETCHECK = xyes ]; then
       $bperl -e 'add_attribute("$conf/bacula-fd.conf", "SDPacketCheck", "500", "FileDaemon")'
       variant_name="${variant_name} SDCheckPacket"
   fi
   if [ x$FORCE_ENCRYPTION = xyes ]; then
       $bperl -e 'setup_fd_encryption()'
       variant_name="${variant_name} Encryption"
   fi
   if [ x$FORCE_TLS = xyes ]; then
      local h=`hostname`
      local file
      for file in $conf/bacula-fd.conf $conf/bacula-dir.conf $conf/bacula-sd.conf $conf/bconsole.conf
      do
        sed "s/${h}-dir/localhost-dir/g" "$file" | sed "s/${h}-sd/localhost-sd/g" | sed "s/${h}-fd/localhost-fd/g" | sed "s/Address = ${h}/Address = localhost/ig"  > $tmp/1
        mv $tmp/1 "$file"
      done
      $bperl -e 'setup_fd_tls("$conf/bacula-fd.conf")'
      $bperl -e 'setup_sd_tls("$conf/bacula-sd.conf")'
      $bperl -e 'setup_dir_tls("$conf/bacula-dir.conf")'
      $bperl -e 'setup_cons_tls("$conf/bconsole.conf")'
      variant_name="${variant_name} TLS"
   fi
   if [ x$FORCE_FDCALLS = xyes ]; then
       $bperl -e 'setup_fdcallsdir()'
       variant_name="${variant_name} FDcall"
   fi
   if [ x$FORCE_COLLECTOR = xyes ]; then
       $bperl -e 'setup_collector("$conf/bacula-dir.conf", "dir")'
       $bperl -e 'setup_collector("$conf/bacula-fd.conf", "fd")'
       $bperl -e 'setup_collector("$conf/bacula-sd.conf", "sd")'
       variant_name="${variant_name} Collector"
   fi
   if [ x$FORCE_EVENTS = xyes ]; then
      $bperl -e "add_attribute('$conf/bacula-dir.conf', 'catalog', 'all,events', 'Messages')"
      $bperl -e "add_attribute('$conf/bacula-dir.conf', 'append', '\"$working/bacula.log\" = all, !skipped,events', 'Messages')"
   fi
   reset_test
}

# Helper to check if all expected connection logs occured
# arg1: logfile to check
# arg2: with or without tls expected
# arg3: expected DIR->SD log lines
# arg4: expected DIR->FD log lines
# arg5: expected FD->SD log lines
# arg6: expected SD->FD log lines
check_connection_tls_logs()
{
   tls_str="with TLS"
   if [ $2 -eq 0 ]; then
      tls_str="without encryption"
   fi

   n=`cat $1 | grep ".*\-dir .* Connected to Storage .* ${tls_str}" | wc -l`
   if [ $n -ne $3 ]; then
      estat=1
      print_debug "Wrong log lines regarding Director Connecting Storage ${tls_str}: ${n} in restore log, expected $3"
      print_debug "see: $1"
   fi


   n=`cat $1 | grep ".*\-dir .* Connected to Client .* ${tls_str}" | wc -l`
   if [ $n -ne $4 ]; then
      estat=1
      print_debug "Wrong log lines regarding Director Connecting Client ${tls_str}: ${n} in restore log, expected $4"
      print_debug "see: $1"
   fi

   n=`cat $1 | grep ".*\-sd .* Connected to Client .* ${tls_str}" | wc -l`
   if [ $n -ne $5 ]; then
      estat=1
      print_debug "Wrong log lines regarding Storage Connecting Client ${tls_str}: ${n} in restore log, expected $5"
      print_debug "see: $1"
   fi

   n=`cat $1 | grep ".*\-fd .* Connected to Storage .* ${tls_str}" | wc -l`
   if [ $n -ne $6 ]; then
      estat=1
      print_debug "Wrong log lines regarding Client Connecting Storage ${tls_str}: ${n} in restore log, expected $6"
      print_debug "see: $1"
   fi
}

set_debugsettings()
{
   if [ -f $log_setdebug ]; then rm $log_setdebug; fi
   if [ -z "$4" ]; then daemon_type=4; else daemon_type=""; fi
cat <<END_OF_DATA >${cwd}/tmp/bconcmds
   @output /tmp/tempi
   @$out $log_setdebug
   setdebug level=$1 trace=$2 options=$3 $4 tags=$5
   $daemon_type
   quit
END_OF_DATA
}

reset_test()
{
   variant_name="${variant_name}"
   ./test_starttime
   echo " "
   echo " "
   echo " === Start $TestName ${variant_name} at `date +%R:%S` ==="
   echo " === Start $TestName ${variant_name} at `date +%R:%S` ===" >> ${working}/log
   echo " "
   export TestName
   export zstat
   export estat
   export ddestat
   estat=0
   zstat=0
   bstat=0
   rstat=0
   vstat=0
   dstat=0
   ddestat=0
}

# Change setup so that we run with shared storage plugin
setup_shstore()
{
if test x${USE_SHSTORE} = xyes ; then
   require_tape_drive
   /bin/cp -f ${rscripts}/bacula-sd-lock-changer.conf ${scripts}/bacula-sd.conf
   scripts/cleanup-tape

   # install the shstore plugin
   rm -f bin/plugins/shstore-sd.so
   make -C build/src/plugins/sd install-shstore-plugin >/dev/null
fi
}

require_cloud()
{
    if [ "$FORCE_CLOUD" != yes ]; then
       echo "$TestName can run only with FORCE_CLOUD"
       exit 0
    fi
}

require_root()
{
MUID=`/usr/bin/id | awk -F= '{print $2}' | awk -F\( '{print $1}'`
if [ $MUID != 0 ] ; then
   echo " "
   echo "You must be root to run this test."
   echo "  ===== !!!! $TestName not run at `date +%R:%S` ==="
   echo "  ===== !!!! $TestName not run at `date +%R:%S` !!!! ===== " >>test.out
   echo " "
   exit 1
fi
}

require_tape_drive()
{
#  tape not comptible with aligned
if test x$FORCE_ALIGNED = xyes; then
   echo "$TestName test not compatible with FORCE_ALIGNED."
   exit 0
fi
#  tape not comptible with cloud
if test x$FORCE_CLOUD = xyes; then
   echo "$TestName test not compatible with FORCE_CLOUD."
   exit 0
fi
#  tape not comptible with dedup
if test x$FORCE_DEDUP = xyes; then
   echo "$TestName test not compatible with FORCE_DEDUP."
   exit 0
fi
if test x${TAPE_DRIVE} = x/dev/null ; then
   echo "$TestName test needs a tape drive, but has none."
   exit 1
fi
}

require_second_drive()
{
if test x${TAPE_DRIVE1} = x/dev/null ; then
   echo "$JobName needs second drive, but has none."
   exit 1
fi
}

require_autochanger()
{
if test x${AUTOCHANGER} = x/dev/null ; then
   echo "$TestName needs an autochanger, but has none."
   exit 1
fi
}

require_vtape()
{
#  vtape not comptible with aligned
if test x$FORCE_ALIGNED = xyes; then
   echo "$TestName test not compatible with FORCE_ALIGNED."
   exit 0
fi
#  vtape not comptible with cloud
if test x$FORCE_CLOUD = xyes; then
   echo "$TestName test not compatible with FORCE_CLOUD."
   exit 0
fi
#  vtape not comptible with dedup
if test x$FORCE_DEDUP = xyes; then
   echo "$TestName test not compatible with FORCE_DEDUP."
   exit 0
fi
if test x${USE_VTAPE} = x ; then
   echo "$TestName test needs the vtape driver."
   exit 0
fi
}

require_disk()
{
#  vtape not comptible with aligned
if test x$FORCE_ALIGNED = xyes; then
   echo "$TestName test not compatible with FORCE_ALIGNED."
   exit 0
fi
#  vtape not comptible with cloud
if test x$FORCE_CLOUD = xyes; then
   echo "$TestName test not compatible with FORCE_CLOUD."
   exit 0
fi
#  vtape not comptible with dedup
if test x$FORCE_DEDUP = xyes; then
   echo "$TestName test not compatible with FORCE_DEDUP."
   exit 0
fi
if test x${USE_VTAPE} = xyes ; then
   echo "$TestName test not compatible with FORCE_VTAPE."
   exit 0
fi
}

require_changer()
{
#  disk changer not comptible with cloud
if test x$FORCE_CLOUD = xyes; then
   echo "$TestName test not compatible with FORCE_CLOUD."
   exit 0
fi
}

require_linux()
{
os=`uname`
if [ $os != 'Linux' ]; then
   echo "$TestName test runs only on Linux"
   exit 0
fi
}

skip_if_no_autochanger()
{
if test x${AUTOCHANGER} = x/dev/null ; then
   echo "$TestName test skipped. No autochanger."
   exit
fi
}

set_debug()
{
   debug=$1
   if test "$debug" -eq 1 ; then
     out="tee"
   else
     out="output"
   fi
}

print_debug()
{
   echo $* | grep ERROR > /dev/null
   if test $? -eq 0; then
     echo $* >> $tmp/err.log
   fi
   if test "$debug" -eq 1 ; then
     echo $*
   fi
}

check_files_written()
{
    LOG=$1
    NB=$2
    FILES=`awk '/FD Files Written:/ { last=$4 } END { print last }' $LOG`

    if [ "$NB" != "$FILES" ]; then
        print_debug "ERROR: Expect $NB files, get $FILES"
        bstat=2
    fi
}

################################################################
# Get information from logs
get_mig_info()
{
    # Prev Backup JobId
    JOBID=$1
    LOG=$2
    RET=`awk -F: "BEGIN { jobid=$JOBID } "'/Prev Backup JobId/ { cjid=$2 } /New Backup JobId/  { if (cjid == jobid) { print $2 } }' $LOG`
}

get_duration()
{
   LOG=$1
   RET=`awk 'BEGIN {t["secs"]=1;t["sec"]=1;t["min"]=60;t["mins"]=60}; /Elapsed time:/ { last=$3*t[$4] } END { print last }' $LOG`
}

check_duration()
{
   LOG=$1
   TIME=$2
   OP=${3:-gt}

   get_duration $LOG
   if [ "$RET" -$OP "$TIME" ]; then
       print_debug "Error, got $RET $OP $TIME sec on $LOG"
       bstat=2
   fi
}

run_bacula()
{
   debug_wait
   zstat=0
   estat=0
   ddestat=0
   if test "$debug" -eq 1 ; then

     ${scripts}/bacula-ctl-sd start -m
     ${scripts}/bacula-ctl-fd start -m $1
     ${scripts}/bacula-ctl-dir start -m
     cat ${tmp}/bconcmds | ${bin}/bconsole -c ${conf}/bconsole.conf
     return $?
   else
     ${scripts}/bacula start >/dev/null 2>&1
     cat ${tmp}/bconcmds | ${bin}/bconsole -c ${conf}/bconsole.conf >/dev/null 2>&1
     return $?
   fi
}

run_bconsole()
{
   bconsole_file=${1:-${tmp}/bconcmds}
   if test "$debug" -eq 1 ; then
     cat $bconsole_file | ${bin}/bconsole -c ${conf}/bconsole.conf
   else
     cat $bconsole_file | ${bin}/bconsole -c ${conf}/bconsole.conf  2>&1 >/dev/null
   fi
}

run_btape()
{
   if test "$debug" -eq 1 ; then
     cat ${tmp}/bconcmds | ${bin}/btape -c ${conf}/bacula-sd.conf tape | tee ${tmp}/log1.out
   else
     cat ${tmp}/bconcmds | ${bin}/btape -c ${conf}/bacula-sd.conf tape >${tmp}/log1.out 2>&1
   fi
}

run_bscan()
{
   if test "$debug" -eq 1 ; then
      ${bin}/bscan $* | tee ${tmp}/log.out
   else
      ${bin}/bscan $* 2>&1 >/dev/null
   fi
}

bscan_libdbi()
{
   B=`echo $LIBDBI | sed 's/;//' | sed 's/;//g'`
   B_D=`echo $B | awk '{print $3}'`
   B_t=`echo $B | awk '{print $6}'`
   B_p=`echo $B | awk '{print $9}'`

   BSCANLIBDBI="${LIBDBI:+1}"

   if test "$BSCANLIBDBI" = "1" ; then
      BSCANLIBDBI="-D $B_D -h $B_t -t $B_p"
   else
      BSCANLIBDBI=" "
   fi
}

stop_bacula()
{
   if [ x$FORCE_DOT_STATUS = xyes ]; then
      rm -f $tmp/check_dot_status.ctrl
   fi
   if [ "$CHECK_OPENFILE" != 0 ]; then
      rm -f $tmp/stop.$$.out
      cat << EOF > $tmp/stop.$$
@output /dev/null
message
@output $tmp/stop.$$.out
.api 2
.status storage header
quit
EOF
      cat  $tmp/stop.$$ | $bin/bconsole -c $conf/bconsole.conf -u 1 2>&1 > /dev/null
      pid=`awk -F= '/pid=/ { print $2; exit; }' $tmp/stop.$$.out 2> /dev/null`
      if [ "$pid" != "" ]; then
         $bperl -e "check_openfile('/proc/$pid/fd')"
         if [ $? -ne 0 ]; then
            echo " "
            echo "  !!!!! $TestName ${variant_name} failed!!! `date +%R:%S` !!!!! "
            echo "     Files still open!!"
            echo " " >>test.out
            echo " " >>test.out
            echo "  !!!!! $TestName ${variant_name} failed!!! `date +%R:%S` !!!!! " >>test.out
            echo "     Files still open!!" >>test.out
            echo " "
            exit 1
         fi
      fi
   fi
   if [ "$CHECK_JOBMEDIA" != 0 ]; then
      $bperl -e 'check_jobmedia()'
      if [ $? -ne 0 ]; then
         echo " "
         echo "  !!!!! $TestName ${variant_name} failed!!! `date +%R:%S` !!!!! "
         echo "     JobMedia is corrupted"
         echo " " >>test.out
         echo " " >>test.out
         echo "  !!!!! $TestName ${variant_name} failed!!! `date +%R:%S` !!!!! " >>test.out
         echo "     JobMedia is corrupted" >>test.out
         echo " "
         exit 1
      fi
   fi
   if [ "$CHECK_ENCRYPTION" != 0 -a "$FORCE_ENCRYPTION" = yes ]; then
      $bperl -e 'check_encryption("$tmp/log1.out")'
      if [ $? -ne 0 ]; then
         echo " "
         echo "  !!!!! $TestName ${variant_name} failed!!! `date +%R:%S` !!!!! "
         echo "     Encryption problem"
         echo " " >>test.out
         echo " " >>test.out
         echo "  !!!!! $TestName ${variant_name} failed!!! `date +%R:%S` !!!!! " >>test.out
         echo "     Encryption problem" >>test.out
         echo " "
         exit 1
      fi
   fi
   if [ "$CHECK_JSON" != 0 ]; then
      $bperl -e 'check_json_tools()'
      if [ $? -ne 0 ]; then
         echo " "
         echo "  !!!!! $TestName ${variant_name} failed!!! `date +%R:%S` !!!!! "
         echo "     JSON Data is incorrect"
         echo " " >>test.out
         echo " " >>test.out
         echo "  !!!!! $TestName ${variant_name} failed!!! `date +%R:%S` !!!!! " >>test.out
         echo "     JSON Data is incorrect" >>test.out
         echo " "
         exit 1
      fi
   fi
   if [ "x$FORCE_CLOUD" = xyes ]; then
      $bperl -e 'check_parts()'
      if [ $? -ne 0 ]; then
	      print_debug "ERROR: FORCE_CLOUD check_parts"
         estat=1
      fi
   fi
   if [ "$FORCE_COLLECTOR" = yes ]; then
      if ! [ -s $tmp/sd.csv -a -s $tmp/fd.csv -a -s $tmp/dir.csv ]; then
        print_debug "ERROR: One or more collector CSV file are empty"
        estat=1
      fi
   fi
   if [ "$FORCE_EVENT" = yes ]; then
      $bperl -e 'check_events()'
      if [ $? -ne 0 ]; then
         print_debug "ERROR: FORCE_EVENT check_events"
         estat=1
      fi
   fi
   if test "$debug" -eq 1 ; then
      ${scripts}/bacula stop
   else
      ${scripts}/bacula stop 2>&1 >/dev/null
   fi
   # Any File/Dir with @ as the first character is a lock file
   ls ${working}/@* 2>/dev/null 1>/dev/null
   if test $? -eq 0 ; then
      echo " "
      echo "  !!!!! $TestName ${variant_name} failed!!! `date +%R:%S` !!!!! "
      echo "     SCSI lock still set"
      echo " " >>test.out
      echo " " >>test.out
      echo "  !!!!! $TestName ${variant_name} failed!!! `date +%R:%S` !!!!! " >>test.out
      echo "     SCSI lock still set" >>test.out
      echo " "
      exit 1
   fi
}

check_for_zombie_jobs()
{
   ${rscripts}/check_for_zombie_jobs $*
}

change_jobname()
{
   if test $# -eq 1; then
      oldname=NightlySave
      newname=$1
   else
      oldname=$1
      newname=$2
   fi
   rm -f $tmp/1 $tmp/2
   mv ${conf}/bacula-dir.conf $tmp/1
   echo "s%${oldname}%${newname}%g" >$tmp/2
   sed -f $tmp/2 $tmp/1 >$conf/bacula-dir.conf
#  echo "Job ${oldname} changed to ${newname}"
}

check_two_logs()
{
   bstat=${bstat:-99}   # We must find at least one job in log1.out
   echo "$TestName" | grep restart.*-test > /dev/null
   restartjob=0
   if [ $? -eq 0 ]; then
      restartjob=1
   fi
   grep "^  Termination: *Backup OK" ${tmp}/log1.out 2>&1 >/dev/null
   if test $? -ne 0; then
      bstat=2
   fi
   grep "^  Termination: .*Backup Error" ${tmp}/log1.out 2>&1 >/dev/null
   if test $? -eq 0; then
      bstat=2
   fi
   # Do not check for restart jobs in restart tests
   if [ $restartjob = 0 ]; then
      grep "^  Termination: .*Backup failed" ${tmp}/log1.out 2>&1 >/dev/null
      if test $? -eq 0; then
         bstat=3
      fi
   fi
   grep "^  Termination: *Restore OK" ${tmp}/log2.out 2>&1 >/dev/null
   rstat=${rstat:-$?}
   grep "^  Termination: .*Restore Error" ${tmp}/log2.out 2>&1 >/dev/null
   if test $? -eq 0; then
      rstat=2
   fi
   if [ $restartjob = 0 ]; then
      grep "SD Errors: *[1-9]" ${tmp}/log1.out 2>&1 >/dev/null
      if test $? -eq 0; then
         bstat=3
      fi
   fi
   grep "^  Termination: *Restore OK -- warning file count mismatch" ${tmp}/log2.out 2>&1 >/dev/null
   if test $? -eq 0; then
      rstat=3
   fi
   grep "^  Termination: .*Verify Differences" ${tmp}/log2.out 2>&1 >/dev/null
   if test $? -eq 0; then
      vstat=4
   fi
   grep "Encoding error for database" ${tmp}/log1.out > /dev/null
   if test $? -eq 0; then
      print_debug "Found database encoding error"
      bstat=2
   fi
   grep "Orphaned buffer" ${tmp}/log1.out ${tmp}/log2.out
   if test $? -eq 0; then
      print_debug "ERROR: Found orphaned buffers in log1.out or log2.out"
      estat=1
   fi
   if [ x$REGRESS_CHECK_CORRUPTION = xyes ]; then
       perl -Mscripts::functions -e "check_volumes('$tmp/log1.out', '$tmp/log2.out')" 2>&1 >/dev/null
       if test $? -ne 0; then
           print_debug "ERROR: Found volume corruption"
           estat=1
       fi
   fi
}

die_dde()
{
   code=$1
   msg=$2

   print_debug $msg
   stop_bacula

   if test "$code" -gt "$ddestat" ; then
      ddestat=$code
   fi
   end_test
   exit 1
}

die_test()
{
   code=$1
   msg=$2

   print_debug $msg
   stop_bacula

   if test "$code" -gt "$estat" ; then
      estat=$code
   fi
   end_test
   exit 1
}

die_early()
{
   msg=$1
   print_debug $msg
   exit 2
}

#
# must be called just after "functions" by tests that can run only when dedup is on
#
check_dedup_enable()
{
   dedup_drivers=${1:-Legacy}
   if [ "$FORCE_DEDUP" != "yes" ] ; then
      echo "This test is dedicated to DEDUP, set variable FORCE_DEDUP to 'yes'"
      exit 0
   fi
   if [ "$DEDUP_FS_OPTION" != "bothsides" -a "$DEDUP_FS_OPTION" != "storage" -a "$DEDUP_FS_OPTION" != "none" ] ; then
      echo "variable DEDUP_FS_OPTION must be set to bothsides, storage or none"
      exit 1
   fi
   if [ -n $dedup_drivers ] ; then
      # a list of valid drivers for the test has been specified
      # check if one match the active one
      active_driver=${DEDUP_DRIVER=:-Legacy}
      result="no"
      for driver in $dedup_drivers ; do
         if [ "$driver" = "$active_driver" ] ; then
            result="ok"
            break
         fi
      done
      if [ $result != ok ] ; then
         echo "This test is designed for dedup drivers: "$dedup_drivers", not $active_driver"
         exit 0
      fi
   fi
}


#
# be sure that dedup is on and DDE will receive data
#
check_dedup_forced()
{
   check_dedup_enable $*
   if [ "$DEDUP_FS_OPTION" = "none" ] ; then
      echo "This test expect to see the DDE grow then DEDUP_FS_OPTION cannot be none"
      exit 0
   fi
}

#
# load all the modules required by query_dde, if not yet loaded
#
require_query_dde()
{
   QUERY_DDE_ADVANCED="yes" $rscripts/query_dde.py checkmodules
   if [ $? -eq 0 ] ; then
      return
   fi
   local query_dde_url=https://www.baculasystems.com/ml/ohweekah9WawuiB/depkgs-query-dde
   local name
   for name in lz4.so pytc.so argparse.py ; do
      if [ ! -f $rscripts/$name ] ; then
         if ! wget -O $rscripts/$name $query_dde_url/$name ; then
            echo Failed to load $query_dde_url/$name
            exit 1
         fi
      fi
   done
}

check_dedupengine_health()
{
   local logfile=$1
   if grep "dde_errors=[1-9]" $logfile >/dev/null; then
      ddestat=99
   fi
   if grep "containers_errors=[1-9]" $logfile >/dev/null; then
      ddestat=99
   fi
   if grep "vacuum_errors=[1-9]" $logfile >/dev/null; then
      ddestat=99
   fi
}

check_dde_status()
{
   local filename="$1"
   local hash_count=$2
   local chunk_used=$3

   grep "DDE:" ${filename} | grep "hash_count=${hash_count}" >/dev/null && \
      grep "Containers:" ${filename} | grep "chunk_used=${chunk_used}" >/dev/null
}

is_dde_empty()
{
   filename="$1"
   check_dde_status "$filename" 0 0
}

dtitle()
{
   if test "$debug" -eq 1 ; then
      echo "============================================================"
      echo $*
      echo "============================================================"
   fi
}

dmsg()
{
   test "$debug" -eq 1 && echo $*
}

check_size_interval()
{
   # if mi == -1 then then ignore mi (idem for ma)
   mi=$1
   value=$2
   ma=$3

   test \( -1 -eq $mi -o $mi -le $value \) -a \( -1 -eq $ma -o $value -le $ma \)
}

check_restore_diff()
{
   if test "$debug" -eq 1 ; then
      $rscripts/diff.pl -notop -s ${src} -d ${tmp}/bacula-restores${src} 2>&1 >/tmp/d$$
      if test $? -ne 0; then
         dstat=1
         cat /tmp/d$$
         ls -Rl ${src}
         ls -Rl ${tmp}/bacula-restores${src}
      fi
      rm -f /tmp/d$$
      diff -ur ${src} ${tmp}/bacula-restores${src}
   else
      $rscripts/diff.pl -notop -s ${src} -d ${tmp}/bacula-restores${src} 2>&1 >/dev/null
      if test $? -ne 0; then
         dstat=1
      fi
      diff -ur ${src} ${tmp}/bacula-restores${src} 2>&1 >/dev/null
   fi
   if test $? -ne 0; then
     dstat=1
   fi
}

check_restore_bin_diff()
{
   if test "$debug" -eq 1 ; then
      $rscripts/diff.pl -notop -s ${bin} -d ${tmp}/bacula-restores${bin} 2>&1 >/tmp/d$$
      if test $? -ne 0; then
         dstat=1
         cat /tmp/d$$
         ls -Rl ${src}
         ls -Rl ${tmp}/bacula-restores${src}
      fi
      rm -f /tmp/d$$
      diff -ur ${bin} ${tmp}/bacula-restores${bin}
   else
      $rscripts/diff.pl -notop -s ${bin} -d ${tmp}/bacula-restores${bin} 2>&1 >/dev/null
      if test $? -ne 0; then
         dstat=1
      fi
      diff -ur ${bin} ${tmp}/bacula-restores${bin} 2>&1 >/dev/null
   fi
   if test $? -ne 0; then
      dstat=1
   fi
}


check_restore_tmp_build_diff()
{
   if test "$debug" -eq 1 ; then
      $rscripts/diff.pl -notop -s ${tmpsrc} -d ${tmp}/bacula-restores${tmpsrc} 2>&1 >/tmp/d$$
      if test $? -ne 0; then
         dstat=1
         cat /tmp/d$$
         ls -Rl ${src}
         ls -Rl ${tmp}/bacula-restores${src}
      fi
      rm -f /tmp/d$$
      diff -ur ${tmpsrc} ${tmp}/bacula-restores${tmpsrc}
   else
      $rscripts/diff.pl -notop -s ${tmpsrc} -d ${tmp}/bacula-restores${tmpsrc} 2>&1 >/dev/null
      if test $? -ne 0; then
         dstat=1
      fi
      diff -ur ${tmpsrc} ${tmp}/bacula-restores${tmpsrc} 2>&1 >/dev/null
   fi
   if test $? -ne 0; then
      dstat=1
   fi
}

# bstat is backup error
# dstat is diff difference
# estat is special error status (shown by print_debug message)
# rstat is restore status
# zstat is zombie job(s)
# vstat is verify status
# ddestat is dedupengine error
#
end_test()
{
   if [ x$notracedump != xyes ]; then
      cat ${working}/bacula.*.traceback 2>/dev/null
      cp -f  ${working}/bacula.*.traceback ${dumps} 2>/dev/null
   fi
   if [ -f $tmp/err.log ]; then
      cat $tmp/err.log
   fi
   d=`./test_duration`
   t=`date +%R:%S`
   if [ "$ddestat" != 0 ] ; then
      echo " " | tee -a test.out
      echo "  !!!!! $TestName ${variant_name} failed!!! $t $d !!!!! " | tee -a test.out
      echo "     Status: estat=$estat zombie=$zstat backup=$bstat restore=$rstat diff=$dstat verify=$vstat dde=$ddestat" | tee -a test.out
      echo " "
      exit 1
   fi
   if [ $estat != 0 ] ; then
      echo " "
      echo "  !!!!! $TestName ${variant_name} failed!!! $t $d !!!!! "
      echo "     Status: estat=$estat zombie=$zstat backup=$bstat restore=$rstat diff=$dstat verify=$vstat"
      echo " " >>test.out
      echo "  !!!!! $TestName ${variant_name} failed!!! $t $d !!!!! " >>test.out
      echo "     Status: estat=$estat zombie=$zstat backup=$bstat restore=$rstat diff=$dstat verify=$vstat" >>test.out
      echo " "
      exit 1
   fi
   if [ $zstat != 0 ] ; then
      echo " "
      echo "  !!!!! $TestName ${variant_name} failed!!! $t $d !!!!! "
      echo "     Status: zombie=$zstat backup=$bstat restore=$rstat diff=$dstat verify=$vstat"
      echo " " >>test.out
      echo "  !!!!! $TestName ${variant_name} failed!!! $t $d !!!!! " >>test.out
      echo "     Status: zombie=$zstat backup=$bstat restore=$rstat diff=$dstat verify=$vstat" >>test.out
      echo " "
      exit 1
   fi
   if [ $dstat != 0 -o $bstat != 0 -o $rstat != 0 -o $vstat != 0 ] ; then
      echo " "
      echo "  !!!!! $TestName ${variant_name} failed!!! $t $d !!!!! "
      echo "     Status: zombie=$zstat backup=$bstat restore=$rstat diff=$dstat verify=$vstat"
      echo " " >>test.out
      echo "  !!!!! $TestName ${variant_name} failed!!! $t $d !!!!! " >>test.out
      echo "     Status: zombie=$zstat backup=$bstat restore=$rstat diff=$dstat verify=$vstat" >>test.out
      if [ $bstat != 0 -o $rstat != 0 -o $vstat != 0 ] ; then
         echo "     !!! Bad termination status       !!! "
         echo "     !!! Bad termination status       !!! " >>test.out
      else
         echo "     !!! Restored files differ        !!! "
         echo "     !!! Restored files differ        !!! " >>test.out
      fi
      echo "     Status: backup=$bstat restore=$rstat diff=$dstat verify=$vstat"
      echo "     Status: backup=$bstat restore=$rstat diff=$dstat verify=$vstat" >>test.out
      echo "     Test owner of $SITE_NAME is $EMAIL"
      echo "     Test owner of $SITE_NAME is $EMAIL" >>test.out
      echo " " >>test.out
      echo " "
      exit 1
   else
      # KES -- remove variant to make line fit in 80 chars
      echo "  ===== End $TestName OK $t $d ===== "
      echo "  ===== End $TestName OK $t $d ===== " >>test.out
      if test "$debug" -eq 0 ; then
         ${rscripts}/cleanup
      fi
   fi
}

copy_tape_confs()
{
   ${rscripts}/copy-tape-confs
   ${rscripts}/cleanup-tape
}

copy_test_confs()
{
   ${rscripts}/copy-test-confs
   ${rscripts}/cleanup
}

disable_plugins()
{
   local i
   for i in ${conf}/bacula-fd.conf; do
      sed 's/Plugin/#Plugin/' $i > $tmp/1
      cp -f $tmp/1 $i
   done
}

update_win32()
{
   if [ -d $cwd/build/src/win32/release32   \
     -o -d $cwd/build/src/win32/release64 ] \
   || [ -d $cwd/release32 -o -d $cwd/release64 ] \
   || [ -d $cwd/../bacula/src/win32/release32 \
     -o -d $cwd/../bacula/src/win32/release64 ]
   then
       echo "Try to upgrade the FileDaemon:\t"
       wget -qO - "$WIN32_ADDR:8091/install"
   else
       echo "Windows binaries not found, skiping upgrade"
   fi
}

debug_wait()
{
  if test "x${REGRESS_WAIT}" = "x1"; then
     echo "Start Bacula under debugger and enter anything when ready ..."
     read a
  fi
}

init_slot()
{
   DRIVE=$1
   SLOT=$2
   if test -n "$DRIVE" -a -n "$SLOT"; then
      if test ! -c $DRIVE -a ! -b $DRIVE -a x$USE_VTAPE != x ; then
         dir=`dirname $DRIVE`
         if [ ! -d "$dir" ]; then
            mkdir -p "$dir"
         fi
         touch $dir/slot$SLOT
      fi
   fi
}

init_drive()
{
  if test a$USE_VTAPE = a; then
    mt -f $1 rewind
    mt -f $1 weof
  else
    cp /dev/null $1
  fi
}

rewind_drive()
{
  if test a$USE_VTAPE = a; then
    mt -f $1 rewind
  fi
}

load_slot1()
{
# Get a tape from slot1
slot=`${scripts}/$MTX ${AUTOCHANGER} loaded 0 ${TAPE_DRIVE} $DRIVE1`
case $slot in
 0)
    ${scripts}/$MTX ${AUTOCHANGER} load $SLOT1 ${TAPE_DRIVE} $DRIVE1
    slot=$SLOT1
    ;;
 $SLOT1)
    slot=$SLOT1
    ;;
 *)
    rewind_drive ${TAPE_DRIVE}
    ${scripts}/$MTX ${AUTOCHANGER} unload $slot  ${TAPE_DRIVE} $DRIVE1
    ${scripts}/$MTX ${AUTOCHANGER} load   $SLOT1 ${TAPE_DRIVE} $DRIVE1
    slot=$SLOT1
    ;;
esac
}

#
# $1 has currently loaded slot, load the other one i.e. if 1, load 2;
#    if 2, load 1; if 0 load 1
#
load_other_slot()
{
rewind_drive ${TAPE_DRIVE}
case $1 in
 0)
    ${scripts}/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} load $SLOT1 ${TAPE_DRIVE} $DRIVE1
    slot=1
    ;;
 $SLOT1)
    ${scripts}/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} unload $1 ${TAPE_DRIVE} $DRIVE1
    ${scripts}/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} load $SLOT2 ${TAPE_DRIVE} $DRIVE1
    slot=2
    ;;
 $SLOT2)
    ${scripts}/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} unload $1 ${TAPE_DRIVE} $DRIVE1
    ${scripts}/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} load $SLOT1 ${TAPE_DRIVE} $DRIVE1
    slot=1
    ;;
 *)
    echo "Something went wrong. Expected $SLOT1 or $SLOT2, got $1"
    exit 1
    ;;
esac
}

check_variable()
{
   if [ "x$1" = "x" ]
   then
       echo "Variable $2 not set."
       exit -1
   fi
}

check_path()
{
   if [ ! -d $1 ]
   then
       echo "Path $2 does not exist: $1"
       exit -1
   fi
}

check_file()
{
   if [ ! -f $1 ]
   then
       echo "File $2 does not exist: $1"
       exit -1
   fi
}

# Save current directory
cwd=`pwd`
if test "x${REGRESS_DEBUG}" = "x1"; then
   set_debug 1
else
   set_debug 0
fi

# Source the configuration variables
. ${cwd}/config

db_name=${db_name:-"regress"}
db_user=${db_user:-"regress"}
db_password=${db_password:-""}
working=${working:-"$cwd/working"}
dumps=${dumps:-"$cwd/dumps"}
bin=${bin:-"$cwd/bin"}
FORCE_DEDUP=${PREVAIL_FORCE_DEDUP:-$FORCE_DEDUP}
DEDUP_FS_OPTION=${PREVAIL_DEDUP_FS_OPTION:-$DEDUP_FS_OPTION}
DEDUP_FD_CACHE=${PREVAIL_DEDUP_FD_CACHE:-$DEDUP_FD_CACHE}
PERL5LIB=${PERL5LIB}:$cwd

# Bacula scripts
scripts=${scripts:-"$cwd/bin"}

# Bacula conf files
conf=${conf:-"$cwd/bin"}

# Regress scripts
rscripts=${rscripts:-"$cwd/scripts"}

tmp=${tmp:-"$cwd/tmp"}

# Bacula source directory when copied here
#  also build directory
src=${src:-"$cwd/build"}

# Temp source directory so we don't mess up $src
tmpsrc=${tmpsrc:-"$cwd/tmp/build"}

# Unit Tests source directory
unitsrc=${unitsrc:-"$cwd/src"}

estat=0
bstat=0
rstat=0
ddestat=0
zstat=0
dstat=0
vstat=0
export estat bstat rstat ddestat zstat dstat vstat


export bin
export conf
export working
export dumps
export scripts
export rscripts
export tmp
export src
export tmpsrc
export PERL5LIB
export unitsrc

bperl="perl -Mscripts::functions"
export bperl
btools="$scripts/btools.py"
export btools

mkdir -p ${tmp}
touch ${tmp}/dir.out ${tmp}/fd.out ${tmp}/sd.out

CLIENT=${HOST}-fd

if [ x$USE_VTAPE = xyes ]; then
   mkdir -p $working/ach
   SLOT1=1
   SLOT2=2
   TAPE_DRIVE=$working/ach/drive0
   TAPE_DRIVE1=$working/ach/drive1
   AUTOCHANGER=$working/ach/config
   AUTOCHANGER_SCRIPT=disk-changer
   DRIVE1=0
   DRIVE2=1
   cp /dev/null $working/ach/slot$SLOT1
   cp /dev/null $working/ach/slot$SLOT2
   cat > $AUTOCHANGER <<EOF
maxdrive=8
maxslot=80
EOF
fi

AUTOCHANGER_SCRIPT=${AUTOCHANGER_SCRIPT:-mtx-changer}
LD_LIBRARY_PATH=$bin:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH

trap "{ estat=999; end_test; }" TERM
