# PaCkAgE DaTaStReAm CSWpkgget 1 147 # end of header 0707010000cdb1000081a400000000000000000000000148abff2f000001ab000000b500010002ffffffffffffffff0000001200000000CSWpkgget/pkginfoARCH=all BASEDIR=/opt/csw PATH=/sbin:/usr/sbin:/usr/bin:/usr/sadm/install/bin PKG=CSWpkgget NAME=pkg_get - CSW version of automated package download tool VERSION=3.8.4 CATEGORY=system DESC=A convinient way to automate package installs VENDOR=http://www.blastwave.org/pkg-get.html packaged for CSW by Philip Brown EMAIL=phil@opencsw.org HOTLINE=http://www.opencsw.org/bugtrack/ PSTAMP=hamachi.usc.edu20080108060518 CLASSES=none 0707010000cdb0000081a400000000000000000000000148abff2f00000227000000b500010002ffffffffffffffff0000001100000000CSWpkgget/pkgmap: 1 147 1 d none /var ? ? ? 1 d none /var/pkg-get 0755 root bin 1 f none /var/pkg-get/admin-fullauto 0755 root bin 468 42766 1016264596 1 d none bin ? ? ? 1 f none bin/pkg-get 0755 root bin 53589 29118 1199801034 1 i copyright 300 26493 1197135281 1 d none etc ? ? ? 1 f none etc/pkg-get.conf.csw 0755 root bin 1566 6370 1197135400 1 i pkginfo 427 36919 1219231535 1 i postinstall 684 55006 1197135714 1 d none share ? ? ? 1 d none share/man ? ? ? 1 d none share/man/man1m ? ? ? 1 f none share/man/man1m/pkg-get.1m 0755 root bin 6678 11962 1197135555 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000b00000000TRAILER!!!0707010000cdb1000081a400000000000000000000000148abff2f000001ab000000b500010002ffffffffffffffff0000000800000000pkginfoARCH=all BASEDIR=/opt/csw PATH=/sbin:/usr/sbin:/usr/bin:/usr/sadm/install/bin PKG=CSWpkgget NAME=pkg_get - CSW version of automated package download tool VERSION=3.8.4 CATEGORY=system DESC=A convinient way to automate package installs VENDOR=http://www.blastwave.org/pkg-get.html packaged for CSW by Philip Brown EMAIL=phil@opencsw.org HOTLINE=http://www.opencsw.org/bugtrack/ PSTAMP=hamachi.usc.edu20080108060518 CLASSES=none 0707010000cdb0000081a400000000000000000000000148abff2f00000227000000b500010002ffffffffffffffff0000000700000000pkgmap: 1 147 1 d none /var ? ? ? 1 d none /var/pkg-get 0755 root bin 1 f none /var/pkg-get/admin-fullauto 0755 root bin 468 42766 1016264596 1 d none bin ? ? ? 1 f none bin/pkg-get 0755 root bin 53589 29118 1199801034 1 i copyright 300 26493 1197135281 1 d none etc ? ? ? 1 f none etc/pkg-get.conf.csw 0755 root bin 1566 6370 1197135400 1 i pkginfo 427 36919 1219231535 1 i postinstall 684 55006 1197135714 1 d none share ? ? ? 1 d none share/man ? ? ? 1 d none share/man/man1m ? ? ? 1 f none share/man/man1m/pkg-get.1m 0755 root bin 6678 11962 1197135555 0707010000cdbd000041ed00000000000000000000000248abff2f00000000000000b500010002ffffffffffffffff0000000800000000install0707010000cdbe000081a4000000000000000000000001475ad5b10000012c000000b500010002ffffffffffffffff0000001200000000install/copyrightYou may use and copy this software without charge, as you see fit. The software is copyright (C) Philip Brown, Nov 2000-2007 Dont forget to update /opt/csw/etc/pkg-get.conf with your nearest archive site. (or /etc/opt/csw/pkg-get.conf) The default site ibiblio.org may or may not be slow for you! 0707010000cdc2000081a4000000000000000000000001475ad762000002ac000000b500010002ffffffffffffffff0000001400000000install/postinstall#!/bin/sh CONFFILE=$BASEDIR/etc/pkg-get.conf echo "" if [ -f $CONFFILE ] ; then echo $CONFFILE already exists. Not altering it. else echo Installing $CONFFILE.csw to pkg-get.conf cp $CONFFILE.csw $CONFFILE echo "" echo '**** IMPORTANT ****' echo 'A default configuration file for pkg-get has been created in' echo " $CONFFILE" echo "You should edit it to change the 'site' configuration, to point to" echo "the most appropriate mirror for you, from the list at" echo " http://www.blastwave.org/mirrors" echo "" fi if [ "$BASEDIR" = "/opt/csw" ] ; then #if the directory did not exist previously, it gets set to #root:other. fix that! chown root:bin $BASEDIR fi 0707010000cdb9000041ed00000000000000000000000548abff2f00000000000000b500010002ffffffffffffffff0000000600000000reloc0707010000cdbf000041ed00000000000000000000000248abff2f00000000000000b500010002ffffffffffffffff0000000a00000000reloc/etc0707010000cdc1000081ed000000000000000000000001475ad6280000061e000000b500010002ffffffffffffffff0000001b00000000reloc/etc/pkg-get.conf.csw# Configuration file for "pkg-get" # man pkg-get for details on the program # This config file has been pre-customized for use with CSW packages. # The latest set of CSW mirrors is always available at # http://www.blastwave.org/mirrors.html # default site, in USA: url=http://ibiblio.org/pub/packages/solaris/csw/unstable # secondary US mirror #url=http://mirrors.usc.edu/pub/blastwave/unstable # See above url for other sites to use. # If you are behind a firewall, set one of these as appropriate #ftp_proxy=http://your-proxy:8023 #http_proxy=http://your-proxy:8023 #export http_proxy ftp_proxy # You may also set PROXYFLAGS in your environment to set flags # for wget like # export PROXYFLAGS="--proxy-user=xxxx --proxy-passwd=yyy" # Or set them here. but make sure the perms are readable. # And consider that anyone on the machine can check your environment # and grab the user/password combo. # Solaris 10: If you wish to limit pkg-get to installing packages # ONLY to the global zone, then uncomment this line #PKGADDFLAGS=-G # # pkg-get now defaults to downloading to /var/pkg-get/downloads # If you'd like it somewhere else, change it here # PKGGET_DOWNLOAD_DIR=/some/large/dir/pkg-get # # By default, pkg-get keeps downloaded files, in PKGGET_DOWNLOAD_DIR, # but removes them once they have been successfully pkgadd'd to the system. # IF you set the following var to something, it will keep the # downloaded file around, even after add. #PKGGET_CACHE_FILES=true # To disable use of gpg or md5, uncomment these #use_gpg=false #use_md5=false 0707010000cdba000041ed00000000000000000000000248abff2f00000000000000b500010002ffffffffffffffff0000000a00000000reloc/bin0707010000cdbb000081ed000000000000000000000001478382ca0000d155000000b500010002ffffffffffffffff0000001200000000reloc/bin/pkg-get#!/bin/ksh -p # The -p says "ignore .profile for ksh" # This is loosely modeled after debian "apt-get". # Philip Brown, phil@bolthole.com, http://www.bolthole.com/solaris/ # Internal SCCS rev @(#) pkg-get 3.11@(#) # See the config file, $CONFFILE, for things you can tweak. # (commonly /etc/pkg-get.conf, or ${prefix}/etc/pkg-get.conf ) #currently undocumented vars of interest: #PKGGET_DOWNLOAD_DIR #PKGGET_CACHE_FILES (set to anything, means true, # means "dont remove after download") umask 022 ###################################################################### ###################################################################### # Dont change anything below here ###################################################################### ###################################################################### progname=$0 # There is a BUG, in "New ksh", that makes its built-in uname, differ # from standard one. (specifically for "uname -p") # So make sure to use external binary. UNAME=/bin/uname AWK=nawk # The difference cases: # pkg-get # /path/to/pkg-get # local/path/to/pkg-get # ./pkg-get case $progname in /*) progdir=${progname%/*} ;; */*) progdir=${progname%/*} progdir=`cd $progdir && /bin/pwd` ;; *) # no slashes? probably just "pkg-get" progdir=`/bin/pwd` ;; esac # This block attempts to be "intelligent", and keep pkg-get to be # distribution-neutral, while still being able to look in distribution-specific # locations. # IFF it is installed in /opt/csw/bin/pkg-get, for example, it will look first # in /opt/csw/etc/pkg-get.conf, then /etc/opt/csw/pkg-get.conf for an # override. Only if it cannot find either of them, will it look in # /etc/pkg-get.conf # case $progdir in */bin) prefix=${progdir%/bin} conffile=$prefix/etc/pkg-get.conf if [[ -f $conffile ]] ; then CONFFILE=$conffile fi shortprefix=${prefix##*/} if [[ -f /etc/opt/$shortprefix/pkg-get.conf ]] ; then CONFFILE=/etc/opt/$shortprefix/pkg-get.conf fi unset conffile if [[ "$CONFFILE" = "" ]] && [[ -d /etc/opt/$shortprefix ]] && [[ ! -f /etc/pkg-get.conf ]] then # do this, so that the default conf file will # get created in THIS location, rather than # /etc/pkg-get.conf CONFFILE=/etc/opt/$shortprefix/pkg-get.conf fi ;; esac # last-ditch fallback: look in /etc, if we cant tell a "normal" prefix CONFFILE=${CONFFILE:-/etc/pkg-get.conf} PAGER=${PAGER:-more} CHEATDIR=/var/sadm/pkg PKGASKDIR=/var/pkg-get/pkgask if [[ "$TMPDIR" != "" ]] ; then if [[ "$TMPDIR" != "/tmp" ]] ; then print "WARNING: TMPDIR is not /tmp" print "This may result in pkgadd failing, due to a pkgadd bug" fi fi function get_wget { # We need wget ( or a reasonable lookalike ) to function. # If this function is called.. we cant find one. so grab # a temporary one that will work well enough for pkg-get use. # Except that this is too yeukky right now. # SO punt back to the user. print ERROR: no working version of wget found, in PATH print "( $PATH )" print "" print Please install a working copy of wget, print or set WGET to name another program, in $CONFFILE if [[ "$SITE" != "" ]] ; then print You should be able to find a working binary for wget at print $SITE/wget.$ARCH print "download it, rename to 'wget', chmod 0755 wget," print "and put it somewhere in your PATH" fi exit 1 } # Grab the file named by the first arg # It will be downloaded to the same filename in the current directory. # Note that there is some special handling of "file://" urls. # function grabfunc { graburl="$1" if [[ "$WGET" = "wget" ]] ; then WGETFLAGS="--dot-style=mega" fi case $graburl in file://*) fname=${graburl#file://} # if multiple match to wildcard only use first one fname=${fname%% *} fname=$(print $fname) if [[ ! -f $fname ]] ; then print ERROR: file $fname does not exist >/dev/fd/2 return 1 fi cp $fname `basename $fname` return 0 ;; ftp://*) if [[ "$WGET" = "wget" ]] ; then WGETFLAGS="$WGETFLAGS --passive-ftp" fi ;; esac #-nv means NO progress meter at all. You dont get the dots. # wget -nv --dot-style=mega --passive-ftp $WGET $PROXYFLAGS $WGETFLAGS $graburl } function usage { print 'pkg-get, by Philip Brown , phil@bolthole.com' print ' (Internal SCCS code revision 3.11)' print Originally from http://www.bolthole.com/solaris/pkg-get.html print "" print "pkg-get is used to install free software packages" print "pkg-get" print "Need one of 'install', 'upgrade', 'available','compare'" print " '-i|install' installs a package" print " '-u|upgrade' upgrades already installed packages if possible" print " '-a|available' lists the available packages in the catalog" print " '-c|compare' shows installed package versions vs available" print " '-l|list' shows installed packages by software name only" print "" print "Optional modifiers:" print " '-d|download' just download the package, not install" print " '-D|describe' describe available packages, or search for one" print " '-U|updatecatalog' updates download site inventory" print " '-S|sync' Makes update mode sync to version on mirror site" print " '-f' dont ask any questions: force default pkgadd behaviour" print " Normally used with an override admin file" print " See /var/pkg-get/admin-fullauto" print "" print " '-s ftp://site/dir' temporarily override site to get from" } ###################################################################### # Funky version comparision code here. probably needs improving # ###################################################################### # return true (0) if first char in string is a digit function startsnumeric { case $1 in [0-9]*) return 0; ;; *) return 1; esac } # trimrev: pass it a revision string, and it will break it up # into integer components, and print out the initial number and remainder. # Samples: # 1.2 ==> 1 2 # beta ==> beta # beta3 ==> beta 3 # WARNING: WILL ALWAYS print out ' ' as minimum!!! function trimrev { if [[ "$1" == "" ]] ; then print " " return fi # if string starts with a number, the return leading number. # Otherwise, return initial letter tag, like "beta", or whatever. # THis is for potential comparison between "alpha" and "beta" case $1 in [0-9]*) echo $1 | sed 's/^\([0-9][0-9]*\)[-_.+]*\(.*\)/\1 \2/' return esac # No leading digits, so split off leading ascii echo $1 | sed 's/^\([^0-9]*[^0-9]*\)[-_.+]*\(.*\)/\1 \2/' } # Pass in two strings. # Return (print) longest string that is common to both of them function trimshared { if (( $# < 2 )) ; then print ERROR: trimshared needs TWO args cleanup exit 1 fi savedstring=""; while (( 1 == 1 )) ; do one_end=${1##?} two_end=${2##?} trimsnip=${1%%$one_end} if [[ "$trimsnip" == "" ]] ; then print $savedstring return fi case $2 in ${trimsnip}*) set -- "$one_end" "$two_end" savedstring=${savedstring}${trimsnip} ;; *) # default print $savedstring return esac done } # newer_rev rev1 rev2 # Returns true (0) if rev1 is newer than rev2 # Otherwise, return false (1) # Up to caller to only pass in revision id. # from a filename "GNU-tar-v2.13.tar.gz" only pass in "v2.13" function newer_rev { # set -x if (( $# < 2 )) ; then print Need TWO args to newer_rev exit 1 fi # First, snip off any common string at the front shared_start=`trimshared $1 $2` if [[ "$shared_start" != "" ]] ; then val1=${1##$shared_start} val2=${2##$shared_start} else val1="$1" val2="$2" fi # Pathalogical case: exact same values if [[ "$val1" = "$val2" ]] ; then return 1 fi # If first value has number, and second has not, then # that probably means something like 0.12, vs 0.1.2 # (if so, now comparing '2' vs '.2' # Thus if first is numeric then first one has higher rev! if startsnumeric $val1 ; then # either val2 is ALSO numeric, or then return 0 startsnumeric $val2 || return 0 else if startsnumeric $val2 ; then # val1 is NOT numeric, val2 IS, therefore # val2 has higher rev. return 1 fi fi # BOTH are numeric? # IF so, then we must have differing initial numbers. Since # if they were the same, trimshared should have stripped them. # Should thus be able # to do a straight numeric comparison, and know our answer. # Isolate leading numeric components, then compare numbers if startsnumeric $val1 && startsnumeric $val2 ; then num1="" ; num2="" tmprev1=`trimrev $val1` set -- $tmprev1 num1=$1 tmprev2=`trimrev $val2` set -- $tmprev2 num2=$1 if (( $num1 > $num2 )) ; then return 0 fi if (( $num1 < $num2 )) ; then return 1 fi # Else, must be same number, which means "not newer" return 1 fi # print "STRONG COMPRE: '$val1' '$val2'" # We are now facing two mixedtype strings (one of which may be empty) # State table: ("string" may be "") # val1 val2 equality # ----- ------ -------------- # "*#*" "*#*" unknown, recurse # "*#*" "string" > # "string" "*#*" < # "string" "string" unknown, stop # case $val1 in *[0-9]*) case $val2 in *[0-9]*) return newer_rev "$val1" "$val2" ;; *) return 0; ;; esac ;; *) case $val2 in *[0-9]*) return 1 ;; esac ;; esac if [[ "$val1" = "" ]] ; then case $val2 in [Bb]eta*) return 0; ;; esac fi if [[ "$val2" = "" ]] ; then case $val1 in [Bb]eta*) return 1; ;; esac fi print 'newer_rev: fell off end of compare routine!' >/dev/fd/2 print "Dont know how to compare ascii strings '$val1' '$val2'" >/dev/fd/2 return 1; } ###################################################################### # End of software name version comparision code # ###################################################################### ###################################################################### # This expects a REAL "pkg" name, eg PKGINST name, eg "SUNWapchd" # It then looks up the VERSION field, and prints it to stdout # return 1 if not installed, 0 otherwise. function get_pkg_versionfield { #pkgname="$1" vtmp=`pkgparam $1 VERSION 2>/dev/null` if [[ "$vtmp" == "" ]] ; then return 1 fi case $vtmp in *,REV=*) # Okay, we accept this format now ;; *,*) # Arrg. someone was "creative" with the version field vtmp=${vtmp%%,*} esac print $vtmp } # This expects a SOFTWARENAME string, not a package name # It will then check the catalog for versions of that software bundle, # and return the version field for the version in the catalog. # Normally, if there are multiple versions available, it will return the # 'MULTIPLE' flag. # However, if we are in upgrade mode, it will just return the # highest-rev version available (I hope) # function get_remote_version { remver=`$AWK '$1 ~ /^#/ {next} $1 == "'$1'" { print $2; }' $CATALOGFILE` count=0 for rev in $remver ; do count=$(($count + 1)) done if (( $count <= 1 )) ; then print $remver return fi if (( $do_upgrade == 0 )) ; then print MULTIPLE $remver return fi # We are in upgrade mode! for rev in $remver ; do if [[ "$maxver" == "" ]] ; then maxver=$rev continue fi #print DEBUG: get_remote_version calling newer_rev >/dev/fd/2 newer_rev $rev $maxver if (( $? == 0 )) ; then maxver=$rev fi done print $maxver } #call this with # explain_multiple softwarename MULTIPLE ver1 ver2 function explain_multiple_install { if (( $# < 4 )) ; then print INTERNAL ERROR: explain multiple called badly print \"explain_multiple $* \" return fi print "Sorry, there are multiple versions possible" print "Please specify one, in the following syntax" software="$1" shift ; shift while (( $# > 0 )) ; do print pkg-get $mode ${software}-$1 shift done } function explain_multiple_remove { print "Sorry, there are multiple SysV pkgs installed" print "This is usually not possible, if pkg-get is used." print "You will have to resolve this by hand, [with pkgrm]" print "or try being more specific about the version of software" print "" print "The following related SysV packages have been detected" print $* } # Given a software (NOT pkg) name, and a revision number, # generate a filename. prints out exact filename if available, # or a wildcard pattern. # $1=software, $2=revnum function get_filename { typeset net_name net_name=`$AWK '$1 == "'$1'" && $2 == "'$2'" {print $4}' $CATALOGFILE` if [[ -z "$net_name" ]] ; then print ERROR: could not find filename for $1 $2 >/dev/fd/2 cleanup exit 1 fi print "${net_name}" } # # Top level routine for "pkg-get upgrade" # # If no argument is given, tries to download and pkgadd newer versions # of every single net package already installed. # # If a specific software name are given, download/update each of those # specific ones. function upgrade { do_upgrade=1 #global var if [[ "$1" == "" ]] ; then set -- `egrep -v '^#' $CATALOGFILE | $AWK '{print $1}'|sort -u` print note: upgrading ALL INSTALLED PACKAGES upgrade_all=1 #global var for name in $* ; do pkgname=`$AWK '$1 == "'$name'" {print $3; exit;}' $CATALOGFILE` if [[ -d $CHEATDIR/$pkgname ]] ; then upgradelist="$name $upgradelist" fi done print Installed software packages: print $upgradelist set -- $upgradelist fi # Since user specified specific packages, try to # install/upgrade those for name in $* ; do install_one_software "$name" done } # Given a SysV pkg name, look up the software package name for it in # our catalog. # print out result, or return 1 if not found function find_software_name { findname="$1" sftname=`$AWK '$1 ~ /^#/ {next} $3 == "'$findname'" { print $1 }' $CATALOGFILE` if [[ "$sftname" == "" ]] ; then return 1 fi print $sftname } # called by both install_one_software, and remove_pkg # Given a common name for a software package, figure out the # SysV pkg name and print it, or print "",and an errormesasge # to stderr. # It is POSSIBLE it may return multiple SysV names. # remove_pkg() actually tries to take advantage of this. # # So if you want a guaranteed single return print, it is best to call it # with a second argument, giving the specific package version name. # function find_pkg_name { findname="$1" if [[ "$2" == "" ]] ; then pkgname=`$AWK '$1 ~ /^#/ {next} $1 == "'$findname'" { print $3 }' $CATALOGFILE` else pkgname=`$AWK '$1 ~ /^#/ {next} $1 == "'$findname'" && $2 == "'$2'" { print $3 }' $CATALOGFILE` fi if [[ "$pkgname" == "" ]] ; then # try name-version syntax now # assume XXX-YY-ZZ is XXX, ver YY-ZZ soft=${findname%%-*} find_version=${findname#*-} pkgname=`$AWK '$1 ~ /^#/ {next} $1 == "'$soft'" && $2 == "'$find_version'" { print $3 }' $CATALOGFILE` fi # Still no match? if [[ "$pkgname" == "" ]] ; then print ERROR: no matching SysV PKG found. >/dev/fd/2 print $pkgname $soft $find_version >/dev/fd/2 print '(either you mistyped it, or you need to 'updatecatalog', or' >/dev/fd/2 print ' it isnt available for your OSREV yet)' >/dev/fd/2 return fi print $pkgname } # Given a software name, return true if we have a pkg of the same or newer # version than what is in the catalog. # Since "true" == 0, that means there are two cases of "false": # Return 1 if there is no installed version # Return 2 if there is an existing but older version. # function uptodate { typeset pkgname # make pkgname a local var typeset i_sftname i_remversion i_currversion pkgname i_sftname="$1" i_remversion=`get_remote_version $i_sftname` if [[ "$i_remversion" == "" ]] ; then print INTERNAL ERROR: cannot get remote version for $i_sftname >/dev/fd/2 print Perhaps your catalog is out of date >/dev/fd/2 return 0 fi pkgname=`find_pkg_name $1 $i_remversion` i_currversion=`get_pkg_versionfield $pkgname` if [[ $? -ne 0 ]] ; then return 1 # return false: no version installed fi if [[ "$i_remversion" == "$i_currversion" ]] ; then if (( $debug == 1 )); then print "dependancy check to $i_sftname: up to date" fi return 0 fi newer_rev $i_remversion $i_currversion if [[ $? -ne 0 ]] ; then # remote version not the same, and not newer: must be older? if (( $debug == 1 )); then print "dependancy check to $i_sftname: local NEWER?" print "Ignoring" fi return 0 fi # Must have an old version installed return 1 } # Called by install_software, upgrade, and # Also called internally via recursion, in handle_dependancies # # Must have one and only one argument: the name of a software package. # eg "bison" # This is NOT to be confused with a pkgname, like SUNWcar # # (at one point, I supported calling it with a specific version. # eg bison-2.34 # I am no longer sure this works, but there is legacy code from it ) # # We try to find the actual pkgname from the $CATALOG file # and compare the catalog version to the version installed. # # If missing or out-of-date, # we then call net_install to download and install the actual package, # if it is a valid target for install # (or just return, doing nothing, otherwise) # function install_one_software { # local var definitions typeset i_sftname i_remversion i_currversion pkgname if [[ "$1" == "" ]] ; then print INTERNAL ERROR: install_one_software has no args cleanup exit 1 fi i_sftname="$1" i_remversion="" case $i_sftname in *-*) i_remversion=${i_sftname#*-} i_sftname=${i_sftname%%-*} ;; esac # XXX should check for conflicts/multiples here if [[ "$i_remversion" == "" ]] ; then i_remversion=`get_remote_version $i_sftname` if [[ "$i_remversion" == "" ]] ; then print ERROR: $i_sftname unrecognized >/dev/fd/2 print Perhaps you need to run pkg-get -U>/dev/fd/2 cleanup exit 1 fi fi case "$i_remversion" in MULTIPLE*) explain_multiple_install $i_sftname $i_remversion >/dev/fd/2 return ;; esac pkgname=`find_pkg_name $1 $i_remversion` if [[ "$pkgname" == "" ]] ; then return fi if (( "$downloadonly" == 1 )) ; then # net_install checks downloadonly also net_install `get_filename $i_sftname $i_remversion` return fi # else... i_currversion=`get_pkg_versionfield $pkgname` if [[ $? -ne 0 ]] ; then print No existing install of $pkgname found. Installing... >/dev/fd/2 net_install `get_filename $i_sftname $i_remversion` if (( $? == 10 )) ; then print "" print Attempting to update catalog, then retry print "" update_catalog i_newversion=`get_remote_version $i_sftname` if [[ "$i_newversion" = "i_remversion" ]] ; then print "Didn't help, sorry." return fi net_install `get_filename $i_sftname $i_newversion` fi return fi if [[ "$i_remversion" == "$i_currversion" ]] ; then if (( $debug == 1 )) || (( $upgrade_all == 1 )); then print "$i_sftname is up to date" return fi print "No worries... you already have version $i_remversion of $i_sftname" print "If you doubt this message, run 'pkg-get -U', then run" print " 'pkg-get upgrade $i_sftname'" return fi newer_rev $i_remversion $i_currversion if [[ $? -ne 0 ]] ; then if [[ "$sync" != "true" ]] ; then print "WARNING: remote version older than current version." print "Not installing remote package of $i_sftname" print "(remote=$i_remversion, local=$i_currversion)" return else print WARNING: down-revving $i_sftname to sync to site fi fi # Special handling for "pkg-get upgrade pkg-get", # when we have determined that there is an older version of # pkg-get installed already. # (in theory, this block would not get called, if # we were installed as BOLTpget instead of CSWpget) if [[ "$i_sftname" = "pkg-get" ]] ; then mv $progname ${progname}.old progname=${progname}.old fi net_install `get_filename $i_sftname $i_remversion` } # Top routine for "pkg-get install" # Recognizes : # No arguments == update all installed packages # One or more arguments == treat each argument as a software name, # and try to either install or update it, as appropriate function install_software { softwarename="$1" if [[ "$softwarename" == "" ]] ; then print Please specify packages you want installed. print "if you want 'all' packages installed, use" print " pkg-get install all" return fi if [[ "$softwarename" == "all" ]] ; then set -- `egrep -v '^#' $CATALOGFILE | $AWK '{print $1}'|sort -u` # using 'upgrade' ensures we install only the latest versions print "Installing ALL AVAILABLE SOFTWARE" upgrade $* return fi for name in $* ; do install_one_software "$name" done } # Given a SysV package name, recursively remove *ALL* # instances of it. function remove_sysv_pkg { if [[ -d $CHEATDIR/$1 ]] ; then pkgrm $ADMINFLAG ${1}'.*' elif [ -d $CHEATDIR/$1.* ] ; then # MUST use single [] here pkgrm $ADMINFLAG ${1}'.*' fi } # Given a common-name for a package, figure out the SysV pkg name # and pkgrm it function remove_pkg { rm_softname="$1" rm_version="" case $rm_softname in *-*) rm_version=${rm_softname#*-} rm_softname=${rm_softname%%-*} ;; esac rm_pkgname=`find_pkg_name $rm_softname $rm_version` if [[ "$rm_pkgname" == "" ]] ; then return fi set -- $rm_pkgname rm_pkgname="$1" # First, look at all the externally possible unique pkgnames while [[ "$2" != "" ]] ; do if [[ "$2" != "$1" ]] ; then rm_pkgname="$rm_pkgname $2" fi shift done # Then see how many of them are actually INSTALLED set -- $rm_pkgname if [[ "$2" != "" ]] ; then while [[ "$1" != "" ]] ; do version=`get_pkg_versionfield $1` if [[ "$version" != "" ]] ; then rm_pkgname="$rm_pkgname $1" fi shift done fi set -- $rm_pkgname if [[ "$2" != "" ]] ; then explain_multiple_remove $rm_pkgname >/dev/fd/2 return fi remove_sysv_pkg $rm_pkgname } # Given a common name for a software package, hand it off to # remove_pkg function remove_packages { if [[ "$1" == "" ]] ; then print ERROR: no packages given to remove cleanup exit 1 fi print "WARNING: the remove option is not very intelligent." print "If there are multiple versions of a package with the same" print "PKG style name, it will remove the first one it can" print "(will continue in 5 seconds)" sleep 5 print "Starting remove operations now..." print "" for name in $* ; do remove_pkg "$name" done } # Passed in a 'depend' file as arg 1. # parse it, and try to install any missing dependancies. # XXX this wont handle dependancies with revisions, currently. # Additionally, it will REMOVE conflicting packages. # The benefit of this, is that it allows for renaming of PKGnames. # The drawback is that you have to be really really careful what you # specify in as a conflict when you create a PKG. # # return 1 on fail function handle_dependancies { typeset removelist removepkg typeset dependlist dependpkg dependsoftname removelist=`$AWK ' $1 == "I" {print $2}' $1` for removepkg in $removelist ; do pkginfo -q $removepkg if (( $? == 0 )) ; then print "" print Removing designated conflict package $removepkg print "" remove_sysv_pkg $removepkg fi done dependlist=`$AWK ' $1 == "P" {print $2}' $1` for dependpkg in $dependlist ; do pkginfo -q $dependpkg if [[ $? -ne 0 ]] ; then # Dependancy not installed. So install it. if [[ "$DIRECTORY" != "" ]] ; then # no point in using upgrade: # can only be one pkgname in a dir. $progname install $DIRECTORY $dependpkg continue fi # otherwise, we have to go through this whole # long thing of looking up the name, # so we can use pkg-get to install by softwarename. # dependsoftname=`find_software_name $dependpkg` if [[ $? -ne 0 ]] ; then print ERROR: no info for $dependpkg. Cannot install dependancy. return 1 fi print Trying to install dependancy $dependsoftname upgrade $dependsoftname #did it work? pkginfo -q $dependpkg 2>/dev/null if [[ $? -ne 0 ]] ; then print ERROR: install of $dependpkg failed return 1 fi # We have installed the dependancy. next! continue fi dependsoftname=`find_software_name $dependpkg` if [[ "$dependsoftname" = "" ]] ; then # cant find a software name for it. Probably # a SUNWxxx package. ignore. if (( $debug == 1 )) ; then print $dependpkg not in catalog. Presuming up to date fi continue fi # dependancy present.. but is it up to date? # if not, it must be updated first. which can only be done # safely, if we are in upgrade_all mode if ! uptodate $dependsoftname; then if [[ "$upgrade_all" -ne 1 ]]; then print "Error: dependancy $dependsoftname ($dependpkg) not up to date" print "Call pkg-get again in 'upgrade all' mode" print "eg: '$progname upgrade'" print This will then upgrade all packages cleanly print "" return 1 fi # # This is recursive. We have probably been called # by this same function. install_one_software $dependsoftname fi done ### for dependpkg in $dependlist } # This function exists for two reasons: # 1. solaris pkgtrans is BUGGY. it leaves droppings in /var/tmp # 2. THis way is much more efficient if the pkg is very large. # # SO, this works similar to pkgtrans (pkgtrans srcfile destdir pkgname) # except that it ONLY extracts the depend file, if it exists, to # $destdir/$pkgname/install/depend # function extract_depend { typeset hdrblks if [[ ! -d $2 ]] ; then print ERROR: $2 is not a directory >/dev/fd/2 return 1 fi rm -rf $2/$3 2>/dev/null # sometimes, old attempts get left over mkdir $2/$3 || return 1 # and sometimes, we just dont have perms # "lang=C" here, because cpio orders output differently otherwise hdrblks=`(dd if=$1 skip=1 2>/dev/null| LANG=C LC_ALL=C cpio -i -t >/dev/null) 2>&1 | $AWK '{print $1}'` ## print initial hdrblks=$hdrblks hdrblks=$(($hdrblks + 1)) print Analysing special files... # There HAS to be a "install" directory for CSW packages. # (because there must always be a copyright file) # but there may not always be a "depend" file in it. dd if=$1 skip=$hdrblks 2>/dev/null | (cd $2/$3 ; cpio -ivd 'install/*') >/dev/null 2>&1 # on fail, SOMETIMES cpio returns 1, but sometimes it returns 0!! if [[ ! -d $2/$3/install ]] ; then print -n Hmmm. Retrying with different archive offset... # no, I cant tell in advance why/when the prev fails hdrblks=$(($hdrblks + 1)) # yes, leave stderr unmasked in this case dd if=$1 skip=$hdrblks 2>/dev/null| (cd $2/$3 ; cpio -ivd 'install/*') >/dev/null if [[ $? -ne 0 ]] ; then print ERROR: cpio still failed >/dev/fd/2 return 1 fi print "" fi # now ensure we have the right exit status, rather than # relying on "return 0 == good" from cpio if [[ -d $2/$3 ]] ; then return 0 ; else return 1 ; fi } # Given a filename for a pkg, gzipped or not, pkgadd it. # Remove the file when done, if successfully # Previously, we extracted to /var/spool/pkg. # But these days, we assume we have already created own own unique # download directory, and cd'd to it already. # So extract and transform pkg in the current directory and look at 'depend' # # If there are unmet dependancies, try to grab them, # by invoking pkg-get in a SEPARATE process, so that # variable names dont conflict. # However, we can only install dependancies if they are from the same # site, since we need to look up software name from pkgname. # # If do_upgrade is set, remove any older version of pkg before doing install # # It is up to the calling function to determine whether the supplied file # is a higher rev than any existing package. We just remove all package # instances with the same sysv_pkg name. function install_pkg_file { typeset filename pkgname srcfilename tmpfilename srcfilename="$1" env LANG=C LC_ALL=C file $srcfilename | grep 'compressed ' >/dev/null if (( $? == 0 )) ; then filename=${srcfilename}.tmp tmpfilename=$filename gzip -d -c $srcfilename >$filename if [[ $? -ne 0 ]] ; then print ERROR: could not expand downloaded file $srcfilename >/dev/fd/2 rm $filename exit 1 fi else filename="$srcfilename" fi pkgname=`$AWK 'NR==2 {print $1;exit}' $filename` # Special-case pkg upgrade of 'wget' package. use failsafe version typeset fallbackdir=/var/pkg-get/`$UNAME -p` case $pkgname in *[A-Z]wget) if [[ ! -d $fallbackdir ]] ; then mkdir $fallbackdir fi if [[ -x $prefix/sbin/wget.static ]] ; then cp $prefix/sbin/wget.static /var/pkg-get/`$UNAME -p`/wget fi export PATH=$fallbackdir:$PATH ;; esac if (( $do_upgrade == 1 )) ; then remove_sysv_pkg $pkgname fi # convert from file to to "spool" format, to check depends. extract_depend $filename $PWD $pkgname if [[ $? -ne 0 ]] ; then print ERROR: could not verify downloaded file correctly return 1 fi if [[ -f $pkgname/install/depend ]] ; then handle_dependancies $pkgname/install/depend if [[ $? -ne 0 ]] ; then print ERROR: could not install required dependancies for $pkgname print "Once dependancies are up to date, call" print " $0 -i ${1%%-*}" print "to (re)install" /bin/rm -r $pkgname $tmpfilename return 1 fi fi if [[ -f $PKGASKDIR/$pkgname ]] ; then PKGASK=" -r $PKGASKDIR/$pkgname" else PKGASK="" ; fi pkgadd -d $filename $PKGADDFLAGS$PKGASK $pkgname status=$? if [[ $status -ne 0 ]] ; then print ERROR: could not add $pkgname. else # remove pkg file, only if successfully if [[ "$PKGGET_CACHE_FILES" = "" ]] ; then rm $srcfilename fi fi /bin/rm -r $pkgname $tmpfilename return $status } # grab either gzip or wget "the hard way" # return 0 on okay, 1 on fail function ftp_prog_hardway { typeset targetprog targetprog="$1" print Press return or enter email when asked for a password sleep 2 mkdir /tmp/ftp.tmp cd /tmp/ftp.tmp rm -f * rootcheck=`ls -ld | $AWK '{print $3}'` if [[ "$rootcheck" != "root" ]] ; then print SECURITY ERROR: /tmp/ftp.tmp not owned by ROOT #exit 1 fi ftp -id $MASTERSITE <$CONFFILE </dev/null if (( $? == 0 )) ; then return ; fi if [[ -x /opt/csw/bin/gzip ]] ; then export PATH="$PATH":/opt/csw/bin return fi print "ERROR: gzip not in path. " print "( $PATH )" print "" print "You must have a working gzip installed." print "It comes with the Solaris 8 (and later) media" print "Check 'CD 2 of 2' if you do not know where to find it" exit 1 } # Dont bother calling this unless you already know MD5 is available! # return 0 if "true" (file matches checksum), # return 1 if FAIL # return 2 if checksum program not available (broken due to upgrades?) # return 3 if checksum field not present in catalog function md5_check_file { typeset local_md5 remote_md5 if [[ "$MD5" = "" ]] ; then if [[ "$use_md5" != "false" ]] ; then print Note: No md5 checksum program >/dev/fd/2 else print Note: Use of md5 disabled in config >/dev/fd/2 fi return 2 fi local_md5=`$MD5 $1` remote_md5=`$AWK '$1 ~ /^#/ {next} $4 == "'$1'" { print $5; }' $CATALOGFILE` if [[ "$remote_md5" = "" ]] ; then return 3 fi if [[ "$local_md5" = "" ]] ; then # md5 currently non-functional return 2 fi if [[ "$local_md5" != "$remote_md5" ]] ; then return 1 fi return 0 } # Currently takes as args # 1. descriptive software name # 2. PKGname # 3. revisionnum # # Currently called by upgradeall, and install_one_software # Will download a package, and install it using install_pkg_file # # Or, if downloadonly set, just leave the file as-is once downloaded. # # Return 0 on okay, or 10 if wget failed (yes, 10!) # Any other returnval is undefined status # function net_install { typeset net_name fullurl graburl shortname net_name="$1" fullurl=$url/$CPU/$OSREV if [[ -f $net_name ]] ; then ## Found the file already downloaded. Use it, ## IF valid, and not in "download only" mode md5_check_file $net_name case $? in 0) print Pre-existing local file $net_name matches checksum print Keeping existing file if [[ "$downloadonly" -ne 1 ]] ; then install_pkg_file $net_name fi return 0 ;; 2) print md5 utility temporarily non-functional print assuming local file $net_name valid to use if [[ "$downloadonly" -ne 1 ]] ; then install_pkg_file $net_name fi return 0 ;; *) print Removing invalid local file $net_name rm -f $net_name ;; esac fi graburl=$fullurl/$net_name print Trying $graburl case $graburl in *\*) print ERROR: no wildcards allowed in net_install exit ;; esac if [[ "$debug" = 1 ]] ; then print DEBUG: would try to grab $graburl now print " Not downloading, so cannot check dependancies" return 0; fi # IF PKGGET_CACHE_FILES is set, we would keep ALL files. # Otherwise, we only want ONE copy of a particular software. # It will be kept around until successful pkgadd only. # remember, if the EXACT filename we need already exists, we should # have already returned, earlier in this function shortname=${net_name%%-*} rm -f -- "$shortname"-* grabfunc $graburl if [[ $? -ne 0 ]] || [[ ! -s $net_name ]] ; then print "Error downloading $graburl" print "(Perhaps you need to update your catalog?)" rm $net_name return 10 fi if [[ "$MD5" != "" ]] ; then md5_check_file $net_name case $? in 0) break ;; 1) print ERROR: checksum $net_name does not match remote checksum print "(perhaps you need to pkg-get -U ?)" return ;; 2) # Sometimes, md5 util is broken. print WARNING: md5 capability not available break ;; *) print "NOTE: No checksum available for package" ;; esac fi if (( $downloadonly == 1 )) ; then print downloaded $net_name return 0 fi # else... really install # Duplicate any changes here, to the "file already downloaded" # section at top. install_pkg_file $net_name return 0 } #compare_pkg # called by compare_installed # # This takes info for a SINGLE PACKAGE, and compares it to # what is locally available. # The printout format must match the header in compare_installed() # Expects: # compare_pkg softwarename availablerev pkgname function compare_pkg { typeset software rem_rev pkgname software="$1" rem_rev="$2" pkgname="$3" # gzip triggers this. if [[ "$pkgname" == "" ]] ; then # print ERROR: compare_pkg did not get all arguments passed # print "[" $* "]" return 1 fi if [[ ! -d $CHEATDIR/$pkgname ]] ; then localrev='[Not installed]' else localrev=`get_pkg_versionfield $pkgname 2>/dev/null` fi if [[ "$localrev" == "$rem_rev" ]] ; then rem_rev="SAME" fi # match with headers in compare_installed printf "%15s %25s %25s\n" "$software" "$localrev" "$rem_rev" } # This cross-references all known install packages that match # the catalog file, with the installed version, vs the potential version function compare_installed { print "# (From site $url )" # match with output of compare_pkg printf "%15s %25s %25s\n" "software" "localrev" "remoterev" if [[ "$1" = "" ]] ; then egrep -v '^#' $CATALOGFILE | while read line ; do compare_pkg $line done return fi while [[ "$1" != "" ]] ; do $AWK '$1 == "'$1'" {print}' $CATALOGFILE | read line compare_pkg $line shift done } # stolen from compare_pkg # but we just list the software name here, IF installed function list_pkg { typeset software rem_rev pkgname software="$1" rem_rev="$2" pkgname="$3" if [[ -d $CHEATDIR/$pkgname ]] ; then print $software fi } # Just list installed packages, by "software name" # This is primarily so that people can take a list of 'installed software' # on one machine, then bring the other machine to an exact match # function list_installed { egrep -v '^#' $CATALOGFILE | while read line ; do list_pkg $line done } # If a description file is available, show either matches to given args, # or the whole file. # If there is no desc file ... oh well. function show_descriptions { if [[ ! -f "$DESCFILE" ]] ; then print "Sorry, no description file available" return; fi print "# (Descriptions from site $SITE )" if [[ "$1" = "" ]] ; then cat $DESCFILE return fi while [[ "$1" != "" ]] ; do egrep "$1" $DESCFILE shift done } # This is called to process a "catalog" file in the current directory. # It has already been determined to be a GPG/PGP signed file. function verify_catalog { mv catalog catalog.asc if [[ "$GPG" = "" ]] ; then # gpg is not available. So just trim off the extras, # and treat as unsigned if [[ "$use_gpg" != "false" ]] ; then print WARNING: gpg not available. fi print Stripping off catalog signature without verifying sed -e '1,3d' -e '/BEGIN PGP SIGNATURE/,$d' catalog.asc >catalog rm catalog.asc return 0 fi gpg catalog.asc status=$? #gpg will normally create a 'catalog' file from 'catalog.asc' if [[ $status -ne 0 ]] ; then print "" print "ERROR: catalog failed signature check (status $status)" print "" if [[ "$status" = 2 ]] ; then print You need to install the public key, either manually, print or automatically through a keyserver. print "For keyserver use, try one of" print ' echo keyserver search.keyserver.net >>/.gnupg/options' print ' echo keyserver search.keyserver.net >>/.gnupg/gpg.conf' fi if grep blastwave catalog.asc >/dev/null ; then print "For manual install of the key (recommended), try" print " wget http://www.blastwave.org/mirrors.html" print " gpg --import mirrors.html " fi # in case they try to follow the above directions, # make it easier for them. if [[ ! -d $HOME/.gnupg ]] ; then mkdir $HOME/.gnupg ; fi return 1 fi rm catalog.asc return 0 } # Downloads the catalog file (and descriptions file if present) # from the current SITE. # Calls verify_catalog if catalog is signed # Note that "normally", we are in /var/pkg-get/cache, # but sometimes, we might need to be called before then... MAYBE? # (probably I need to go back and look at this some time, but I'm # rushing out a quick bugfix right now) function update_catalog { OSREV=$OSREV CPU=$CPU if [[ ! -d /var/pkg-get ]] ; then print Warning: making /var/pkg-get mkdir /var/pkg-get fi print Getting catalog... # note: we first download catalog with name of "catalog". # but then we rename it to the site-specific catalog name rm -f catalog grabfunc $url/$CPU/$OSREV/catalog if [[ $? -ne 0 ]] ; then print ERROR: could not get catalog file cleanup exit 1 fi if [[ ! -s catalog ]] ; then print ERROR: catalog file is zero length. Removing and quitting. rm catalog return fi grep -l 'BEGIN PGP SIGNED MESSAGE' catalog >/dev/null if (( $? == 0 )) ; then # Has a PGP/GPG signature... verify_catalog if [[ $? -ne 0 ]] ; then print "Catalog failed signature verify. Quitting." cleanup exit 1 fi fi print "Updating catalog file" # egrep -v '^(gzip)' catalog >$CATALOGFILE cat catalog >$CATALOGFILE print $CATALOGFILE updated print "" grabfunc $url/$CPU/$OSREV/descriptions if [[ -s descriptions ]] ; then mv descriptions $DESCFILE print Updated description file else print Failed to get a description file fi } # create our download directory if available, and then cd to it # There is currently an ambiguity between "DOWNLOAD_DIR" and "CACHE" # which I should really resolve in the future. # CACHE files stay around forever. download dir files stay until they # are successfully pkgadded. function make_download_dir { if [[ "$debug" = 1 ]] ; then return ; fi PKGGET_DOWNLOAD_DIR=${PKGGET_DOWNLOAD_DIR:-/var/pkg-get/downloads} ## trap cleanup 2 3 ## We no longer auto-rm all files on exit # If downloadonly is set, we dump everything into the # current directory, rather than our "official", normal directory # OTHERWISE, make a reasonable temp directory. if (( $downloadonly == 1 )) then # paranoia always pays off in the end PKGGET_DOWNLOAD_DIR="no_tmp_dir_used" return fi if [[ ! -d $PKGGET_DOWNLOAD_DIR ]] ; then mkdir -p $PKGGET_DOWNLOAD_DIR if [[ $? -ne 0 ]] ; then print ERROR: cannot create $PKGGET_DOWNLOAD_DIR exit 1 fi fi cd $PKGGET_DOWNLOAD_DIR } function cleanup { # We used to automatically remove the entire download directory. # We dont do that any more. # if [[ "$PKGGET_DOWNLOAD_DIR" = "" ]] ; then # return # fi # if [[ "$PKGGET_DOWNLOAD_DIR" = "no_tmp_dir_used" ]] ; then # return # fi : } ###################################################################### # This whole section, until the "main" routine, is a special off-shoot, # that works on CD-type distribution directories. # Assumes a bunch of directory, NOT stream, format PKGs. # Just a sneaky alias for "pkginfo -d dirname" right now - # its purpose is to show what packages are "available" to install # from the named directory. # Only call this if you have verified first arg is a directory function dir_available { pkginfo -d "$1"| $PAGER } #"Directory"-package compare. # Look in an existing directory for packages, instead of downloading them # Compare installed packages, to what's in a directory # For speed reasons, we "Cheat", and do not go through the long # hasses of comparing individual pkginfo output. # First arg is directory, rest are optional pkgnames # WHICH HAVE TO BE DIRECTORY NAMES, NOT the "cute" names function dir_compare { if [[ ! -d "$1" ]] ; then print ERROR: $1 not valid directory return fi comparedir="$1" shift # This must match up to "dir_compare_one" output. # It is similar to compare_installed printf "%15s %25s %25s\n" "PKGNAME" "Directory-rev" "Installed-rev" if (( $# > 1 )) ; then while (( $# > 1 )) ; do dir_compare_one $comparedir "$1" done return fi #else for pkg_d in $comparedir/* ; do if [[ -d "$pkg_d" ]]; then pkg_d=${pkg_d##*/} dir_compare_one $comparedir $pkg_d fi done } # # arg1 is a directory. arg2 is a directory name IN that directory: # MUST BE RELATIVE TO arg1!! # Will then compare pkg there, to any installed package # function dir_compare_one { tmpdir="$1" tmppkg="$2" tmpver=`grep VERSION $tmpdir/$tmppkg/pkginfo` tmpver=${tmpver#VERSION=} tmpoldver=`grep VERSION /var/sadm/pkg/$tmppkg/pkginfo 2>/dev/null` if (( $? == 0 )) ; then tmpoldver=${tmpoldver#VERSION=} if [[ "$tmpoldver" == "$tmpver" ]] ; then tmpoldver="SAME" fi else tmpoldver="[Not installed]" fi # match with headers in dir_compare printf "%15s %25s %25s\n" "$tmppkg" "$tmpver" "$tmpoldver" } # Given the name of a directory, install ALL packages present in # 'spool' form (directory, not a single file) # Or just install the named packages in the directory # # Remove any old versions first, IF upgrade option given function dir_install { # we use 'DIRECTORY' as a global flag that we are installing # from a directory. Or we shall use it, someday. DIRECTORY="$1" shift if (( $# > 0 )) ; then while (( $# > 0 )) ; do dir_install_one $DIRECTORY "$1" shift done return fi #else for d in $DIRECTORY/* ; do if [[ -d "$d" ]]; then d=${d##*/} dir_install_one $DIRECTORY $d fi done } #Given the name of a directory, and the name of a pkg-directory in it, # Remove any pre-existing packages, and install the new one # # Check dependancies while we are at it. function dir_install_one { tmpdir="$1" tmppkg="$2" if [[ -f $tmpdir/$tmppkg/install/depend ]] ; then handle_dependancies $tmpdir/$tmppkg/install/depend if [[ $? -ne 0 ]] ; then print ERROR: could not install required dependancies for $tmppkg return 1 fi fi if [[ "$debug" = 1 ]] ; then print DEBUG: would try to pkgadd $tmpdir/$tmppkg now return 0; fi if [[ -f $PKGASKDIR/$pkgname ]] ; then PKGASK=" -r $PKGASKDIR/$pkgname" else PKGASK="" ; fi if (( do_upgrade == 0 )) ; then # Dont bother to upgrade, just install and get out of here. # If it conflicts with any existing, then it stops here. pkgadd $PKGADDFLAGS$PKGASK -d $tmpdir $tmppkg return $?; fi # Otherwise, we're doing the whole nine yards. Clean up any existing, # so that we effectively "upgrade" any pre-existing package if [[ -f /var/sadm/pkg/$tmppkg ]] ; then print "Removing old version of package" pkgrm $ADMINFLAG $tmppkg fi for f in /var/sadm/pkg/${tmppkg}.* ; do if [[ -d $f ]] ; then f=${f##*/} print "Removing old instance $f" pkgrm $ADMINFLAG $f fi done pkgadd $PKGADDFLAGS$PKGASK -d $tmpdir $tmppkg } ############################################################################### ############################################################################### # 'main' routine here ############################################################################### ############################################################################### ###### First, basic config file parsing, and variable setup if [[ "$1" == "" ]] ; then usage exit 1 fi check_conffile . $CONFFILE if [[ "$url" == "" ]] ; then print ERROR: url variable not set in $CONFFILE exit 1 fi OSREV=`$UNAME -r` CPU=`$UNAME -p` ###################################################################### # Arg parsing time. There's a whole lot of different ways to pass args. # We do the standard way first. # Then duplicate everything lower down, for longopts type args # explicitly defaulting these vars to 0 allows for faster compares export debug=0 do_upgrade=0 downloadonly=0 upgrade_all=0 while getopts "dDSs:uUacfhilrv" mode_var ; do case $mode_var in d) mode=install downloadonly=1 ;; D) mode=describe ;; v) export debug=1 print DEBUG-ONLY MODE ON ;; s) url=$OPTARG ;; u) mode=upgrade ;; U) do_update=1 ;; a) mode=available ;; c) mode=compare ;; i) mode=install ;; l) mode=list ;; r) mode=remove ;; f) force=true ;; S) sync=true ;; *) usage exit 1 ;; esac done shift $(($OPTIND - 1 )) # Set these AFTER -s arg has been checked! # Precedence for SITE is: commandline, conf file, fallback SITE=${url##*//} SITE=${SITE%%/*} CATALOGFILE=/var/pkg-get/catalog-$SITE DESCFILE=/var/pkg-get/desc-$SITE ############################################################ # This type of arg parsing is to keep some sort of compatibility # with debian "apt-get", the program that inspired pkg-get # if [[ "$mode" == "" ]] ; then case "$1" in updatecatalog|--updatecatalog) do_update=1 shift ;; upgrade|--upgrade) mode=upgrade shift ;; available|--available) mode=available shift ;; compare|--compare) mode=compare shift ;; describe|--describe) mode=describe shift ;; download|--download) mode=install downloadonly=1 shift ;; install|--install) mode=install shift ;; list|--list) mode=list shift ;; remove|--remove) mode=remove shift ;; sync|--sync) sync=true shift ;; moo|--moo) mode=moo shift ;; *) mode=help esac fi ###################################################################### # End of arg-interpretation section. # Now for sanity checks, and utility function checking. # Sanity check for SITE variable case $url in ftp://*|http://*) ;; file://*) SITE=localhost ;; *) print ERROR: unsupported url type print $url not acceptible as source location exit 1 ;; esac # MUST HAVE gzip! check_gzip # Try to make sure we have wget SOMEWHERE in our path. # Try to cover all potential reasonable places to look for it. # Unless the conf file tells us to use another program, that is. WGET=${WGET:-wget} if [[ "$WGET" = "wget" ]] ; then # special 'static' (non-dependant) version, that makes upgrades safe if [[ -x /opt/csw/sbin/wget.static ]] ; then WGET=/opt/csw/sbin/wget.static fi fi if [[ "$WGET" = "wget" ]] ; then # If WGET var has not been explicitly set, we might not actually # HAVE wget available. Check for it. whence wget >/dev/null if [[ $? -ne 0 ]] ; then export PATH=$PATH:/opt/csw/bin:/opt/sfw/bin:/usr/sfw/bin:/usr/local/bin:/var/pkg-get/`$UNAME -p` # Note the /var/pkg-get/ location is a special fallback case # for when we've tried to upgrade wget, and failed. # we may have a special backup copy of wget there. fi whence wget >/dev/null || get_wget fi GPG=${GPG:-gpg} if [[ $use_gpg == "false" ]] ; then GPG="" elif [[ "$GPG" = "gpg" ]] ; then PATH=/opt/csw/bin:$PATH whence gpg >/dev/null if [[ $? -ne 0 ]] ; then print WARNING: gpg not found GPG="" fi fi # # Check if we have md5. Use it later, if we do, via $MD5 # function md5wrap { md5 $1 | $AWK '{print $4}' } function gmd5sumwrap { gmd5sum $1 | $AWK '{print $1}' } MD5="" if [[ -x /usr/bin/digest ]] ; then MD5="/usr/bin/digest -a md5" elif whence md5 >/dev/null ; then MD5=md5wrap elif whence gmd5sum >/dev/null ; then MD5=gmd5sumwrap fi if [[ "$use_md5" = "false" ]] ; then MD5="" elif [[ "$MD5" = "" ]] ; then print NOTE: To have checksums compared, you must install one of: print " md5 or gmd5sum (gmd5sum is available with GNU textutils)" print " try 'pkg-get install textutils'" fi ######################################################################## # Now some basic up-to-date checks if [[ "$do_update" = 1 ]] ; then make_download_dir update_catalog fi # Auto-Update catalog, UNLESS we are in special # "install packages from directory" mode, which specifies dir as first arg. if [[ ! -d $1 ]] ; then if [[ ! -f $CATALOGFILE ]] ; then print "" print WARNING: no catalog file for site $SITE print "Updating catalog file first" update_catalog fi datecheck=`find $CATALOGFILE -mtime +30 -print 2>/dev/null` if [[ "$datecheck" != "" ]] && [[ "$mode" != "updatecatalog" ]] ; then print "WARNING: catalog out of date." print "Automatically updating catalog first" update_catalog fi fi # check for special override file that tells pkgadd, "shut up and just do it". # man -s4 admin to see the format of it, and/or see # /var/sadm/install/admin/default for the default file # # -n means "ask no questions". If you dont have the fullauto version, # perhaps you dont want the -n flag here. if [[ -f /var/pkg-get/admin ]] ; then ADMINFLAG="-a /var/pkg-get/admin" fi if [[ "$force" != "" ]] ; then ADMINFLAG="-n $ADMINFLAG" fi # This is addative, so that the user can add # PKGADDFLAGS=-G # in pkg-get.conf PKGADDFLAGS="$PKGADDFLAGS $ADMINFLAG" # Yes, I strive for a high level of compatibility with apt-get... function super_moo { cat <