feat: Inline local variable declarations (#1951)

This commit is contained in:
Kroese
2026-07-24 20:05:12 +02:00
committed by GitHub
parent 173b67b2af
commit 28b5ee1f08
7 changed files with 152 additions and 221 deletions
+22 -27
View File
@@ -6,14 +6,13 @@ validateResolution() {
local name="$1" local name="$1"
local value="$2" local value="$2"
local minimum="$3" local minimum="$3"
local number
if [[ ! "$value" =~ ^[0-9]+$ ]] || [ "${#value}" -gt 5 ]; then if [[ ! "$value" =~ ^[0-9]+$ ]] || [ "${#value}" -gt 5 ]; then
error "The $name variable must be between $minimum and 16384!" error "The $name variable must be between $minimum and 16384!"
return 1 return 1
fi fi
number=$((10#$value)) local number=$((10#$value))
if [ "$number" -lt "$minimum" ] || [ "$number" -gt 16384 ]; then if [ "$number" -lt "$minimum" ] || [ "$number" -gt 16384 ]; then
error "The $name variable must be between $minimum and 16384!" error "The $name variable must be between $minimum and 16384!"
@@ -64,7 +63,7 @@ validateComputerName() {
validateWorkgroup() { validateWorkgroup() {
local value="$1" local value="$1"
local safe="" local safe
[ -z "$value" ] && return 0 [ -z "$value" ] && return 0
@@ -498,7 +497,7 @@ updateDomain() {
local asset="$1" local asset="$1"
local domain account auth pass local domain account auth pass
local cred_domain ou arch tmp result local ou arch tmp
domain=$(escapeXML "$2") || return 1 domain=$(escapeXML "$2") || return 1
account=$(escapeXML "$3") || return 1 account=$(escapeXML "$3") || return 1
@@ -512,7 +511,7 @@ updateDomain() {
[ -z "$arch" ] && return 1 [ -z "$arch" ] && return 1
cred_domain="$domain" local cred_domain="$domain"
case "$4" in case "$4" in
*@* ) cred_domain="" ;; *@* ) cred_domain="" ;;
@@ -521,7 +520,7 @@ updateDomain() {
grep -Eq 'Microsoft-Windows-UnattendedJoin|<DomainAccounts([[:space:]/>])' "$asset" && return 1 grep -Eq 'Microsoft-Windows-UnattendedJoin|<DomainAccounts([[:space:]/>])' "$asset" && return 1
tmp=$(mktemp -d) || return 1 tmp=$(mktemp -d) || return 1
result="$tmp/answer.xml" local result="$tmp/answer.xml"
if ! DOMAIN_XML="$domain" ACCOUNT_XML="$account" \ if ! DOMAIN_XML="$domain" ACCOUNT_XML="$account" \
AUTH_XML="$auth" PASS_XML="$pass" \ AUTH_XML="$auth" PASS_XML="$pass" \
@@ -618,7 +617,7 @@ updateDomain() {
updateWorkgroup() { updateWorkgroup() {
local asset="$1" local asset="$1"
local workgroup arch tmp result local workgroup arch tmp
workgroup=$(escapeXML "$2") || return 1 workgroup=$(escapeXML "$2") || return 1
arch=$(sed -n -E '0,/processorArchitecture="/s/.*processorArchitecture="([^"]+)".*/\1/p' "$asset") || return 1 arch=$(sed -n -E '0,/processorArchitecture="/s/.*processorArchitecture="([^"]+)".*/\1/p' "$asset") || return 1
@@ -627,7 +626,7 @@ updateWorkgroup() {
grep -q 'Microsoft-Windows-UnattendedJoin' "$asset" && return 1 grep -q 'Microsoft-Windows-UnattendedJoin' "$asset" && return 1
tmp=$(mktemp -d) || return 1 tmp=$(mktemp -d) || return 1
result="$tmp/answer.xml" local result="$tmp/answer.xml"
if ! WORKGROUP_XML="$workgroup" ARCH_XML="$arch" awk ' if ! WORKGROUP_XML="$workgroup" ARCH_XML="$arch" awk '
/<settings[^>]*pass="specialize"[^>]*>/ { section = "specialize" } /<settings[^>]*pass="specialize"[^>]*>/ { section = "specialize" }
@@ -661,9 +660,8 @@ updateXML() {
local asset="$1" local asset="$1"
local language="$2" local language="$2"
local app value culture region keyboard edition local app value culture admin key
local user user_xml auth_user admin pass pw local user user_xml edition pw host
local domain qualifier host workgroup key
[ -z "${WIDTH:-}" ] && WIDTH="1280" [ -z "${WIDTH:-}" ] && WIDTH="1280"
[ -z "${HEIGHT:-}" ] && HEIGHT="720" [ -z "${HEIGHT:-}" ] && HEIGHT="720"
@@ -693,7 +691,7 @@ updateXML() {
sed -i "s|<UILanguage>en-US</UILanguage>|<UILanguage>$value</UILanguage>|g" "$asset" || return 1 sed -i "s|<UILanguage>en-US</UILanguage>|<UILanguage>$value</UILanguage>|g" "$asset" || return 1
fi fi
region="${REGION:-}" local region="${REGION:-}"
[ -z "$region" ] && region="$culture" [ -z "$region" ] && region="$culture"
if [ -n "$region" ] && [[ "${region,,}" != "en-us" ]]; then if [ -n "$region" ] && [[ "${region,,}" != "en-us" ]]; then
@@ -702,7 +700,7 @@ updateXML() {
sed -i "s|<SystemLocale>en-US</SystemLocale>|<SystemLocale>$value</SystemLocale>|g" "$asset" || return 1 sed -i "s|<SystemLocale>en-US</SystemLocale>|<SystemLocale>$value</SystemLocale>|g" "$asset" || return 1
fi fi
keyboard="${KEYBOARD:-}" local keyboard="${KEYBOARD:-}"
[ -z "$keyboard" ] && keyboard="$culture" [ -z "$keyboard" ] && keyboard="$culture"
if [ -n "$keyboard" ] && [[ "${keyboard,,}" != "en-us" ]]; then if [ -n "$keyboard" ] && [[ "${keyboard,,}" != "en-us" ]]; then
@@ -711,8 +709,8 @@ updateXML() {
sed -i "s|<InputLocale>0409:00000409</InputLocale>|<InputLocale>$value</InputLocale>|g" "$asset" || return 1 sed -i "s|<InputLocale>0409:00000409</InputLocale>|<InputLocale>$value</InputLocale>|g" "$asset" || return 1
fi fi
domain="${DOMAIN:-}" local domain="${DOMAIN:-}"
workgroup="${WORKGROUP:-}" local workgroup="${WORKGROUP:-}"
if [ -n "$domain" ]; then if [ -n "$domain" ]; then
@@ -728,8 +726,8 @@ updateXML() {
validateDomainName "$domain" || return 1 validateDomainName "$domain" || return 1
auth_user="$USERNAME" local auth_user="$USERNAME"
qualifier="" local qualifier=""
if [[ "$auth_user" == *\\* ]]; then if [[ "$auth_user" == *\\* ]]; then
error "The USERNAME variable must use either \"user\" or \"user@domain\" format!" error "The USERNAME variable must use either \"user\" or \"user@domain\" format!"
@@ -785,7 +783,7 @@ updateXML() {
sed -i "s|<Username>Docker</Username>|<Username>$user_xml</Username>|g" "$asset" || return 1 sed -i "s|<Username>Docker</Username>|<Username>$user_xml</Username>|g" "$asset" || return 1
fi fi
[ -n "${PASSWORD:-}" ] && pass="$PASSWORD" || pass="admin" local pass="${PASSWORD:-admin}"
pw=$(printf '%s' "${pass}Password" | iconv -f utf-8 -t utf-16le | base64 -w 0) || return 1 pw=$(printf '%s' "${pass}Password" | iconv -f utf-8 -t utf-16le | base64 -w 0) || return 1
admin=$(printf '%s' "${pass}AdministratorPassword" | iconv -f utf-8 -t utf-16le | base64 -w 0) || return 1 admin=$(printf '%s' "${pass}AdministratorPassword" | iconv -f utf-8 -t utf-16le | base64 -w 0) || return 1
@@ -966,13 +964,11 @@ validateLegacyUsername() {
legacyInstall() { legacyInstall() {
local pid=""
local file=""
local dir="$2" local dir="$2"
local desc="$3" local desc="$3"
local driver="$4" local driver="$4"
local drivers="/tmp/drivers" local drivers="/tmp/drivers"
local shortcut="Y" local pid file shortcut="Y"
if disabled "$SHORTCUT" || disabled "${SAMBA:-Y}"; then if disabled "$SHORTCUT" || disabled "${SAMBA:-Y}"; then
shortcut="N" shortcut="N"
@@ -989,9 +985,10 @@ legacyInstall() {
error "Failed to locate file \"$ETFS\" in $desc ISO image!" && return 1 error "Failed to locate file \"$ETFS\" in $desc ISO image!" && return 1
fi fi
local arch target local arch="amd64"
[ -d "$dir/AMD64" ] && arch="amd64" || arch="x86" [ ! -d "$dir/AMD64" ] && arch="x86"
[[ "${arch,,}" == "x86" ]] && target="$dir/I386" || target="$dir/AMD64" local target="$dir/AMD64"
[[ "${arch,,}" == "x86" ]] && target="$dir/I386"
if [ ! -d "$target" ]; then if [ ! -d "$target" ]; then
error "Failed to locate directory \"$target\" in $desc ISO image!" && return 1 error "Failed to locate directory \"$target\" in $desc ISO image!" && return 1
@@ -1449,14 +1446,12 @@ legacyPrepare() {
rm -f "$dir/$ETFS" || return 1 rm -f "$dir/$ETFS" || return 1
rm -rf "$tmp" || return 1 rm -rf "$tmp" || return 1
local rc
LC_ALL=C xorriso \ LC_ALL=C xorriso \
-no_rc \ -no_rc \
-osirrox on \ -osirrox on \
-indev "$iso" \ -indev "$iso" \
-extract_boot_images "$tmp" >/dev/null 2>&1 || { -extract_boot_images "$tmp" >/dev/null 2>&1 || {
rc=$? local rc=$?
rm -rf "$tmp" || true rm -rf "$tmp" || true
(( rc > 128 )) && exit "$rc" (( rc > 128 )) && exit "$rc"
+46 -97
View File
@@ -541,7 +541,7 @@ printEdition() {
local desc="$2" local desc="$2"
local show_eval="${3:-N}" local show_eval="${3:-N}"
local normalized="${id,,}" local normalized="${id,,}"
local result="" edition="" suffix="" local result edition="" suffix=""
result=$(printVersion "$id" "x") result=$(printVersion "$id" "x")
[[ "$result" == "x" ]] && echo "$desc" && return 0 [[ "$result" == "x" ]] && echo "$desc" && return 0
@@ -636,14 +636,11 @@ fromFile() {
case "$file" in case "$file" in
*"_x64_"* | *"_x64."*) *"_x64_"* | *"_x64."*)
arch="x64" arch="x64" ;;
;;
*"_x86_"* | *"_x86."*) *"_x86_"* | *"_x86."*)
arch="x86" arch="x86" ;;
;;
*"_arm64_"* | *"_arm64."*) *"_arm64_"* | *"_arm64."*)
arch="arm64" arch="arm64" ;;
;;
esac esac
local add="" local add=""
@@ -651,59 +648,41 @@ fromFile() {
case "$file" in case "$file" in
"win7"* | "win_7"* | *"windows7"* | *"windows_7"* ) "win7"* | "win_7"* | *"windows7"* | *"windows_7"* )
id="win7${arch}" id="win7${arch}" ;;
;;
"win8"* | "win_8"* | *"windows8"* | *"windows_8"* ) "win8"* | "win_8"* | *"windows8"* | *"windows_8"* )
id="win81${arch}" id="win81${arch}" ;;
;;
"win10"*| "win_10"* | *"windows10"* | *"windows_10"* ) "win10"*| "win_10"* | *"windows10"* | *"windows_10"* )
id="win10${arch}" id="win10${arch}" ;;
;;
"win11"* | "win_11"* | *"windows11"* | *"windows_11"* ) "win11"* | "win_11"* | *"windows11"* | *"windows_11"* )
id="win11${arch}" id="win11${arch}" ;;
;;
*"winxp"* | *"win_xp"* | *"windowsxp"* | *"windows_xp"* ) *"winxp"* | *"win_xp"* | *"windowsxp"* | *"windows_xp"* )
id="winxpx86" id="winxpx86" ;;
;;
*"winvista"* | *"win_vista"* | *"windowsvista"* | *"windows_vista"* ) *"winvista"* | *"win_vista"* | *"windowsvista"* | *"windows_vista"* )
id="winvista${arch}" id="winvista${arch}" ;;
;;
"nano11"* | "nano_11"* ) "nano11"* | "nano_11"* )
id="nano11" id="nano11" ;;
;;
"tiny11core"* | "tiny11_core"* | "tiny_11_core"* ) "tiny11core"* | "tiny11_core"* | "tiny_11_core"* )
id="core11" id="core11" ;;
;;
"tiny11"* | "tiny_11"* ) "tiny11"* | "tiny_11"* )
id="tiny11" id="tiny11" ;;
;;
"tiny10"* | "tiny_10"* ) "tiny10"* | "tiny_10"* )
id="tiny10" id="tiny10" ;;
;;
*"_serverhypercore_"* ) *"_serverhypercore_"* )
id="win2019${add}-hv" id="win2019${add}-hv" ;;
;;
*"server2025"* | *"server_2025"* ) *"server2025"* | *"server_2025"* )
id="win2025${add}" id="win2025${add}" ;;
;;
*"server2022"* | *"server_2022"* ) *"server2022"* | *"server_2022"* )
id="win2022${add}" id="win2022${add}" ;;
;;
*"server2019"* | *"server_2019"* ) *"server2019"* | *"server_2019"* )
id="win2019${add}" id="win2019${add}" ;;
;;
*"server2016"* | *"server_2016"* ) *"server2016"* | *"server_2016"* )
id="win2016${add}" id="win2016${add}" ;;
;;
*"server2012"* | *"server_2012"* ) *"server2012"* | *"server_2012"* )
id="win2012r2${add}" id="win2012r2${add}" ;;
;;
*"server2008"* | *"server_2008"* ) *"server2008"* | *"server_2008"* )
id="win2008r2${add}" id="win2008r2${add}" ;;
;;
*"server2003"* | *"server_2003"* ) *"server2003"* | *"server_2003"* )
id="win2003r2${add}" id="win2003r2${add}" ;;
;;
esac esac
if [ -n "$id" ]; then if [ -n "$id" ]; then
@@ -774,41 +753,34 @@ normalizeEditionID() {
case "$edition" in case "$edition" in
"pro" | "professional" | "business" ) "pro" | "professional" | "business" )
edition="" edition="" ;;
;;
"pro-n" | "professional-n" ) "pro-n" | "professional-n" )
edition="n" edition="n" ;;
;;
esac esac
case "${id,,}" in case "${id,,}" in
"winvista"* ) "winvista"* )
case "$edition" in case "$edition" in
"business" ) "business" )
edition="" edition="" ;;
;;
"home-basic" | "home-premium" ) "home-basic" | "home-premium" )
edition="home" edition="home" ;;
;;
esac esac
;; ;;
"win7"* ) "win7"* )
case "$edition" in case "$edition" in
"home-basic" | "home-premium" ) "home-basic" | "home-premium" )
edition="home" edition="home" ;;
;;
esac esac
;; ;;
"win10"* | "win11"* ) "win10"* | "win11"* )
case "$edition" in case "$edition" in
"iot-enterprise-ltsc" | \ "iot-enterprise-ltsc" | \
"iot-enterprise-ltsc-"[0-9][0-9][0-9][0-9] ) "iot-enterprise-ltsc-"[0-9][0-9][0-9][0-9] )
edition="iot" edition="iot" ;;
;;
"enterprise-ltsc" | \ "enterprise-ltsc" | \
"enterprise-ltsc-"[0-9][0-9][0-9][0-9] ) "enterprise-ltsc-"[0-9][0-9][0-9][0-9] )
edition="ltsc" edition="ltsc" ;;
;;
esac esac
;; ;;
esac esac
@@ -821,31 +793,24 @@ getEditionID() {
local name="${1,,}" local name="${1,,}"
local id="${2,,}" local id="${2,,}"
local edition="" local edition
case "$id" in case "$id" in
"winvista"* ) "winvista"* )
edition="${name#*vista}" edition="${name#*vista}" ;;
;;
"win7"* ) "win7"* )
edition="${name#*7}" edition="${name#*7}" ;;
;;
"win8"* ) "win8"* )
if [[ "$name" == *"8.1"* ]]; then if [[ "$name" == *"8.1"* ]]; then
edition="${name#*8.1}" edition="${name#*8.1}"
else else
edition="${name#*8}" edition="${name#*8}"
fi fi ;;
;;
"win10"* ) "win10"* )
edition="${name#*10}" edition="${name#*10}" ;;
;;
"win11"* ) "win11"* )
edition="${name#*11}" edition="${name#*11}" ;;
;; * ) return 1 ;;
* )
return 1
;;
esac esac
edition=$(normalizeEditionID "$edition" "$id") edition=$(normalizeEditionID "$edition" "$id")
@@ -924,33 +889,17 @@ getServerEditionID() {
local name="${1,,}" local name="${1,,}"
local id="${2,,}" local id="${2,,}"
local edition="" local edition
case "$id" in case "$id" in
"win2025"* ) "win2025"* ) edition="${name#*server 2025}" ;;
edition="${name#*server 2025}" "win2022"* ) edition="${name#*server 2022}" ;;
;; "win2019"* ) edition="${name#*server 2019}" ;;
"win2022"* ) "win2016"* ) edition="${name#*server 2016}" ;;
edition="${name#*server 2022}" "win2012"* ) edition="${name#*server 2012}" ;;
;; "win2008"* ) edition="${name#*server 2008}" ;;
"win2019"* ) "win2003"* ) edition="${name#*server 2003}" ;;
edition="${name#*server 2019}" * ) return 1 ;;
;;
"win2016"* )
edition="${name#*server 2016}"
;;
"win2012"* )
edition="${name#*server 2012}"
;;
"win2008"* )
edition="${name#*server 2008}"
;;
"win2003"* )
edition="${name#*server 2003}"
;;
* )
return 1
;;
esac esac
edition=$(normalizeServerEditionID "$edition") edition=$(normalizeServerEditionID "$edition")
@@ -1581,7 +1530,7 @@ validVersion() {
local id="$1" local id="$1"
local lang="$2" local lang="$2"
local url i=0 local url i
isMido "$id" "$lang" && return 0 isMido "$id" "$lang" && return 0
+18 -24
View File
@@ -6,7 +6,6 @@ getPlatform() {
local xml="$1" local xml="$1"
local tag="ARCH" local tag="ARCH"
local platform="x64" local platform="x64"
local arch
local -a arches=() local -a arches=()
@@ -18,7 +17,7 @@ getPlatform() {
if [ "${#arches[@]}" -gt 1 ]; then if [ "${#arches[@]}" -gt 1 ]; then
platform="mixed" platform="mixed"
elif [ "${#arches[@]}" -eq 1 ]; then elif [ "${#arches[@]}" -eq 1 ]; then
arch="${arches[0]}" local arch="${arches[0]}"
case "${arch,,}" in case "${arch,,}" in
"0" ) platform="x86" ;; "0" ) platform="x86" ;;
@@ -60,9 +59,7 @@ hasVersion() {
local wanted="$1" local wanted="$1"
shift shift
local actual expected_id selected_id file source local actual i
local i
local -a actuals=("$@") local -a actuals=("$@")
local -a expected=("$wanted") local -a expected=("$wanted")
local -a selected=("$wanted") local -a selected=("$wanted")
@@ -79,13 +76,13 @@ hasVersion() {
for (( i=0; i<${#expected[@]}; i++ )); do for (( i=0; i<${#expected[@]}; i++ )); do
expected_id="${expected[$i]}" local expected_id="${expected[$i]}"
selected_id="${selected[$i]}" local selected_id="${selected[$i]}"
for actual in "${actuals[@]}"; do for actual in "${actuals[@]}"; do
[[ "${actual,,}" == "${expected_id,,}" ]] || continue [[ "${actual,,}" == "${expected_id,,}" ]] || continue
file="/run/assets/$selected_id.xml" local file="/run/assets/$selected_id.xml"
if [ -s "$file" ]; then if [ -s "$file" ]; then
echo "$selected_id" echo "$selected_id"
@@ -93,7 +90,7 @@ hasVersion() {
fi fi
if [[ "${selected_id,,}" == *"-eval" ]]; then if [[ "${selected_id,,}" == *"-eval" ]]; then
source="/run/assets/${selected_id%-eval}.xml" local source="/run/assets/${selected_id%-eval}.xml"
if [ -s "$source" ]; then if [ -s "$source" ]; then
echo "$selected_id" echo "$selected_id"
@@ -169,10 +166,8 @@ detectVersion() {
local xml="$1" local xml="$1"
local suggested="${2:-}" local suggested="${2:-}"
local tag name id base match platform
local tag name id base prefer match platform local priority edition suffix i tried=""
local priority actual edition suffix i
local tried=""
local -a tags=( local -a tags=(
"DISPLAYNAME" "DISPLAYNAME"
@@ -251,7 +246,7 @@ detectVersion() {
esac esac
tried="Y" tried="Y"
prefer="$base" local prefer="$base"
[ -n "$edition" ] && prefer+="-$edition" [ -n "$edition" ] && prefer+="-$edition"
if match=$(hasVersion "$prefer" "${versions[@]}"); then if match=$(hasVersion "$prefer" "${versions[@]}"); then
@@ -279,7 +274,7 @@ detectVersion() {
# still allows its Evaluation counterpart when the normal variant is absent. # still allows its Evaluation counterpart when the normal variant is absent.
for suffix in "${suffixes[@]}"; do for suffix in "${suffixes[@]}"; do
for base in "${bases[@]}"; do for base in "${bases[@]}"; do
prefer="$base$suffix" local prefer="$base$suffix"
if match=$(hasVersion "$prefer" "${versions[@]}"); then if match=$(hasVersion "$prefer" "${versions[@]}"); then
echo "$match" echo "$match"
@@ -294,7 +289,7 @@ detectVersion() {
for (( i=0; i<${#versions[@]}; i++ )); do for (( i=0; i<${#versions[@]}; i++ )); do
[[ "${groups[$i]}" == "$priority" ]] || continue [[ "${groups[$i]}" == "$priority" ]] || continue
actual="${versions[$i]}" local actual="${versions[$i]}"
if match=$(hasVersion "$actual" "${versions[@]}"); then if match=$(hasVersion "$actual" "${versions[@]}"); then
echo "$match" echo "$match"
@@ -480,8 +475,7 @@ detectImage() {
local dir="$1" local dir="$1"
local version="$2" local version="$2"
local desc msg language local desc language
local file source
XML="" XML=""
@@ -492,12 +486,12 @@ detectImage() {
if [ -z "$DETECTED" ] && [ -z "$CUSTOM" ] && if [ -z "$DETECTED" ] && [ -z "$CUSTOM" ] &&
[ -z "${REUSED_ISO:-}" ] && [[ "${version,,}" != "http"* ]]; then [ -z "${REUSED_ISO:-}" ] && [[ "${version,,}" != "http"* ]]; then
file="/run/assets/$version.xml" local file="/run/assets/$version.xml"
if [ -s "$file" ]; then if [ -s "$file" ]; then
DETECTED="$version" DETECTED="$version"
elif [[ "${version,,}" == *"-eval" ]]; then elif [[ "${version,,}" == *"-eval" ]]; then
source="/run/assets/${version%-eval}.xml" local source="/run/assets/${version%-eval}.xml"
[ -s "$source" ] && DETECTED="$version" [ -s "$source" ] && DETECTED="$version"
fi fi
@@ -524,7 +518,7 @@ detectImage() {
return 0 return 0
fi fi
local src wim info index suggested edition rc=0 local src wim info index suggested edition
src=$(find "$dir" -maxdepth 1 -type d -iname sources -print -quit) src=$(find "$dir" -maxdepth 1 -type d -iname sources -print -quit)
if [ ! -d "$src" ]; then if [ ! -d "$src" ]; then
@@ -542,7 +536,7 @@ detectImage() {
info=$(wimlib-imagex info -xml "$wim" | info=$(wimlib-imagex info -xml "$wim" |
iconv -f UTF-16LE -t UTF-8) || { iconv -f UTF-16LE -t UTF-8) || {
rc=$? local rc=$?
if (( rc >= 129 )); then if (( rc >= 129 )); then
exit "$rc" exit "$rc"
@@ -578,7 +572,7 @@ detectImage() {
fi fi
if [ -z "$DETECTED" ]; then if [ -z "$DETECTED" ]; then
msg="Failed to determine Windows version from image" local msg="Failed to determine Windows version from image"
if setXML "" || enabled "$MANUAL"; then if setXML "" || enabled "$MANUAL"; then
info "${msg}!" info "${msg}!"
@@ -609,7 +603,7 @@ detectImage() {
return 1 return 1
fi fi
msg="the answer file for $desc was not found ($DETECTED.xml)" local msg="the answer file for $desc was not found ($DETECTED.xml)"
local fallback="/run/assets/${DETECTED%%-*}.xml" local fallback="/run/assets/${DETECTED%%-*}.xml"
if setXML "$fallback" "$index" || enabled "$MANUAL"; then if setXML "$fallback" "$index" || enabled "$MANUAL"; then
+29 -33
View File
@@ -11,7 +11,7 @@ backup () {
local count=1 local count=1
local name="unknown" local name="unknown"
local root="$STORAGE/backups" local root="$STORAGE/backups"
local file previous find_pid failed="" local file previous failed=""
previous=$(readState "base") || return 1 previous=$(readState "base") || return 1
[ -n "$previous" ] && name="${previous%.*}" [ -n "$previous" ] && name="${previous%.*}"
@@ -53,7 +53,7 @@ backup () {
-not -iname '*.iso' -print0 -not -iname '*.iso' -print0
) )
find_pid=$! local find_pid=$!
if ! wait "$find_pid"; then if ! wait "$find_pid"; then
error "Failed to enumerate files in \"$STORAGE\"." error "Failed to enumerate files in \"$STORAGE\"."
@@ -122,10 +122,8 @@ detectCustom() {
skipInstall() { skipInstall() {
local iso="$1" local iso="$1"
local method="" local method magic previous
local magic byte
local boot="$STORAGE/windows.boot" local boot="$STORAGE/windows.boot"
local previous
previous=$(readState "base") || return 1 previous=$(readState "base") || return 1
@@ -178,7 +176,8 @@ skipInstall() {
# Check if the ISO was already processed by our script # Check if the ISO was already processed by our script
magic=$(dd if="$iso" bs=1 count=1 status=none | tr -d '\000') magic=$(dd if="$iso" bs=1 count=1 status=none | tr -d '\000')
magic="$(printf '%s' "$magic" | od -A n -t x1 -v | tr -d ' \n')" magic="$(printf '%s' "$magic" | od -A n -t x1 -v | tr -d ' \n')"
byte="16" && enabled "$MANUAL" && byte="17" local byte="16"
enabled "$MANUAL" && byte="17"
if [[ "$magic" != "$byte" ]]; then if [[ "$magic" != "$byte" ]]; then
@@ -293,7 +292,7 @@ finishInstall() {
local iso="$1" local iso="$1"
local aborted="$2" local aborted="$2"
local base byte local base
if [ ! -s "$iso" ] || [ ! -f "$iso" ]; then if [ ! -s "$iso" ] || [ ! -f "$iso" ]; then
error "Failed to find ISO file: $iso" && return 1 error "Failed to find ISO file: $iso" && return 1
@@ -307,7 +306,8 @@ finishInstall() {
if [[ "$aborted" != [Yy1]* ]]; then if [[ "$aborted" != [Yy1]* ]]; then
# Mark ISO as prepared via magic byte # Mark ISO as prepared via magic byte
byte="16" && enabled "$MANUAL" && byte="17" local byte="16"
enabled "$MANUAL" && byte="17"
if ! printf '%b' "\x$byte" | dd of="$iso" bs=1 seek=0 count=1 conv=notrunc status=none; then if ! printf '%b' "\x$byte" | dd of="$iso" bs=1 seek=0 count=1 conv=notrunc status=none; then
warn "failed to set magic byte in ISO file: $iso" warn "failed to set magic byte in ISO file: $iso"
fi fi
@@ -443,21 +443,18 @@ extractESD() {
local version="$3" local version="$3"
local desc="$4" local desc="$4"
local msg ret index size
local minSize freeSpace bootPad
local info count totals links local info count totals links
local bootTotal bootLinks bootSize local bootTotal bootLinks
local wimTotal wimLinks wimSize local wimTotal wimLinks
local installSize installPad local installSize size
local bootWim installWim
local edition imgEdition local edition imgEdition
minSize=100000000 local minSize=100000000
freeSpace=9606127360 local freeSpace=9606127360
bootPad=60000000 local bootPad=60000000
installPad=3000000 local installPad=3000000
msg="Extracting $desc bootdisk" local msg="Extracting $desc bootdisk"
info "$msg..." && html "$msg..." info "$msg..." && html "$msg..."
if ! size=$(stat -c%s -- "$iso"); then if ! size=$(stat -c%s -- "$iso"); then
@@ -510,7 +507,7 @@ extractESD() {
return 1 return 1
fi fi
bootSize=$(( bootTotal - bootLinks )) local bootSize=$(( bootTotal - bootLinks ))
wimTotal=$(getEsdField "$totals" 3) wimTotal=$(getEsdField "$totals" 3)
wimLinks=$(getEsdField "$links" 3) wimLinks=$(getEsdField "$links" 3)
@@ -520,13 +517,13 @@ extractESD() {
return 1 return 1
fi fi
wimSize=$(( wimTotal - wimLinks + bootPad )) local wimSize=$(( wimTotal - wimLinks + bootPad ))
/run/progress.sh "$dir" "$bootSize" "$msg ([P])..." & /run/progress.sh "$dir" "$bootSize" "$msg ([P])..." &
index="1" local index="1"
wimlib-imagex apply "$iso" "$index" "$dir" --quiet 2>/dev/null || { wimlib-imagex apply "$iso" "$index" "$dir" --quiet 2>/dev/null || {
ret=$? local ret=$?
fKill "progress.sh" fKill "progress.sh"
error "Extracting $desc bootdisk failed ($ret)" error "Extracting $desc bootdisk failed ($ret)"
return 1 return 1
@@ -534,8 +531,8 @@ extractESD() {
fKill "progress.sh" fKill "progress.sh"
bootWim="$dir/sources/boot.wim" local bootWim="$dir/sources/boot.wim"
installWim="$dir/sources/install.wim" local installWim="$dir/sources/install.wim"
msg="Extracting $desc environment" msg="Extracting $desc environment"
info "$msg..." && html "$msg..." info "$msg..." && html "$msg..."
@@ -544,7 +541,7 @@ extractESD() {
/run/progress.sh "$bootWim" "$wimSize" "$msg ([P])..." & /run/progress.sh "$bootWim" "$wimSize" "$msg ([P])..." &
wimlib-imagex export "$iso" "$index" "$bootWim" --compress=none --quiet || { wimlib-imagex export "$iso" "$index" "$bootWim" --compress=none --quiet || {
ret=$? local ret=$?
fKill "progress.sh" fKill "progress.sh"
error "Adding WinPE failed ($ret)" error "Adding WinPE failed ($ret)"
return 1 return 1
@@ -559,7 +556,7 @@ extractESD() {
/run/progress.sh "$bootWim" "$wimSize" "$msg ([P])..." & /run/progress.sh "$bootWim" "$wimSize" "$msg ([P])..." &
wimlib-imagex export "$iso" "$index" "$bootWim" --compress=none --boot --quiet || { wimlib-imagex export "$iso" "$index" "$bootWim" --compress=none --boot --quiet || {
ret=$? local ret=$?
fKill "progress.sh" fKill "progress.sh"
error "Adding Windows Setup failed ($ret)" error "Adding Windows Setup failed ($ret)"
return 1 return 1
@@ -594,7 +591,7 @@ extractESD() {
/run/progress.sh "$installWim" "$installSize" "$msg ([P])..." & /run/progress.sh "$installWim" "$installSize" "$msg ([P])..." &
wimlib-imagex export "$iso" "$index" "$installWim" --compress=LZMS --chunk-size 128K --quiet || { wimlib-imagex export "$iso" "$index" "$installWim" --compress=LZMS --chunk-size 128K --quiet || {
ret=$? local ret=$?
fKill "progress.sh" fKill "progress.sh"
error "Addition of $index to the $desc image failed ($ret)" error "Addition of $index to the $desc image failed ($ret)"
return 1 return 1
@@ -781,7 +778,7 @@ prepareImage() {
addFolder() { addFolder() {
local src="$1" local src="$1"
local folder="/oem" file="" local folder="/oem" file
local dest="$src/\$OEM\$/\$1/OEM" local dest="$src/\$OEM\$/\$1/OEM"
[ ! -d "$folder" ] && folder="/OEM" [ ! -d "$folder" ] && folder="/OEM"
@@ -830,8 +827,7 @@ addDriver() {
local path="$2" local path="$2"
local target="$3" local target="$3"
local driver="$4" local driver="$4"
local desc="" local folder="" desc
local folder=""
if [ -z "$id" ]; then if [ -z "$id" ]; then
warn "no Windows version specified for \"$driver\" driver!" && return 0 warn "no Windows version specified for \"$driver\" driver!" && return 0
@@ -944,7 +940,7 @@ updateImage() {
local xml="autounattend.xml" local xml="autounattend.xml"
local bak="${xml//.xml/.org}" local bak="${xml//.xml/.org}"
local dat="${xml//.xml/.dat}" local dat="${xml//.xml/.dat}"
local desc path src wim name info idx local desc path src wim name info
skipVersion "${DETECTED,,}" && return 0 skipVersion "${DETECTED,,}" && return 0
@@ -973,7 +969,7 @@ updateImage() {
return 1 return 1
fi fi
idx="1" local idx="1"
if ! info=$(wimlib-imagex info -xml "$wim" | iconv -f UTF-16LE -t UTF-8); then if ! info=$(wimlib-imagex info -xml "$wim" | iconv -f UTF-16LE -t UTF-8); then
warn "failed to read boot image information, $FB" warn "failed to read boot image information, $FB"
+35 -38
View File
@@ -6,7 +6,7 @@ handleCurlError() {
local code="$1" local code="$1"
local server="$2" local server="$2"
local reason="${3:-}" local reason="${3:-}"
local signal="" local signal
if [ -n "$reason" ] && (( code <= 125 )); then if [ -n "$reason" ] && (( code <= 125 )); then
error "Request to $server servers failed: ${reason%.}." error "Request to $server servers failed: ${reason%.}."
@@ -43,8 +43,7 @@ curlRequest() {
local agent="$3" local agent="$3"
shift 3 shift 3
local log reason local log reason response
local rc=0 response=""
if ! log=$(mktemp -p "$QEMU_DIR"); then if ! log=$(mktemp -p "$QEMU_DIR"); then
error "Failed to create a temporary curl log." error "Failed to create a temporary curl log."
@@ -62,7 +61,7 @@ curlRequest() {
--tlsv1.2 \ --tlsv1.2 \
--http1.1 \ --http1.1 \
"$@" 2>"$log") "$@" 2>"$log")
rc=$? local rc=$?
} || : } || :
if (( rc != 0 )); then if (( rc != 0 )); then
@@ -90,14 +89,14 @@ downloadWindows() {
local lang="$2" local lang="$2"
local desc="$3" local desc="$3"
local ovToken="" ovTicks="" ovTime="" local ovToken="" ovTicks="" ovTime
local skuId="" skuUrl="" skuJson="" local skuId skuJson
local linkUrl="" linkJson="" link="" local linkJson link
local language="" orgId="" ovData="" local language ovData
local instance="" vlsUrl="" ovUrl="" local session agent
local session="" agent="" type="" local type winVer
local winVer="" page="" productId="" local page productId
local rc=0 profile="606624d44113" local profile="606624d44113"
agent=$(getAgent) agent=$(getAgent)
language=$(getLanguage "$lang" "name") language=$(getLanguage "$lang" "name")
@@ -142,8 +141,8 @@ downloadWindows() {
# Microsoft download "protection" requires the sessionId to be whitelisted through vlscppe.microsoft.com/tags # Microsoft download "protection" requires the sessionId to be whitelisted through vlscppe.microsoft.com/tags
orgId="y6jn8c31" local orgId="y6jn8c31"
vlsUrl="https://vlscppe.microsoft.com/tags?org_id=$orgId&session_id=$session" local vlsUrl="https://vlscppe.microsoft.com/tags?org_id=$orgId&session_id=$session"
enabled "$DEBUG" && echo "Getting Session ID: $session" enabled "$DEBUG" && echo "Getting Session ID: $session"
@@ -157,8 +156,8 @@ downloadWindows() {
# Microsoft download "protection" also requires an ov-df.microsoft.com request/reply # Microsoft download "protection" also requires an ov-df.microsoft.com request/reply
# 1) Request mdt.js to get w and rticks. InstanceId is (currently) constant. # 1) Request mdt.js to get w and rticks. InstanceId is (currently) constant.
instance="560dc9f3-1aa5-4a2f-b63c-9e18f8d0e175" local instance="560dc9f3-1aa5-4a2f-b63c-9e18f8d0e175"
ovUrl="https://ov-df.microsoft.com/mdt.js?instanceId=$instance&PageId=si&session_id=$session" local ovUrl="https://ov-df.microsoft.com/mdt.js?instanceId=$instance&PageId=si&session_id=$session"
enabled "$DEBUG" && echo -n "Getting OV data: " enabled "$DEBUG" && echo -n "Getting OV data: "
@@ -199,7 +198,7 @@ downloadWindows() {
enabled "$DEBUG" && echo -n "Getting language SKU ID: " enabled "$DEBUG" && echo -n "Getting language SKU ID: "
skuUrl="https://www.microsoft.com/software-download-connector/api/getskuinformationbyproductedition?profile=$profile&ProductEditionId=$productId&SKU=undefined&friendlyFileName=undefined&Locale=en-US&sessionID=$session" local skuUrl="https://www.microsoft.com/software-download-connector/api/getskuinformationbyproductedition?profile=$profile&ProductEditionId=$productId&SKU=undefined&friendlyFileName=undefined&Locale=en-US&sessionID=$session"
curlRequest skuJson "Microsoft" "$agent" \ curlRequest skuJson "Microsoft" "$agent" \
--referer "$url" \ --referer "$url" \
@@ -207,7 +206,7 @@ downloadWindows() {
--max-filesize 100K \ --max-filesize 100K \
-- "$skuUrl" || return 1 -- "$skuUrl" || return 1
{ skuId=$(echo "$skuJson" | jq --arg LANG "$language" -r '.Skus[] | select(.Language==$LANG).Id') 2>/dev/null; rc=$?; } || : { skuId=$(echo "$skuJson" | jq --arg LANG "$language" -r '.Skus[] | select(.Language==$LANG).Id') 2>/dev/null; local rc=$?; } || :
if [ -z "$skuId" ] || [[ "${skuId,,}" == "null" ]] || (( rc != 0 )); then if [ -z "$skuId" ] || [[ "${skuId,,}" == "null" ]] || (( rc != 0 )); then
language=$(getLanguage "$lang" "desc") language=$(getLanguage "$lang" "desc")
@@ -221,7 +220,7 @@ downloadWindows() {
# Get ISO download link # Get ISO download link
# If any request is going to be blocked by Microsoft it's always this last one (the previous requests always seem to succeed) # If any request is going to be blocked by Microsoft it's always this last one (the previous requests always seem to succeed)
linkUrl="https://www.microsoft.com/software-download-connector/api/GetProductDownloadLinksBySku?profile=$profile&ProductEditionId=undefined&SKU=$skuId&friendlyFileName=undefined&Locale=en-US&sessionID=$session" local linkUrl="https://www.microsoft.com/software-download-connector/api/GetProductDownloadLinksBySku?profile=$profile&ProductEditionId=undefined&SKU=$skuId&friendlyFileName=undefined&Locale=en-US&sessionID=$session"
curlRequest linkJson "Microsoft" "$agent" \ curlRequest linkJson "Microsoft" "$agent" \
--referer "$url" \ --referer "$url" \
@@ -262,8 +261,8 @@ downloadWindowsEval() {
local id="$1" local id="$1"
local lang="$2" local lang="$2"
local desc="$3" local desc="$3"
local filter="" culture="" compare="" language="" local culture compare type
local agent="" type="" winVer="" local agent language winVer
case "${id,,}" in case "${id,,}" in
"win11${PLATFORM,,}-enterprise-eval" ) "win11${PLATFORM,,}-enterprise-eval" )
@@ -301,9 +300,7 @@ downloadWindowsEval() {
culture=$(getLanguage "$lang" "culture") culture=$(getLanguage "$lang" "culture")
local country="${culture#*-}" local country="${culture#*-}"
local link="" local link="" links page
local links=""
local page=""
local url="https://www.microsoft.com/en-us/evalcenter/download-$winVer" local url="https://www.microsoft.com/en-us/evalcenter/download-$winVer"
enabled "$DEBUG" && echo "Parsing download page: ${url}" enabled "$DEBUG" && echo "Parsing download page: ${url}"
@@ -321,7 +318,7 @@ downloadWindowsEval() {
enabled "$DEBUG" && echo "Getting download link.." enabled "$DEBUG" && echo "Getting download link.."
filter="https://go.microsoft.com/fwlink/?linkid=[0-9]\+&clcid=0x[0-9a-z]\+&culture=${culture,,}&country=${country,,}" local filter="https://go.microsoft.com/fwlink/?linkid=[0-9]\+&clcid=0x[0-9a-z]\+&culture=${culture,,}&country=${country,,}"
if ! echo "$page" | grep -io "$filter" > /dev/null; then if ! echo "$page" | grep -io "$filter" > /dev/null; then
filter="https://go.microsoft.com/fwlink/p/?linkid=[0-9]\+&clcid=0x[0-9a-z]\+&culture=${culture,,}&country=${country,,}" filter="https://go.microsoft.com/fwlink/p/?linkid=[0-9]\+&clcid=0x[0-9a-z]\+&culture=${culture,,}&country=${country,,}"
@@ -474,8 +471,7 @@ downloadWindowsLtsc() {
local id="$1" local id="$1"
local lang="$2" local lang="$2"
local desc="$3" local desc="$3"
local alternate="" local alternate alternate_desc
local alternate_desc=""
case "${id,,}" in case "${id,,}" in
"win11${PLATFORM,,}-enterprise-iot-eval" ) "win11${PLATFORM,,}-enterprise-iot-eval" )
@@ -691,7 +687,7 @@ getESD() {
local xmlFile="products.xml" local xmlFile="products.xml"
local esdFile="esd_edition.xml" local esdFile="esd_edition.xml"
local filterFile="products_filter.xml" local filterFile="products_filter.xml"
local log query rc=0 reason="" local log
file=$(getCatalog "$version" "file") file=$(getCatalog "$version" "file")
catalog=$(getCatalog "$version" "url") catalog=$(getCatalog "$version" "url")
@@ -721,11 +717,12 @@ getESD() {
{ {
LC_ALL=C wget "$catalog" -O "$dir/$file" --no-verbose --timeout=30 \ LC_ALL=C wget "$catalog" -O "$dir/$file" --no-verbose --timeout=30 \
--no-http-keep-alive --output-file="$log" --no-http-keep-alive --output-file="$log"
rc=$? local rc=$?
} || : } || :
if (( rc != 0 )); then if (( rc != 0 )); then
local reason
reason=$(sed -n \ reason=$(sed -n \
-e 's/^wget: //p' \ -e 's/^wget: //p' \
-e 's/^[0-9-]\{10\} [0-9:]\{8\} ERROR //p' \ -e 's/^[0-9-]\{10\} [0-9:]\{8\} ERROR //p' \
@@ -771,7 +768,7 @@ getESD() {
return 1 return 1
fi fi
query='//File[Architecture="'${PLATFORM,,}'"]'"${edition}"'' local query='//File[Architecture="'${PLATFORM,,}'"]'"${edition}"''
result=$(xmllint --nonet --xpath "${query}" "$dir/$xmlFile" 2>/dev/null || true) result=$(xmllint --nonet --xpath "${query}" "$dir/$xmlFile" 2>/dev/null || true)
if [ -z "$result" ]; then if [ -z "$result" ]; then
@@ -854,7 +851,7 @@ verifyFile() {
fi fi
local algo="SHA256" local algo="SHA256"
local hash="" rc=0 local hash
[ -z "$check" ] && return 0 [ -z "$check" ] && return 0
! enabled "$VERIFY" && return 0 ! enabled "$VERIFY" && return 0
@@ -866,7 +863,7 @@ verifyFile() {
if [[ "${algo,,}" != "sha256" ]]; then if [[ "${algo,,}" != "sha256" ]]; then
hash=$(sha1sum "$iso" | cut -f1 -d' ') || { hash=$(sha1sum "$iso" | cut -f1 -d' ') || {
rc=$? local rc=$?
if (( rc >= 129 )); then if (( rc >= 129 )); then
exit "$rc" exit "$rc"
@@ -879,7 +876,7 @@ verifyFile() {
else else
hash=$(sha256sum "$iso" | cut -f1 -d' ') || { hash=$(sha256sum "$iso" | cut -f1 -d' ') || {
rc=$? local rc=$?
if (( rc >= 129 )); then if (( rc >= 129 )); then
exit "$rc" exit "$rc"
@@ -939,7 +936,7 @@ tryDownload() {
local desc="$6" local desc="$6"
local seconds="$7" local seconds="$7"
local web_desc="$8" local web_desc="$8"
local total rc=0 local total
if downloadRetry \ if downloadRetry \
"$iso" \ "$iso" \
@@ -952,9 +949,9 @@ tryDownload() {
"$size" \ "$size" \
"$desc" \ "$desc" \
"$web_desc"; then "$web_desc"; then
rc=0 local rc=0
else else
rc=$? local rc=$?
fi fi
(( rc == 0 )) || return "$rc" (( rc == 0 )) || return "$rc"
@@ -987,9 +984,9 @@ fallbackEnglish() {
local lang="$3" local lang="$3"
local desc="$4" local desc="$4"
local web_desc="$5" local web_desc="$5"
local culture msg web_msg local culture web_msg
msg="No working download method was found for $desc, falling back to English..." local msg="No working download method was found for $desc, falling back to English..."
info "$msg" info "$msg"
# Preserve the requested regional format and keyboard layout. # Preserve the requested regional format and keyboard layout.
+1 -1
View File
@@ -164,7 +164,7 @@ abortDuringSetup() {
gracefulShutdown() { gracefulShutdown() {
local sig="$1" local sig="$1"
local pid="" code=0 local pid code
[[ $BASHPID != "$TRAP_PID" ]] && return [[ $BASHPID != "$TRAP_PID" ]] && return
+1 -1
View File
@@ -81,7 +81,7 @@ addShare() {
local name="$3" local name="$3"
local comment="$4" local comment="$4"
local cfg="$5" local cfg="$5"
local owner="" local owner
local tmp="/tmp/smb" local tmp="/tmp/smb"
if [ ! -d "$dir" ]; then if [ ! -d "$dir" ]; then