Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #! /bin/bash
- #
- # bash script to check how up to date the pacman mirrors are
- #
- # This script reads the /etc/pacman.d/mirrorlist file to obtain a
- # list of mirrors; then queries only those mirrors from countries
- # of your choosing for their last update. If you want to ignore a
- # given mirror, then give it the old "double comment" in the
- # mirrorlist file, i.e.:
- #
- ##Server = ftp://mirrors.kernel.org/archlinux/$repo/os/$arch
- #Server = http://mirrors.kernel.org/archlinux/$repo/os/$arch
- #
- # in this case the ftp mirror would be ignored, while the http
- # mirror would be queried.
- #
- # It uses wget to read the "lastsync" file from each server then
- # writes this information to a file named /etc/pacman.d/mirrors.
- #
- # One of the these mirrors is then choosen as the preferred mirror
- # using a simple heurstic. The wget's are run in parallel and the
- # order in which they respond is noted. The most recently updated
- # mirror of the first 8 to respond (excluding those mirrors that
- # have not been updated since the last time you ran 'pacman -Sy')
- # will become the choosen mirror.
- #
- # This info will be written to the /etc/pacman.d/mirrors file.
- # My /etc/pacman.conf is set up to Include this file for core,
- # extra, and community.
- #
- # The choice of this mirror as the preferred one may not be the best
- # choice, but it is both responsive and has been recently updated.
- #
- ############## Edit this block to suit your taste ##############
- #
- # each country has to match listing in mirrorlist file (you may have
- # any number of countries, but DON'T separate the list with commas!)
- #
- countries=("Any" "United States" "Canada")
- #
- # suitable defaults
- #
- pd=/etc/pacman.d/
- infile=mirrorlist
- outfile=mirrors
- config=/etc/pacman.conf
- log=/var/log/pacman.log
- #
- ################################################################
- #
- get_sync_data() {
- sync_url=$(sed -e "s/\\\$repo.*/lastsync/" <<< $1)
- sync_time=$(wget -q -O - --tries=1 --timeout=10 $sync_url)
- if [[ "$?" == "0" ]]
- then
- [[ $sync_time =~ .*[^0-9] ]] && sync_time=$(date --date="$sync_time" +%s)
- let "delta = $2 - sync_time"
- let "d = delta / 86400"
- let "h = delta % 86400 / 3600"
- let "m = delta % 86400 % 3600 / 60"
- printf "#%3dd %2dh %2dm %s %d\n" $d $h $m $1 $delta
- fi
- }
- #
- # Acquire last sync data from mirrors
- #
- current_time=$(date +%s)
- echo -n "Querying mirrors ..."
- sync_data=$(
- for country in "${countries[@]}"
- do
- for url in $(sed -n -r "/# $country/,/^$/ s/^#?Server = // p" < $pd$infile)
- do (get_sync_data $url $current_time) & done
- done
- )
- echo
- script_name=$(sed "s!.*/\\(.*\\)!\\1!" <<< "$0")
- if [[ -z $sync_data ]]
- then
- echo "The network appears to be down as no mirrors could be contacted"
- echo "Retaining original $pd$outfile file."
- echo
- echo "$script_name aborted."
- echo
- exit
- fi
- #
- # Start building new 'mirrors' file ($pd$outfile)
- #
- [[ -e $pd$outfile ]] && mv $pd$outfile $pd$outfile~
- printf "# File auto-generated by '$script_name', do not edit.\n# $(date +%c)\n#\n" > $pd$outfile
- sed -r "s@((f|ht)tp://[^/]+).*\$@\\1/@" <<< "$sync_data" >> $pd$outfile
- echo "#" >> $pd$outfile
- #
- # Read pacman log file to determine date/time of last 'pacman -Sy'
- #
- b=[[:blank:]]
- logfile=$(sed -n "s/^LogFile$b*=$b*\\(.*\\)/\\1/p" $config)
- [[ -z $logfile ]] && logfile=$log
- diff_t=999999999
- dstr=$(grep "pacman *-S[^ ]*y" $logfile | tail -1 | sed -n "s/^\[\\(.*\\)\].*\$/\\1/ p")
- if [[ ! -z $dstr ]]
- then
- last_sync_time=$(date --date="$dstr" +%s)
- [[ "$?" -eq "0" ]] && let "diff_t = current_time - last_sync_time"
- fi
- #
- # Append preferred mirror to 'mirrors' file. Disgard any mirror that
- # has not been updated since last 'pacman -Sy'
- #
- awk "BEGIN{cnt=0}\$NF<$diff_t{if(cnt<8){cnt++; print;}}" <<< "$sync_data" |
- sort -s --key=2n --key=3n --key=4n |
- awk 'NR == 1 {print "Server =", $5}' >> $pd$outfile
- #
- # Check if any mirror has been updated recently enough
- #
- mirror_count=$(tail -1 $pd$outfile | sed -n '/^Server = / p' | wc --lines)
- if [[ "$mirror_count" -eq "0" ]]
- then
- [[ -e $pd$outfile~ ]] && mv $pd$outfile~ $pd$outfile
- cat $pd$outfile
- echo
- echo "No server has been updated since you last ran 'pacman -Sy'"
- echo "Retaining original $pd$outfile file."
- echo
- echo "$script_name aborted."
- echo
- exit
- fi
- #
- # Use preferred mirror and update
- #
- [[ -e $pd$outfile~ ]] && rm $pd$outfile~
- echo
- cat $pd$outfile
- echo
- echo "using log file: $logfile"
- tail $logfile
- echo
- echo "pacman -Syy"
- pacman -Syy
- echo
- #
- # declare two associative arrays
- #
- declare -A local_version
- declare -A sync_version
- #
- # obtain list of packages needing upgrade along with current version number
- #
- pkg_count=0
- while read name version
- do
- [[ -z $version ]] && break
- local_version[$name]=$version
- let "pkg_count += 1"
- done <<< "$(pacman -Qu)"
- echo -n "$pkg_count updated packages available."
- if [[ $pkg_count -gt "0" ]]
- then
- #
- # obtain new version numbers
- #
- echo " Run 'pacman -Su'."
- db_dir=$(pacman -v | sed -n 's/.*DB Path *: *\([^ ]*\).*/\1/p')
- for name in "${!local_version[@]}"
- do
- # x=(../foo*) expands x into an array containing the names
- # of each file currently matching '../foo*'
- sync_files=(${db_dir}sync/*/$name*/desc)
- for file in "${sync_files[@]}"
- do
- sname=''
- version=''
- lastline=''
- while read line
- do
- [[ "$lastline" =~ %NAME% ]] && sname=$line
- [[ "$lastline" =~ %VERSION% ]] && version=$line
- if [[ ! -z $sname && ! -z $version ]]
- then
- sync_version[$sname]=$version
- version=''
- sname=''
- fi
- lastline=$line
- done < $file
- done
- done
- # output update information
- black='\e[0m'
- red='\e[0;31m'
- blue='\e[0;34m'
- green='\e[0;32m'
- for name in "${!local_version[@]}"
- do
- echo
- echo -ne " $name: $blue${local_version[$name]}"
- echo -ne " $black=> $red${sync_version[$name]}$black"
- done
- fi
- echo
- echo
- exit 0
Advertisement
Add Comment
Please, Sign In to add comment