home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-08-11 | 25.6 KB | 1,000 lines |
- :
- # @(#) custom.sh 3.15 88/05/05
- #
- # Copyright (C) The Santa Cruz Operation, 1985, 1986, 1987.
- # This Module contains Proprietary Information of
- # The Santa Cruz Operation and is Confidential.
- #
- # CUSTOM - Xenix System V installation tool
- #
- # Executable dependencies:
- # awk cat comm cpio df env expr find fixperm fsck getopt
- # mount mv pr rm rmdir sed sh sort tr tar umount
- #
- PATH=/bin:/usr/bin:/etc
- # Return codes for init, prep and rmv scripts
- : ${OK=0} ${FAIL=1} ${STOP=10} ${HALT=11}
-
- # export variables that may be used in init scripts
- export mnt prd rdev bdev rel vol typ
-
- # root directory, must be non-null, must work w/ xnx-net (// -> mch name)
- # and w/ # directory names (e.g., /mnt)
- case $CUSTOMROOT in
- //*) echo "Invalid root directory." >&2 ; exit $FAIL ;;
- */) ;; # ok
- "") CUSTOMROOT=/ ;;
- *) CUSTOMROOT=$CUSTOMROOT/ ;;
- esac
- # home of init scripts, may be null
- : ${CUSTOMINIT="${CUSTOMROOT}tmp/init.*[!%]"}
- # home of prep scripts, may be null
- : ${CUSTOMPREP="${CUSTOMROOT}tmp/perms/prep.*[!%]"}
-
- # set defaults - all paths are relative to CUSTOMROOT
- last=4 lst=4 # last item on set menu
- quit=quit # q option printed by prompt
- tmp=${CUSTOMROOT}tmp/cus$$ # temporary file name prefix
- defdev=${CUSTOMROOT}dev/install # default device for mounting filesystems
- defrdev=${CUSTOMROOT}dev/rinstall # default device for extracting tar volumes
- defmnt=N01 # default list of mountable volumes
- null=${CUSTOMROOT}dev/null # bit sink for unwanted error messages
- lib=${CUSTOMROOT}usr/lib/custom # home of removal scripts
- pfx=./tmp/_lbl # software label prefix
- ser="${CUSTOMROOT}tmp/*.ser" # serialization files created by init scripts
- retn="\007\nand press <RETURN> " # common in prompts
-
- # must be at root
- cd $CUSTOMROOT
-
- # known permlist names
- perms="*/\*|*/inst|*/rts|*/ext|*/dsmd|*/soft|*/tpmd|*/text"
-
- (set -h) 2> $null || {
- echo "$0: must be invoked with System V shell" >&2
- exit 1
- }
- # Remember functions as they are defined
- set -h
-
- # Print error message
- error() {
- echo "\nError: $*" >&2
- return 1
- }
-
- warngetyn() {
- echo "\nWarning: $*\nDo you wish to continue? (y/n) \c" >&2
- getyn
- }
-
- # Remove temp files and exit w/ argument as status
- cleanup() {
- trap '' 1 2 3 15
- rm -f $CUSTOMINIT $CUSTOMPREP $tmp* $ser
- exit $1
- }
-
- # Initialize list of packages in current set
- getsetlist() {
- [ "$notty" ] && return 0
- echo > $tmp.$sid "
- Name Inst Size $set packages
- --------------------------------------------------------------------"
- fixperm -iv $ignorepkgs $perm |
- sed "s/^\(.*\) .*$/s:^#!\1[ ][ ]*: & :p/" > $tmp.fl
- sed -n -f $tmp.fl $perm >> $tmp.$sid
- }
-
- # Update package list after installation or removal
- # Can't use $ignorepkgs here (much as I'd like to) since fixperm considers
- # having a -u AND a -d a fatal error, so I've got $lpkgs which indicates
- # exactly those things pertinent to the report of "No, Part, All" status
- updatesetlist() {
- [ "$notty" -o ! -f $tmp.$sid ] && return 0
- fixperm -iv $lpkgs $perm |
- sed "s/^\(.*\) .*$/s:\1 [^ ]*:&:/" > $tmp.fl
- sed -f $tmp.fl $tmp.$sid > $tmp.tl
- mv $tmp.tl $tmp.$sid
- }
-
- # Usage: logit [status]
- # Add a record to the system installation history file
- # Argument overrides current status variable
- logit() {
- trap 'intr=true' 1 2 3 15
- echo "date=\"`date`\" \\
- prd=$prd rel=$rel upd=$upd typ=$typ set=\"$set\" \\
- action=$action status=\"${*:-${status:-"Successful"}}\" \\
- pkgs=\"$spkgs\"\n" >> $lib/history
- status=
- [ "$intr" = true ] && cleanup 1
- trap 'cleanup 1' 1 2 3 15
- }
-
- # Usage: addstat status
- # Add argument to current status variable
- addstat() {
- [ "$status" ] && status="$status, $*" || status="Failed: $*"
- }
-
- # Set trap to log interrupts along w/status info (spkgs are pkgs for status log)
- setlogtrap() {
- action= # action (Installation or Removal)
- status= # status of action
- spkgs= # pkgs/files being manipulated
- intr= # flag for interrupts during logit exec
- trap 'addstat Interrupted; logit; cleanup 1' 1 2 3 15
- }
-
- # Prompt with arguments, return non-zero on q
- # -x and +x toggle debug mode
- # ! gets shell escape (can modify current shell)
- # anything else is returned in $cmd
- prompt() {
- while echo "\n${*}or enter q to $quit: \c" >&2
- read cmd
- do case $cmd in
- +x|-x) set $cmd ;;
- Q|q) return 1 ;;
- !*) eval `expr "$cmd" : "!\(.*\)"` ;;
- *) return 0 ;;
- esac
- done
- }
-
- # Mount a filesystem and clean if necessary
- # Returns non-zero on failure
- mntvol() {
- until mount -r $dev /mnt 2> $null
- do [ $? = 2 ] && fsck -y $dev || {
- addstat Extract
- error "corrupted or non-filesystem volume"
- return 1
- }
- done
- }
-
- # Usage: getsetvals sid [vkey|perm]
- # Set all values needed for specified set - called frequently.
- # Can be used to associate a permlist with a keyletter and vice-versa.
- # Default keyletter (vkey) will be used for os, ds, or tp if not specified.
- # Update permlists must be named $prd.$upd where upd=$vkey to work properly.
- getsetvals() {
- # clear all values
- set= perm= lbl= vkey= typ= ver= prd= upd= rel=
- # these values have reasonable defaults
- mnt=$defmnt dev=$defdev rdev=$defrdev
- ignorepkgs="-uINIT -uPERM"
- case $1 in
- 0) eval $k0 perm=$k0perm
- ;;
- 1) set="Operating System" prd=xos
- ignorepkgs="-uINIT -uPERM -uSER1 -uSER2 -uSER3 -uSER4 -uFD48\
- -uFD96 -uHD1 -uHD1AD -uHD1WD -uHD2 -uHD3"
- N=./etc/inst.perms B=./etc/rts.perms X=./etc/ext.perms
- perm="$N $B $X $k1perm" lbl=$set
- case $2 in
- $N|N|"") vkey=N
- lbl="$set (Installation)" ;;
- $B|B) vkey=B
- lbl="$set (Basic Utilities)" ;;
- $X|X) vkey=X
- lbl="$set (Extended Utilities)" ;;
- *U*) updtvkey $2
- lbl="$set (Update)" ;;
- esac
- eval eval \$k1$vkey
- ;;
- 2) set="Development System" prd=xds
- N=./etc/dsmd.perms D=./etc/soft.perms
- perm="$N $D $k2perm" lbl=$set
- case $2 in
- $N|N) vkey=N
- lbl="Operating System (Installation)" ;;
- $D|D|"") vkey=D ;;
- *U*) updtvkey $2
- lbl="$set (Update)" ;;
- esac
- eval eval \$k2$vkey
- ;;
- 3) set="Text Processing System" prd=xtp
- N=./etc/tpmd.perms T=./etc/text.perms
- perm="$N $T $k3perm" lbl=$set
- case $2 in
- $N|N) vkey=N
- lbl="Operating System (Installation)" ;;
- $T|T|"") vkey=T ;;
- *U*) updtvkey $2
- lbl="$set (Update)" ;;
- esac
- eval eval \$k3$vkey
- ;;
- 4) # New add-on products have permlist in ./tmp/perms
- set="distribution" perm="./tmp/perms"
- lbl=$set
- ;;
- [4-$lst]|[$tens][$ones])
- # Supported products already installed
- savid=$1
- case $2 in
- *U*) updtvkey $2 ;;
- esac
- eval eval \$k$savid$vkey
- eval perm=\$k${savid}perm
- unset savid
- lbl=$set
- ;;
- *) return 1
- ;;
- esac
- return 0
- }
-
- # Usage: getperms
- # $perm should be set on entry to this routine.
- # If any member of $perm is not found then try to install it.
- # Return non-zero on errors or failure to install a permlist.
- getperms() {
- for h in $perm
- do [ -f $h ] && continue
- # getsetvals finds vkey
- getsetvals $sid $h
- echo "\nInstalling custom data files ... \c" >&2
- vol=${vkey}01
- until prompt "\nInsert $lbl volume ${vkey}1$retn" || return 1
- chkswlabel noperm
- do case $? in
- 1) continue ;;
- 4) echo "\nThis volume is not custom installable."
- echo "Please consult your installation notes."
- return 1 ;;
- *) error "getperms $?"
- return 1 ;;
- esac
- done
- extract $h || return 1
- # $h might be a directory for new products
- [ -d $h ] && return 0
- fixperm -c -dPERM $h
- done
- }
-
- # Check for release, version, etc. in permlists
- # sid must be set on entry
- checkperms() {
- # getsetvals finds permlist names
- getsetvals $sid
- for i in $perm
- do # getsetvals finds vkey
- getsetvals $sid $i
- eval k$sid$vkey='`getpermvals $i`'
- done
- }
-
- # Usage: getpermvals files
- # Extract lines beginning w/ #name=value and print name=value pair on stdout
- getpermvals() {
- sed -n '/^#set=/s/#//p
- /^#prd=/s/#//p
- /^#ver=/s/#//p
- /^#typ=/s/#//p
- /^#rel=/s/#//p
- /^#mnt=/s/#//p
- /^#dev=/s/#//p
- /^#rdev=/s/#//p
- /^#lbl=/s/#//p
- /^#upd=/s/#//p' $*
- }
-
- # Set values from label as local variables; ignore errors.
- getswlabel() {
- # clear all values
- _prd= _ver= _upd= _typ= _rel= _vol=
- eval 'case $vol in
- '${mnt:-!}') mntvol || return 1
- eval `find /mnt/$pfx -type f -print | pathtovals`
- umount $dev ;;
- *) eval `tar tqnf $rdev $pfx 2> $null | pathtovals` ;;
- esac'
- }
-
- # Convert a path of the form ./tmp/_lbl/name=val/name=val ...
- # to shell variables w/ leading underscores and print on stdout.
- pathtovals() {
- sed -n "s|^.*$pfx||
- s|/| _|gp"
- }
-
- # Check volume number, release, and version; returns:
- # 1 - wrong volume
- # 2 - update needed but not wanted
- # 3 - update attempted
- # 4 - missing volume label
- chkswlabel() {
- noperm=$1
- # get set/vkey specific values from permlist
- getsetvals $sid $vkey
- # set values from the label
- getswlabel || return 1
- # if no permlist present, assume values are correct
- [ "$noperm" ] && prd=$_prd ver=$_ver typ=$_typ rel=$_rel
- # compare permlist and label values
- case $_prd in
- $prd) # product matches
- ;;
- xnxsv) # forever correcting for our youth ...
- case $prd in
- xos|xds|xtp) : installing 2.1 vols ;;
- *) error "incorrect product in drive"
- return 1 ;;
- esac ;;
- xos|xds|xtp) # more youthful corrections ...
- case $prd in
- xnxsv) : updating from 2.1 to 2.2 ;;
- *) error "incorrect product in drive"
- return 1 ;;
- esac ;;
- "") error "volume label not found"
- return 4 ;;
- *) error "incorrect product in drive"
- return 1 ;;
- esac
-
- for i in $_typ $_ver
- do case $i in
- $typ|$ver) # type and/or version matches
- break ;;
- *) warngetyn "product type in drive (${_typ:-$_ver}) is
- different than previously installed type (${typ:-$ver})." && break
- return 1 ;;
- esac
- done
-
- case $_vol in
- $vol|$_upd$vol) : volume number matches ;;
- *) error "incorrect volume in drive"
- return 1 ;;
- esac
-
- [ "$rel" = "$_rel" ] && return 0
- # || there is a permlist from an old release, vkey is correct,
- # and noperm is not a consideration.
- # Do not proceed if we are updating the release.
- [ "$nest" = y ] && {
- error "volume ${vkey}1 must be Release $rel"
- return 1
- }
- nest=y
- echo "\nUpdating custom data files ... \c" >&2
- # Permlists always on volume ?01
- [ "$_vol" != "${vkey}01" ] && {
- # Volume containing permlist must be new release
- eval k$sid$vkey="rel=$_rel\ \$k$sid$vkey"
- vol=${vkey}01
- until prompt "\nInsert $lbl volume ${vkey}1$retn" || {
- nest=
- return 2
- }
- chkswlabel
- do case $? in
- [14]) continue ;;
- [!2]) error "chkswlabel $?" ;;
- esac
- nest=
- return 2
- done
- }
- nest=
- if [ "$sid" -lt 4 ]; then
- # only extract perms matching vkey
- eval extract \$$vkey || return 2
- eval fixperm -c -dPERM \$$vkey
- else
- # add on product perms live in the directory ./tmp/perms
- rm -rf ./tmp/perms
- extract ./tmp/perms && execinit $CUSTOMPREP &&
- countperms ./tmp/perms/* || return 2
- mv ./tmp/perms/* $perm
- rm -rf ./tmp/perms
- fi
- echo >&2
- # spkgs is not applicable when only the permlist was updated.
- # spkgs gets reset using $save in the calling function.
- spkgs=
- logit "Updated custom datafiles"
- return 3
- }
-
- # Usage: execinit files
- # Move files to unique names and execute them.
- # This is trickier than it seems. We cannot simply append our pid
- # since children must remove all files matching init.* except these.
- # Returns exit status of last file executed.
- # Scripts are passed the argument "-c" to indicate that they were
- # invoked by custom. Execute with "sh -c" because they may be binaries,
- # but we have space problems if scripts are executed in the current shell.
- execinit() {
- [ -x $lib/execinit ] && {
- $lib/execinit $*
- return $?
- }
- # append % to scripts prevent children from removing them
- for i do [ -x $i ] && mv $i $i% && ilist="$ilist $i"; done
- j=0
- for i in $ilist
- do sh -c "$i% -c"; j=$?
- case $j in
- $OK) : All is well ;;
- $STOP) logit "Stopped by Init/Prep Script"
- unset ilist; return $STOP ;;
- $HALT) error "haltsys not supported" ;;
- $FAIL) addstat "Init/Prep Script"; error "$i failed" ;;
- esac
- rm -f $i%
- done
- unset ilist
- return $j
- }
-
- # Prompt for yes or no answer - returns non-zero for no
- getyn() {
- while read yn
- do case $yn in
- [yY]) return 0 ;;
- [nN]) return 1 ;;
- *) error "enter either y or n" ;;
- esac
- done
- }
-
- # Extract a list of files - returns non-zero on failure
- extract() {
- case $1 in
- -F) shift; flags=F ;;
- *) flags= ;;
- esac
- filelist=$*
- eval 'case $vol in
- '${mnt:-!}') mntvol || return 1
- until (cd /mnt; tar cf$flags - $filelist) | tar xf -
- do error "extraction failed: try again? (y/n) \c"
- getyn && continue
- umount $dev
- return 1
- done
- umount $dev ;;
- *) until tar xnf$flags $rdev $filelist
- do error "extraction failed: try again? (y/n) \c"
- getyn || return 1
- done
- esac'
- unset filelist flags
- }
-
- # Usage: updtvkey [vkey|permlist]
- # Get vkey corresponding to an update for a supported product
- # vkey is set to either the suffix of the argument (ie vkey=UA
- # for lyrix.UA), or the entire argument if no suffix exists.
- updtvkey() {
- ifs=$IFS; IFS=.
- set -- ${*?}
- IFS=$ifs; unset ifs
- eval vkey=\$$#
- }
-
- # Get vkey from 1st letter of argument and create pvol
- # pvol has leading zero stripped and is for prompts only
- # (can't take multiple arguments, so always uses first arg for safety)
- getvkey() {
- vkey=`expr $1 : "\(.*\).."`
- pvol=$vkey`expr $1 : "${vkey}0*\(.*\)"`
- }
-
- # countperms - passed a list of permlists as arguments
- # returns ok if only one is found
- countperms() {
- case $# in
- 0) error "missing custom data files" ;;
- 1) [ -f $1 ] && return 0 ;;
- *) error "multiple custom data files" ;;
- esac
- return 1
- }
-
- # convert the argument passed in from a set name to a set id
- # returns either the sid or zero if no legal conversion can be made
- nametosid() {
- j=$1
- for i in 1 2 3 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
- do getsetvals $i || return 0
- [ "$j" = "$prd" ] && return $i
- done
- error "nametosid search overrun"
- }
-
- # check ./etc/perms for new set to add to menu
- # returns zero if no new sets were found, otherwise returns
- # the sid of the last new set found.
- chkfornewsets() {
- stat=0
- # only check if forced (-f) or if no check done yet
- [ "$setchkdone" = y -a "$1" != -f ] && return $stat
- for h in ./etc/perms/*
- do eval "case $h in $perms) continue; esac"
- # add perm to known list and get values from it
- perms="$perms|$h" k0perm=$h
- k0=`getpermvals $k0perm`
- # are the required values all there?
- getsetvals 0
- [ "$set" -a "$prd" -a "$rel" ] || {
- error "invalid custom data file: $k0perm"
- continue
- }
- # new sets are added to menu, but updates are not
- if [ "$upd" ]; then
- # allow product it updates to be different from
- # "#prd=" in the permlist, as in case of files in
- # tpmd and dsmd
- case $k0perm in
- *.$upd) prdname=`expr $k0perm : "\./etc/perms/\(.*\)\.$upd"`
- ;;
- *) prdname=$prd
- ;;
- esac
- # find the sid of the product it updates
- if nametosid $prdname; then
- error "update for unknown product: $k0perm"
- else # save sid and reset to update values
- stat=$?; getsetvals 0
- # add to product $perm and save update values
- eval k${stat}perm="\$k${stat}perm\ $k0perm" \
- k${stat}$upd='$k0'
- fi
- else
- last=`expr $last + 1`
- eval k$last='$k0' k${last}perm=$k0perm
- lst=$last newsets="$newsets$last. $set\n\t"
- stat=$last
- fi
- done
- # allow for more than ten sets to be added
- [ $last -gt 9 ] && {
- tens="1-`expr $last / 10`"
- ones="0-`expr $last % 10`"
- lst=9
- }
- setchkdone=y
- return $stat
- }
-
- listpkgs() {
- cat $tmp.$sid
- echo "\nPress <RETURN> to continue \c" >&2
- read i
- }
-
- printhelp() {
- pr -ptl24 $lib/help
- echo "\nPress <RETURN> to continue \c" >&2
- read i
- }
-
- installpkgs() {
- action=Installation
- cmd=$*
- [ "$cmd" ] || {
- cat $tmp.$sid
- prompt "Enter the package(s) to install\n" || return 1
- }
- pkgs= regx= not= save=$cmd lpkgs=
- for i in `echo $cmd | tr "[a-z]" "[A-Z]"`
- do case $i in
- RTS|INST) if [ $CUSTOMROOT = / ]; then
- error "Re-installing $i is not supported"
- else # allow RTS installation on alternate root
- pkgs="$pkgs -d$i" regx=${regx}${regx:+"|"}$i
- lpkgs="$pkgs"
- spkgs="$spkgs${spkgs:+' '}$i"
- fi ;;
- ALL) pkgs="-uRTS -uPERM -uINIT -uINST -uSER1 -uSER2 -uSER3 \
- -uSER4 -uFD48 -uFD96 -uHD1 -uHD1AD -uHD1WD -uHD2 -uHD3"
- regx=$i
- # subtract size of RTS, INST and PERM from ALL
- not='$1 ~ /^#!(RTS|INST|PERM)$/ { s -= $2 }'
- lpkgs="-uPERM -uINIT -uSER1 -uSER2 -uSER3 -uSER4 \
- -uFD48 -uFD96 -uHD1 -uHD1AD -uHD1WD -uHD2 -uHD3"
- spkgs=ALL
- break ;;
- *) pkgs="$pkgs -d$i" regx=${regx}${regx:+"|"}$i
- lpkgs="$pkgs"
- spkgs="$spkgs${spkgs:+' '}$i" ;;
- esac
- done
- [ "$pkgs" ] || return 1
-
- # put the contents list for each volume into a separate file
- > $tmp.fl; > $tmp.tl; > $tmp.ul
- fixperm -fw $pkgs $perm |
- sort -u +1 +0 |
- awk '$2 <= 0 { next } # missing or zero vol field
- $2 != vol { if (vol) print "EOF" vol
- vol = $2
- print "cat>" t vol "<<\EOF" vol
- # put N and upgrade volumes in separate files
- if (vol ~ /N+/)
- print vol >> (t "tl")
- else if (vol ~ /U+/)
- print vol >> (t "ul")
- else
- print vol >> (t "fl")
- }
- { print $1 }
- ' t=$tmp. - |
- sh || { addstat "Fixperm/File List"; return 0; }
-
- [ -s $tmp.fl -o -s $tmp.tl -o -s $tmp.ul ] || {
- error "$set has no package(s) named $cmd"
- return 1
- }
-
- size=`awk "\\$1 ~ /^#!($regx)$/ { s += \\$2 }
- $not
- END { print s+0 }" $perm`
- set -- `df /dev/root` # third arg is free space
- [ "$size" -gt "$3" ] && {
- warngetyn "$size blocks are required and only
- $3 blocks are available on the root filesystem." || return 1
- }
- unset size
- rm -f $CUSTOMINIT
- # extract generic, then non-generic (N), then update (U) volumes
- for vol in `cat $tmp.fl $tmp.tl $tmp.ul`
- do getvkey $vol
- # get lbl string for prompt
- getsetvals $sid $vkey
- until prompt "Insert $lbl volume $pvol$retn" || {
- addstat "Quit at vol $pvol"
- return 0
- }
- chkswlabel
- do case $? in
- 1|4) continue ;;
- 2) addstat "Improper Data File"
- return 0 ;;
- 3) # evaluate new permlist and redo cmd
- checkperms; installpkgs $save; getsetlist
- return 0 ;;
- esac
- done
- echo "Extracting files ... \c" >&2
- extract -F $tmp.$vol || addstat Extract
- echo >&2
- execinit $CUSTOMINIT || { [ $? = $STOP ] && break; }
- done
- echo "Checking file permissions ... \c" >&2
- fixperm -c $pkgs $perm || addstat Fixperm
- updatesetlist
- echo >&2
- }
-
- removepkgs() {
- action=Removal
- cmd=$*
- [ "$cmd" ] || {
- cat $tmp.$sid
- prompt "Enter the package(s) to remove\n" || return 1
- }
- pkgs= upkgs= rmvp=
- for i in `echo $cmd | tr "[a-z]" "[A-Z]"`
- do case $i in
- RTS|PERM|INST) error "cannot remove $i package";;
- ALL) pkgs="-uRTS -uPERM -uINIT -uINST -uSER1 -uSER2 -uSER3 \
- -uSER4 -uFD48 -uFD96 -uHD1 -uHD1AD -uHD1WD -uHD2 -uHD3"
- upkgs="-dRTS -dINST -dPERM"
- lpkgs="-uPERM -uINIT -uSER1 -uSER2 -uSER3 -uSER4 \
- -uFD48 -uFD96 -uHD1 -uHD1AD -uHD1WD -uHD2 -uHD3"
- spkgs=ALL
- rmvp=ALL
- break ;;
- *) pkgs="$pkgs -d$i"
- lpkgs="$pkgs"
- upkgs="$upkgs -u$i"
- spkgs="$spkgs${spkgs:+' '}$i"
- rmvp="$rmvp $i" ;;
- esac
- done
- [ "$pkgs" ] || return 1
- fixperm -fg $pkgs $perm | sort > $tmp.fl
- [ -s $tmp.fl ] || {
- error "$set has no package(s) named $cmd"
- return 1
- }
- # make sure that $prd is set!
- getsetvals $sid
- # execute product specific removal scripts (may be keyed)
- for i in $lib/$prd.rmv $lib/$prd[A-Z].rmv $lib/$prd[A-Z][A-Z].rmv
- do [ -x $i ] || continue
- sh -c "$i $rmvp"
- case $? in
- $OK) ;;
- $STOP) addstat "Remove Script"
- error "$rmvp removal aborted"
- return 0 ;;
- $HALT) error "haltsys not supported " ;;
- *) addstat "Remove Script"
- error "$rmvp removal failed" ;;
- esac
- done
- # create list of files not to be removed since they exist in
- # packages not being removed
- # if removing "ALL", then don't need to weed out UPD.$upd files
- # from this list
- [ "$rmvp" = "ALL" ] || {
- for i in $perm
- do updtvkey $i # set vkey to perm suffix
- case $vkey in # add only if an update
- U*) upkgs="$upkgs -uUPD.$vkey" ;;
- esac
- done
- }
- fixperm -fg $upkgs $perm > $tmp.tl
- unset rmvp
- # check all installed perms since some files cross set boundaries
- for i in 1 2 3 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
- do getsetvals $i || break
- [ $i != $sid ] && cat -s $perm
- done | fixperm -fg - >> $tmp.tl
- # reset values to real sid
- getsetvals $sid
-
- # remove the files that are not in more than one package
- # but do not exceed max argument list size
- sort -y $tmp.tl |
- comm -23 $tmp.fl - |
- awk 'BEGIN { ORS=" "; print "/bin/rm -f"; }
- { if ((argsiz += length) > 2500) {
- print ";/bin/rm -f", $0
- argsiz = length
- } else print
- }' |
- env - HZ=$HZ sh || addstat Removal
- # remove empty directories, if any
- rmdir `fixperm -D $pkgs $perm | sort -r` 2> $null
- updatesetlist
- return 0
- }
-
- listfiles() {
- cmd=$*
- [ "$cmd" ] || {
- cat $tmp.$sid
- prompt "Enter the package(s) to list\n" || return
- }
- pkgs=
- for i in `echo $cmd | tr "[a-z]" "[A-Z]"`
- do case $i in
- ALL) pkgs="-uINST"; break ;;
- *) pkgs="$pkgs -d$i" ;;
- esac
- done
- [ "$pkgs" ] || continue
- [ -t ] && echo "\nPress <RETURN> each time the bell rings\n" >&2
- fixperm -l $pkgs $perm | pr -2ptl12 ||
- error "$set has no package(s) named $cmd"
- }
-
-
- installfile() {
- action=Installation
- cmd=$1 # single file only supported
- [ "$cmd" ] || {
- prompt "Enter the pathname of the file to install\n" || return 1
- }
- set -- "$cmd" # quotes allow null $cmd
- cmd=$1 # single file only supported
- case $cmd in
- "") return ;;
- ./*) file=$cmd ;;
- /*) file=.$cmd ;;
- *) file=./$cmd ;;
- esac
- spkgs="$file"
- > $tmp.vol
- fixperm -fw $perm | sed -n "s!^$file[ ][ ]*!!p" |
- sort -u -r | while read vol # sort -r: U before N
- do
- echo $vol > $tmp.vol
- case $vol in # will keep looping
- U*|N*) break ;; # until finds U, or N
- esac # or end of list
- done
-
- read vol < /tmp/cus$$.vol
- [ "$vol" ] || {
- error "$set has no file named $file"
- return 1
- }
- rm -f $tmp.vol
- getvkey $vol
- until prompt "Insert $lbl volume $pvol$retn" || return 1
- chkswlabel
- do case $? in
- 1|4) continue ;;
- 2) addstat "Improper Data File"
- return 0 ;;
- 3) # evaluate new permlist after completing cmd
- checkperms; installfile $file; getsetlist
- return 0 ;;
- esac
- done
- echo "Extracting $file ... \c" >&2
- extract $file || addstat Extract
- echo >&2
- unset file
- }
-
- diskusage() {
- bar="------------------------------------------------------"
- echo "\n\t\tCurrent Disk Usage\n$bar\n`df -v`\n$bar" >&2
- unset bar
- }
-
- # select a new set by menu
- # returns non-zero on q
- setmenu() {
- # save old set id in case user quits without selecting new one
- save=$sid
- chkfornewsets
- while :
- do prompt "
- 1. Operating System
- 2. Development System
- 3. Text Processing System
- 4. Add a Supported Product
- $newsets\nSelect a set to customize "
- case $cmd in
- [1-$lst]|[$tens][$ones])
- setselect $cmd || continue
- [ -f $tmp.$sid ] || getsetlist
- return 0 ;;
- [qQ]) [ "$save" ] && setselect $save
- return 1 ;;
- *) error "enter 1 through $last or q" ;;
- esac
- done
- }
-
-
- # usage: setselect sid
- # The global set id (sid) is set argument.
- # sid can only be reset in this routine.
- setselect() {
- sid=$1
- case $sid in
- [1-3]) # builtin sets
- chkfornewsets
- getsetvals $sid
- getperms && checkperms
- ;;
- 4) # add a supported product
- chkfornewsets
- getsetvals $sid
- rm -rf $perm
- getperms && execinit $CUSTOMPREP || return 1
- countperms $perm/* || return 1
- i=`cd $perm; echo *`
- [ -f ./etc/perms/$i ] && {
- error "./etc/perms/$i already exists"
- return 1
- }
- mv $perm/$i ./etc/perms/$i
- rm -rf $perm
- # chkfornewsets prints an error if perm is invalid
- chkfornewsets -f && return 1 || sid=$?
- [ "$upd" ] && {
- # ensure all perms in set are installed
- getsetvals $sid $upd
- getperms && checkperms
- # install entire update
- installpkgs UPD.$upd && logit || return 1
- # cause list of packages to be regenerated
- rm -f $tmp.$sid
- }
- getsetvals $sid
- ;;
- [0-9]*) chkfornewsets
- getsetvals $sid || error "invalid set number: $sid"
- ;;
- *) # set was specified by name
- chkfornewsets
- nametosid $sid && error "unknown set name: $sid" || sid=$?
- ;;
- esac
- return $?
- }
-
-
- # main()
-
- # Initialize variables
- perm= arg= vkey= set= setflg= cmdflg= setchkdone= tens=z
- sid= nest= save= cmd= pvol= argflg= notty= ones=z
- ignorepkgs=
-
- # (already at root)
- # evaluate arguments
- [ $# != 0 ] && {
- set -- `getopt odtirlfs:m: $*` || {
- echo "Usage: custom [-s set] [-ilr [pkgs]] [-f [file]] [-m rdev]" >&2
- exit 1
- }
- while case $1 in
- -o) setflg=1 ;;
- -d) setflg=2 ;;
- -t) setflg=3 ;;
- -s) setflg=$2; shift ;;
- -i) cmdflg='setlogtrap;installpkgs $arglst && logit';;
- -r) cmdflg='setlogtrap;removepkgs $arglst && logit' ;;
- -l) cmdflg='listfiles $arglst' ;;
- -f) cmdflg='setlogtrap;installfile $arglst && logit';;
- -m) defdev=$CUSTOMROOT`echo $2 | sed "s:^/*::"`
- [ -c $defdev -o -b $defdev ] || {
- error "$defdev not a valid device"
- exit $FAIL
- }
- defrdev=$defdev
- shift ;;
- --) shift; break ;;
- esac
- do shift
- done
- arglst="$*"
- }
- trap 'cleanup 1' 1 2 3 15
-
- # is everything here? if so we are fully non-interactive
- [ "$setflg" -a "$cmdflg" -a "$arglst" ] && {
- notty=y
- setselect $setflg || exit 1
- eval $cmdflg
- cleanup $?
- }
-
- # if a valid set was given, generate a list of pkgs,
- # otherwise user must select a valid set now
- [ "$setflg" ] && setselect $setflg && getsetlist || setmenu || cleanup 0
-
- # if a cmd was given, execute it
- eval $cmdflg
-
- unset setflg cmdflg arglst
- quit="return to the menu"
-
- # central processing loop
- while echo "
- 1. Install one or more packages
- 2. Remove one or more packages
- 3. List the available packages
- 4. List the files in a package
- 5. Install a single file
- 6. Select a new set to customize
- 7. Display current disk usage
- 8. Help
-
- Select an option or enter q to quit: \c" >&2
- do read cmd arg
- case $cmd in
- 1) setlogtrap; installpkgs $arg && logit ;;
- 2) setlogtrap; removepkgs $arg && logit ;;
- 3) listpkgs ;;
- 4) listfiles $arg ;;
- 5) setlogtrap; installfile $arg && logit ;;
- 6) setmenu $arg ;;
- 7) diskusage ;;
- 8) printhelp ;;
- Q|q) cleanup 0 ;;
- *) error "enter 1 through 8 or q" ;;
- esac
- done
-