# PaCkAgE DaTaStReAm BOLTpget 1 164 # end of header 0707011c33107c000081a4000002bc00000001000000013df6f2a80000017e0000000000000002ffffffffffffffff0000001100000006BOLTpget/pkginfoARCH=all CLASSES=none BASEDIR=/usr PATH=/sbin:/usr/sbin:/usr/bin:/usr/sadm/install/bin PKG=BOLTpget NAME=pkg-get VERSION=1.9.9 CATEGORY=system DESC=A convinient way to automate packages install VENDOR=Philip Brown, Bolthole Software, http://www.bolthole.com EMAIL=phil@bolthole.com URL=http://www.bolthole.com/solaris/ PKGSAV=/var/sadm/pkg/BOLTpget/save PSTAMP=zaphod20021211000912 0707011c4a03cc000081a4000002bc00000001000000013df6f2a80000018b0000000000000002ffffffffffffffff0000001000000006BOLTpget/pkgmap: 1 164 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 33416 13653 1039594149 1 i pkginfo 382 32572 1039594152 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 6080 21946 1038646883 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000b00000000TRAILER!!!0707011c33107c000081a4000002bc00000001000000013df6f2a80000017e0000000000000002ffffffffffffffff0000000800000006pkginfoARCH=all CLASSES=none BASEDIR=/usr PATH=/sbin:/usr/sbin:/usr/bin:/usr/sadm/install/bin PKG=BOLTpget NAME=pkg-get VERSION=1.9.9 CATEGORY=system DESC=A convinient way to automate packages install VENDOR=Philip Brown, Bolthole Software, http://www.bolthole.com EMAIL=phil@bolthole.com URL=http://www.bolthole.com/solaris/ PKGSAV=/var/sadm/pkg/BOLTpget/save PSTAMP=zaphod20021211000912 0707011c4a03cc000081a4000002bc00000001000000013df6f2a80000018b0000000000000002ffffffffffffffff0000000700000006pkgmap: 1 164 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 33416 13653 1039594149 1 i pkginfo 382 32572 1039594152 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 6080 21946 1038646883 0707011c3a587c000041ed000002bc00000001000000043df6f2a8000000000000000000000002ffffffffffffffff0000000600000006reloc0707011c47c552000041ed000002bc00000001000000023df6f2a8000000000000000000000002ffffffffffffffff0000000a00000006reloc/bin0707011c49d398000081a4000002bc00000001000000013df6f2a5000082880000000000000002ffffffffffffffff0000001200000006reloc/bin/pkg-get#!/bin/ksh -p # the -p says "ignore profile" # This is loosely modeled after debian "apt-get". # Philip Brown, phil@bolthole.com, http://www.bolthole.com/solaris/ # MASTERSITE is always the fallback. # Precedence is: commandline, conf file, fallback MASTERSITE=ftp.sunfreeware.com SITE=$MASTERSITE # "WGET" needs to be set to something that # 1. can do wildcarding ftp gets # 2. will dump the file to stdout # 3. will handle file:// urls as well as ftp stuff. # If you really think you have a replacement, you can actually # override this var in /etc/pkg-get.conf # But note that if you do that, file:// urls may not work as well. WGET=${WGET:-grabfunc} # If you prefer something else than wget, feel free to substitute! :-) ###################################################################### # Dont change anything below here # # # Try to make sure we have wget SOMEWHERE in our path. # We may possibly be using multiple binary directories. Try to cover # all of them if [[ -x /opt/csw/bin/wget ]] ; then case $PATH in */opt/csw/bin*) ;; *) PATH=$PATH:/opt/csw/bin ;; esac fi if [[ -x /opt/sfw/bin/wget ]] ; then case $PATH in */opt/sfw/bin*) ;; *) PATH=$PATH:/opt/sfw/bin ;; esac fi if [[ -x /usr/local/bin/wget ]] ; then case $PATH in */usr/local/bin*) ;; *) PATH=$PATH:/usr/local/bin ;; esac fi # Grab file, and dump it to stdout # But this is a special wrapper to handle file:// urls # grabfunc(){ graburl="$1" if [[ $# -eq 2 ]] ; then graburl="$2"; fi if [[ $# -eq 3 ]] ; then graburl="$3"; 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 cat $fname return 0 ;; ftp://*) WGET_PASSIVE="--passive-ftp" ;; esac # else #-nv means NO progress meter at all. You dont get the dots. # wget -nv --dot-style=mega --passive-ftp -O /dev/fd/1 $* wget $PROXYFLAGS $WGET_PASSIVE --dot-style=mega -O /dev/fd/1 $* } CONFFILE=/etc/pkg-get.conf CHEATDIR=/var/sadm/pkg if [[ ! -f $CONFFILE ]] ; then print ERROR: $CONFFILE not present print Creating a default file cat >$CONFFILE < 1 2 # beta ==> beta # beta3 ==> beta 3 # WARNING: WILL ALWAYS print out ' ' as minimum!!! 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 trimshared(){ if [[ $# -lt 2 ]] ; then print ERROR: trimshared needs TWO args exit 1 fi savedstring=""; while [[ 1 -eq 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" newer_rev(){ remainder1=""; remainder2="" if [[ $# -lt 2 ]] ; then print Need TWO args to newer_rev exit 1 fi # First, snip off common string at the front rev_shared=`trimshared $1 $2` if [[ "$rev_shared" != "" ]] ; then val1=${1##$rev_shared} val2=${2##$rev_shared} set "$val1" "$val2" fi val1="$1" val2="$2" # Now, split off leading numeric components tmprev=`trimrev $val1` if [[ "$tmprev" != " " ]] ; then set $tmprev val1=$1 remainder1=$2 else val1="" ; remainder1="" fi tmprev=`trimrev $val2` if [[ "$tmprev" != " " ]] ; then set $tmprev val2=$1 remainder2=$2 else val2="" ; remainder2="" fi if startsnumeric $val1 && startsnumeric $val2 ; then if [[ $val1 -gt $val2 ]] ; then return 0 fi if [[ $val1 -lt $val2 ]] ; then return 1 fi # have same digits. Do recursion on remainder newer_rev "$remainder1" "$remainder2" return $? fi # Otherwise, we have something like # 1.1alpha vs 1.1beta, I think. # or [1.1] vs [1.1]"beta" # OR 1.1.1 vs 1.1 # Note that if 1.1 vs 1.1.1, second arg will be truncated to ".1". # trimrev will return val2=. and ]remainder2[ will have # the numeric value. # If there is something extra for #1, and not for #2, then # it may be a 'beta' suffix, which means #1 is # OLDER, not newer if [[ "$val2" == "" ]] ; then if startsnumeric $remainder1 ; then return 0 # yes, $1 is greater! else return 1 # nope. got beta or similar suffix: bad fi fi #and now the mirror case if [[ "$val1" == "" ]] ; then if startsnumeric $remainder2 ; then return 1 else return 0 fi fi print "WARNING: 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. get_pkg_versionfield(){ #pkgname="$1" vtmp=`pkginfo -l $1 | awk '$1 == "VERSION:" {print $2}'` if [[ "$vtmp" == "" ]] ; then return 1 fi case $vtmp in *,*) # Arrg. Sun was "creative" with version string 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) # 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 -le 1 ]] ; then print $remver return fi if [[ $do_upgrade -eq 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 [[ $? -eq 0 ]] ; then maxver=$rev fi done print $maxver } #call this with # explain_multiple softwarename MULTIPLE ver1 ver2 explain_multiple_install(){ if [[ $# -lt 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 [[ $# -gt 0 ]] ; do print pkg-get $mode ${software}-$1 shift done } 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 get_filename(){ net_name=`nawk '$1 == "'$1'" && $2 == "'$2'" {print $4}' $CATALOGFILE` if [[ -z "$net_name" ]] ; then print ERROR: could not find filename for $1 $2 >/dev/fd/2 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 # If a specific software name is given, download latest version upgrade() { do_upgrade=1 #global var if [[ "$1" == "" ]] ; then set `egrep -v '^#' $CATALOGFILE | awk '{print $1}'|sort -u` print note: upgrading ALL INSTALLED PACKAGES 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_pkg "$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 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_pkg, 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. # find_pkg_name(){ findname="$1" if [[ "$2" == "" ]] ; then pkgname=`awk '$1 ~ /^#/ {next} $1 == "'$findname'" { print $3 }' $CATALOGFILE` else pkgname=`nawk '$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` # if [[ "$pkgname" != "" ]] ; then # findname="$soft" # fi # print DEBUG: after version decode # print findname=$findname # print pkgname=$pkgname # print find_version=$find_version 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 } # called by install_pkg # 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 # We try to find the actual pkgname from the $CATALOG file # 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) # install_one_pkg(){ if [[ "$1" == "" ]] ; then print INTERNAL ERROR: install_one_pkg has no args 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 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" -eq 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` return fi if [[ "$i_remversion" == "$i_currversion" ]] ; then 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 print "ERROR: remote version older than current version." print "Not installing remote package of $i_sftname" print "(remote=$i_remversion, local=$i_currversion)" return 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 install_pkg(){ 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_pkg "$name" done } # Given a SysV package name, recursively remove *ALL* # instances of it. # silently do nothing, if no instance is installed. remove_sysv_pkg() { rm_pkgname="$1" # Sneaky check for orphaned packages or something # We do NOT LIKE the funny .x instance names of packages if [[ -d /var/sadm/pkg/$rm_pkgname.2 ]] ; then print Removing old instance of $rm_pkgname pkgrm $ADMINFLAG $rm_pkgname.2 fi if [[ -d /var/sadm/pkg/$rm_pkgname ]] ; then print Removing old instance of $rm_pkgname pkgrm $ADMINFLAG $rm_pkgname fi } # Given a common-name for a package, figure out the SysV pkg name # and pkgrm it 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 remove_packages(){ if [[ "$1" == "" ]] ; then print ERROR: no packages given to remove 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. # # return 1 on fail install_dependancies(){ dependlist=`awk ' $1 == "P" {print $2}' $1` for dependpkg in $dependlist ; do pkginfo $dependpkg 2>/dev/null 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. $0 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. # dependname=`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 $dependname # XXX would be nice if we knew a specific version # to install. Otherwise, if multiple, get the newest. if [[ "$url" != "" ]] ; then $0 -s $url upgrade $dependname else $0 upgrade $dependname fi #did it work? pkginfo $dependpkg 2>/dev/null if [[ $? -ne 0 ]] ; then print ERROR: install of $dependpkg failed return 1 fi fi done } # Given a filename for a pkg, gzipped or not, pkgadd it, and # remove the file when done. # We first do a pkgtrans to /var/spool/pkg so we can check # dependancies by HAND. # # 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. install_pkg_file() { filename="$1" file $filename | grep 'compressed ' >/dev/null if [[ $? -eq 0 ]] ; then gzip -d -c $filename >$filename.tmp mv -f $filename.tmp $filename fi pkgname=`nawk 'NR==2 {print $1;exit}' $filename` if [[ $do_upgrade -eq 1 ]] ; then remove_sysv_pkg $pkgname fi # convert from file to to "spool" format, to check depends. # pkgtrans will quit if there already is one there. pkgtrans $filename /var/spool/pkg $pkgname if [[ $? -ne 0 ]] ; then return 1 fi if [[ -f /var/spool/pkg/$pkgname/install/depend ]] ; then install_dependancies /var/spool/pkg/$pkgname/install/depend if [[ $? -ne 0 ]] ; then print ERROR: could not install required dependancies for $pkgname /bin/rm -r /var/spool/pkg/$pkgname return 1 fi fi pkgadd $ADMINFLAG $pkgname status=$? if [[ $status -ne 0 ]] ; then print ERROR: could not add $pkgname. fi rm $filename /bin/rm -r /var/spool/pkg/$pkgname return $status } # grab either gzip or wget "the hard way" # return 0 on okay, 1 on fail ftp_prog_hardway(){ progname="$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 </dev/null if [[ $? -eq 0 ]] ; then return ; fi print "ERROR: gzip not in path. Install(y/n)?" read ans case $ans in y|Y) ;; *) print Quitting exit 1 ;; esac ftp_prog_hardway gzip status=$? if [[ $status -ne 0 ]] ; then print Pkgadd of gzip failed. Cannot continue exit 1 fi print "" return 0 } # Checks if we have wget. If not, tries to get it. # If cannot get, fails entire progam check_wget() { whence wget >/dev/null if [[ $? -eq 0 ]] ; then return ; fi print ERROR: cannot find wget. Attempting to install ftp_prog_hardway wget status=$? if [[ $status -eq 0 ]] ; then print "wget added successfully" print "" return fi print " " Recommend you install wget from print " " $fullurl/'wget*gz' print " " ftp the file, gunzip it, and then print " " 'pkgadd -d wget*' exit 1 } # Currently takes as args # 1. descriptive software name # 2. PKGname # 3. revisionnum # # Currently called by upgradeall, and install_one_pkg # Will download a package, and install it using install_pkg_file() # net_install() { net_name="$1" fullurl=$url/$CPU/$OSREV check_wget graburl=$fullurl/$net_name print trying $graburl case $graburl in *\*) print ERROR: no wildcards allowed in net_install exit ;; esac tmpfile=$net_name.tmp $WGET $graburl >$tmpfile if [[ $? -ne 0 ]] || [[ ! -s $tmpfile ]] ; then print error downloading $graburl rm $tmpfile return fi if [[ "$downloadonly" -eq 1 ]] ; then mv $tmpfile $net_name print downloaded package to $net_name return fi # else... really install install_pkg_file $tmpfile # install_pkg_file will remove tmp file } # This takes info for a SINGLE PACKAGE, and compares it to # what is locally available. # The printout format must match the header in show_installed() # Expects: # compare_pkg softwarename availablerev pkgname compare_pkg() { 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 printf "%15s %15s %15s\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 show_installed() { print "# (From site $SITE )" printf "%15s %15s %15s\n" "software" "localrev" "remoterev" egrep -v '^#' $CATALOGFILE | while read line ; do compare_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. 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 } update_catalog() { OSREV=$OSREV CPU=$CPU TMPDIR=/tmp/pkg.$$ TMPFILE=$TMPDIR/catalog if [[ ! -d /var/pkg-get ]] ; then print Warning: making /var/pkg-get mkdir /var/pkg-get fi check_wget mkdir /tmp/pkg.$$ if [[ $? -ne 0 ]] ; then print error making temp dir rmdir $TMPDIR exit 1 fi print Getting catalog... $WGET $url/$CPU/$OSREV/catalog > $TMPFILE if [[ $? -ne 0 ]] ; then print ERROR: could not get catalog file rm $TMPFILE rmdir $TMPDIR exit 1 fi if [[ ! -s $TMPFILE ]] ; then print ERROR: catalog file is zero length rm $TMPFILE rmdir $TMPDIR exit 1 fi print "Updating catalog file, EXCLUDING gzip" egrep -v '^(gzip)' $TMPFILE >$CATALOGFILE rm $TMPFILE print $CATALOGFILE updated $WGET $url/$CPU/$OSREV/descriptions > $TMPFILE if [[ -s $TMPFILE ]] ; then mv $TMPFILE $DESCFILE print Updated description file else print "Failed to get description file. That's okay, it's optional." rm $TMPFILE fi rmdir $TMPDIR } ################################################### # main routine if [[ "$1" == "" ]] ; then usage exit 1 fi # MUST HAVE gzip! Try to grab, if needed check_gzip ###################################################################### # 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 while getopts "dDs:uUacirhvf" mode_var ; do case $mode_var in d) mode=install downloadonly=1 ;; D) mode=describe ;; v) debug=1 ;; s) url=$OPTARG ;; u) mode=upgrade ;; U) mode=updatecatalog ;; a) mode=available ;; c) mode=compare ;; i) mode=install ;; r) mode=remove ;; f) force=true ;; *) usage exit 1 ;; esac done shift $(($OPTIND - 1 )) ############################################################ # 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) mode=updatecatalog 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 ;; remove|--remove) mode=remove shift ;; moo|--moo) mode=moo shift ;; *) mode=help esac fi ###################################################################### # End of arg-interpretation section. # Now for the action handling, after this one important check SITE=${url##*//} SITE=${SITE%%/*} # Takes the url var and parses out the value for SITE # but also makes sure url is NOT http # because we use wildcard in wget to grab package case $url in ftp://*|http://*) ;; file://*) SITE=localhost ;; *) print ERROR: right now url to the site MUST be ftp:// print $url not acceptible as source location exit 1 ;; esac CATALOGFILE=/var/pkg-get/catalog-$SITE DESCFILE=/var/pkg-get/desc-$SITE if [[ ! -f $CATALOGFILE ]] ; then if [[ "$mode" != "updatecatalog" ]] ; then print "" print WARNING: no catalog file for site $SITE print "Updating catalog file first" update_catalog fi fi # check for special override file that says, "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 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 PAGER=${PAGER:-more} ###################################################################### # 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 # Only call this if you have verified first arg is a directory 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 dir_compare(){ if [[ ! -d "$1" ]] ; then print ERROR: $1 not valid directory return fi shift # This must match up to "dir_compare_one" output. printf "%15s %15s %15s\n" "PKGNAME" "Directory-rev" "Installed-rev" if [[ $# -gt 1 ]] ; then while [[ $# -gt 1 ]] ; do dir_compare_one $1 "$1" done return fi #else for d in $1/* ; do if [[ -d "$d" ]]; then d=${d##*/} dir_compare_one $1 $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 # 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 [[ $? -eq 0 ]] ; then tmpoldver=${tmpoldver#VERSION=} if [[ "$tmpoldver" == "$tmpver" ]] ; then tmpoldver="SAME" fi else tmpoldver="[Not installed]" fi printf "%15s %15s %15s\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 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 [[ $# -gt 0 ]] ; then while [[ $# -gt 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. dir_install_one(){ tmpdir="$1" tmppkg="$2" if [[ -f $tmpdir/$tmppkg/install/depend ]] ; then install_dependancies $tmpdir/$tmppkg/install/depend if [[ $? -ne 0 ]] ; then print ERROR: could not install required dependancies for $tmppkg return 1 fi fi if [[ do_upgrade -eq 0 ]] ; then # Dont bother to upgrade, just install and get out of here. pkgadd $ADMINFLAG -d $tmpdir $tmppkg return $?; fi # otherwise, we're doing the whole nine yards. 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 $ADMINFLAG -d $tmpdir $tmppkg } # Yes, I strive for a high level of compatibility... do_moo() { cat <