#!/bin/bash
# /etc/bacula/scripts/_restore_multiples_version_of_file.sh
# Config
DBUSER="bacula"                      # database user
DBPASSWORD="bacula"                  # databse password
DBNAME="bacula"                      # database name

RESTOREDIR="/tmp/bacula_restore"     # directory to restore
BSRDIR="${RESTOREDIR}/bsr"           # directory for bootstrap files
SDCONF="/etc/bacula/bacula-sd.conf"  # path to bacula-sd.conf
DEVICE="/mnt/disco01"                # path to storage

BCONSOLE="/sbin/bconsole"            # path to bconsole
BLS="/sbin/bls"                      # path to bls
BEXTRACT="/sbin/bextract"            # path to bextract
DEFAULT=1                            # if 1 use bconsole - else if 2 use bextract (restore just in bacula server)


# Create folders 
if [ ! -d "${RESTOREDIR}" ]; then
   echo -ne "Directory \"${RESTOREDIR}\" not found! Will be created...\n"
   mkdir "${RESTOREDIR}"
fi

if [ ! -d "${BSRDIR}" ]; then
   echo -ne "Directory \"${BSRDIR}\" not found! Will be created...\n"
   mkdir "${BSRDIR}"
fi


# Exlude all bootstrapfiles
rm -Rf ${BSRDIR}/*.bsr


# List clients from bconsole
echo -ne "List Jobs where a given File is saved\n"
echo -ne "Defined Clients:\n"
CLIENTS=(`echo ".clients" | bconsole | sed '1,4d' | grep -v "You have messages"`)
count=0
for i in ${CLIENTS[@]}; do count=`expr $count + 1`; printf "%5s:%s\n" $count $i; done

echo -ne "Select the Client (1-$count): "
read CLIENTID


# Read client
while [ ${CLIENTID} -eq 0 ] || [ ${CLIENTID} -gt ${#CLIENTS[@]} ]; do
   if [ ${CLIENTID} -eq 0 ] || [ ${CLIENTID} -gt ${#CLIENTS[@]} ]; then
      echo -ne "Select the Client (1-$count): ";
      read CLIENTID
   else
     break
   fi
done
CLIENTNAME=${CLIENTS[$CLIENTID-1]};
echo -ne "\nClient selected: ${CLIENTNAME}\n"

# List restore clients from bconsole
echo -ne "\nDefined Restore Clients:\n"
count=0
for i in ${CLIENTS[@]}; do count=`expr $count + 1`; printf "%5s:%s\n" $count $i; done
echo -ne "Select the Restore Client (1-$count): "
read RESTORECLIENTID

# Read client
while [ ${RESTORECLIENTID} -eq 0 ] || [ ${RESTORECLIENTID} -gt ${#CLIENTS[@]} ]; do
   if [ ${RESTORECLIENTID} -eq 0 ] || [ ${RESTORECLIENTID} -gt ${#CLIENTS[@]} ]; then
      echo -ne "Select the Client (1-$count): ";
      read RESTORECLIENTID
   else
     break
   fi
done
RESTORECLIENTNAME=${CLIENTS[$RESTORECLIENTID-1]};
echo -ne "\nRestore Client selected: ${RESTORECLIENTNAME}\n"


# Read filename
echo -ne "\nType filename without path: "
read FILENAME
FILENAME=`echo ${FILENAME} | sed 's/^"\(.*\)"$/\1/'`
echo -ne "\n"

# Read filepth
echo -ne "Type part or full path or leave blank: "
read FILEPATH
FILEPATH=`echo ${FILEPATH} | sed 's/^"\(.*\)"$/\1/'`
echo -ne "\n"


# Query SQL get JobId's where file is
sql_query="SELECT Job.JobId as JobId,cast(CONCAT(Path.Path,Filename.Name) as char) as Name, StartTime,cast(Type as char) as JobType, cast(JobStatus as char) as JobStatus,JobFiles,JobBytes 
FROM Client,Job,File,Filename,Path
WHERE Client.Name='${CLIENTNAME}' AND Client.ClientId=Job.ClientId AND Job.JobId=File.JobId 
AND File.FileIndex > 0 AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId
AND Filename.Name='${FILENAME}' and Path.Path like '%${FILEPATH}%'
ORDER BY StartTime DESC limit 20"
query=`mysql -u ${DBUSER} -p${DBPASSWORD} -D ${DBNAME} -t -N -e "$sql_query"`

# if not found files exit
if [ `echo -ne "$query" | wc -l` -eq 0 ]; then
  echo "No files were found! Try again!"
  exit
fi 

echo -ne "$query\n\n"

echo -ne "Enter JobId(s), comma separated, to restore: "
read JOBIDS
JOBIDS=`echo $JOBIDS | sed 's/[^0-9,]//g'`

if [ "${JOBIDS}" == "" ]; then
  echo "No JobId's selected!"
  exit
fi 

# Start restore
JOBIDS=`echo ${JOBIDS} | tr "," " "`
for j in ${JOBIDS}; do 
   echo -ne "$query" | sed '1d;$d' | while read i; do
     JOBID=`echo $i | cut -d"|" -f2 | sed 's/^ \(.*\) $/\1/'`;
     FILENAME=`echo $i | cut -d"|" -f3 | sed 's/^ \(.*\) $/\1/'`;
     STARTTIME=`echo $i | cut -d"|" -f4 | sed 's/^ \(.*\) $/\1/' | sed 's/ /_/g' | sed 's/[^0-9_]//g'`;
     if [ ${JOBID} -eq $j ]; then
        
        # Check if directory not exists and create
        if [ ! -d "$RESTOREDIR/${JOBID}_${STARTTIME}" ]; then
           echo -ne "\nDirectory \"$RESTOREDIR/${JOBID}_${STARTTIME}\" not found! Will be created...\n"
           mkdir "$RESTOREDIR/${JOBID}_${STARTTIME}"
        else
           echo -ne "\nDirectory already \"$RESTOREDIR/${JOBID}_${STARTTIME}\" exists!\n"
        fi

        # Restore using bconsole  
        if [ ${DEFAULT} -eq 1 ]; then
           echo -ne "restore jobid=${JOBID} client=${CLIENTNAME} restoreclient=${RESTORECLIENTNAME} file=\"${FILENAME}\" where=${RESTOREDIR}/${JOBID}_${STARTTIME} bootstrap=${BSRDIR}/${JOBID}_${STARTTIME}.bsr\nyes\n" | ${BCONSOLE}       

        # Restore using bextract
        elif [ ${DEFAULT} -eq 2 ]; then
           echo -ne "restore jobid=${JOBID} client=${CLIENTNAME} restoreclient=${RESTORECLIENTNAME} file=\"${FILENAME}\" where=${RESTOREDIR} bootstrap=${BSRDIR}/${JOBID}_${STARTTIME}.bsr\nno\n" | ${BCONSOLE} > /dev/null
           echo -ne "${BLS} -c ${SDCONF} -b ${BSRDIR}/${JOBID}_${STARTTIME}.bsr ${DEVICE}\n" 
           ${BLS} -c ${SDCONF} -b ${BSRDIR}/${JOBID}_${STARTTIME}.bsr ${DEVICE}
           echo "Restoring files in: \"$RESTOREDIR/${JOBID}_${STARTTIME}\""
           ${BEXTRACT} -c ${SDCONF} -b ${BSRDIR}/${JOBID}_${STARTTIME}.bsr ${DEVICE} "${RESTOREDIR}/${JOBID}_${STARTTIME}"
        fi
     fi
   done
done
echo "All files were restored!"
