#!/usr/bin/env bash PORT="`which port`" CURL="`which curl`" OPENSSL="`which openssl`" RM="`which rm` -f" usage() { echo "Usage: $1 port-spec" >&2 echo >&2 echo " port-spec can by in any format understood by port(1)" >&2 } handle_port() { local PORT="$1" local line="" declare -A checksums echo "** $PORT" # read checksums local firstrun=1 while read line; do local regex='\[(.*)\].*' if [[ $line =~ $regex ]]; then TARGETFILE=${BASH_REMATCH[1]} echo "Processing file ${TARGETFILE}" continue fi local regex='(md5|sha1|sha256|rmd160): ([0-9a-fA-F]+)' if [[ $line =~ $regex ]]; then # this is a checksum line echo "Found ${BASH_REMATCH[1]} checksum: ${BASH_REMATCH[2]}" checksums["${BASH_REMATCH[1]}"]=${BASH_REMATCH[2]} continue; fi URL=${line# } if [ -z "$line" ]; then continue; fi tput hpa 0 tput el echo $URL # try to get file local CMD="pee" for checksum in "${!checksums[@]}"; do local indirect="OPENSSL_${checksum}[1]" CMD="${CMD} '${OPENSSL} dgst -${checksum} /dev/stdin'" done # fork check process coproc CHECK { eval "$CMD"; } # duplicate fd for check so the pipe doesn't get closed when check is over eval "exec 3<&${CHECK[0]}" # run the download and pipe output into pee eval "$CURL --connect-timeout 15 -L -f -# '${URL}' >&${CHECK[1]}" local status="$?" # remove curl output tput cuu 1 tput hpa 0 tput el # close the pipe to pee eval "exec ${CHECK[1]}>&-" if [[ $status != 0 ]]; then # if it failed, ignore the checksums tput cuu 1 echo -e "\tfailed" >&2 continue fi # otherwise, test the checksums while read -u 3 line; do local regex='(MD5|SHA1|SHA256|RIPEMD160)\(/dev/stdin\)= ([0-9a-fA-F]+)' if [[ $line =~ $regex ]]; then local openssl_index="${BASH_REMATCH[1]}" local index="" case "${openssl_index}" in MD5) index="md5";; SHA1) index="sha1";; SHA256) index="sha256";; RIPEMD160) index="rmd160";; *) echo "Unknown hash type ${openssl_index}" >&2 return esac local chash="${BASH_REMATCH[2]}" if [ "${chash}" != "${checksums["${index}"]}" ]; then echo -e "\tChecksum mismatch: ${index}" >&2 echo -e "\t Portfile value: ${checksums["${index}"]}" >&2 echo -e "\t Local value: ${chash}" >&2 fi else echo "Error parsing openssl output: ${line}" >&2 fi done done } if [ -z $1 ]; then usage $0 exit 1 fi coproc DISTFILELIST { $PORT distfiles $1; } eval "exec 4<&${DISTFILELIST[0]}" eval "exec ${DISTFILELIST[1]}>&-" wait $DISTFILELIST_PID if [[ $? != 0 ]]; then echo "port(1) failed, check your arguments" >&2 exit 1 fi # open list while read -u 4 line; do if [ -z "$line" ]; then continue; fi regex='---> Distfiles for (.*)' if [[ $line =~ $regex ]]; then PORT=${BASH_REMATCH[1]} handle_port $PORT <&4 fi done