00-distfiles.sh (8621B)
1# This hook downloads the distfiles specified in a template by 2# the $distfiles variable and then verifies its sha256 checksum comparing 3# its value with the one stored in the $checksum variable. 4 5# Get the checksum for $curfile at index $dfcount 6get_cksum() { 7 local curfile="$1" dfcount="$2" ckcount cksum i 8 9 ckcount=0 10 cksum=0 11 for i in ${checksum}; do 12 if [ $dfcount -eq $ckcount -a -n "$i" ]; then 13 cksum=$i 14 fi 15 ckcount=$((ckcount + 1)) 16 done 17 if [ -z "$cksum" ]; then 18 msg_error "$pkgver: cannot find checksum for $curfile.\n" 19 fi 20 echo "$cksum" 21} 22 23# Return the checksum of the contents of a tarball 24contents_cksum() { 25 local curfile="$1" cursufx cksum 26 27 case $curfile in 28 *.tar.lzma) cursufx="txz";; 29 *.tar.lz) cursufx="tlz";; 30 *.tlz) cursufx="tlz";; 31 *.tar.xz) cursufx="txz";; 32 *.txz) cursufx="txz";; 33 *.tar.bz2) cursufx="tbz";; 34 *.tbz) cursufx="tbz";; 35 *.tar.gz) cursufx="tgz";; 36 *.tgz) cursufx="tgz";; 37 *.gz) cursufx="gz";; 38 *.bz2) cursufx="bz2";; 39 *.tar) cursufx="tar";; 40 *.zip) cursufx="zip";; 41 *.rpm) cursufx="rpm";; 42 *.patch) cursufx="txt";; 43 *.diff) cursufx="txt";; 44 *.txt) cursufx="txt";; 45 *.7z) cursufx="7z";; 46 *.gem) cursufx="gem";; 47 *.crate) cursufx="crate";; 48 *) msg_error "$pkgver: unknown distfile suffix for $curfile.\n";; 49 esac 50 51 case ${cursufx} in 52 tar|txz|tbz|tlz|tgz|crate) 53 cksum=$($XBPS_DIGEST_CMD <($TAR_CMD -x -O -f "$curfile")) 54 if [ $? -ne 0 ]; then 55 msg_error "$pkgver: extracting $curfile to pipe.\n" 56 fi 57 ;; 58 gz) 59 cksum=$($XBPS_DIGEST_CMD <(gunzip -c "$curfile")) 60 ;; 61 bz2) 62 cksum=$($XBPS_DIGEST_CMD <(bunzip2 -c "$curfile")) 63 ;; 64 zip) 65 if command -v unzip &>/dev/null; then 66 cksum=$($XBPS_DIGEST_CMD <(unzip -p "$curfile")) 67 if [ $? -ne 0 ]; then 68 msg_error "$pkgver: extracting $curfile to pipe.\n" 69 fi 70 else 71 msg_error "$pkgver: cannot find unzip bin for extraction.\n" 72 fi 73 ;; 74 rpm) 75 if command -v rpmextract &>/dev/null; then 76 cksum=$($XBPS_DIGEST_CMD <(rpm2cpio "$curfile" | $TAR_CMD -x -f -)) 77 if [ $? -ne 0 ]; then 78 msg_error "$pkgver: extracting $curfile to pipe.\n" 79 fi 80 else 81 msg_error "$pkgver: cannot find rpmextract for extraction.\n" 82 fi 83 ;; 84 txt) 85 cksum=$($XBPS_DIGEST_CMD "$curfile") 86 ;; 87 7z) 88 if command -v 7z &>/dev/null; then 89 cksum=$($XBPS_DIGEST_CMD <(7z x -o "$curfile")) 90 if [ $? -ne 0 ]; then 91 msg_error "$pkgver: extracting $curfile to pipe.\n" 92 fi 93 else 94 msg_error "$pkgver: cannot find 7z bin for extraction.\n" 95 fi 96 ;; 97 gem) 98 cksum=$($XBPS_DIGEST_CMD <($TAR_CMD -x -O -f "$curfile" data.tar.gz | $TAR_CMD -xzO )) 99 ;; 100 *) 101 msg_error "$pkgver: cannot guess $curfile extract suffix. ($cursufx)\n" 102 ;; 103 esac 104 105 if [ -z "$cksum" ]; then 106 msg_error "$pkgver: cannot find contents checksum for $curfile.\n" 107 fi 108 echo "$cksum" 109} 110 111# Verify the checksum for $curfile stored at $distfile and index $dfcount 112verify_cksum() { 113 local curfile="$1" distfile="$2" dfcount="$3" filesum cksum 114 115 cksum=$(get_cksum $curfile $dfcount) 116 117 # If the checksum starts with an commercial at (@) it is the contents checksum 118 if [ "${cksum:0:1}" = "@" ]; then 119 cksum=${cksum:1} 120 msg_normal "$pkgver: verifying contents checksum for distfile '$curfile'... " 121 filesum=$(contents_cksum "$curfile") 122 if [ "${cksum}" != "$filesum" ]; then 123 echo 124 msg_red "SHA256 mismatch for '$curfile:'\n@$filesum\n" 125 errors=$((errors + 1)) 126 else 127 msg_normal_append "OK.\n" 128 fi 129 else 130 msg_normal "$pkgver: verifying checksum for distfile '$curfile'... " 131 filesum=$(${XBPS_DIGEST_CMD} "$distfile") 132 if [ "$cksum" != "$filesum" ]; then 133 echo 134 msg_red "SHA256 mismatch for '$curfile:'\n$filesum\n" 135 errors=$((errors + 1)) 136 else 137 if [ ! -f "$XBPS_SRCDISTDIR/by_sha256/${cksum}_${curfile}" ]; then 138 mkdir -p "$XBPS_SRCDISTDIR/by_sha256" 139 ln -f "$distfile" "$XBPS_SRCDISTDIR/by_sha256/${cksum}_${curfile}" 140 fi 141 msg_normal_append "OK.\n" 142 fi 143 fi 144} 145 146# Link an existing cksum $distfile for $curfile at index $dfcount 147link_cksum() { 148 local curfile="$1" distfile="$2" dfcount="$3" filesum cksum 149 150 cksum=$(get_cksum $curfile $dfcount) 151 152 if [ -n "$cksum" -a -f "$XBPS_SRCDISTDIR/by_sha256/${cksum}_${curfile}" ]; then 153 ln -f "$XBPS_SRCDISTDIR/by_sha256/${cksum}_${curfile}" "$distfile" 154 msg_normal "$pkgver: using known distfile $curfile.\n" 155 fi 156} 157 158try_mirrors() { 159 local curfile="$1" distfile="$2" dfcount="$3" subdir="$4" f="$5" 160 local filesum cksum basefile mirror path scheme 161 [ -z "$XBPS_DISTFILES_MIRROR" ] && return 162 basefile="${f##*/}" 163 cksum=$(get_cksum $curfile $dfcount) 164 for mirror in $XBPS_DISTFILES_MIRROR; do 165 scheme="file" 166 if [[ $mirror == *://* ]]; then 167 scheme="${mirror%%:/*}" 168 path="${mirror#${scheme}://}" 169 else 170 path="$mirror" 171 fi 172 if [ "$scheme" == "file" ]; then 173 # Skip file:// mirror locations (/some/where or file:///some/where) 174 # where the specified directory does not exist 175 if [ ! -d "$path" ]; then 176 msg_warn "$pkgver: mount point $path does not exist...\n" 177 continue 178 fi 179 fi 180 if [[ "$mirror" == *voidlinux* ]]; then 181 # For distfiles.voidlinux.* append the subdirectory 182 mirror="$mirror/$subdir" 183 fi 184 msg_normal "$pkgver: fetching distfile '$curfile' from '$mirror'...\n" 185 $fetch_cmd "$mirror/$curfile" 186 # If basefile was not found, but a curfile file may exist, try to fetch it 187 if [ ! -f "$distfile" -a "$basefile" != "$curfile" ]; then 188 $fetch_cmd "$mirror/$basefile" 189 fi 190 [ ! -f "$distfile" ] && continue 191 flock -n ${distfile}.part rm -f ${distfile}.part 192 filesum=$(${XBPS_DIGEST_CMD} "$distfile") 193 [ "$cksum" == "$filesum" ] && break 194 msg_normal "$pkgver: checksum failed - removing '$curfile'...\n" 195 rm -f ${distfile} 196 done 197} 198 199hook() { 200 local srcdir="$XBPS_SRCDISTDIR/$pkgname-$version" 201 local dfcount=0 dfgood=0 errors=0 max_retries 202 203 if [ ! -d "$srcdir" ]; then 204 mkdir -p -m775 "$srcdir" 205 chgrp $(id -g) "$srcdir" 206 fi 207 208 cd $srcdir || msg_error "$pkgver: cannot change dir to $srcdir!\n" 209 210 # Disable trap on ERR; the code is smart enough to report errors and abort. 211 trap - ERR 212 213 # Detect bsdtar and GNU tar (in that order of preference) 214 TAR_CMD="$(command -v bsdtar)" 215 if [ -z "$TAR_CMD" ]; then 216 TAR_CMD="$(command -v tar)" 217 fi 218 219 # Detect distfiles with obsolete checksum and purge them from the cache 220 for f in ${distfiles}; do 221 curfile="${f#*>}" 222 curfile="${curfile##*/}" 223 distfile="$srcdir/$curfile" 224 225 if [ -f "$distfile" ]; then 226 cksum=$(get_cksum $curfile $dfcount) 227 if [ "${cksum:0:1}" = "@" ]; then 228 cksum=${cksum:1} 229 filesum=$(contents_cksum "$distfile") 230 else 231 filesum=$(${XBPS_DIGEST_CMD} "$distfile") 232 fi 233 if [ "$cksum" = "$filesum" ]; then 234 dfgood=$((dfgood + 1)) 235 else 236 inode=$(stat "$distfile" --printf "%i") 237 msg_warn "$pkgver: wrong checksum found for ${curfile} - purging\n" 238 find ${XBPS_SRCDISTDIR} -inum ${inode} -delete -print 239 fi 240 fi 241 dfcount=$((dfcount + 1)) 242 done 243 244 # We're done, if all distfiles were found and had good checksums 245 [ $dfcount -eq $dfgood ] && return 246 247 # Download missing distfiles and verify their checksums 248 dfcount=0 249 for f in ${distfiles}; do 250 curfile="${f#*>}" 251 curfile="${curfile##*/}" 252 distfile="$srcdir/$curfile" 253 254 # If file lock cannot be acquired wait until it's available. 255 while true; do 256 flock -w 1 ${distfile}.part true 257 [ $? -eq 0 ] && break 258 msg_warn "$pkgver: ${curfile} is already being downloaded, waiting for 1s ...\n" 259 done 260 # If distfile does not exist, try to link to it. 261 if [ ! -f "$distfile" ]; then 262 link_cksum $curfile $distfile $dfcount 263 fi 264 # If distfile does not exist, download it from a mirror location. 265 if [ ! -f "$distfile" ]; then 266 try_mirrors $curfile $distfile $dfcount $pkgname-$version $f 267 fi 268 # If distfile does not exist, download it from the original location. 269 if [[ "$FTP_RETRIES" && "${f}" =~ ^ftp:// ]]; then 270 max_retries="$FTP_RETRIES" 271 else 272 max_retries=1 273 fi 274 for retry in $(seq 1 1 $max_retries); do 275 if [ ! -f "$distfile" ]; then 276 if [ "$retry" == 1 ]; then 277 msg_normal "$pkgver: fetching distfile '$curfile'...\n" 278 else 279 msg_normal "$pkgver: fetch attempt $retry of $max_retries...\n" 280 fi 281 flock "${distfile}.part" $fetch_cmd "$f" 282 fi 283 done 284 if [ ! -f "$distfile" ]; then 285 msg_error "$pkgver: failed to fetch $curfile.\n" 286 fi 287 # distfile downloaded, verify sha256 hash. 288 flock -n ${distfile}.part rm -f ${distfile}.part 289 verify_cksum $curfile $distfile $dfcount 290 dfcount=$((dfcount + 1)) 291 done 292 293 unset TAR_CMD 294 295 if [ $errors -gt 0 ]; then 296 msg_error "$pkgver: couldn't verify distfiles, exiting...\n" 297 fi 298}