diff --git a/src/image.sh b/src/image.sh index 48e94bce..ad4bed48 100644 --- a/src/image.sh +++ b/src/image.sh @@ -1405,12 +1405,12 @@ extractESD() { local version="$3" local desc="$4" - local bootTotal bootLinks wimTotal wimLinks local installSize size edition imgEdition - local bootWim installWim bootSize wimSize - local image index line ret metadata count - local result resultCount resultEdition xml - local -a fields + local bootTotal bootLinks wimTotal wimLinks + local bootWim installWim bootSize wimSize xml + local image index line ret metadata count output + local result resultCount resultEdition installXml + local -a detected fields local minSize=100000000 local bootPad=60000000 @@ -1558,30 +1558,68 @@ extractESD() { msg="Extracting image from ESD file" info "$msg..." && html "$msg..." - edition=$(getCatalog "$version" "name") - - if [ -z "$edition" ]; then - error "Invalid VERSION specified, value \"$version\" is not recognized!" - return 1 - fi - index="" - for line in "${fields[@]:5}"; do + if [[ "${version,,}" == "http"* ]]; then - IFS=$'\t' read -r image imgEdition <<< "$line" + # Direct ESD URLs have no catalog identity. Restrict automatic detection + # to installable images because indexes 1-3 contain setup components. + if ! installXml=$(xmlstarlet ed \ + -d '/WIM/IMAGE[number(@INDEX) < 4]' \ + <<< "$xml" 2>/dev/null); then + error "Cannot read installable images from ESD file!" + return 1 + fi - [[ ! "$image" =~ ^[0-9]+$ ]] && continue - [[ "${imgEdition,,}" != "${edition,,}" ]] && continue + checkPlatform "$xml" || return 1 - index="$image" - break + output=$(detectVersion "$installXml") || return 1 + mapfile -t detected <<< "$output" - done + index="${detected[1]:-}" + + for line in "${fields[@]:5}"; do + + IFS=$'\t' read -r image imgEdition <<< "$line" + + [[ "$image" == "$index" ]] || continue + + edition="$imgEdition" + break + + done + + if [ -z "$index" ] || [ -z "$edition" ]; then + error "Failed to select an installation image from install.esd!" + return 1 + fi + + else + + edition=$(getCatalog "$version" "name") + + if [ -z "$edition" ]; then + error "Invalid VERSION specified, value \"$version\" is not recognized!" + return 1 + fi + + for line in "${fields[@]:5}"; do + + IFS=$'\t' read -r image imgEdition <<< "$line" + + [[ ! "$image" =~ ^[0-9]+$ ]] && continue + [[ "${imgEdition,,}" != "${edition,,}" ]] && continue + + index="$image" + break + + done + + if [ -z "$index" ]; then + error "Failed to find product '$edition' in install.esd!" + return 1 + fi - if [ -z "$index" ]; then - error "Failed to find product '$edition' in install.esd!" - return 1 fi installSize=$(( size + installPad )) diff --git a/src/install.sh b/src/install.sh index aa5abe79..39f681d0 100644 --- a/src/install.sh +++ b/src/install.sh @@ -722,16 +722,52 @@ needsExtraction() { return 1 } +getArchiveSize() { + + local file="$1" + local result_name="$2" + local -n result="$result_name" + + local listing line value + local found=0 + + result=0 + + if ! listing=$(7z l -slt "$file" 2>/dev/null); then + error "Failed to read archive information: $file" + return 1 + fi + + while IFS= read -r line; do + + [[ "$line" == "Size = "* ]] || continue + + value="${line#Size = }" + [[ "$value" =~ ^[0-9]+$ ]] || continue + + result=$(( result + value )) + found=1 + + done <<< "$listing" + + if (( ! found )); then + error "Failed to determine archive contents size: $file" + return 1 + fi + + return 0 +} + extractImage() { local iso="$1" local dir="$2" local version="$3" - local file size + local target="$dir" local desc="local ISO" local archive="${dir}.archive" - local target="$dir" + local file size required archiveSize if [ -z "$CUSTOM" ]; then desc="downloaded ISO" @@ -770,7 +806,14 @@ extractImage() { return 1 fi - checkFreeSpace "$target" "$size" || return 1 + required="$size" + + if enabled "${UNPACK:-}"; then + getArchiveSize "$iso" archiveSize || return 1 + required="$archiveSize" + fi + + checkFreeSpace "$target" "$required" || return 1 if ! rm -rf -- "$target"; then error "Failed to remove directory \"$target\" !" @@ -804,18 +847,6 @@ extractImage() { return 1 fi - if ! makeDir "$dir"; then - error "Failed to create directory \"$dir\" !" - return 1 - fi - - if ! 7z x "$file" -o"$dir" > /dev/null; then - error "Failed to extract nested ISO file: $file" - return 1 - fi - - LABEL=$(isoinfo -d -i "$file" | sed -n 's/Volume id: //p') || LABEL="" - if ! mv -f -- "$file" "$iso"; then error "Failed to preserve extracted ISO file: $file" return 1 @@ -826,6 +857,25 @@ extractImage() { return 1 fi + if ! makeDir "$dir"; then + error "Failed to create directory \"$dir\" !" + return 1 + fi + + if ! size=$(stat -c%s "$iso"); then + error "Failed to determine nested ISO file size: $iso" + return 1 + fi + + checkFreeSpace "$dir" "$size" || return 1 + + if ! 7z x "$iso" -o"$dir" > /dev/null; then + error "Failed to extract nested ISO file: $iso" + return 1 + fi + + LABEL=$(isoinfo -d -i "$iso" | sed -n 's/Volume id: //p') || LABEL="" + UNPACK="" fi