#!/bin/sh # # This program copys additional packages within a Product tree to # an existing net install server. # # It is a hacked up version created by chris marget to run under # bourne shell on osx. it makes a lot of assumptions, and isn't # nearly as careful as the version shipped by sun. # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CleanupExit() { [ "$DEBUG" = "true" ] && set -x TurnOffSpinner rm -fr $TMPFILES echo ""; echo "" [ "$1" = "0" ] && echo "Processing completed successfully." || \ echo "Processing did not complete successfully." exit $1 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Usage() { echo "Usage: add_to_install_server [-s] [-p ] " exit 1 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CreateSpinnerProgram() { cat > $SPINNER << EOF #!/bin/sh if [ $# -ge 1 ] then kill \$1 exit fi state=0 while [ 1 ] do case \$state in 0) echo -e "|\b\c" state=1 ;; 1) echo -e "/\b\c" state=2 ;; 2) echo -e "-\b\c" state=3 ;; 3) echo -e "\\\" "\b\b\c" state=0 ;; esac sleep 1 done exit 0 EOF } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TurnOnSpinner() { [ "$DEBUG" = "true" ] && set -x if [ -x $SPINNER ]; then $SPINNER & DIAL_PID=$! fi } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TurnOffSpinner() { [ "$DEBUG" = "true" ] && set -x [ "$DIAL_PID" != "0" ] && kill $DIAL_PID && DIAL_PID=0 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PrintErr() { echo "$@" >&2 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AbsolutePath() { [ "$DEBUG" = "true" ] && set -x typeset -r path=$1 if ! valpath -a $path; then echo "$(pwd)/$path" elif valpath -a $path; then echo "$path" fi } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DetermineProductAreas() { [ "$DEBUG" = "true" ] && set -x # Gather this info from the .cdtoc file #typeset -r cdtoc="$SOURCE/.cdtoc" DPAcdtoc="$SOURCE/.cdtoc" prodDirs=$(GetProdDirs $DPAcdtoc) } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GetProdNames() { #typeset -r cdtoc=$1 GPNcdtoc=$1 awk -F= '/PRODNAME/ {print $2}' $GPNcdtoc } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GetProdDirs() { GPDcdtoc=$1 #typeset -r cdtoc=$1 ############### Use 2nd line of code once RE typo gets fixed grep DIR $GPDcdtoc | awk -F= '{print $2}' #awk -F= '/PRODDIR/ {print $2}' $cdtoc } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DetermineSpaceNeeded() { echo "Skipping disk space check" && echo "" } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GetNonABIpkgs() { [ "$DEBUG" = "true" ] && set -x grep "^:" */pkgmap | awk -F/ '{print $1}' > $TMPFILES/abipkgs \ls > $TMPFILES/allpkgs fgrep -v -f $TMPFILES/abipkgs $TMPFILES/allpkgs rm $TMPFILES/allpkgs $TMPFILES/abipkgs } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GetDUSize() { [ "$DEBUG" = "true" ] && set -x typeset -r nonABIpkg=$1 typeset -i size=0 typeset -i totalSize=0 for pkg in $nonABIpkg; do size=$(du -s $pkg | awk '{print $1}') totalSize=totalSize+size done echo $totalSize } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CheckSource() { [ "$DEBUG" = "true" ] && set -x SOURCE=$(pwd) # if we find a .cdtoc file then we can assume this is a valid CD # to process. [ ! -f ".cdtoc" ] && \ PrintErr "Cannot find the .cdtoc file on $SOURCE" && \ CleanupExit 1 # ADD OTHER CHECKS ONCE THE CD LAYOUT IS COMPLETE } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HandleUsrSelection() { [ "$DEBUG" = "true" ] && set -x typeset -i totalProds=0 DisplayChoiceHeader DisplayProducts "no" typeset result=$(ProcessResult) || return 1 typeset -r cdtoc="$SOURCE/.cdtoc" typeset -r prodDirs=$(GetProdDirs "$cdtoc") for items in $prodDirs; do totalProds=totalProds+1 done CheckEntry "$prodDirs" "$totalProds" "$result" || return 1 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CheckEntry() { [ "$DEBUG" = "true" ] && set -x typeset -r prodDirs=$1 typeset totalProds=$2 typeset result=$3 typeset -i ctr=0 typeset -i num=0 typeset -i atLeastOneSelected=0 for selProd in $prodDirs; do ctr=ctr+1 for num in $result; do (( num > totalProds)) && \ PrintErr "$num is not a valid selection!" && return 1 (( num == ctr )) && \ echo $selProd && \ atLeastOneSelected=1 && \ break done done (( atLeastOneSelected != 1 )) && PrintErr "$result is not valid" \ && return 1 return 0 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ProcessResult() { [ "$DEBUG" = "true" ] && set -x #typeset result=$1 while read result; do echo "" >&2 [ -z "$result" ] && CommonMsg && return 1 [ -n $(echo $result | grep " |,|\n") >/dev/null 2>&1 ] \ && PrintErr "The numbers must be seperated by a space or comma." \ CommonMsg && return 1 [ "$result" = "all" ] && result=$(SelectAllProducts) && break alphas="" alphas=$(echo $result | awk '/[a-z]|[A-Z]/ {print}') [ -n "$alphas" ] && \ PrintErr "Only numbers are valid" && \ CommonMsg && return 1 # OK looks like a valid entry. See if commas are provided result=$(echo $result | sed 's/,/ /g') break done echo "$result" return 0 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SelectAllProducts() { [ "$DEBUG" = "true" ] && set -x typeset -i ctr=0 typeset result typeset -r cdtoc="$SOURCE/.cdtoc" typeset -r prodDirs=$(GetProdDirs "$cdtoc") for i in $prodDirs; do ctr=ctr+1 result="$result $ctr" done echo "$result" } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CommonMsg() { echo "Please enter number(s) or the keyword all" >&2 echo "" } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DisplayProducts() { [ "$DEBUG" = "true" ] && set -x typeset -r suppressCtr=$1 typeset -r cdtoc="$SOURCE/.cdtoc" [ -f $TMPFILES/prdNames.$$ ] && rm -f $TMPFILES/prdNames.$$ GetProdNames "$cdtoc" > $TMPFILES/prdNames.$$ [ "$suppressCtr" = "yes" ] && cat $TMPFILES/prdNames.$$ >&2 \ || cat -n $TMPFILES/prdNames.$$ >&2 echo "" >&2 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DisplayChoiceHeader() { [ "$DEBUG" = "true" ] && set -x echo "" >&2 echo "Enter the number of the product(s) you want to add" >&2 echo "to $TARGET or 'all' for all products." >&2 echo "" >&2 echo "The following are valid products:" >&2 echo "" >&2 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CheckProducts() { [ "$DEBUG" = "true" ] && set -x #typeset -r cdtoc="$SOURCE/.cdtoc" CPcdtoc="$SOURCE/.cdtoc" FINALPRODDIRS=$(GetProdDirs "$CPcdtoc") FINALPRODNAMES=$(GetProdNames "$CPcdtoc") echo "The following Products will be copied to $TARGET:" echo "" echo "$FINALPRODNAMES" echo "" } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CheckTarget() { [ "$DEBUG" = "true" ] && set -x cd $TARGET > /dev/null 2>&1 TARGET=$(pwd) if [ ! -f "$TARGET/.cdtoc" ]; then PrintErr "An existing install server cannot be found at $TARGET." PrintErr "This tool can only add packages to an install server" \ "that already exists." CleanupExit 1 else # construct target from .cdtoc #typeset -r tmpTARGET=$(GetProdDirs "$TARGET/.cdtoc") tmpTARGET=$(GetProdDirs "$TARGET/.cdtoc") TARGET="$TARGET/$tmpTARGET" fi } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CopyEADirectory() { [ "$DEBUG" = "true" ] && set -x EASource="$(dirname $ORIGDIR)/EA" EATarget="$(dirname $TARGET)/EA" [ ! -d $EASource ] && return echo ""; echo "Copying the Early Access products..." [ -d $EATarget ] && rm -fr $EATarget mkdir -m 755 $EATarget cd $EASource find . -print -depth | cpio -pdmu $EATarget } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CopyProducts() { [ "$DEBUG" = "true" ] && set -x for prod in $FINALPRODDIRS; do #typeset pName=$(dirname $prod);pName=$(dirname $pName) #pName=$(basename $pName) #echo "Copying $pName packages..." [ ! -d $SOURCE/$prod ] && \ PrintErr "Can't find $SOURCE/$prod" && \ CleanupExit 1 [ ! -d $TARGET ] && \ PrintErr "Can't find $TARGET" && \ CleanupExit 1 cd $SOURCE/$prod pkgDirs=$(\ls) for pkg in $pkgDirs; do if CheckSrcAndDstPkgs "$pkg" ; then # cp is used instead of 'find ... | cpio' # since this will give us more control # over previously failed attempts cp -pr $pkg $TARGET [ $? != 0 ] && \ PrintErr "cp could not complete the" \ "copy of $pkg" && \ CleanupExit 1 [ -d "$TARGET/.virtual_packages/$pkg" ] && \ rm -fr $TARGET/.virtual_packages/$pkg else PrintErr "Skipping $pkg it has already been copied." fi done done } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GetPkgabbrevVersionArch() { [ "$DEBUG" = "true" ] && set -x pkgDir=$1 awk -F= ' /^VERSION=|^ARCH=|^PKG=/ { print $2} ' $pkgDir/pkginfo } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CheckSrcAndDstPkgs() { [ "$DEBUG" = "true" ] && set -x srcPkg=$1 dstPkg=$TARGET/$srcPkg if [ -d "$dstPkg" ]; then # The pkg already seems to exist check the qualifiers. srcqualifiers=$(GetPkgabbrevVersionArch $srcPkg) dstqualifiers=$(GetPkgabbrevVersionArch $dstPkg) [ "$srcqualifiers" = "$dstqualifiers" ] && return 1 fi return 0 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MergePkgHistory() { [ "$DEBUG" = "true" ] && set -x # First see what pkgs exist in the target install servers .pkghistory # file. If there are no pkgs with the same PKG, ARCH and VERSION # then we can append the source .pkghistory file to the targets. dstPkgHistory="$TARGET/.pkghistory" for prodDir in $FINALPRODDIRS; do srcPkgHistory="$SOURCE/$prodDir/.pkghistory" # First check for the existence of the source .pkghistory [ ! -f "$srcPkgHistory" ] && continue # Check for the PKG variables first. if CheckForMatchingPKGs "$srcPkgHistory" "$dstPkgHistory"; then AppendHistoryFiles "$srcPkgHistory" "$dstPkgHistory" else MergEm "$srcPkgHistory" "$dstPkgHistory" fi done } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CheckForMatchingPKGs() { [ "$DEBUG" = "true" ] && set -x srcPkgHistory=$1 dstPkgHistory=$2 awk -F= '$1 ~ /PKG/ {print $2}' $srcPkgHistory > $TMPFILES/srcpkgs.$$ awk -F= '$1 ~ /PKG/ {print $2}' $dstPkgHistory > $TMPFILES/dstpkgs.$$ result=$(fgrep -f $TMPFILES/srcpkgs.$$ $TMPFILES/dstpkgs.$$) [ -n "$result" ] && return 0 || return 1 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AppendHistoryFiles() { [ "$DEBUG" = "true" ] && set -x srcPkgHistory=$1 dstPkgHistory=$2 cat $srcPkgHistory >> $dstPkgHistory } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Initialize() { echo "" DIAL_PID=0 # Set PATH PATH=/usr/bin:/usr/sadm/bin:/usr/etc:/usr/sbin:${PATH} ORIGDIR=$(pwd) cmdArgs=$* progName=$0 TMPFILES=/tmp/add_to_is.$$ mkdir $TMPFILES SPINNER=$TMPFILES/spinner CreateSpinnerProgram chmod 500 $SPINNER } #~~~~~~~~~~~~~~~~~~~~~ Main ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trap "CleanupExit 1" 1 2 3 15 Initialize $@ TARGET=$1 NOSPACECHK="true" CheckSource CheckTarget CheckProducts TurnOnSpinner DetermineSpaceNeeded CopyProducts CopyEADirectory MergePkgHistory CleanupExit 0