fetch.sh 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #!/bin/bash
  2. #
  3. # OpenConnect (SSL + DTLS) VPN client
  4. #
  5. # Copyright © 2014 Kevin Cernekee <cernekee@gmail.com>
  6. #
  7. # This program is free software; you can redistribute it and/or
  8. # modify it under the terms of the GNU Lesser General Public License
  9. # version 2.1, as published by the Free Software Foundation.
  10. #
  11. # This program is distributed in the hope that it will be useful, but
  12. # WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. # Lesser General Public License for more details.
  15. #
  16. set -e
  17. libxml2_MIRROR_0=ftp://xmlsoft.org/libxml2
  18. libxml2_MIRROR_1=http://gd.tuwien.ac.at/pub/libxml
  19. libxml2_MIRROR_2=http://distfiles.macports.org/libxml2
  20. gmp_MIRROR_0=http://ftp.gnu.org/gnu/gmp
  21. gmp_MIRROR_1=https://gmplib.org/download/gmp
  22. gmp_MIRROR_2=http://www.mirrorservice.org/sites/ftp.gnu.org/gnu/gmp
  23. nettle_MIRROR_0=http://www.lysator.liu.se/~nisse/archive
  24. nettle_MIRROR_1=http://ftp.gnu.org/gnu/nettle
  25. nettle_MIRROR_2=http://gd.tuwien.ac.at/gnu/gnusrc/nettle
  26. gnutls_MIRROR_0=https://www.gnupg.org/ftp/gcrypt/gnutls/v3.6
  27. gnutls_MIRROR_1=http://ftp.heanet.ie/mirrors/ftp.gnupg.org/gcrypt/gnutls/v3.6
  28. gnutls_MIRROR_2=http://gd.tuwien.ac.at/pub/gnupg/gnutls/v3.6
  29. stoken_MIRROR_0=http://sourceforge.net/projects/stoken/files
  30. stoken_SUFFIX_0=/download
  31. oath_toolkit_MIRROR_0=http://download.savannah.gnu.org/releases/oath-toolkit
  32. oath_toolkit_MIRROR_1=https://download-mirror.savannah.gnu.org/releases/oath-toolkit
  33. lz4_MIRROR_0=https://github.com/lz4/lz4/archive
  34. MAX_TRIES=5
  35. function make_url
  36. {
  37. local tarball="$1"
  38. local mirror_idx="$2"
  39. local pkg="${tarball%-*}"
  40. pkg="${pkg/-/_}"
  41. if [[ "$pkg" =~ [^[:alnum:]_] ]]; then
  42. echo ""
  43. return
  44. fi
  45. eval local mirror_base="\$${pkg}_MIRROR_${mirror_idx}"
  46. eval local mirror_suffix="\$${pkg}_SUFFIX_${mirror_idx}"
  47. if [ -z "$mirror_base" ]; then
  48. echo ""
  49. return
  50. fi
  51. if [[ "${mirror_base}" = *//github.com*/archive* ]]; then
  52. # typical format: https://github.com/USER/PKG/archive/TAG.tar.gz
  53. echo "${mirror_base}/${tarball#*-}"
  54. else
  55. # typical format: http://.../PKG-TAG.tar.gz
  56. echo "${mirror_base}/${tarball}${mirror_suffix}"
  57. fi
  58. return
  59. }
  60. function check_hash
  61. {
  62. local tarball="$1"
  63. local good_hash="$2"
  64. local actual_hash
  65. if [ "${#good_hash}" = "40" ]; then
  66. actual_hash=$(sha1sum "$tarball")
  67. actual_hash=${actual_hash:0:40}
  68. elif [ "${#good_hash}" = "64" ]; then
  69. actual_hash=$(sha256sum "$tarball")
  70. actual_hash=${actual_hash:0:64}
  71. else
  72. echo "Unrecognized hash: $good_hash"
  73. exit 1
  74. fi
  75. if [ "$actual_hash" = "$good_hash" ]; then
  76. return 0
  77. else
  78. echo "$tarball: hash mismatch"
  79. echo " expected: $good_hash"
  80. echo " got instead: $actual_hash"
  81. return 1
  82. fi
  83. }
  84. function download_and_check
  85. {
  86. local url="$1"
  87. local tmpfile="$2"
  88. local hash="$3"
  89. rm -f "$tmpfile"
  90. if curl --location --connect-timeout 30 --speed-limit 1024 \
  91. -o "$tmpfile" "$url"; then
  92. if [ -n "$hash" ]; then
  93. if ! check_hash "$tmpfile" "$hash"; then
  94. return 1
  95. fi
  96. fi
  97. return 0
  98. fi
  99. return 1
  100. }
  101. # iterate through all available mirrors and make sure they have a good copy
  102. # of $tarball
  103. function mirror_test
  104. {
  105. local tarball="$1"
  106. local good_hash="$2"
  107. if [ -z "$good_hash" ]; then
  108. echo "ERROR: you must specify the hash for testing mirrors"
  109. exit 1
  110. fi
  111. local mirror_idx=0
  112. local tmpfile="${tarball}.mirror-test.tmp"
  113. while :; do
  114. local url=$(make_url "$tarball" "$mirror_idx")
  115. if [ -z "$url" ]; then
  116. break
  117. fi
  118. echo ""
  119. echo "Testing mirror $url"
  120. echo ""
  121. if download_and_check "$url" "$tmpfile" "$good_hash"; then
  122. echo ""
  123. echo "SHA $good_hash OK."
  124. echo ""
  125. else
  126. exit 1
  127. fi
  128. echo ""
  129. mirror_idx=$((mirror_idx + 1))
  130. done
  131. rm -f "$tmpfile"
  132. echo "Mirror test for $tarball PASSED"
  133. echo ""
  134. exit 0
  135. }
  136. #
  137. # MAIN
  138. #
  139. if [ "$1" = "--mirror-test" ]; then
  140. mirror_test=1
  141. shift
  142. else
  143. mirror_test=0
  144. fi
  145. if [ -z "$1" ]; then
  146. echo "usage: $0 [ --mirror-test ] <tarball_to_fetch> [ <sha1_hash> ]"
  147. exit 1
  148. fi
  149. tarball="$1"
  150. hash="$2"
  151. if [ $mirror_test = 1 ]; then
  152. mirror_test "$tarball" "$hash"
  153. exit 1
  154. fi
  155. if [ -e "$tarball" -a -n "$hash" ]; then
  156. if check_hash "$tarball" "$hash"; then
  157. echo "$tarball hash check passed. Done."
  158. echo ""
  159. exit 0
  160. fi
  161. fi
  162. tries=1
  163. tmpfile="${tarball}.tmp"
  164. while :; do
  165. mirror_idx=0
  166. while :; do
  167. url=$(make_url "$tarball" "$mirror_idx")
  168. if [ -z "$url" ]; then
  169. if [ $mirror_idx = 0 ]; then
  170. echo "No mirrors found for $tarball"
  171. exit 1
  172. else
  173. break
  174. fi
  175. fi
  176. echo ""
  177. echo "Attempt #$tries for mirror $url:"
  178. echo ""
  179. if download_and_check "$url" "$tmpfile" "$hash"; then
  180. mv "$tmpfile" "$tarball"
  181. exit 0
  182. fi
  183. echo ""
  184. mirror_idx=$((mirror_idx + 1))
  185. done
  186. tries=$((tries + 1))
  187. if [ $tries -gt $MAX_TRIES ]; then
  188. break
  189. fi
  190. echo "All mirrors failed; sleeping 10 seconds..."
  191. echo ""
  192. sleep 10
  193. done
  194. rm -f "$tarball" "$tmpfile"
  195. echo "ERROR: Unable to download $tarball"
  196. echo ""
  197. exit 1