diff --git a/test/merge_debian_isos b/test/merge_debian_isos index 1df25356..c7b96604 100755 --- a/test/merge_debian_isos +++ b/test/merge_debian_isos @@ -12,9 +12,20 @@ usage() { echo "Mounts by sudo the ISO 9660 images iso1 to isoN at directories" >&2 echo "mount_template1 to mount_templateN, if not already mounted that way." >&2 echo "Then the Debian pools and package lists get merged and a new" >&2 - echo "ISO 9660 image result_iso is produced, which must not yet exist." >&2 - echo "If iso1 is bootable then the new image will be bootable by the" >&2 - echo "same means." >&2 + echo "ISO 9660 image result_iso is produced. If iso1 is bootable then" >&2 + echo "then the new image will be bootable by the same means." >&2 + echo >&2 + echo "The file depicted by result_iso must not yet exist or has to be a" >&2 + echo "device which is acceptable for Linux-specific helper script" >&2 + echo "xorriso-dd-target. If xorriso-dd-target agrees and the user" >&2 + echo 'confirms by input "yes" then xoriso will be run under sudo.' >&2 + echo 'Exempted from this evaluation are addresses which begin by "mmc:"' >&2 + echo 'for an optical drive on Linux, BSDs, Solaris, or by "stdio:/dev/"' >&2 + echo 'for which the user takes full and dangerous responsibility.' >&2 + echo 'Special result_iso path "xorriso-dd-target-plug-test" determines' >&2 + echo "on Linux the target USB stick by a dialog around plugging it in." >&2 + echo "xorriso will be run under sudo, if xorriso-dd-target agrees." >&2 + echo >&2 echo "At least the parent directory of mount_template must already exist." >&2 echo "All arguments must be single words without using quotation marks." >&2 echo "None of the isoN must be equal to another isoM." >&2 @@ -41,6 +52,9 @@ usage() { echo "Exported non-empty variable XORRISO overrides command xorriso." >&2 echo "This may be needed if installed xorriso is older than 1.4.2." >&2 echo 'If XORRISO is set to "dummy" then no new ISO will emerge.' >&2 + echo "Exported non-empty variable XORRISO_DD_TARGET_PATH names the" >&2 + echo "directory where to find xorriso-dd-target, which evaluates the" >&2 + echo "suitability of result_iso devices or does the plug-test dialog." >&2 echo >&2 echo "Example using GNU xorriso-1.5.4 instead of /usr/bin/xorriso:" >&2 echo " export XORRISO="'"$HOME"'"/xorriso-1.5.4/xorriso/xorriso" >&2 @@ -48,6 +62,20 @@ usage() { echo " $(basename "$0") merged.iso merge_mount/iso "'\' >&2 echo " debian-11.2.0-amd64-DVD-[12345].iso" >&2 echo " rmdir merge_mount" >&2 + echo >&2 + echo "Example writing to optical drive /dev/sr0 :" >&2 + echo " $(basename "$0") mmc:/dev/sr0 merge_mount/iso "'\' >&2 + echo " debian-11.2.0-amd64-DVD-[12345].iso" >&2 + echo >&2 + echo \ + "Example on Linux writing to USB stick with xorriso-dd-target-plug-test:" >&2 + echo " wget https://dev.lovelyhq.com/libburnia/libisoburn/raw/master/xorriso-dd-target/xorriso-dd-target" >&2 + echo " chmod u+x xorriso-dd-target" >&2 + echo ' export XORRISO_DD_TARGET_PATH="$(pwd)"' >&2 + echo " $(basename "$0") xorriso-dd-target-plug-test merge_mount/iso "'\' >&2 + echo " debian-11.2.0-amd64-DVD-[12345].iso" >&2 + echo "This leads to the first two steps of the xorriso-dd-target device" >&2 + echo "plug dialog. See: https://wiki.debian.org/XorrisoDdTarget" >&2 } check_single_word() { @@ -289,6 +317,14 @@ then exit 5 fi +XORRISO_DD_TARGET= +if test -z "$XORRISO_DD_TARGET_PATH" +then + XORRISO_DD_TARGET=xorriso-dd-target +else + XORRISO_DD_TARGET="$XORRISO_DD_TARGET_PATH"/xorriso-dd-target +fi + existing_tempfiles= for i in merged_dists merged_md5sum.txt merged_README.txt temp_file do @@ -316,16 +352,147 @@ trap cleanup_and_end INT TERM QUIT trap cleanup_for_exit EXIT RESULT_ISO="$1" -check_single_word "$2" "result_iso" || cleanup_and_end 1 -if test -e "$RESULT_ISO" +check_single_word "$1" "result_iso" || cleanup_and_end 1 +XORRISO_STDIO_DEV= +XORRISO_SUDO= +XORRISO_BLANK_CMD= +XORRISO_STDIO_SYNC=off +xorriso_rm_result_iso=1 +if test "$RESULT_ISO" = xorriso-dd-target-plug-test then - echo "--- A file '${RESULT_ISO}' is already existing." >&2 - echo "--- Will not overwrite it by the resulting ISO image." >&2 - cleanup_and_end 1 + # Get device name from xorriso-dd-target + advice=NO + echo >&2 + echo \ + 'Special result_iso path "xorriso-dd-target-plug-test" causes a run of' >&2 + echo " $XORRISO_DD_TARGET -with_sudo -plug_test" >&2 + echo "to determine the USB stick or memory card:" >&2 + echo "---------------------------------------------------------" >&2 + plugged="$("$XORRISO_DD_TARGET" -with_sudo -plug_test)" + ret=$? + echo "---------------------------------------------------------" >&2 + if test "$ret" = 0 && test -n "$plugged" + then + name="$(echo "$plugged" | awk '{print $1}')" + advice="$(echo "$plugged" | awk '{print $3}')" + fi + if test "$advice" = YES + then + RESULT_ISO=/dev/"$name" + XORRISO_STDIO_DEV=stdio: + XORRISO_SUDO=sudo + XORRISO_BLANK_CMD="-blank as_needed" + XORRISO_STDIO_SYNC=16m + xorriso_rm_result_iso=0 + echo "Will use sudo with xorriso and write to ${RESULT_ISO}" >&2 + else + echo "--- No suitable device was determined." >&2 + cleanup_and_end 1 + fi +elif echo "$RESULT_ISO" | grep '^mmc:' >/dev/null +then + xorriso_rm_result_iso=0 + # Let xorriso judge over optical drives + # (The /dev/sr patterns are Linux specific. The mmc: prefix is not.) + if test "$XORRISO" = dummy + then + echo "Dummy mode: Accepting '${RESULT_ISO}' as optical drive." >&2 + XORRISO_BLANK_CMD="-blank as_needed" + elif "$XORRISO" -outdev "$RESULT_ISO" 2>/dev/null + then + echo "${XORRISO} accepts '${RESULT_ISO}' as optical drive." >&2 + XORRISO_BLANK_CMD="-blank as_needed" + else + echo "--- $XORRISO refuses to accept '${RESULT_ISO}' as optical drive." >&2 + cleanup_and_end 1 + fi +elif echo "$RESULT_ISO" | grep '^stdio:/dev/' >/dev/null +then + xorriso_rm_result_iso=0 + echo \ +"WARNING: User insists in using '${RESULT_ISO}' without further preparations" \ + >&2 + echo \ + " or safety checks. The device might need blanking by xorriso" >&2 + echo \ + " before it will be willing to write to it. Permissions might not" >&2 + echo \ + " suffice. Be cautious when removing such obstacles. They might be" \ + >&2 + echo \ + " there for a good reason." >&2 + echo \ + "If you agree to xorriso trying to overwrite the content of '${RESULT_ISO}'" \ + >&2 + echo "then enter 'yes' :" >&2 + answer= + read answer + if test "$answer" = yes + then + echo \ + "Will try to overwrite the device content without sudo or pseudo-blanking." \ + >&2 + else + echo "--- Answer was not 'yes'. Will not write to device." >&2 + cleanup_and_end 1 + fi +elif test -e "$RESULT_ISO" +then + if test "$(dirname $RESULT_ISO)" = "/dev" + then + echo >&2 + echo "The result_iso path '${RESULT_ISO}' is an existing File in /dev." >&2 + echo "Will only write to it if $XORRISO_DD_TARGET agrees." >&2 + if type "$XORRISO_DD_TARGET" + then + echo >&2 + echo \ + "Performing: $XORRISO_DD_TARGET -with_sudo $(basename $RESULT_ISO)" >&2 + echo "---------------------------------------------------------" >&2 + "$XORRISO_DD_TARGET" -with_sudo "$(basename $RESULT_ISO)" + ret=$? + echo "---------------------------------------------------------" >&2 + if test "$ret" = 0 + then + echo "$XORRISO_DD_TARGET agrees that this is a suitable device." >&2 + echo \ + "If you agree to xorriso running under sudo and overwriting the content" \ + >&2 + echo "of '${RESULT_ISO}', then enter 'yes' :" >&2 + answer= + read answer + if test "$answer" = yes + then + XORRISO_STDIO_DEV=stdio: + XORRISO_SUDO=sudo + XORRISO_BLANK_CMD="-blank as_needed" + XORRISO_STDIO_SYNC=16m + xorriso_rm_result_iso=0 + echo "Will use sudo with xorriso and write to device." >&2 + else + echo "--- Answer was not 'yes'. Will not write to device." >&2 + fi + else + echo \ + "--- $XORRISO_DD_TARGET refuses to accept this device as result_iso" >&2 + fi + else + echo "--- Helper program $XORRISO_DD_TARGET is missing." >&2 + echo \ + "--- Cannot evaluate suitability of '${RESULT_ISO}' as result_iso path" \ + >&2 + fi + fi + if test -z "$XORRISO_STDIO_DEV" + then + echo "--- A file '${RESULT_ISO}' is already existing." >&2 + echo "--- Will not overwrite it by the resulting ISO image." >&2 + cleanup_and_end 1 + fi fi MOUNT_TEMPLATE="$2" -check_single_word "$1" "mount_template" || cleanup_and_end 1 +check_single_word "$2" "mount_template" || cleanup_and_end 1 x=$(dirname "$MOUNT_TEMPLATE") if test -d "$x" then @@ -858,6 +1025,11 @@ then echo "Planned xorriso commands in temp_file:" >&2 cat temp_file echo >&2 + if test -n "$XORRISO_SUDO" + then + echo "NOTE: xorriso would run under control of '${XORRISO_SUDO}'" >&2 + XORRISO_SUDO= + fi echo 'NOTE: Variable XORRISO is set to "dummy".' >&2 echo ' Will not perform xorriso run but only show its arguments:' >&2 XORRISO=echo @@ -867,12 +1039,17 @@ fi echo >&2 # Mark the result path for possible removal by cleanup -EMERGING_ISO="$RESULT_ISO" - -if "$XORRISO" \ +if test -z "$XORRISO_STDIO_DEV" +then + EMERGING_ISO="$RESULT_ISO" +else + EMERGING_ISO= +fi +if $XORRISO_SUDO "$XORRISO" \ -no_rc \ -indev "$iso_1" \ - -outdev "$RESULT_ISO" \ + -outdev "$XORRISO_STDIO_DEV""$RESULT_ISO" \ + $XORRISO_BLANK_CMD \ -options_from_file temp_file \ -map merged_dists /dists \ -map merged_md5sum.txt /md5sum.txt \ @@ -882,8 +1059,10 @@ if "$XORRISO" \ -chmod_r a-w /dists /md5sum.txt -- \ -chmod_r a=r /README.txt -- \ -boot_image any replay \ - -stdio_sync off \ + -fs 16m \ + -stdio_sync "$XORRISO_STDIO_SYNC" \ -padding included \ + -stream_recording on \ -compliance no_emul_toc then # Revoke mark for possible removal by cleanup diff --git a/test/merge_debian_isos.sig b/test/merge_debian_isos.sig index c4d78221..39eec19e 100644 Binary files a/test/merge_debian_isos.sig and b/test/merge_debian_isos.sig differ