#!/bin/bash # Download DS-Mod packages from a randomly chosen mirror server. There are # predefined servers in 'make menuconfig' which can be edited, but there is # also an empty input field for a user-defined server. Additionally, another # download source maybe specified on the command line as $2. $1 is the name # of the file to be downloaded. # # This script is designed to be called by makefile includes (*.mk), but can # also be called directly. It expects to find a file with necessary variables # at a relative location '../.config' to this script. The variables are: # - DS_MOD_DL_NUM_SITES (numeric value, e.g. 3) # - DS_MOD_DL_SITE_1 (URL, e.g. http://dsmod.3dfxatwork.de) # - ... # - DS_MOD_DL_SITE_n (n = DS_MOD_DL_NUM_SITES) helpmsg() { cat << 'EOF' ds_download - download DS-Mod packages Usage: ds_download (-?|--help) | ( []) download-dir - target directory for download file dot-config - path to .config for DS-Mod filename - download file name mirror - fallback mirror to download file from if preconfigured mirrors fail -?, --help - print this help text Examples: ds_download dl .config package.tar.bz2 ds_download dl .config package.tar.bz2 http://myserver.com/dsmod Debugging: just set DEBUG=1, like this: DEBUG=1 ds_download dl .config package.tar.bz2 EOF } rand() { # Create random 1-byte integer (for up to 255 download sites). # If more bytes are needed, increase 'count' parameter. rnd=$(dd if=/dev/urandom bs=1 count=1 2> /dev/null | od -d | head -n 1 | awk '{print $2}') # Normalise random number to return a value in range 1..$1 echo $(( $rnd % $1 + 1 )) } do_download() { # $1 = full download URL, $2 = target directory echo if [ "$DEBUG" == "1" ]; then echo -e "wget -P $1 $2"; fi wget -P "$1" "$2" wget_result=$? if [ "$wget_result" != "0" ]; then echo "Download failed - $2 -> error code $wget_result" >&2 return $wget_result fi echo "Download succeeded - $2 -> saved to folder $1" } # Regular use: help parameter -> exit without error if [ "$1" == "-?" -o "$1" == "--help" ]; then helpmsg exit 0 fi # Wrong number of parameters -> exit with error if [ $# -lt 3 -o $# -gt 4 ]; then helpmsg >&2 exit 1 fi DL_DIR="$1" DOT_CONFIG="$2" DL_FILE="$3" FALLBACK_MIRROR="$4" # Import DS-Mod config variables . $DOT_CONFIG if [ "$DEBUG" == "1" ]; then echo "ds_download parameters:" echo " DL_DIR=$1" echo " DOT_CONFIG=$2" echo " DL_FILE=$3" echo " FALLBACK_MIRROR=$4" fi # Fill array 'sites' with download server URLs (exclude empty strings) for (( i=1 ; $i<=$DS_MOD_DL_NUM_SITES ; i++ )); do # Trim whitespace from download site name eval "dl_site=\$DS_MOD_DL_SITE_$i" read dl_site <<< "$dl_site"; if [ "$dl_site" != "" ]; then (( num_sites++ )) sites[$num_sites]=$dl_site fi done # Randomly loop over preconfigured servers until a download succeeds # or all requests have failed. n=$num_sites while [ $n -gt 0 ]; do i=$(rand $num_sites) if [ -z ${sites[$i]} ]; then continue; fi (( n-- )) do_download "$DL_DIR" "${sites[$i]}/$DL_FILE" if [ "$?" != "0" ]; then sites[$i]="" continue fi exit 0 done # Trim whitespace from fallback mirror, too read dl_site <<< "$FALLBACK_MIRROR"; if [ -z $dl_site ]; then echo "No fallback site specified - could not download file $DL_FILE" >&2 exit 1 fi # Try to download from fallback mirror do_download "$DL_DIR" "${sites[$i]}/$DL_FILE" if [ "$?" != "0" ]; then exit 1 fi