#!/bin/bash
#
# stcard - Mount Atari partitions from SD card
# Version 0.2
# by "Genral Failure" (c) 2020
#
# This script acts like a toggle switch. The first call mounts
# an SD card, the second call umounts the SD card, and so forth...
#
# Change DEVICE and MOUNTPOINT to your needs
#
# This script depends on
# - parted

DEVICE=/dev/sde
MOUNTPOINT=~kai/stcard
MAXSECTORSIZE=4096

function is_power_of_two () {
# e.g. 4096 is binary 100000 0000000
# minus 1 is binary   011111 1111111
# logical AND both    000000 0000000
    declare -i n=$1
    (( n > 0 && (n & (n - 1)) == 0 ))
}

# Check for root permission 
if [ "$EUID" -ne '0'  ]; then
    echo "ERROR: root permission required."
    echo " Run ${0##*/} as root or run with sudo"
  exit
fi

# If card is mounted, unmount it and remove mountpoints
for FOLDER in $(find $MOUNTPOINT -maxdepth 1 -mindepth 1 -type d); do
    umount -q $FOLDER && rmdir $FOLDER
done

# If there are loop devices from previous calls, remove them and quit
LOOPDEVS=($(losetup --raw -O BACK-FILE,NAME | grep "^$DEVICE /dev/loop"))
NUMLOOPS=${#LOOPDEVS[@]}
if [ $NUMLOOPS -gt 0 ]; then
    for (( i=0; i < $NUMLOOPS; i++ )); do
        ((i++))
        losetup -d ${LOOPDEVS[i]}
    done
    sync
    exit
fi

# Prepare mountpoint
mkdir -p $MOUNTPOINT
chown --reference ${MOUNTPOINT}/.. $MOUNTPOINT
MOUNTUID=$(stat -c '%u' $MOUNTPOINT)
MOUNTGID=$(stat -c '%g' $MOUNTPOINT)

PARTITIONS=($(parted -m $DEVICE unit B print | awk -F : '/^[1-9]/ {print int($2),int($4)}'))
NUMPARTS=${#PARTITIONS[@]}

# Process partitions
for (( i=0; i < $NUMPARTS; i++ )); do
    PARTSTART=${PARTITIONS[$i]}
    ((i++))
    PARTSIZE=${PARTITIONS[$i]}

    # Create loop device only, when it not already exists
    if ! losetup --raw -O BACK-FILE,OFFSET,SIZELIMIT,NAME | grep -q "^$DEVICE $PARTSTART $PARTSIZE /dev/loop"; then
        LOOPDEVICE=$(losetup --find --show --offset $PARTSTART --sizelimit $PARTSIZE $DEVICE)
	MOUNTDIR=${MOUNTPOINT}/${DEVICE##*/}$((i/2+1))
	SECTORSIZE=$(od -j 0x0B -N 0x02 -An -td2 -v $LOOPDEVICE)

	if [ $SECTORSIZE -le $MAXSECTORSIZE ] && is_power_of_two "$SECTORSIZE"; then
            mkdir -p $MOUNTDIR
            chown --reference $MOUNTPOINT $MOUNTDIR
            mount -t msdos -o uid=$MOUNTUID,gid=$MOUNTGID $LOOPDEVICE $MOUNTDIR
	    echo $MOUNTDIR
        fi
    fi
done

