From 7c803c1865e0a7d3ebb14946436df0b0fe523ba7 Mon Sep 17 00:00:00 2001 From: Humberto Dias Date: Sun, 11 Oct 2026 11:02:51 -0300 Subject: [PATCH] Resume source downloads across GNU mirrors. Keep partial files and try GNU fallbacks when Sourceware stalls. Every tarball still has to be listed in archives.txt so the SHA256 is checked, and file_size reads that size with stat. --- download.sh | 96 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 18 deletions(-) diff --git a/download.sh b/download.sh index 7807826d..9ec8690c 100755 --- a/download.sh +++ b/download.sh @@ -5,7 +5,8 @@ cd "$(dirname "$0")" cd archives || exit 1 ARCHIVE="archives.txt" -WGET="wget --tries=5 --timeout=15 --quiet --show-progress" +# 15s was aborting slow Sourceware transfers. Keep the partial file and resume. +WGET_OPTS=(--continue --tries=20 --timeout=60 --waitretry=5 --retry-connrefused --quiet --show-progress) # ----------------------------------------------------------------------------- # verify_sha256 @@ -29,17 +30,67 @@ verify_sha256() { return 0 } +file_size() { + wc -c "$1" | awk '{print $1}' +} + # ----------------------------------------------------------------------------- -# fetch +# mirror_urls +# Prints the primary URL plus GNU/kernel.org fallbacks. # ----------------------------------------------------------------------------- -fetch() { +mirror_urls() { url="$1" - dest="$2" - $WGET -O "$dest" "$url" || { - echo " !! Download failed: $url" >&2 - rm -f "$dest" - return 1 - } + file="$(basename "$url")" + printf '%s\n' "$url" + + case "$url" in + */binutils/releases/*|*/gnu/binutils/*) + printf '%s\n' \ + "https://ftpmirror.gnu.org/gnu/binutils/${file}" \ + "https://ftp.gnu.org/gnu/binutils/${file}" \ + "https://sourceware.org/pub/binutils/releases/${file}" \ + "https://mirrors.kernel.org/sourceware/binutils/releases/${file}" + ;; + */gcc/releases/*|*/gnu/gcc/*) + ver="${file%.tar.*}" + printf '%s\n' \ + "https://ftpmirror.gnu.org/gnu/gcc/${ver}/${file}" \ + "https://ftp.gnu.org/gnu/gcc/${ver}/${file}" \ + "https://sourceware.org/pub/gcc/releases/${ver}/${file}" \ + "https://gcc.gnu.org/pub/gcc/releases/${ver}/${file}" + ;; + */gdb/releases/*|*/gnu/gdb/*) + printf '%s\n' \ + "https://ftpmirror.gnu.org/gnu/gdb/${file}" \ + "https://ftp.gnu.org/gnu/gdb/${file}" \ + "https://sourceware.org/pub/gdb/releases/${file}" + ;; + */newlib/*) + printf '%s\n' \ + "https://sourceware.org/pub/newlib/${file}" \ + "https://mirrors.kernel.org/sourceware/newlib/${file}" + ;; + esac +} + +# ----------------------------------------------------------------------------- +# fetch [url...] +# Resumes into dest; does not delete a partial file on failure. +# ----------------------------------------------------------------------------- +fetch() { + dest="$1" + shift + url="" + for url in "$@"; do + [ -n "$url" ] || continue + echo " -> $url" + if wget "${WGET_OPTS[@]}" -O "$dest" "$url"; then + return 0 + fi + echo " !! failed, trying next mirror..." >&2 + done + echo " !! Download failed: ${1:-$url}" >&2 + return 1 } # ----------------------------------------------------------------------------- @@ -54,7 +105,6 @@ download() { printf '==> %s\n' "$file" - # If already present, verify immediately — size alone is not enough. if [ -f "$file" ]; then if [ "$sha" = "-" ]; then echo " -- no checksum, skipping re-download of existing file" @@ -64,19 +114,27 @@ download() { echo " -- already good" return 0 fi - echo " -- existing file failed verification, re-downloading..." - rm -f "$file" + actual=$(file_size "$file") + if [ "$size" != "-" ] && [ "$actual" -lt "$size" ]; then + echo " -- incomplete (${actual}/${size} bytes), resuming..." + else + echo " -- existing file failed verification, re-downloading..." + rm -f "$file" + fi fi - # First attempt - fetch "$url" "$file" + # Unique mirror list, primary URL first. + urls=$(mirror_urls "$url" | awk 'NF && !seen[$0]++') + + # shellcheck disable=SC2086 + fetch "$file" $urls - # Verify, with one retry on mismatch if [ "$sha" != "-" ]; then if ! verify_sha256 "$file" "$sha"; then - echo " -- retrying download..." + echo " -- checksum failed, retrying from another mirror..." rm -f "$file" - fetch "$url" "$file" + # shellcheck disable=SC2086 + fetch "$file" $urls verify_sha256 "$file" "$sha" || { rm -f "$file" echo " !! Giving up on $file" >&2 @@ -125,6 +183,7 @@ run_one() { found=0 while IFS= read -r line; do case "$line" in + \#*|"") continue ;; *"$target"*) ;; *) continue ;; esac @@ -138,6 +197,7 @@ EOF done < "$ARCHIVE" [ "$found" -eq 1 ] || { echo "Not found: $target" >&2 + echo "Add a line to archives/archives.txt, including the SHA256." >&2 exit 1 } } @@ -147,4 +207,4 @@ if [ "$#" -eq 0 ]; then run_all else run_one "$1" -fi \ No newline at end of file +fi