#!/bin/ksh # $Id: checkpatches.sh 229 2009-06-07 11:27:10Z elkner $ # (C) 2008 by Jens Elkner jel+lu@cs.uni-magdeburg.de # Licence: CDDL - see http://opensource.org/licenses/cddl1.php usage() { printf 'Usage: %s [-d] [-h] [-R root_path] [-a] [-f file] patch_number ... Check, whether the given patch with at least the given revision is installed on the system and print out the latest one to stdout. Inofficial Patches (IR, T, etc.) are not covered by this simple script. patch_number .. Patch number to lookup - non-numeric characters except the dash (-) are ignored, the part before the dash is called patch, the part after the dash the revision of the patch. (e.g. 119703-07 or 119703 or 119703-07, or 119703-07a ). -R root_path .. Define the full path name of a directory to use as the root_path (same as in showrev(1M)). Default: / -a .. Show all installed revisions of the given patch. -h .. Print this help text and exit. -f file .. Use the given file produced by showrev -p instead of using showrev internally. -l .. just create a patch revision list from installed packages -p .. use pkginfo files instead of "showrev -p" -d .. enable debug ' $0 } cleanup() { [ -z "$NORM" ] && rm $TF } createPkgObsoleteList() { find $RPATH/var/sadm/pkg -type f -name pkginfo | grep -v /save/ | \ while read PF ; do PI=`fgrep PATCH_INFO_ $PF | sed -e 's/PATCH_INFO_/Patch: /' \ -e 's/=Installed:.*Obsoletes:/ Obsoletes:/' \ -e 's/\([0-9]\) \([0-9]\)/\1, \2/g'` [ -n "$PI" ] && echo "$PI" >>$TF done } getObsoletingPatch() { PB="$1" PR="$2" OB="" XOB="" REM="" cut -f2,3 -d: $TF | /usr/xpg4/bin/fgrep "${PB}-" | while read P T O ; do if [ -n "$XOB" ]; then # exact match found - chomp the rest continue fi # if has no Obsoletes: patches or the line is for the patch itself cont. [ "$O" = "Requires" -o "$P" != "${P#${PB}}" ] && continue if [ -n "$PR" ]; then # on exact match stop # grr - no ksh93 // X=`echo $O | sed -e "s,${PB}-${PR},,"` if [ "$X" != "$O" ]; then XOB="$P" else OR=${O##*${PB}-} OR=${OR%% *} OR=${OR%%,} if [ $OR -gt $PR ]; then OB="${OB} $P" fi fi else OB="${OB} $P" fi done if [ -n "$XOB" ]; then echo $XOB else echo ${OB## } fi } ALL="" RPATH="" TF="" NORM="" PKGPL="" LISTONLY="" while getopts "dhalpR:f:" option ; do case "$option" in "h") usage; exit 1;; "a") ALL="true";; "R") RPATH="$OPTARG";; "f") TF="$OPTARG"; NORM="true";; "l") LISTONLY="true";; "p") PKGPL="true";; "d") typeset -ft $(typeset +f);; esac done shift $((OPTIND-1)) if [ -z "$1" -a -z "$LISTONLY" ]; then usage exit 1 fi export PATH="/usr/bin:/usr/sbin" if [ -n "$TF" ]; then if [ ! -r "$TF" ]; then echo "Unable to read patch file $TF" exit 1 fi RPATH="" elif [ -x /usr/bin/mktemp ]; then TF=`mktemp -t patches.XXXXXX` else TF="/tmp/patches.$$" cp /dev/null $TF fi ARGS="-p" if [ -n "$RPATH" ]; then if [ ! -d "$RPATH" ]; then echo "Invalid root_path $RPATH" cleanup exit 2 else ARGS="-p -R \"$RPATH\"" fi fi if [ "$PKGPL" = "true" ]; then createPkgObsoleteList sort -u -o $TF $TF else showrev ${ARGS} | sort -k2 1>$TF fi if [ "$LISTONLY" = "true" ]; then ls -al $TF exit 0 fi PATCHES="" while [ -n "$1" ]; do PATCHNO=`echo $1 | tr -dc -- -0123456789` PATCH=${PATCHNO%%-*} REV=${PATCHNO#$PATCH} REV=${REV#-} REV=${REV%%-*} if [ -z "$PATCH" ]; then print -u2 "Invalid patch number \"$PATCHNO\" ignored" else PATCHES="${PATCHES} ${PATCH}-${REV}" fi shift done for p in $PATCHES ; do PATCH=${p%-*} REV=${p#*-} if [ -z "$REV" ]; then PN="$PATCH " else PN="${PATCH}-$REV" fi if [ -z "$ALL" ]; then INFO=`/usr/xpg4/bin/egrep "^Patch: ${PATCH}-" $TF | tail -1 | cut -f2 -d:` if [ -z "$INFO" ]; then # not installed - might be obsoleted by another one X=`getObsoletingPatch $PATCH "$REV"` if [ -n "$X" ]; then echo "${PN}: ok - obsoleted by: $X" else echo "${PN}: MISSING" fi else # installed: check revisions if [ -n "$REV" ]; then FPR=${INFO#*-} FPR=${FPR% *} if [ $REV -gt $FPR ]; then X=`getObsoletingPatch $PATCH $REV` if [ -z "$X" ]; then echo "${PN}: MISSING - latest revison found: $FPR" else echo "${PN}: probably obsoleted by: $X" fi else echo "${PN}: ok - found: ${INFO%Obsoletes}" fi else echo "${PN}: ok - found: ${INFO%Obsoletes}" fi fi else echo "### PATCH $PATCH ###" /usr/xpg4/bin/egrep "^Patch: ${PATCH}-" $TF | awk '{ print $2 }' fi done cleanup