#!/bin/bash
#
# stcard - Mount Atari partitions from SDCARD
# by "Genral Failure" (c) 2020
#
# This script acts like a toggle switch. The first call mounts
# an SDCARD, the second call umounts the SDCARD, and so forth...
#
# Change DEVICE, MOUNTPOINT and MAXPARTSIZE to your needs
#
# MAXIMUM PARTITION SIZES
# - Phys. sector size is always 512 Bytes/Sector
# - TOS has a fixed cluster size  of 2 sectors (sic)
# - Linux can only mount partions with a sector size of max. 4KB
# - Max. mountable size = MaxNumberOfClusters * 2 * 4096
#
# TOS 1.02
# - Max. number of cluster limit of 2^14 = 16384 Clusters
# - Max. size = 16384 * 2 * 4096 = 134217728
#
# TOS 1.04
# - Max. number of cluster limit of 2^15 = 32768 Clusters
# - Max. size = 32768 * 2 * 4096 = 268435456
#
# TOS 3+
# - I'm too lazy right now. Google it.

DEVICE=/dev/sde
MOUNTPOINT=~kernal/stcard
MAXPARTSIZE=134217728

# Check for root permission
if [ "$EUID" -ne '0'  ]; then
    echo "ERROR: root permission required."
    echo " Run stcard 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))

	if [ $PARTSIZE -le $MAXPARTSIZE ]; then
            mkdir -p $MOUNTDIR
            chown --reference $MOUNTPOINT $MOUNTDIR
            mount -t msdos -o uid=$MOUNTUID,gid=$MOUNTGID $LOOPDEVICE $MOUNTDIR
        fi
    fi
done