#!/bin/bash -e

# Lists all users (i.e., all home directories on all ostree devices)

USERID=$(id -u)
if [ "$USERID" != "0" ]; then
    echo "Program requires superuser privileges"
    exit 1
fi

MOUNT=`mktemp -d`
LOOPBACK=

cleanup() {
    set +e
    if mount | grep --quiet $MOUNT; then
        umount "$MOUNT"

        if [ -n "$LOOPBACK" ]; then
            losetup -d "$LOOPBACK"
            udevadm settle

            umount "$MOUNT"
        fi
    fi
    rmdir $MOUNT
}
trap cleanup EXIT

list_users() {
    local DEVICE=$1
    local PHYSICAL_DEVICE=$2

    if ! mount $DEVICE $MOUNT; then
        echo "Can't list users on $PHYSICAL_DEVICE" >&2
        return
    fi

    # FIXME A more robust approach would be the following:
    # - read /usr/etc/login.defs and extract UID_MIN
    # - read /etc/passwd and get all users with uid >= UID_MIN
    echo Users on $PHYSICAL_DEVICE:
    ls $MOUNT/home
    echo

    umount $MOUNT
}

list_dualboot_users() {
    local PHYSICAL_DEVICE=${1:?}

    if ! mount $PHYSICAL_DEVICE $MOUNT; then
        echo "Can't list users on $PHYSICAL_DEVICE" >&2
        return
    fi

    local ENDLESS_IMG="$MOUNT/endless/endless.img"

    if [ -e "$ENDLESS_IMG" ] && [ ! -e "$MOUNT/endless/live" ]; then
        # Time for a loopback mount!
        LOOPBACK=$(losetup --find --show "$ENDLESS_IMG")
        partprobe "$LOOPBACK"

        # Find the ostree partition
        local DEVICE=$(lsblk --raw --paths -o LABEL,NAME "$LOOPBACK" |
                 awk '/^ostree / { print $2 }')
        if [ -z "$DEVICE" ]; then
            echo "Cannot find ostree partition in $ENDLESS_IMG on $PHYSICAL_DEVICE" >&2
            exit 1
        fi

        list_users $DEVICE $PHYSICAL_DEVICE
        losetup -d "$LOOPBACK"
        LOOPBACK=
    fi

    umount $MOUNT
}

# Basic Data partition types for MBR and GPT partition tables
BD_MBR="0x7"
BD_GPT="EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"

echo
DEVICES=$(lsblk --raw --paths --noheadings -o NAME,PARTTYPE,LABEL,RO)
while read NAME PARTTYPE LABEL RO; do
    if [ "${RO}" == "1" ]; then
        # Skip read-only partitions, such as the eoslive partition on a live
        # USB or the /dev/mapper/endless-image3 ostree partition mapped within
        # it.
        :
    elif [ "${LABEL}" == "ostree" ]; then
        list_users $NAME $NAME
    elif [ "${PARTTYPE}" == "${BD_MBR}" ] || \
         [ "${PARTTYPE^^}" == "${BD_GPT}" ]; then
        list_dualboot_users $NAME
    fi
done <<< "$DEVICES"
