#!/bin/bash
# Gui for making a xfs .dat container in which changes are saved
# when using a FAT file system.

# Switch to root
if [ `whoami` != "root" ]; then
    echo "Please enter your root password below"
    su - -c "/opt/porteus-scripts/make-changes.sh" || sleep 1
    exit
fi

. /usr/lib/macroport

NM=save.dat
WRK=/tmp/savdat_$$
TITLE="Porteus save.dat manager"

setup(){
[ -d $WRK ] && rm -rf $WRK
mkdir $WRK
}

chkbut(){
case $? in
	1 )
	rm -rf $WRK
	exit
	;;
	255 )
	rm -rf $WRK
	exit
	;;
esac
}

cleanup(){
[ -d $WRK ] && rm -rf $WRK
if [ -d /mnt/olddat ]; then
  umount /mnt/olddat >/dev/null 2>&1
  rm -rf /mnt/olddat
fi

if [ -d /mnt/newdat ]; then
  umount /mnt/newdat >/dev/null 2>&1
  rm -rf /mnt/newdat
fi
}

get_name(){
input "Enter a name for new save.dat file"
NAM=${ANSW}
NAME=`echo $NAM|sed 's/.dat//'`
}

get_place(){
Xdialog --title "$TITLE" --backtitle \
"Please choose a place to create your save.dat" \
--fselect / 0 0 2> $WRK/.savdir
chkbut
TARG=`cat $WRK/.savdir`
yesno "Please confirm that you chose \n\n$TARG\n"
[ $? -eq 1 ] && get_place
}

get_size(){
Xdialog --title "$TITLE" --no-cancel --rangebox \
"Use slider (or arrow keys) to choose a size (Mb) for your save.dat " \
0 0 64 10000 2> $WRK/size.txt
chkbut
SIZE=`cat $WRK/size.txt`
BYTES=$(($SIZE*1024))
}

check_free_space(){
FSPACEB=`df $TARG|tail -n1|awk '{print$4}'`
FSPACE=$(($FSPACEB/1024))
if [ $SIZE -gt $FSPACE ]; then
message "Sorry, there is not enough space at:\n$TARG"
chkbut
get_size
fi
}

create_dat_file(){
Xdialog --wrap --left --stdout --no-buttons --infobox "Processing - wait few seconds..." 0 0 3000 &
dd if=/dev/zero of=$TARG/$NAME.dat bs=1024 count=$BYTES 2> /dev/null &
P=`pgrep -l '^dd$'|awk '{print$1}'`
# Get amount completed in bytes
sleep 3
COUNT=10
while [ $COUNT -lt $SIZE ]; do
COUNT=`du -h $TARG/$NAME.dat|awk '{print$1}'|sed 's/\(.*\)./\1/'`
#echo $COUNT
echo "XXX"
echo "Building save.dat ($COUNT Mb)"
echo "XXX"
COUNT=`du -h $TARG/$NAME.dat|awk '{print$1}'|sed 's/\(.*\)./\1/'`
done
}

check_free_loop_device(){
x=`grep /dev/loop /proc/mounts | tail -n1 | cut -d " " -f1 | sed 's@/dev/loop@@'`; let y=x+1
loop=/dev/loop$y
if [ ! -e $loop ]; then mknod $loop b 7 $y; fi
}

format_dat_file(){
check_free_loop_device
losetup $loop $TARG/$NAME.dat
mkfs.xfs $loop > /dev/null 2>&1
sleep 2
losetup -d $loop
}

get_old_dat(){
Xdialog --title "$TITLE" --backtitle \
"Please select the save container you wish to modify: " \
--fselect /mnt 0 0 2> $WRK/.orig
chkbut
RFILE=`cat $WRK/.orig`
RPATH=${RFILE%/*}
}

mount_old_dat(){
if [ -d /mnt/olddat ]; then
  umount /mnt/olddat >/dev/null 2>&1
  rm -rf /mnt/olddat
fi
mkdir /mnt/olddat
check_free_loop_device
mount -o loop $RFILE /mnt/olddat
}

mount_new_dat(){
if [ -d /mnt/newdat ]; then
  umount /mnt/newdat >/dev/null 2>&1
  rm -rf /mnt/newdat
fi
mkdir /mnt/newdat
check_free_loop_device
mount -o loop $TARG/$NAME.dat /mnt/newdat
}

copy_old_new(){
Xdialog --wrap --left --stdout --no-buttons --infobox "Copying files from old to new - wait few seconds..." 0 0 2000 &
cp -af /mnt/olddat/.[a-zA-Z0-9]* /mnt/newdat 2>/dev/null; cp -af /mnt/olddat/* /mnt/newdat 2>/dev/null

# unmount old and new and remove dirs
umount /mnt/olddat
umount /mnt/newdat
rm -rf /mnt/olddat /mnt/newdat
}

make_help_file(){
cat >> $WRK/help << EOF
When saving changes to a FAT file system Porteus uses posixovl which is a FUSE filesystem that provides functionality such as unix style permissions, ownership & special files for for filesystems that lack them (like FAT). Occasionally this posixovl can become corrupt resulting in a damaged filesystem and loss of changes. For this reason, instead of saving changes directly onto FAT, Porteus will save your changes in a container file made of a linux file system (xfs) which is stored on FAT. This greatly lessens the chance of corruption.
EOF
Xdialog --title "$TITLE" --wrap --left --msgbox "`cat $WRK/help`" 0 70

}

final_report(){
message "Your save.dat file has been created succesfully.\nTo use it during next boot add 'changes=' cheatcode to the bootloader config.\nExample:\nchanges=/mnt/sdb1/$NAME.dat"
}
###### START WORK
setup

Xdialog --title "$TITLE" --menubox \
"Please choose an option from the menu below:" 0 0 7 \
1 "Create a new save.dat file" \
2 "Resize an existing save.dat file" \
3 "Attempt recovery of corrupt save.dat" \
4 "Explain why i need a save.dat file" \
5 "Exit this application" 2> $WRK/.mmenuansw
chkbut
ANSW=`cat $WRK/.mmenuansw`

case $ANSW in
  1 )
  get_name
  get_place
  get_size
  check_free_space
  create_dat_file
  format_dat_file
  final_report
  exit
  ;;
  2 )
  get_old_dat
  get_name
  get_place
  get_size
  check_free_space
  create_dat_file
  format_dat_file
  mount_old_dat
  mount_new_dat
  copy_old_new
  final_report
  exit
  ;;
  3 )
  get_old_dat
  xfs_repair -d $RFILE 2> $WRK/xfs-repair.log
  Xdialog --title "xfs repair log" --logbox $WRK/xfs-repair.log 25 60
  exit
  ;;
  4 )
  make_help_file
  exit
  ;;
  5 )
  echo "Pressed 2"
  exit
esac
