void-packages

Void Source Packages
git clone git://ezup.dev/void-packages.git
Log | Files | Refs | README | LICENSE

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}