#!/bin/zsh
set -euo pipefail
SCRIPT_DIR="${0:a:h}"
PROJ="${SCRIPT_DIR:h}"
VARIANT=exp
VM_DIR="$PROJ/vm"
while (( $# )); do
case "$1" in
--variant) VARIANT="$2"; shift 2 ;;
*) VM_DIR="$1"; shift ;;
esac
done
case "$VARIANT" in
regular) INSTALLER=cfw_install.sh ;;
dev) INSTALLER=cfw_install_dev.sh ;;
jb) INSTALLER=cfw_install_jb.sh ;;
exp) INSTALLER=cfw_install_exp.sh ;;
*) echo "[-] unknown variant: $VARIANT (regular|dev|jb|exp)" >&2; exit 1 ;;
esac
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
exec sudo ${SUDO_ASKPASS:+-A} -E /bin/zsh "$0" --variant "$VARIANT" "$VM_DIR"
fi
unset SUDO_ASKPASS
VM_DIR="${VM_DIR:a}"
IMG="$VM_DIR/Disk.img"
[[ -f "$IMG" ]] || { echo "[-] no Disk.img at $IMG" >&2; exit 1; }
if [[ -n "${VPHONE_PYTHON:-}" ]]; then
P="$PROJ/.tools/bin:$(dirname "$VPHONE_PYTHON"):/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"
else
P="$PROJ/.tools/bin:$PROJ/.venv/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"
fi
export PATH="$P"
PY="${VPHONE_PYTHON:-$PROJ/.venv/bin/python3}"
if lsof "$IMG" >/dev/null 2>&1; then
echo "[-] $IMG is in use — stop the VM first." >&2; exit 1
fi
echo "[*] host-mode CFW install: variant=$VARIANT vm=$VM_DIR"
AO=$(hdiutil attach -nomount -imagekey diskimage-class=CRawDiskImage "$IMG" 2>/dev/null)
BASEDISK=$(awk 'NR == 1 { print $1; exit }' <<< "$AO")
CONT=$(diskutil info -plist "${BASEDISK}s1" | /usr/bin/plutil -extract APFSContainerReference raw -o - - 2>/dev/null || true)
SYS=$(diskutil apfs list "$CONT" 2>/dev/null | awk '/APFS Volume Disk \(Role\):/{for(i=1;i<=NF;i++) if($i ~ /^disk[0-9]+s[0-9]+$/) dev=$i} /Name:.*System \(Case-sensitive\)/{print dev; exit}')
[[ -n "$CONT" && -n "$SYS" ]] || { echo "[-] System volume not found in $IMG" >&2; hdiutil detach "$BASEDISK" 2>/dev/null; exit 1; }
echo "[*] attached: container=$CONT system=$SYS"
cleanup() {
for m in /private/tmp/cfwhost/mnt1 /private/tmp/cfwhost/mnt3 /private/tmp/cfwhost/mnt5; do
umount "$m" 2>/dev/null || true
done
hdiutil detach "$BASEDISK" 2>/dev/null || diskutil eject "$BASEDISK" 2>/dev/null || true
}
trap cleanup EXIT
echo "[*] running $INSTALLER (files placed on host mounts)..."
( cd "$VM_DIR" && env CFW_HOST_CONTAINER="$CONT" _VPHONE_PATH="$P" \
${SPOOF_BUILD:+SPOOF_BUILD="$SPOOF_BUILD"} \
${FORCE_DSC_MAXSLIDE:+FORCE_DSC_MAXSLIDE="$FORCE_DSC_MAXSLIDE"} \
${VPHONE_FRIDA:+VPHONE_FRIDA="$VPHONE_FRIDA"} \
zsh "$SCRIPT_DIR/$INSTALLER" . )
cleanup
trap - EXIT
echo "[*] flipping boot snapshot offline (com.apple.os.update -> live volume)..."
"$PY" "$PROJ/tools/apfs_snap_rename.py" "$IMG"
if [[ -z "${VPHONE_KEEP_ARTIFACTS:-}" ]]; then
rm -rf "${VM_DIR:?}/cfw_input" "${VM_DIR:?}/cfw_jb_input"
fi
if [[ -n "${SUDO_USER:-}" ]]; then
chown -R "$SUDO_USER" "$VM_DIR" 2>/dev/null || true
[[ -e "$PROJ/scripts/vphoned/vphoned" ]] && chown "$SUDO_USER" "$PROJ/scripts/vphoned/vphoned" 2>/dev/null || true
echo "[*] restored ownership of host-side artifacts to $SUDO_USER"
fi
echo "[+] host-mode CFW install complete. Boot with: make boot"