#!/bin/sh . common.sh DEVNAME=$1 case "$DEVNAME" in /dev/loop*|/dev/ram*|/dev/dm-*|/dev/md*|/dev/fd*) exit ;; esac [ -b "$DEVNAME" ] || exit debug_log "grok-block.${DEVNAME##*/}" addmenu_choosekey() { dev=$1 dir=$2 addmenu "$dev//$dir" \ "[ Use the GPG key on $dev ]" \ "menu-select boot-gpg $dev $dir" } addmenu_repairhfs() { local device="$1" addmenu "$device//reboot" \ "[ Reboot into Mac OS X in order to repair disk $device ]" \ "eject /cdrom; sleep 2; reboot -f" addmenu "$device//fsck" \ "[ (DANGEROUS) Try to repair errors on $device with fsck.hfsplus ]" \ "/bin/openvt -sw -- sh -c 'fsck.hfsplus $device && remenu'" } addmenu_chooseroot() { local device="$1" loopfile="$2" addmenu "$device//$loopfile" \ "[ Boot the system on $device${loopfile:+ in file $(basename $loopfile)} ]" \ "menu-select --fs=$ID_FS_TYPE boot-luks $device ${loopfile:-$device}" } addmenu_makeroot() { local device="$1" loopfile="$2" megs="$3" copy_cdrom="$4" ( addmenu "$device//$loopfile" \ "[ Install Samizdat to $device (in file $(basename $loopfile)) ]" \ "menu-select --fs=$ID_FS_TYPE boot-new $device $loopfile $megs $copy_cdrom" ) & } retry_mount() { tries=20 until mntout="$(mount "$@" 2>&1)" do tries=$(( tries - 1 )) case "$mntout" in *"Device or resource busy"*) if [ $tries -le 0 ]; then warn "mount $@ failed: $mntout" return 1 else sleep 1 continue fi ;; *) warn "mount $@ failed: $mntout" break ;; esac done } gpg_verify() { bootwait samizdat-gpg export GNUPGHOME=/gpg/gnupghome gpg2 --lock-never --no-permission-warning --no-auto-check-trustdb --no-options --verify "$1" } is_lvm() { for n in 0 1 2 3; do [ "LVM2 001" = "$(dd if="$1" bs=1 skip=$((512*n+24)) count=8 2>/dev/null)" ] && return 0 done return 1 } grok_block() { local mountpoint="/mnt/${DEVNAME##*/}" mkdir -p "$mountpoint" case "$ID_FS_TYPE" in ntfs) mount_type='-t ntfs-3g' ;; "") mount_type= ;; *) mount_type="-t $ID_FS_TYPE" ;; esac if [ "$ID_FS_TYPE" = hfsplus ] && ! fsck.hfsplus -q "$DEVNAME"; then (if fsck.hfsplus "$DEVNAME"; then grok-block "$DEVNAME" else addmenu_repairhfs "$DEVNAME" fi) & return fi if ! mountpoint -q "$mountpoint"; then retry_mount $mount_type -o ro "$DEVNAME" "$mountpoint" fi if mountpoint -q "$mountpoint"; then umount=true # Device has an unencrypted filesystem on it. # So we mount it and look for loop-back overlays. if [ -d "$mountpoint/samizdat.gpg" ]; then # check the key somehow? addmenu_choosekey "$DEVNAME" "$mountpoint/samizdat.gpg" fi N=1; while [ -e "$mountpoint/samizdat.$N" ] do if gpg_verify "$mountpoint/samizdat.$N"k; then addmenu_chooseroot "$DEVNAME" "$mountpoint/samizdat.$N" # this menu entry chooses the root fs, and should prompt and wait for the matching key umount=false fi N=$((N+1)) done freeblocks=$(stat -f -c %f "$mountpoint") blocksize=$(stat -f -c %S "$mountpoint") freemegs=$((freeblocks * blocksize / 1024 / 1024)) if [ "$freemegs" -ge 300 ]; then umount=false bootwait samizdat-cdrom cdromblocks=$(stat -f -c %b /cdrom) cdromblocksize=$(stat -f -c %S /cdrom) cdrommegs=$((cdromblocks * cdromblocksize / 1024 / 1024)) if [ "$freemegs" -ge "$((cdrommegs * 3))" ]; then addmenu_makeroot "$DEVNAME" "${mountpoint}/samizdat.$N" "$((cdrommegs * 3))" 1 elif [ "$freemegs" -ge "$((cdrommegs * 2))" ]; then addmenu_makeroot "$DEVNAME" "${mountpoint}/samizdat.$N" "$((cdrommegs * 2))" 1 elif [ "$freemegs" -ge "$cdrommegs" ]; then addmenu_makeroot "$DEVNAME" "${mountpoint}/samizdat.$N" "$((freemegs / 2))" 0 else addmenu_makeroot "$DEVNAME" "${mountpoint}/samizdat.$N" 256 0 fi fi if $umount; then umount "$mountpoint" rmdir "$mountpoint" fi else rmdir "$mountpoint" fi } # Get me all them nice udev variables eval "$(PATH=$PATH:/lib/udev vol_id "$DEVNAME" | sed "s/'/'\\\\''/; s/=\(.*\)/='\1'/" )" CDROM_ID_FS_UUID_ENC='73256269-4002-4e42-adbd-0e49ed1c7438' CDROM_ID_FS_LABEL_ENC=$(sed 's/ /\\x20/g' /lib/samizdat/vol_id.txt) if [ "$ID_FS_UUID_ENC" = "$CDROM_ID_FS_UUID_ENC" -o \ "$ID_FS_LABEL_ENC" = "$CDROM_ID_FS_LABEL_ENC" ] then # Recognize and mount the Samizdat if ! mountpoint -q /cdrom; then mkdir -p /cdrom . mdadm-dup.sh dup_mount_cdrom "$DEVNAME" /cdrom && bootdone samizdat-cdrom fi else grok_block & fi # vim:set et sw=2: