#!/bin/sh - # # ports-check-update # # Copyright (C) 2006-2010 Oliver Fromme # # Update the ports collection via csup (or cvsup), # but do it only if there are currently no work directories. # This is intended to be called via cron in the night. # # The VERBOSE variable (see below) has the following settings: # 0: No output is created at all upon success, so the cron job # will not send any e-mail upon success, but only on errors. # 1: Report start time, end time and duration. Output from # csup is suppressed (except warnings and error messages). # 2: Normal output is generated, and the output from csup is # compressed in a more usable, shorter form that gives an # overview of which ports have actually been updated, but # doesn't list every file within the ports. # 3: Full output is generated, and csup output is not # filtered, so you get a list of every single file that # has been touched. # If any errors occur, they will always be reported, regardless # of the VERBOSE variable. # # The VERBOSE level is forced from 0 to 1 if the total duration # of the update exceeds MAXTIME seconds. # # The VERBOSE Level can be set with the -v option. # The MAXTIME duration can be set with the -m option. # set -Cefu # Be extra paranoid. ME="${0##*/}" LOCKFILE="/var/run/ports-check-update.lock" DEF_VERBOSE=0 # Use the -v option to override. DEF_MAXTIME=600 # Use the -m option to override. Error() { echo "${ME}: $*" >&2 exit 1 } Syntax_Error() { cat <<-tac >&2 ${ME}: Syntax error! Your arguments were: ${ARGS:-} Usage: $ME [-v ] [-m ] [] Options (see top of script for details): -v Set verbosity level to , default is ${DEF_VERBOSE}. -m Set maximum time (report limit) in seconds, default is ${DEF_MAXTIME}. tac exit 1 } Get_make_var() { make -V "$1" -f /dev/null } if [ `id -nu` != root ]; then Error "Must be root!" fi VERBOSE=$DEF_VERBOSE MAXTIME=$DEF_MAXTIME ARGS="${*:-}" if [ $# -gt 9 ]; then Syntax_Error fi while [ $# -gt 0 ]; do case "$#:${1:-}:${2:-}" in [2-9]:-v:[0-9]) VERBOSE="$2" ; shift 2 ;; [1-9]:-v[0-9]:*) VERBOSE="${1#-v}" ; shift ;; [2-9]:-m:[0-9]*) MAXTIME="$2" ; shift 2 ;; [1-9]:-m[0-9]*:*) MAXTIME="${1#-v}" ; shift ;; [1-9]:--:*) shift ; break ;; [1-9]:-*:*) Syntax_Error ;; *) break ;; esac done if [ $# -gt 1 ]; then Syntax_Error elif [ $# -eq 1 ]; then SUPFILE="$1" elif [ -f /usr/local/etc/cvsup/ports-supfile ]; then SUPFILE="/usr/local/etc/cvsup/ports-supfile" else SUPFILE="/usr/local/etc/sup/ports-supfile" fi if [ ! -f "$SUPFILE" ]; then Error "File not found: $SUPFILE" fi # CVSUP=/usr/local/bin/cvsup CVSUP=/usr/bin/csup if [ ! -x "$CVSUP" ]; then Error "Executable not found: $CVSUP" fi if [ ! -f "$SUPFILE" ]; then Error "Supfile not found: $SUPFILE" >&2 fi TIME_A=$(date +"%s/%Y-%m-%d %H:%M:%S") TIMESTAMP_A="${TIME_A#*/}" TIME_A="${TIME_A%/*}" if [ $VERBOSE -gt 0 ]; then echo "$ME starting update at $TIMESTAMP_A" fi PORTSDIR=$(Get_make_var PORTSDIR) WRKDIRPREFIX=$(Get_make_var WRKDIRPREFIX) ports_base="${WRKDIRPREFIX%/}${PORTSDIR:=/usr/ports}" # If $WRKDIRPREFIX is non-empty, $ports_base doesn't have to exist. if ! cd "$ports_base" 2>&1 ; then if [ -z "${WRKDIRPREFIX%/}" ]; then Error "No such directory: $ports_base" fi if [ $VERBOSE -gt 0 ]; then echo "" echo "Warning: The directory $ports_base does not exist." echo "Assuming that there are no work directories." fi else WORK=$(set +f; echo */*/work) if [ -n "$WORK" -a "x$WORK" != "x*/*/work" ]; then echo "${ME}: Not updating the ports collection." echo "" echo "The following \"work\" directories exist:" echo "" echo "$WORK" | tr " " '\n' | sed 's/^/ /' echo "" echo "Update inhibited." exit 1 fi fi if [ $VERBOSE -gt 0 ]; then echo "" echo "No \"work\" directories present. Updating ports collection ..." echo "" fi if [ $VERBOSE -gt 1 ]; then $CVSUP -L 1 $SUPFILE 2>&1 \ | if [ $VERBOSE -gt 2 ]; then cat else awk '{ if ($1 ~ /^(Edit|Checkout|Delete)$/ && $2 ~ /^ports\/[a-z]/) { nam = $2 num = split(nam, n, "/") cat = n[2] port = n[3] if (port == "Makefile") next if (cat != lastcat) { printf " %s:\n", cat lastcat = cat } if (port != lastport) { printf "%16sUpdating port %s\n", "", port lastport = port } } else print }' fi else $CVSUP -l "$LOCKFILE" -L 0 $SUPFILE fi TIME_B=$(date +"%s/%Y-%m-%d %H:%M:%S") TIMESTAMP_B="${TIME_B#*/}" TIME_B="${TIME_B%/*}" cd "$PORTSDIR" || { echo "No such directory: $PORTSDIR" >&2 Error 'Cannot run "make fetchindex"!' } rm -f INDEX*.bz2 if [ $VERBOSE -gt 0 ]; then echo "" echo "$ME fetching index at $TIMESTAMP_B" make fetchindex || { echo "" echo '"make fetchindex" failed. Retrying ...' echo "" rm -f INDEX*.bz2 make fetchindex echo "" echo 'OK, "make fetchindex" succeeded.' } echo "" else FETCHINDEX="fetch -amq -o" make fetchindex || { echo "" echo '"make fetchindex" failed. Retrying ...' echo "" rm -f INDEX*.bz2 FETCHINDEX="fetch -amq -o" make fetchindex echo 'OK, "make fetchindex" succeeded.' echo "" } fi TIME_C=$(date +"%s/%Y-%m-%d %H:%M:%S") TIMESTAMP_C="${TIME_C#*/}" TIME_C="${TIME_C%/*}" TIME_DIFF=$(( $TIME_C - $TIME_A )) Sec2mmss() { local mm ss mm=$(( $1 / 60 )) ss=$(( $1 % 60 )) case "$ss" in [0-9]) echo "${mm}:0$ss";; *) echo "${mm}:$ss";; esac } if [ $VERBOSE -lt 1 -a $TIME_DIFF -gt $MAXTIME ]; then VERBOSE=1 echo "Note: Duration exceeded $MAXTIME seconds, forcing VERBOSE=1." echo "" echo "$ME starting update at $TIMESTAMP_A" echo "$ME fetching index at $TIMESTAMP_B" fi if [ $VERBOSE -gt 0 ]; then echo "$ME finished update at $TIMESTAMP_C" echo "Total duration: $TIME_DIFF seconds (`Sec2mmss $TIME_DIFF`)" fi #--