[csw-users] Installation summary

Jeffery Small jeff at cjsa.com
Wed Feb 23 20:47:16 CET 2005


Daniel Seichter <daniel at dseichter.de> writes:

> But I agree, official in pkg-get would be nice if it going to be more efficient.

Here is a csw(1) script that I wrote to help in this regard.  This is pretty
much a front-end to pkg-get(1) with the following features:

  * It uses a package cache file to save the current state of all packages.  This
    cache file can be quickly displayed without having to rerun the analysis.

  * It borrows some code from pkg-get and modifies it to better format the listing
    for an 80-column window.  Everything will now stay aligned and an asterisk
    is displayed to indicate a field that is too wide for the column.

  * This script uses the sus(1) command to allow me to run updates without having
    to become root or enter a password.  If you do not use sus(1), you can
    convert this to use sudo(1), rip this stuff out altogether, or simply run
    the csw command as root whenever you want to update the catalog or packages.

Regards,
-- 
Jeff

Jeffery Small  <jeff at blastwave.org>
In real life:  <jeff at cjsa.com>


#! /bin/ksh
###############################################################################
#
# SYNOPSIS:	csw [-CU]
#		csw [adln][s]
#		csw -[ir] pkg-name [...]
#		csw -u  [pkg-name [...]]
#		csw -?
#
# DESCRIPTION:	This is a simple abbreviated front end for the pkg-get(1)
#		utility which retrieves and installs Solaris packages from
#		the blastwave site.  It is intended to provide a slightly
#		easier interface with automatic catalog updating when
#		necessary.
#
#		A package cache file is used to store the current state of
#		the blastwave packages so that it may be quickly reviewed
#		without having to wait for the analysis to be rerun.
#
# OPTIONS:	-C	update the CSW package cache file
#		-U	update the CSW catalog and package cache file
#
#		-l	list all CSW packages currently installed    [DEFAULT]
#		-n	list all CSW packages not installed
#		-a	list all CSW packages both installed & not installed
#		-d	list all CSW packaged installed but not current
#		-s	short-list all packages (names only) [use with -{lnad}]
#
#		-i	install the specified package(s)
#		-r	remove  the specified package(s)
#		-u	update  the specified packages(s) [if no pkgs, do all]
#
#		-?	display usage message and exit
#
# NOTES:	* You must be either the super-user (root) or the default user
#		  (jeff) to use options [CUiru].  The default user is able to
#		  run this command through the use of the sus(1) utility.
#
#		* When the catalog or the installed packages are updated, the
#		  package list cache is also automatically updated.
#
# SEE ALSO:	pkg-get(1), sus(1)
#
# REVISIONS:	Original coding: 07-12-04
#		Latest revision: 02-23-05
#
# AUTHOR:	C. Jeffery Small (jeff at cjsa.com)
#
# FILES:	Package list cache:  ${HOME}/lib/bw/packages
#
###############################################################################

###############################################################################
# General initialization
###############################################################################

PROG=$(basename $0)				# name of this program

SUS=""						# no sus(1) command by default

PAGER="less -x4 -+e"				# pager command

TMP="/tmp/csw$$"				# temporary file

MODE="LIST"					# default operating mode
TYPE="INST"					# default listing type
PKGS="${HOME}/lib/bw/packages"			# package list cache

VERBOSE="TRUE"					# default is long listing

PREFIX="/opt/csw"				# pkg-get(1) prefix

PKGGET="${PREFIX}/bin/pkg-get"			# pkg-get(1) script

CFGFILE="${PREFIX}/etc/pkg-get.conf"		# pkg-get(1) config file

DFSITE="ibiblio.org"				# pkg-get(1) dflt download site

DFUSER="jeff"					# default user

###############################################################################
# Set exit traps
###############################################################################

RTN="0"						# default return value

trap "rm -f ${TMP} ; trap 0 ; exit 64"  1 2 3 15
trap "rm -f ${TMP} ; exit \${RTN}"      0

###############################################################################
# Locate the blastwave catalog
###############################################################################

if [[ -f ${PREFIX}/etc/pkg-get.conf ]] ; then
    SITE=$(grep '^url=' ${CFGFILE})		# extract download site
    SITE=${SITE##*//}				# strip prefix
    SITE=${SITE%%/*}				# strip suffix
else
    SITE="${DFSITE}"				# try default site
fi

CATFILE=/var/pkg-get/catalog-${SITE}		# catalog file

if [[ ! -f ${CATFILE} ]] ; then
    echo "ERROR:  No such catalog file:  ${CATFILE}"
    RTN="3"
    exit
fi 

###############################################################################
# usage()	Function to print usage message
###############################################################################

usage() {
    echo "USAGE: ${PROG} -[CU]"
    echo "       ${PROG} -[adln][s]"
    echo "       ${PROG} -[ir] pkg-name [...]"
    echo "       ${PROG} -u  [pkg-name [...]]"
    echo ""
    echo "\t-C       Update the CSW package cache file"
    echo "\t-U       Update the CSW catalog and package cache file"
    echo ""
    echo "\t-l       List all CSW packages currently installed       [DEFAULT]"
    echo "\t-n       List all CSW packages not installed"
    echo "\t-a       List all CSW packages both installed and not installed"
    echo "\t-d       List all CSW packaged installed but not current"
    echo ""
    echo "\t-s       Short-list all packages (names only)    [use with -{lnad}]"
    echo ""
    echo "\t-i       Install the specified package(s)"
    echo "\t-r       Remove  the specified package(s)"
    echo "\t-u       Update  the specified package(s) [if no pkgs: update all]"
    echo ""
    echo "\t-?       Display this usage message and exit"
    echo ""
    echo "NOTE:  Must be super-user (root) or ${DFUSER} to use options: [CUiru]"
}

###############################################################################
# Check if root or ${DFUSER} is running this program
###############################################################################

case $(id) in
uid=0\(root\)*)
    ROOT="YES"
    SUS=""
    ;;
uid=[0-9]*\(${DFUSER}\)*)
    ROOT="YES"
    SUS="sus"
    ;;
*)
    ROOT="NO"
    ;;
esac

###############################################################################
# Process command-line options
###############################################################################

while getopts :CUadi:lnsr:u OPT ; do
    case "${OPT}" in
    C)
	if [[ ${ROOT} = "NO" ]] ; then
	    echo "ERROR: You must be root to use option \"${OPT}\"."
	    RTN="2"
	    exit
	fi

        MODE="CACHE"
	;;
    U)
	if [[ ${ROOT} = "NO" ]] ; then
	    echo "ERROR: You must be root to use option \"${OPT}\"."
	    RTN="2"
	    exit
	fi

	MODE="CATALOG"
        ;;
    a)
	MODE="LIST"
	TYPE="BOTH"
        ;;
    d)
	MODE="DIFF"
        ;;
    i)
	if [[ ${ROOT} = "NO" ]] ; then
	    echo "ERROR: You must be root to use option \"${OPT}\"."
	    RTN="2"
	    exit
	fi

	MODE="INSTALL"
	PACKAGES="${OPTARG}"
        ;;
    l)
	MODE="LIST"
	if [[ "${TYPE}" = "NOT_INSTALLED" ]] ; then
	    TYPE="BOTH"
	elif [[ "${TYPE}" != "BOTH" ]] ; then
	    TYPE="INSTALLED"
	fi
        ;;
    n)
	MODE="LIST"
	if [[ "${TYPE}" = "INSTALLED" ]] ; then
	    TYPE="BOTH"
	elif [[ "${TYPE}" != "BOTH" ]] ; then
	    TYPE="NOT_INSTALLED"
	fi
        ;;
    r)
	if [[ ${ROOT} = "NO" ]] ; then
	    echo "ERROR: You must be root to use option \"${OPT}\"."
	    RTN="2"
	    exit
	fi

	MODE="REMOVE"
	PACKAGES="${OPTARG}"
        ;;
    s)
        VERBOSE="FALSE"
	;;
    u)
	if [[ ${ROOT} = "NO" ]] ; then
	    echo "ERROR: You must be root to use option \"${OPT}\"."
	    RTN="2"
	    exit
	fi

	MODE="UPDATE"
        ;;
    :)
	echo "ERROR: ${OPTARG} requires an argument"
	usage
	RTN="1"
	exit
        ;;
    \?)
	case "${OPTARG}" in
	\?)
	    usage
	    exit
	    ;;
	*)
	    echo "ERROR: Unrecognized option: ${OPTARG}"
	    usage
	    RTN="1"
	    exit
	    ;;
	esac
        ;;
    esac
done

shift $((${OPTIND} - 1))

if [[ $# -gt 0 ]] ; then
    PACKAGES="${PACKAGES} $*"
fi

###############################################################################
# SUBROUTINE:	pg_aver
#
# SYNOPSIS:	pg_aver  pkg_name
#
# DESCRIPTION:	Determine the version number of the specified package and
#		print on stdout.
#
# NOTES:	* This routine expects a real pkg name (ee.g., SUNWapchd)
#		* This code was ripped from the pkg-get(1) script and modified
#
# RETURN VALUE:	1 if the specified package is installed
#		0 if the specified package is not installed
###############################################################################

pg_aver() {
    VTMP=$(pkgparam $1 VERSION 2>/dev/null)

    if [[ "${VTMP}" == "" ]] ; then
	return 1
    fi

    case "${VTMP}" in
    *,REV=*)		# OK: acceptable format
	;;
    *,*)		# Arrg. someone was "creative" with the version field
	VTMP=${VTMP%%,*}
	;;
    esac

    print ${VTMP}
}

###############################################################################
# SUBROUTINE:	pg_cache
#
# SYNOPSIS:	pg_cache
#
# DESCRIPTION:	Update the ${PKGS} package cache file.
###############################################################################

pg_cache() {
    echo "Updating package cache file ... \c"
    cp /dev/null ${TMP}					# initialize tmp file
    egrep -v '^#' ${CATFILE} | while read line ; do
	pg_cmp $line >> ${TMP}
    done
    cat ${TMP} | sort > ${PKGS}
    echo "Done."
}

###############################################################################
# SUBROUTINE:	pg_catalog
#
# SYNOPSIS:	pg_catalog
#
# DESCRIPTION:	Update the pkg-get(1) catalog from the download site and then
#		update the package cache file.
###############################################################################

pg_catalog() {
    ${SUS} ${PKGGET} -U
    pg_cache
}

###############################################################################
# SUBROUTINE:	pg_cmp
#
# SYNOPSIS:	pg_cmp  software_name  available_rev  pkg_name
#
# DESCRIPTION:	Compare each Blastwave package to what is locally installed.
#
# NOTES:	* This code was ripped from the pkg-get(1) script and modified
#		  so that the formatted output is better suited to display in
#		  a typical 80-column window.
#		* If a version field is too wide to fit the display, a "*" is
#		  displayed to indicate missing info.
###############################################################################

pg_cmp() {
    SOFTWARE="$1"
    REM_REV="$2"
    PKGNAME="$3" 
    
    if [[ ! -d /var/sadm/pkg/${PKGNAME} ]] ; then
	LOCALREV='[Not installed]'
    else
	LOCALREV=`pg_aver ${PKGNAME} 2>/dev/null`
    fi 
    
    if [[ "${LOCALREV}" == "${REM_REV}" ]] ; then
	REM_REV="SAME"
    fi

    if [[ ${#LOCALREV} -gt 29 && ${#REM_REV} -gt 29 ]] ; then
	printf "%-18s %29.29s* %29.29s*\n" "$SOFTWARE" "$LOCALREV" "$REM_REV"
    elif [[ ${#LOCALREV} -gt 29 ]] ; then
	printf "%-18s %29.29s* %29.29s\n"  "$SOFTWARE" "$LOCALREV" "$REM_REV"
    elif [[ ${#REM_REV} -gt 29 ]] ; then
	printf "%-18s %29.29s  %29.29s*\n" "$SOFTWARE" "$LOCALREV" "$REM_REV"
    else
	printf "%-18s %29.29s  %29.29s\n"  "$SOFTWARE" "$LOCALREV" "$REM_REV"
    fi
}

###############################################################################
# SUBROUTINE:	pg_diff
#
# SYNOPSIS:	pg_diff
#
# DESCRIPTION:	List all installed packages that are not current.
###############################################################################

pg_diff() {
    if [[ "${VERBOSE}" = "TRUE" ]] ; then
	grep -iv "not installed" ${PKGS} | grep -iv "same$" | ${PAGER}
    else
	grep -iv "not installed" ${PKGS} | grep -iv "same$" | \
    				sed -e "s/[ 	].*$//" | ${PAGER}
    fi
}

###############################################################################
# SUBROUTINE:	pg_install
#
# SYNOPSIS:	pg_install pkg1 [...]
#
# DESCRIPTION:	Install the specified package(s).
###############################################################################

pg_install() {
    ${SUS} ${PKGGET} -f -i ${PACKAGES}
    pg_cache
}

###############################################################################
# SUBROUTINE:	pg_list
#
# SYNOPSIS:	pg_list
#
# DESCRIPTION:	Display the ${PKGS} package cache file using the
#		${PAGER} pager command.
###############################################################################

pg_list() {
    if [[ "${TYPE}" = "INSTALLED" || "${TYPE}" = "INST" ]] ; then
        if [[ "${VERBOSE}" = "TRUE" ]] ; then
	    grep -iv "not installed" ${PKGS} |	${PAGER}
    	else
	    grep -iv "not installed" ${PKGS} | sed -e "s/[ 	].*$//" | \
						${PAGER}
	fi
    elif [[ "${TYPE}" = "NOT_INSTALLED" ]] ; then
        if [[ "${VERBOSE}" = "TRUE" ]] ; then
	    grep -i  "not installed" ${PKGS} |	${PAGER}
    	else
	    grep -i  "not installed" ${PKGS} | sed -e "s/[ 	].*$//" | \
						${PAGER}
	fi
    else
        if [[ "${VERBOSE}" = "TRUE" ]] ; then
	    cat ${PKGS} | ${PAGER}
    	else
	    cat ${PKGS} | sed -e "s/[ 	].*$//" | ${PAGER}
	fi
    fi
}

###############################################################################
# SUBROUTINE:	pg_remove
#
# SYNOPSIS:	pg_remove pkg1 [...]
#
# DESCRIPTION:	Remove the specified package(s) and update the package cache
#		file.
###############################################################################

pg_remove() {
    ${SUS} ${PKGGET} -r ${PACKAGES}
    pg_cache
}

###############################################################################
# SUBROUTINE:	pg_update
#
# SYNOPSIS:	pg_update [pkg1 [...]]
#
# DESCRIPTION:	Update the specified package(s).  If no packages are specified,
#		all installed packages are examined and updated.  The package
#		cache file is then updated.
###############################################################################

pg_update() {
    ${SUS} ${PKGGET} -f -u ${PACKAGES}
    pg_cache
}

###############################################################################
# Execute the appropriate command
###############################################################################

case "${MODE}" in
CACHE)
    pg_cache
    pg_list
    ;;
CATALOG)
    pg_catalog
    pg_list
    ;;
DIFF)
    pg_diff
    ;;
INSTALL)
    pg_install
    ;;
LIST)
    pg_list
    ;;
REMOVE)
    pg_remove
    ;;
UPDATE)
    pg_update
    ;;
esac

exit




More information about the users mailing list