#!/bin/bash

# CryptBackup
# GUI to backup the home directory to an encrypted external device
# Version: 10.02.05 by Markus Mandalka - http://mandalka.name

if [ -e /usr/bin/Xdialog ]
then
  DIALOG="Xdialog"
else
  DIALOG="dialog"
fi

# Language and messages

title_no_setup="No setup"
msg_no_setup="There is no backup-setup for this user.\n\nSetup a backup device using the tool in System / Setup / Backup!"
title_no_mountpoints="The device is not mounted"
msg_no_mountpoints="There is no mounted backup-device.\n\nPlesase plug a device setupped as backup\nand give the system access to it\nwith the right password!\n\nOr create another backup device with the Tool\nSystem / Setup / Backup."
title_backup="Sync the backup?"
msg_backup="The device for the backup is mounted.

Write changed and new files from your home directory to the backup?

Warning: This will not only backup new files and overwrite changed files
on your backup, but it will delete files, which you deleted in your home, too!"
msg_rsync="Syncing the backup on device "
title_error_rsync="Error" 
msg_error_rsync="Error while syncing! The backup may not be complete!\n\nMaybe there is not enough free space on the backup device\nor you deleted files while the backup process was running."
msg_sync="Writing buffers..."
msg_done="Backup done"
title_ask_umount="Backup done - Unmount device?"
msg_ask_umount="Backup done. Unmount?"
msg_umount="Umount backup device"
msg_umount_done="Device unmounted. You are allowed to remove it."
title_error_umount="Unmounting failed!"
msg_error_umount="Unmount failed! Maybe another software is accessing the device."
title_umount_done="Device unmounted"

case "$LANG" in
de*|at*|ch*)

title_no_setup="Backup noch nicht eingerichtet"
msg_no_setup="Bisher wurde für diese(n) BenutzerIn noch kein Backup-Datenträger eingerichtet!

Sie können dies nach dem Anschliessen
des hierfür vorgesehenen Datenträgers mit

System / Systemverwaltung / Backup einrichten

durchführen."
title_no_mountpoints="Keinen Backup-Datenträger gefunden"
msg_no_mountpoints="Momentan ist kein Backup-Datenträger eingebunden.\n\nBitte schliessen Sie ein als Backup-Datenträger\neingerichtetes Gerät an und binden Sie es ein,\nindem Sie das dafür verlangte Passwort eingeben!\n\nOder Sie richten mit\nSystem / Einstellungen / Backup einrichten\neinen weiteren Backup-Datenträger ein."
title_backup="Backup-Datenträger gefunden"
msg_backup="Backup-Datenträger gefunden.\n\nSoll das darauf enthaltene Backup\nmit den Änderungen seit dem letzten Durchlauf\naktualisiert werden?\n\nDabei werden nicht nur neue und geänderte Dateien gesichert,\n sondern die aus Ihrem persönlichen Verzeichnis\ngelöschten Dateien auch im Backup gelöscht!\n\nBackup aktualisieren?"
msg_rsync="Aktualisiere das Backup auf dem Gerät "
title_error_rsync="Fehler beim Synchronisieren"
msg_error_rsync="Beim Synchronisieren ist ein Fehler aufgetreten!\n\nDas Backup konnte deshalb nicht oder nur teilweise durchgeführt werden!\n\nEntweder gibt es zu wenig freien Speicherplatz auf dem Zieldatenträger\noder Sie haben beim Start vorhandene Dateien während des Backup-Vorgangs gelöscht."
msg_sync="Schreibe die restlichen evtl. noch gepufferte Daten auf den Datenträger ..."
msg_done="Backup komplett"
title_ask_umount="Backup durchgeführt - Datenträger aushängen?"
msg_ask_umount="Das Aktualisieren des Backups ist abgeschlossen.\n\nSoll der Datenträger ausgehängt werden?"
msg_umount="Hänge die Backup-Partition aus"
title_umount_done="Datenträger ausgehängt"
msg_umount_done="Der Datenträger wurde erfolgreich ausgehängt.\n\nSie können den Datenträger nun abschalten oder entfernen."
title_error_umount="Aushängen fehlgeschlagen!"
msg_error_umount="Das Aushängen des Datenträgers ist fehlgeschlagen! Unter Umständen greift noch andere Software auf den Datenträger zu."

;;
esac

# Search all mounted luks partitions for backup-directories
# Result: list of directories maching backup-id of the user
# Version: 2009.12.03 by Andreas Mandalka
function get_backup_mountpoints() {
    
    #(all mounted luks partitions are listed in /dev/mapper)
    for i in $(ls /dev/mapper);
    do
	[ ${i} == "control"  ] && continue 	#we don't need "control"
	SV_MOUNTPOINT=$(mount | grep "${i}" | cut -d' ' -f 3)	#extract mountpoint
	
	#Search ID directory in mountpoint
	BACKUP_ID=$(cat ${HOME}/.cryptbackup)
	[ -e "${SV_MOUNTPOINT}/${BACKUP_ID}" ] && SV_LIST="$SV_MOUNTPOINT ${SV_LIST}"
	#if ID directory exists, add it to the list
    done

    # Debian Lenny creates /dev/dm-X instead of /dev/mapper/X
    # while automounting encrypted devices
    if [ -z $SV_LIST ]
    then
    for i in $(ls /dev/dm-*);
    do
	[ ${i} == "control"  ] && continue 	#we don't need "control"
	SV_MOUNTPOINT=$(mount | grep "${i}" | cut -d' ' -f 3)	#extract mountpoint
	
	#Search ID directory in mountpoint
	BACKUP_ID=$(cat ${HOME}/.cryptbackup)
	[ -e "${SV_MOUNTPOINT}/${BACKUP_ID}" ] && SV_LIST="$SV_MOUNTPOINT ${SV_LIST}"
	#if ID directory exists, add it to the list
    done
    fi

    

    echo "$SV_LIST"
    return 0
} 


# Change title of the window
echo -en "\033]2;CryptBackup\007"

echo "CryptBackup v10.02.05"
echo "Copyleft by Markus Mandalka - http://mandalka.name"
echo
echo "Powered by rsync, cryptsetup, dm-crypt/luks, xdialog, bash, gnu/linux ..."
echo

if [ ! -e ${HOME}/.cryptbackup ]
then
 echo "$title_no_setup"
 
 $DIALOG --title "$title_no_setup" --msgbox "$msg_no_setup" 0 0

 exit 0
fi;


BACKUP_ID=$(cat ${HOME}/.cryptbackup)

BACKUP_MOUNTPOINTS=$(get_backup_mountpoints)


if [ ! $BACKUP_MOUNTPOINTS ]; then
  echo "$title_no_mountpoints"
  $DIALOG --title "$title_no_mountpoints" --msgbox "$msg_no_mountpoints" 0 0
  exit 0;
fi


for BACKUP_MOUNTPOINT in $BACKUP_MOUNTPOINTS
do

  if ! $DIALOG --title "$title_backup" --yesno "$msg_backup" 0 0
  then
    exit
  fi


  if [ ! -e $BACKUP_MOUNTPOINT/${BACKUP_ID}/home ]; then
    echo "Creating directory ${BACKUP_MOUNTPOINT}/${BACKUP_ID}/home"

    if ! mkdir ${BACKUP_MOUNTPOINT}/${BACKUP_ID}/home
    then
      echo "Error: Error while mkdir $BACKUP_MOUNTPOINT/${BACKUP_ID}/home !"
      $DIALOG --title "Error" --msgbox "Error: Error while mkdir $BACKUP_MOUNTPOINT/${BACKUP_ID}/home !" 0 0

      exit 1
    fi;
  fi;

  echo "${msg_rsync}${BACKUP_MOUNTPOINT}"
  if ! rsync -P -a -v --delete ${HOME} ${BACKUP_MOUNTPOINT}/${BACKUP_ID}/home
  then
      echo "$title_error_rsync"
      $DIALOG --title "$title_error_rsync" --msgbox "$msg_error_rsync" 0 0

    exit 1
  fi;

  echo
  echo "$msg_sync"
  sync
  echo
  echo $msg_done


  if $DIALOG --title "$title_ask_umount" --yesno "$msg_ask_umount" 0 0
  then

    echo "$msg_umount"
    if ! umount ${BACKUP_MOUNTPOINT}
    then
      echo "$title_error_umount"
      $DIALOG --title "$title_error_umount" --msgbox "$msg_error_umount" 0 0
      exit 1
    else
      echo "$title_umount_done"
      $DIALOG --title "$title_umount_done" --msgbox "$msg_umount_done" 0 0
    fi
  fi


done;
