#!/bin/bash # # Tool to work with sourceforge.net's download mirrors: selects the # fastest (ping response time) mirror which has the wanted file # # Johannes Winkelmann, jw at tks6 dot net # # USAGE: # # 1. Configure your MIRROR_STORE location right after this comment header # to your liking # # 2. Create a mirror store # $ sf-mirror-tool create-store # It's recommended to update it from time to time, i.e. on reboot # # 3. Add the following to pkgmk.conf, after the PKGMK_SOURCE_DIR export # (if you have any): # if [ "$PKGMK_DOWNLOAD" = "yes" ]; then # . /path/to/sf-mirror-tool # sf_replace_source verbose # fi # # You can remove the "verbose" argument to suppress diagnostic output # # 4. [optional] # Manually tweak the mirror store to get an compromise between speed and # available files # # Note that it will check for the files from sourceforge in any case if # you run pkgmk with the '-d' option (every time when using prt-get); # tighter integration with pkgmk could address that ### ## user configuration # MIRROR_STORE=/var/lib/pkg/sf-mirror.store PING_TIMEOUT=5 WGET_TIMEOUT=5 # OUTPUT_TARGET is changed to stderr if you're running # sf_replace_source with "verbose" as argument" OUTPUT_TARGET=/dev/null sf_sort_mirrors() { hosts="`dig dl.sf.net | awk '/IN\W*A\W*[1-9]/{print $NF}'`" for h in $hosts; do name=`host $h|grep "domain name"|awk '{print $NF}'|sed -e 's|\.$||g'` msg=`ping -q -t $PING_TIMEOUT -c 1 $name 2>/dev/null` if [ $? -eq 0 ]; then t=`echo $msg|grep round-trip|sed -e 's|.*= ||g' -e 's|/.*||g'` mirrors="$mirrors $t:$name" fi done for m in $mirrors; do echo $m|sed -e 's|:| |g' done|sort -n |awk '{print $2}' } sf_create_store() { : > $MIRROR_STORE for m in `sf_sort_mirrors`; do echo $m >> $MIRROR_STORE done } # url, nostore="" sf_select_mirror() { url=$1 if [ "$2" != "nostore" ] && [ -f $MIRROR_STORE ]; then mirrors="`cat $MIRROR_STORE`" else mirrors="`sf_sort_mirrors`" fi for m in $mirrors; do ping -t $TIMEOUT -q -c 1 $m &> /dev/null if [ $? -eq 0 ]; then wget -q --timeout=$WGET_TIMEOUT --spider http://$m/$url if [ $? -eq 0 ]; then echo $m return; fi echo "Failed mirror: $m" > $OUTPUT_TARGET fi done # fallback: re-run sf_sort_mirrors if [ "$2" != "nostore" ]; then echo "Mirror store contains no valid servers; rerunning lookup" \ > $OUTPUT_TARGET sf_select_mirror $url "nostore" fi } sf_replace_source() { if [ "$1" = "verbose" ]; then OUTPUT_TARGET=/dev/stderr fi i=0 for s in ${source[*]}; do if [ -f $PKGMK_SOURCE_DIR/`basename $s` ]; then # file already downloaded echo "File already downloaded: `basename $s`" continue fi s=${s/download.sf.net/dl.sf.net} s=${s/download.sourceforge.net/dl.sf.net} s=${s/dl.sourceforge.net/dl.sf.net} url=${s/http:\/\/dl.sf.net/} if [ "$url" != "$s" ]; then mirror=`sf_select_mirror $url` if [ -n "$mirror" ]; then echo "$s -> http://$mirror$url" > $OUTPUT_TARGET source[$i]="http://$mirror$url" else echo "Error: no SF mirror found" > $OUTPUT_TARGET fi fi i=$((i+1)) done } sf_usage() { echo "Usage: sf-mirror-tool " } case "$1" in "create-store") sf_create_store ;; "-h"|"--help") sf_usage ;; esac