cdesktopenv/cde/programs/dtksh/ksh93/ship/shipout

1909 lines
38 KiB
Plaintext
Executable File

:
# @(#)shipout (gsf@research.att.com) 07/17/95
#
# shipout [ options ... ] [ name ... ] [ tool ... ]
#
# ship software to recipient using system|user info in $SHIPINFO
#
# options -- + turns the corresponding option off
#
# -b ship bases with deltas
# -c don't generate tool closure
# -d don't ship deltas
# -i list info on specified recipient(s) only
# -k mark recipient(s) as having received tool(s)
# -l file list of people to ship to
# -m don't send shipment manifest mail message
# -n show but don't execute
# -o set shipment ownership to shipper
# -p name next argument is a recipient to ship to
# -s don't send shipment support files
# -t don't execute but show total shipment
# -u [[yy]mm]dd ignore db info for date pattern
# -v yymmdd override current date stamp
# -w shipment suitable for www
# -x format pax output format and compression
# -C files add to default crate file list
# -D secs delay in seconds between sends
# -F force db override
# -S files add to default support file list
#
# name -- recipient address
#
# machine!user uucp address
# host:directory rcp address
# *%[beta.]bin[.arch] compressed cpio binary archive in Z/*[.arch]
# *%ftp sh script with ftp get's on stdout
# *%[beta.]lib[.arch] compressed cpio binary archive in Z/*[.arch]
# *%list shipment file list on stdout
# *%pull sh script with datakit pull's on stdout
# *%push sh script with datakit push's on stdout
# *%[beta.]src compressed cpio src archive in Z/*
#
# the message file is evaluated by the shell and the following variables
# are predefined by ship:
#
# f list of expanded file names
# name name of shipee
#
umask 02
PATH=:$PATH
SHIPSLOG=${SHIPSLOG:-shipslog}
SHIPINFO=${SHIPINFO:-$SHIPSLOG/info}
SHIPFILES="README shipin shipout"
SHIPAUX="shipiffe.sh shipop.c shipproto.c"
SHIPMENT=*[0-9][0-9][0-9][0-9][0-9][0-9]
SHIPPER=${SHIPPER:-${USER:-${LOGNAME:-${HOME##*/}}}}
SHIPSPOOL=${SHIPSPOOL:-/usr/spool/uucppublic}
SHIPORG=${SHIPORG:-"Software and Systems Research"}
SHIPLOGO=${SHIPLOGO:-"http://www1126.research.att.com/logos/attbllogo.gif align=middle"}
SHIPMM2HTML=${SHIPMM2HTML:-mm2html}
CRATEFILES="copyright items message promo release report"
TMP=${TMPDIR:=/tmp}/ship$$
FROMSYS=$( (uname -n || hostname || cat /etc/whoami) 2>/dev/null )
test -f shipinit && . ./shipinit
function errexit
{
# print out an error message on unit 2 and exit
print -u2 - "$command: $@"
exit 1
}
function warning
{
print -u2 - "$command: warning: $@"
}
function cleanup # exitcode
{
trap - EXIT INT TERM
db_done
rm -f $TMP.?
exit $1
}
db_access=
db_data=
db_disable=
db_key_base=
db_key_delta=
db_pid=
db_status=
#
# send request to dbm server
# status returned in db_status
# data returned in db_data
#
function db_request # op args ...
{
print -p "$@"
read -p db_status db_data
case $db_debug in
?*) print -u2 DB: "$@": $db_status $db_data ;;
esac
case $db_status in
I) return 0 ;;
E) print -u2 $logfile: $db_data; return 1 ;;
*) return 1 ;;
esac
}
#
# initialize db
#
function db_init # machine user
{
typeset log=$logfile machine=$1 user=$2 i j l
case $db_disable in
?*) return 0 ;;
esac
case $db_debug in
grep) db_access=grep ;;
esac
case $db_access in
"") case $log in
"") ifs=$IFS
IFS=:
set -- $PATH
IFS=$ifs
for i
do case $i in
*/bin) i=${i%/bin}
for j in /share/ /
do l=${i}${j}lib/ship/log
if test -f $l.dir -a -r $l.dir -a -w $l.dir
then log=$l
break 2
fi
done
;;
esac
done
case $log in
"") log=$SHIPSLOG/log ;;
esac
;;
esac
case $log in
/*) ;;
*) log=$PWD/$log ;;
esac
db_access=grep
if cs </dev/null >/dev/null 2>&1
then cs -i /dev/tcp/share/dbm/group=ship |&
db_pid=$!
if db_request version
then db_request open $log w || errexit $log: cannot access log
db_access=dbm
logfile=$log
fi
fi
;;
esac
case $db_debug in
?*) print -u2 DB: init: access=$db_access logfile=$logfile ;;
esac
case $db_access in
dbm) first_time=0
db_check - $machine $user shipin "*" base || first_time=1
;;
grep) typeset -L2 dir=$machine
case $logfile in
?*) mv $logfile $SHIPSLOG/.tmp.
sort -r < $SHIPSLOG/.tmp. | sort -m -u +0 -1 > $logfile
rm -f $SHIPSLOG/.tmp.
;;
esac
logfile=$SHIPSLOG/$dir/$machine/$user
if test "" = "$force" -a -r "$logfile"
then first_time=0
else first_time=1
case $noexec in
"") if test ! -d "$SHIPSLOG/$dir"
then mkdir "$SHIPSLOG/$dir" || logfile=$SHIPSLOG/log
fi
if test ! -d "$SHIPSLOG/$dir/$machine"
then mkdir "$SHIPSLOG/$dir/$machine" || logfile=$SHIPSLOG/log
fi
;;
esac
fi
;;
esac
}
#
# end db interaction
#
function db_done #
{
case $db_disable in
?*) return 0 ;;
esac
case $noexec in
"") case $db_access in
dbm) db_request close
db_request quit
kill $db_pid
;;
grep) case $logfile in
?*) mv $logfile $SHIPSLOG/.tmp.
sort -r < $SHIPSLOG/.tmp. | sort -m -u +0 -1 > $logfile
rm -f $SHIPSLOG/.tmp.
;;
esac
;;
esac
;;
esac
}
#
# check if < machine user tool version type > was sent
#
function db_check # [ - ] machine user tool version type
{
typeset k key ks sav x nocheck=
case $db_disable:$first_time:$force in
1:*:*|*:1:*|*:*:1) return 1 ;;
esac
case $1 in
-) shift; nocheck=1 ;;
esac
typeset a=$1!$2 n=$3 v=$4 t=$5 m
case $5 in
"*") ks="base delta" ;;
base) ks=base ;;
*) ks=delta ;;
esac
for k in $ks
do key=$a,$n,$k
eval sav=\$db_key_$k
case $key in
$sav) eval set -- \$db_val_$k
;;
*) case $db_access in
dbm) if db_request get $key
then set -- $db_data
else continue
fi
;;
grep) set -- $(grep "^$key" $logfile)
case $# in
0) continue ;;
esac
shift
;;
esac
eval db_key_$k='$key' db_val_$k='$*'
;;
esac
case $1/$2 in
$v/$t) case $undo in
"") ;;
*) case $nocheck in
"") case $3 in
$undo) continue ;;
esac
;;
esac
;;
esac
case $v in
"*") return 0 ;;
esac
;;
*) case "$v" in
"*") return 0 ;;
esac
continue
;;
esac
if test -d $n
then m=$(shipop time $n/$1/$2)
else m=$(shipop time $n)
fi
case $6 in
""|$m) return 0 ;;
*) return 1 ;;
esac
done
return 1
}
#
# note that < machine user tool version type > was sent
#
function db_note # machine user tool version type name
{
typeset k v m
case $db_disable in
?*) return 0 ;;
esac
case $5 in
base) k=base ;;
*) k=delta ;;
esac
if test -d $3
then m=$(shipop time $3/$4/$5)
else m=$(shipop time $3)
fi
v="$1!$2,$3,$k $4 $5 $date $SHIPPER $6 $m"
case $db_access in
dbm) db_request put $v ;;
grep) print $v >> $logfile ;;
esac
}
#
# output SHIPMENT stamp for file [current date]
#
function shipstamp # file
{
typeset -Z2 day month
typeset -R2 year
integer mon Jan=1 Feb=2 Mar=3 Apr=4 May=5 Jun=6 \
Jul=7 Aug=8 Sep=9 Oct=10 Nov=11 Dec=12
case $# in
0) set -- $(date)
shift 1
;;
*) set -- $(ls -ld $1 2>/dev/null)
while :
do case $# in
[01]) break ;;
esac
case $1 in
Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
case $2 in
[1-9]|[0-3][0-9])
case $3 in
[0-9]*) break ;;
esac
;;
esac
;;
esac
shift
done
;;
esac
mon=$1
day=$2
month=$mon
case $3 in
*:*:*) year=$5
;;
*:*) set -- $(date)
year=$6
if (($mon > $2))
then let year=year-1
fi
;;
*) year=$3
;;
esac
print $year$month$day
}
#
# prepare $tool for shipping
#
function package # tool [blocks]
{
typeset tool=$1
integer package_blocks=${2-20}
integer package_chunk=package_blocks*8*1024
integer size i=0 skip=0
typeset -RZ3 suffix
typeset fsize
if test $tool.000 -nt $tool
then return 0
fi
fsize=$(wc -c $tool)
size=${fsize%$tool}
if ((size <= package_chunk))
then return 1
fi
print packaging $tool
rm -f $tool.???
while (( size > 0))
do suffix=$i
dd if=$tool of=$tool.$suffix bs=8k skip=$skip count=$package_blocks 2> /dev/null
let i=i+1 skip=skip+package_blocks size=size-package_chunk
done
set -- $tool.???
case $1 in
*.\?\?\?) errexit "$tool: cannot package" ;;
esac
return 0
}
function gencontrol # tool
{
typeset tool=${1%/*}
typeset format=${1#$tool/}
typeset init
typeset parts
if test -f $1
then if package $1
then parts='.???'
else parts=''
fi
else # $SHIPFILES
print - "cp $date.$SHIPPER/${tool%/*} \$INSTALLROOT/ship" >> $TMP.u
return
fi
tooldir=${tool%%/*}
{
print - "if test ! -f \$INSTALLROOT/ship/$tooldir/items"
set -- $tool/$format$parts
case $# in
1) print - "then if test -f $tool/$format$parts"
prefix="then"
;;
*) print - "then _unspool_nope=
for i in $*
do if test ! -f \$i
then _unspool_nope=1
break
fi
done
case \$_unspool_nope in"
prefix='"")'
;;
esac
case $format in
base|delete) init= ;;
*) init=$basetoo ;;
esac
case $init in
"") print - " $prefix if test ! -d \$INSTALLROOT/ship/$tooldir
then mkdir \$INSTALLROOT/ship/$tooldir
fi
rm -rf \$INSTALLROOT/ship/$tool
mkdir \$INSTALLROOT/ship/$tool"
prefix=
;;
esac
print - " $prefix cat $tool/$format$parts > \$INSTALLROOT/ship/$tool/$format"
print - " rm -f $tool/$format$parts"
case $init in
"") for i in $CRATEFILES
do if test -s $tool/$i
then print - " echo \"$(cat $tool/$i 2>/dev/null)\" > \$INSTALLROOT/ship/$tool/$i"
elif test -f $tool/$i
then print - " : > \$INSTALLROOT/ship/$tool/$i"
fi
done
if test "" != "$www"
then owner=
else if test "" = "$shipper" -a -s $tool/owner
then owner=$(<$tool/owner)
else owner=$SHIPPER
fi
case ${TOSYS##*!} in
${owner%%!*}) owner=${TOSYS%!*}!$owner ;;
*) owner=$TOSYS!$owner ;;
esac
fi
print - " echo \"$owner\" > \$INSTALLROOT/ship/$tool/owner"
;;
esac
case $# in
1) print - " fi"
;;
*) print - " ;;
esac"
;;
esac
print - "fi"
} >> $TMP.u
}
function instructions # first
{
integer item=0 first=$1
typeset tool pack packages omit main
case $first in
0) print "
As a repeat recipient:"
case $redo in
1) print "
($((item=item+1))) This shipment includes an update to the installation support tools.
Any tools that failed to build previously will be attempted again."
;;
esac
;;
1) print "
As a first time recipient:"
;;
esac
print "
($((item=item+1))) Wait for a \\\`copy succeeded' message from uucp for the file:
\$user/$FROMSYS/$date.$SHIPPER/manifest"
print "
($((item=item+1))) For safety do not run as root. If you are not running as \$user then:
RECIPIENT=\$user
export RECIPIENT"
packages=$(for tool in "${ship_list[@]}"
do tool=${tool%%/*}
if test -f $tool/Mamfile
then sed -e '/^setv PACKAGE/!d' -e 's/^setv / /' -e 's/ /=/' -e 's/\$/\\&/g' $tool/Mamfile
fi
done | sort -t= -u +0 -1)
case $packages in
?*) omit=
for tool in "${ship_list[@]}"
do case $tool in
lib*) tool=${tool%%/*}
tool=${tool#lib}
case $omit in
"") omit="$tool" ;;
*) omit="$omit|$tool" ;;
esac
;;
esac
done
case $omit in
?*) main=$(echo "$packages" | egrep "PACKAGE_($omit)[=_]" | sed -e 's/^ PACKAGE_\([^_=]*\).*/\1/' | sort -u)
packages=$(echo "$packages" | egrep -v "PACKAGE_($omit)[=_]")
;;
esac
esac
case $first in
0) print "
($((item=item+1))) Name the directory under which previous shipments were installed:
INSTALLROOT=<shipment-root-directory>"
;;
1) case $main in
""|*"
"*) main= ;;
*) main="
A good final installation directory name would be /usr/add-on/$main." ;;
esac
print "
($((item=item+1))) Create a shipment root directory under which all source and binaries
will be generated. This should not be a final installation directory.$main
INSTALLROOT=<shipment-root-directory>
test -d \\\$INSTALLROOT || mkdir \\\$INSTALLROOT
cd \\\$INSTALLROOT
test -d ship || mkdir ship"
;;
esac
print "
($((item=item+1))) If $uuspool/\$user/$FROMSYS was copied to \\\$SPOOLROOT then:
SHIPSPOOL=\\\$SPOOLROOT
export SHIPSPOOL"
print "
($((item=item+1))) If your system has att and bsd/ucb universes then in general the tools
will have more functionality when built in the bsd/ucb universe. The
exception is on solaris where /usr/ucb/cc is fubar. Set cc by:
CC='hackcc -systype bsd43' CCFLAGS='-g' # just an example #
export CC CCFLAGS"
case $packages in
?*) print "
($((item=item+1))) This shipment refers to some installation dependent software packages.
Redefine and export any of the following definitions that are incorrect:
$packages"
;;
esac
print "
($((item=item+1))) Execute the following commands to unpack and install the shipment:
cd \\\$INSTALLROOT"
case $first in
1) print "\
cp \\\${SHIPSPOOL-$uuspool/\$user/$FROMSYS}/$date.$SHIPPER/shipin ship/shipin
chmod 0755 ship/shipin"
;;
esac
print "\
nohup ksh ship/shipin &"
print "
($((item=item+1))) Use shipout within \\\$INSTALLROOT/ship to ship to other machines.
\\\$INSTALLROOT/ship/README contains more detailed information."
}
function buildscript # machine user
{
# create mscript to execute as a . script
typeset tool format
integer delta=0 first=1 no_shipin
mscript=$TMP.s tfile=$TMP.f
case $message in
?*) {
print "cat > $tfile <<!EOF!"
print "Subject: software shipment"
if test -f ship.body
then print
cat ship.body
else f=${name#*,}
l=${name%,*}
case $f in
$l) ;;
*) print "\
Dear ${name#*,} ${name%,*}:" ;;
esac
if test -f ship.head
then cat ship.head
print
fi
if db_check $1 $2 shipin "*" base
then no_shipin=0
else no_shipin=1
fi
instructions $((first_time||no_shipin))
fi
print
typeset -L n='tool ' d='release '
t='type'
print "\
This distribution contains:
$n$d$t"
n=----
d=-------
t=----
print "\
$n$d$t"
for tool in "${ship_list[@]}"
do format=${tool##*/}
tool=${tool%/$format}
test -r $tool && eval _notes_${tool%%/*}=0
n=${tool%%/*}
d=${tool##*/}
case $format in
base|delete)
t=$format
;;
$SHIPMENT)
if pax -f $tool/$format -z - 2>/dev/null | egrep 'DELTA!!!|!PAX!D!' >/dev/null
then t="$format delta" delta=1
else t="$format patch"
fi
;;
*) errexit "$format: invalid format"
;;
esac
print " $n$d$t"
done
print
if ((delta))
then print "\
Unpacking delta shipments requires the new pax command.
"
fi
for tool in "${ship_list[@]}"
do if test ! -r $tool
then continue
fi
format=${tool##*/}
tool=${tool%/$format}
if test -s "$tool/message"
then item=${tool%%/*}
eval x='$'_notes_$item
case $x in
0) print "\
$item notes:
"
eval _notes_$item=1
;;
1) if cmp -s "$tool/message" "$item/$format/message"
then continue
fi
;;
esac
cat "$tool/message"
print
fi
done
if test -f ship.tail
then cat ship.tail
elif test -f $HOME/.signature
then cat $HOME/.signature
fi
print '!EOF!'
case $noexec in
"") print 'mail $mail < $tfile'
;;
*) print 'print "mail $mail <<!EOF!"'
print "cat $tfile"
print 'echo !EOF!'
;;
esac
} > $mscript
;;
esac
}
function tosys # machine
{
# construct return mail address
typeset i IFS=!
TOSYS=
for i in $@
do case $i in
%*) ;;
*) TOSYS=$i!$TOSYS ;;
esac
done
case $TOSYS in
$FROMSYS!) TOSYS= ;;
esac
TOSYS=$TOSYS$FROMSYS
}
function genshiplist # machine user mail
{
typeset tool file x n v t need_pax= missing=
integer i=0 j=0
lclfiles= rmtfiles=
db_init $1 $2
db_check - $1 $2 pax "*" base || need_pax=1
machine=$1
user=$2
mail=$3
unset ship_list redo
for file in $SHIPFILES
do v=$(shipstamp $file)
if db_check $machine $user $file $v base
then continue
fi
ship_list[i]=$file/$v/base
i=i+1
case " $SHIPAUX " in
*" $file "*) redo=1 ;;
esac
done
j=i
for tool in "${tool_list[@]}"
do n=${tool%%/*}
case $need_pax in
"") eval t=\$type_$n
case $t in
pax) continue ;;
esac
;;
esac
v=${tool#*/}
v=${v%/*}
t=${tool##*/}
case $tool in
*/*/$SHIPMENT)
if db_check $machine $user $n $t "*"
then case $basetoo in
"") case $noexec in
"") db_note $machine $user $n $t base $name ;;
esac
;;
?*) if db_check $machine $user $n $v base
then :
elif test -f $n/$v/base
then ship_list[i]=$n/$v/base
i=i+1
else print -u2 "$n/$v/base: missing base archive"
missing=1
fi
;;
esac
elif test -f "$n/$v/base"
then if db_check $machine $user $n $v base
then :
else ship_list[i]=$n/$v/base
i=i+1
fi
case $basetoo in
"") continue ;;
esac
elif test -f $n/$t/base
then ship_list[i]=$n/$t/base
i=i+1
else print -u2 "$n/$t/base: missing base archive"
missing=1
fi
;;
esac
if db_check $machine $user $n $v $t
then :
else ship_list[i]=$tool
eval clean_$n=
i=i+1
fi
done
case $missing in
?*) exit 1 ;;
esac
if ((j>=i))
then case $redo in
"") case $total in
"") print -u2 "$mail is up to date" ;;
*) print -u2 "\\n$mail: up to date" ;;
esac
return 0
;;
esac
else case $mark in
?*) case $user:$noexec in
?*:) for tool in "${ship_list[@]}"
do x=${tool#*/}
x=${x%/*}
db_note $machine $user ${tool%%/*} $x ${tool##*/} $name
done
;;
esac
return 0
;;
esac
fi
case $total in
?*) print -u2 "\\n$mail:"
PS3=''
select i in ${ship_list[*]}
do :
done </dev/null
return 0
;;
esac
return 1
}
function sendcontrol # machine user
{
# $transport the control file to <user> on given <machine>
case $transport in
uucp) typeset dest=$1!$uupublic/$2/$FROMSYS/$date.$SHIPPER
print "$rmtfiles
$date.$SHIPPER/unspool
$date.$SHIPPER/manifest" > $TMP.m
print uucp -r -C $TMP.u $dest/unspool
case $noexec in
"") uucp -r -C $TMP.u $dest/unspool ;;
esac
case $SHIPID in
?*) print $date.$SHIPPER/id >> $TMP.m
id="$SHIPPER SEAL $(date) $1!$2"
print "$1!$SHIPID $id" > $TMP.i
print uucp -r -C $TMP.i $dest/id
case $noexec in
"") uucp -r -C $TMP.i $dest/id ;;
esac
case $noexec in
"") print "$id\\t$(shipop seal $lclfiles $TMP.u $TMP.m $TMP.i)" >> $SHIPSLOG/seals
;;
esac
;;
esac
print uucp -r -C -m -n"$2" $TMP.m $dest/manifest
case $noexec in
"") uucp -r -C -m -n"$2" $TMP.m $dest/manifest ;;
esac
;;
uuto) print uuto -m $TMP.u $1!$2
case $noexec in
"") uuto -m $TMP.u $1!$2 ;;
esac
;;
esac
case $noexec in
?*) case $SHIPID in
?*) print "ID:"
cat $TMP.i
;;
esac
print "MANIFEST:"
cat $TMP.m
print "UNSPOOL:"
cat $TMP.u
;;
esac
}
function doship #
{
# ship the files
typeset i j tool file
integer d
case "$info" in
?*) fixedname=${name%% *}
print "$fixedname $address $phone $mail $company $project $transport"
return
esac
user=${mail##*!} machine=${mail%!*}
user=${user%%@*} machine=${machine#*@}
target=$machine!~/$user/$FROMSYS
uuspool=$SHIPSPOOL
case $transport in
uucp) uupublic='~'
;;
uuto) uuspool=$uuspoool/receive
uupublic=$uuspool
print -u2 $transport: transport not supported for $user
return
;;
*) print -u2 $transport: unknown transport for $user
return
;;
esac
if genshiplist $machine $user $mail
then return
fi
tosys $machine
> $TMP.u
for i in "${ship_list[@]}"
do gencontrol "$i"
done
case $redo in
?*) for i in $tools
do print - "for i in \$INSTALLROOT/ship/${i%/*}/*"
print - "do if test -d \$i -a ! -f \$i/BUILT"
print - " then rm -f \$i/[BEU]*"
print - " fi"
print - "done"
done >> $TMP.u
;;
esac
buildscript $machine $user
dtime=0
for tool in "${ship_list[@]}"
do for i in $tool.???
do case $i in
*.\?\?\?|*.000)
d=25
if test -f $tool.001
then j=$i
elif test -f $tool
then i=$tool j=$tool
else # here for $SHIPFILES
i=${tool%%/*}; j=$date.$SHIPPER/$i
fi;;
*) j=$i d=50;;
esac
dfile=$target/$j
if test -f "$i"
then lclfiles="$lclfiles $i"
case $rmtfiles in
"") rmtfiles=$j
;;
*) rmtfiles="$rmtfiles
$j"
;;
esac
print uucp -r $nocopy $PWD/"$i" "$dfile"
case $noexec in
"") uucp -r $nocopy $PWD/"$i" "$dfile"
dtime=dtime+d
;;
esac
fi
done
i=${tool#*/}
i=${i%/*}
case $noexec in
"") db_note $machine $user ${tool%%/*} $i ${tool##*/} $name ;;
esac
done
if test -r $mscript
then . $mscript
fi
sendcontrol $machine $user
}
function dosend # recipient open
{
# lookup <recipient> in database and transport software to them
# if <open> is given, the database is re-opened
addr=$1
db_disable=
case $addr in
*%beta.*|*%bin*|*%ftp|*%lib*|*%list|*%pull|*%push|*%src)
db_disable=1
mail=$addr
transport=${addr##*'%'}
machine=%$transport
user=${addr%"$machine"}
case $transport in
beta.*) beta=$SHIPPER transport=${transport#beta.} ;;
*) beta= ;;
esac
case $transport in
bin*|lib*|src)
dir=ship
out=${user:-${transport%%.*}}
view=
case $transport in
bin) arch=${PWD%/ship}
case $arch in
*/arch/*)
a=${arch##*/}
;;
*) a=${HOSTTYPE:-$(hostinfo type)}
;;
esac
out=$out.$a
type="$a binary"
type_H=".I $a
.B binary"
;;
bin.*) arch=${transport#bin.}
out=$out.$arch
transport=bin
type="$arch binary"
type_H=".I $arch
.B binary"
view=1
;;
lib) arch=${PWD%/ship}
case $arch in
*/arch/*)
a=${arch##*/}
;;
*) a=${HOSTTYPE:-$(hostinfo type)}
;;
esac
out=$out.$a
type="$a binary and library"
type_H=".I $a
.B binary
and
.B library"
;;
lib.*) arch=${transport#lib.}
out=$out.$arch
transport=lib
type="$arch binary and library"
type_H=".I $arch
.B binary
and
.B library"
view=1
;;
*) arch=..
type="source"
type_H=".B source"
;;
esac
ccprobe=
case $view in
?*) case $PWD in
*/arch/*)
arch=${PWD%/arch/*}/arch/$arch
export INSTALLROOT=$arch
vpath $arch ${PWD%/arch/*} 2>/dev/null
export VPATH=$arch:${PWD%/arch/*}
for f in $arch/lib/probe/C/make/[!p]*bincc $arch/lib/probe/C/make/[!p]*cc $arch/lib/probe/C/make/[!p]*
do if test -f $f
then ccprobe=CC.PROBE=$f
break
fi
done
;;
esac
;;
esac
MAKE=$(whence nmake)
;;
*) dir=.
;;
esac
;;
*:*) transport=rcp
mail=$1
host=${addr%:*}
dir=${addr#*:}
case $host in
*@*) user=${host%@*}
host=${host#*@}
;;
*) user=${dir%%/*}
case $user in
'~'*) user=${user#~} ;;
*) user=$SHIPPER ;;
esac
;;
esac
machine=$host
;;
*!*) name=${1##*!} transport=uucp
;;
*@*) name=${1%%@*} transport=uucp
;;
*) transport=db
;;
esac
case $transport in
uucp) address= phone= mail=$1 project=
doship
return 1
;;
db) typeset -l given match
case $shipinfo_test in
"") if test ! -f "$SHIPINFO"
then errexit "$SHIPINFO: cannot find information file"
fi
shipinfo_test=1
;;
esac
case $2 in
?*) exec 3< $SHIPINFO ;;
esac
given=$1
while IFS=: read -ru3 name address phone mail company project unused transport comments
do match=$name
case $match in
\#*) ;;
$given*) doship
return 1
;;
esac
done
;;
*) typeset d i p s
if genshiplist $machine $user $mail
then return 1
fi
tosys $machine
case $transport in
ftp) ftp_address=$(cs -a addr $FROMSYS 2>/dev/null || print - $FROMSYS) ;;
esac
exec 9>&1
case $transport in
bin|lib);;
*) case $transport in
list|push|src)
;;
*) print - "umask 02"
;;
esac
case $transport in
ftp) print - 'case $INSTALLROOT in'
print - '?*) if test -d $INSTALLROOT'
print - ' then cd $INSTALLROOT'
print - ' else echo "$0: $INSTALLROOT: invalid INSTALLROOT" >&2'
print - ' exit 1'
print - ' fi'
print - ' ;;'
print - 'esac'
print - 'if test ! -d ship'
print - 'then mkdir ship || exit 1'
print - 'fi'
print - 'cd ship'
print - 'if test -r "$HOME/.netrc" && grep -c "machine[ ]*'$ftp_address'[ ]*" "$HOME/.netrc"'
print - 'then :'
print - 'else echo "machine '$ftp_address' login anonymous password '$user'" >> "$HOME/.netrc"'
print - ' chmod 0600 "$HOME/.netrc"'
print - 'fi'
;;
esac
for i in "${ship_list[@]}"
do if test -f $i
then d=$i/file
p=${d%%/*}
s=${d#${p}/}
t=$p
while test "$s" != file
do if test "" != "$p"
then case $transport in
list|src)
print - "$dir/$p"
;;
push) ;;
*) print - "if test ! -d $dir/$p"
print - "then mkdir $dir/$p"
print - "fi"
;;
esac
fi
p=${p}/${s%%/*}
s=${d#${p}/}
done
i=${i%/*}
for f in $CRATEFILES
do if test -s $i/$f
then case $transport in
list|push|src)
print - "$dir/$i/$f"
;;
*) print - "echo \"$(cat $i/$f 2>/dev/null)\" > $dir/$i/$f"
;;
esac
elif test -f $i/$f
then case $transport in
list|push|src)
print - "$dir/$i/$f"
;;
*) print - "> $dir/$i/$f"
;;
esac
fi
done
case $transport in
list|push|src)
if test "" = "$www" -a -s $i/owner
then print - "$dir/$i/owner"
fi
;;
*) if test "" != "$www"
then owner=
else if test "" = "$shipper" -a -s $i/owner
then owner=$(<$i/owner)
else owner=$SHIPPER
fi
case ${TOSYS##*!} in
${owner%%!*}) owner=${TOSYS%!*}!$owner ;;
*) owner=$TOSYS!$owner ;;
esac
fi
print - "echo \"$owner\" > $dir/$i/owner"
;;
esac
fi
done
case $transport in
list|push|src)
;;
*) print - "rm -f $dir/ship.$date"
;;
esac
case $transport in
ftp) print - '${FTP-ftp} $FTP_ADDRESS <<!!!'
print - 'user anonymous'
print - 'type image'
print - 'cd $FTP_INSTALLROOT/ship'
;;
esac
;;
esac | case $transport:$noexec in
bin:|lib:|src:)
exec 1>$TMP.f
cat
test -d Z || mkdir Z
;;
bin:*|lib:*|src:*)
print - "(cd $arch; pax -w $paxformat) > Z/$out.Z <<!!!"
cat
;;
ftp:*) print - ': get shipment from remote ftp host'
print - 'case $# in'
print - '0|1|2) ;;'
print - '*) echo "Usage: $0 [ftp-address [remote-INSTALLROOT]]" >&2; exit 1 ;;'
print - 'esac'
print - 'FTP_ADDRESS=${1-'$ftp_address'}'
print - 'FTP_INSTALLROOT=${2-.}'
cat
;;
list:*) cat
;;
pull:*) print - ': pull shipment from remote dk host'
print - 'case $# in'
print - '1|2) ;;'
print - '*) echo "Usage: $0 dk-address [remote-INSTALLROOT]" >&2; exit 1 ;;'
print - 'esac'
print - 'DK_ADDRESS=$1'
print - 'DK_INSTALLROOT=${2-.}'
cat
;;
push:*) print - ': push shipment to remote dk host'
print - 'case $# in'
print - '1|2) ;;'
print - '*) echo "Usage: $0 dk-address [remote-INSTALLROOT]" >&2; exit 1 ;;'
print - 'esac'
print - 'push $1 - ${2:+$2/}ship <<"!!!"'
cat
;;
*:) cat > $TMP.r
rcp $TMP.r $host:$dir/ship.$date || exit
rm -f $TMP.r
case $rsh in
"") for i in rcmd remsh
do if ($i $host date) >/dev/null 2>&1
then rsh=$i
break
fi
done
case $rsh in
"") rsh=rsh ;;
esac
;;
esac
$rsh $host sh $dir/ship.$date || exit
;;
*) print - "cat '"
cat
print - "' > ship.$date"
print - "rcp ship.$date $host:$dir"
print - "rm ship.$date"
print - "rsh $host sh $dir/ship.$date"
;;
esac
chmod=
items=
pwd=.
skip=
for tool in "${ship_list[@]}"
do if test ! -f $tool
then i=${tool%%/*}
else i=$tool
fi
dfile=$mail/$i
if test -f "$i"
then case $transport in
bin|lib)case $i in
*/*) case $i in
$tool) i=${i%/*}
i=${i%/*}
case $i in
$skip) ;;
*) (
cd $arch
r=$PWD
case $i in
lib*) cd src/lib/$i ;;
*) cd src/cmd/$i ;;
esac
list=list.ship
case $transport in
bin) list=$list.$transport ;;
esac
INSTALLROOT=$r $MAKE -o 'accept noexec mismatch reread silent' $list $ccprobe
)
;;
esac
;;
esac
;;
README|shipout)
print - "ship/$i"
skip=${tool%%/*}
;;
*) skip=${tool%%/*}
;;
esac
;;
ftp) case $i in
*/*) t=${i%/*} ;;
*) t=. ;;
esac
case $t in
$pwd) ;;
*) print - cd '$FTP_INSTALLROOT'/ship/${i%/*}
case $pwd in
.) print - lcd $t ;;
*) print - lcd ../../$t ;;
esac
pwd=$t
;;
esac
print - get ${i##*/}
test -x $i && chmod="$chmod $i"
;;
list|push)
print - "$i"
;;
pull) case $i in
*/*) t=${i%/*} ;;
*) t=. ;;
esac
print - echo pull '$DK_ADDRESS' '$DK_INSTALLROOT'/ship/$i $t
print - pull '$DK_ADDRESS' '$DK_INSTALLROOT'/ship/$i $t
;;
rcp) print rcp "$i" "$dfile"
case $noexec in
"") rcp "$i" "$dfile" || exit ;;
esac
;;
src) print - "ship/$i"
case $i in
*/*) ;;
*) skip=${tool%%/*} ;;
esac
;;
esac
fi
i=${tool#*/}
i=${i%/*}
case $user:$noexec in
?*:) db_note $machine $user ${tool%%/*} $i ${tool##*/} $name ;;
esac
i=${tool%%/*}
case $i in
$skip) ;;
*) skip=$i
items="$items $i"
;;
esac
done
exec 1>&9 9>&-
case $transport:$noexec in
bin:|lib:|src:)
test "" != "$www" && {
case $type in
[aehiouAEHIOU]*)
a=an
;;
*) a=a
;;
esac
print - ".TL - - \"$SHIPORG\" \"$SHIPLOGO\"
Software Shipment Contents
This is $a
$type_H
shipment of
.IR $out ."
if test -f ship.${out%%.*}.promo
then print - ".P"
cat ship.${out%%.*}.promo
print - ".P"
fi
print - "The shipment contains:
.EX"
case $transport in
bin) ls -Cd $(ls -d $items 2>/dev/null | grep -v '^lib') 2>/dev/null ;;
*) ls -Cd $items 2>/dev/null ;;
esac
print - ".EE"
hit=" "
for tool in "${ship_list[@]}"
do tool=${tool%/*}
case $hit in
*" $tool "*)
;;
*) hit="$hit$tool "
if test -f $tool/promo
then promo=1
cat $tool/promo
else promo=
fi
if test -f $tool/release
then case $promo in
"") print - ".H 1 ${tool%/*}"
;;
esac
print - ".P"
print - ".DS"
cat $tool/release
print - ".DE"
fi
;;
esac
done
print - ".H 1
If you have problems send mail to
.I advsoft@attmail.att.com
with
.I $out
in the subject field."
} | $SHIPMM2HTML >Z/$out.H
{
print - "#"
print - "# the following ${beta:+beta }$type shipment"
print - "# of $out has been sent"
case $beta in
?*) print - "# this beta shipment may only be interface compatible with itself"
print - "# other shipments will be reconciled after beta testing"
;;
esac
print - "#"
case $transport in
bin) ls -Cd $(ls -d $items 2>/dev/null | grep -v '^lib') 2>/dev/null ;;
*) ls -Cd $items 2>/dev/null ;;
esac | sed 's/^/# /'
print - "#"
print - "# to install:"
print - "#"
print - "INSTALLROOT=<installation-root-dir>${beta:+/beta.$beta}"
print - "SHIPMENT=<shipment-.Z-file>"
print - "cd \$INSTALLROOT"
print - "$paxuncompress \$SHIPMENT | $paxunformat"
case $transport in
bin|lib)(cd $arch; ls -ld $(<$TMP.f) 2>/dev/null) > $TMP.s
for f in $(sed -e '/^-..s..s/!d' -e 's/.* //' $TMP.s)
do set x $(cd $arch; ls -ld $f 2>/dev/null)
n=$#
g=$5
set x $(cd $arch; ls -ldg $f 2>/dev/null)
n1=$#
g1=$5
if test $n -lt $n1
then g=$g1
fi
print - "chgrp $g $f || echo ship: $f would be more efficient if owned by group $g >&2"
done
sed -e '/^-..s/!d' -e 's/^-..s..s.* /chmod ug+s /' -e 's/^-..s.* /chmod u+s /' $TMP.s
rm $TMP.s
for f in $items
do test -f $f/binary && cat $f/binary
done
;;
src) print - "nohup ksh ship/shipin &"
;;
esac
print - "#"
print - "# to use:"
print - "#"
print - "export LD_LIBRARY_PATH=\$INSTALLROOT/lib\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}"
print - "export PATH=\$INSTALLROOT/bin:\$PATH"
print - "export FPATH=\$INSTALLROOT/fun\${FPATH:+:\$FPATH}"
} >Z/$out.M
case $transport in
bin) (cd $arch; sort -u $TMP.f | egrep -v '^(include/.*|lib/lib.*\.a)$' | pax -Lw $paxformat; rm $TMP.f) > Z/$out.Z ;;
*) (cd $arch; sort -u $TMP.f | pax -Lw $paxformat; rm $TMP.f) > Z/$out.Z ;;
esac
;;
bin:*|ftp:*|lib:*|push:*|src:*)
case $transport in
ftp) print - 'quit' ;;
esac
print - '!!!'
case $chmod in
?*) print - "chmod +x$chmod" ;;
esac
;;
esac
return 1
;;
esac
print -u2 "$command: address for $1 not found"
return 1
}
function closure # tools
{
tools=
for tool
do if test ! -d $tool
then case $original in
*" ${tool%/*} "*|*" $tool "*) warning "${tool%/*}: invalid tool" ;;
esac
else case $tool in
*/?*) release=${tool#*/}
tool=${tool#*/}
;;
*) eval items=\"\$items_$item\"
case $items in
"") release= ;;
*) eval release=\$release_$tool ;;
esac
;;
esac
eval release_${tool%/*}=$release
tools="$tools $tool"
fi
done
set -- $tools
#
# now generate the closure of the top level tools and releases
#
tools=
for tool
do old=
new=$tool
while :
do case $new in
$old) break
esac
dup=
for item in $new
do # we assume items_* not in environment
eval items=\"\$items_$item\"
case $items in
"") eval release=\$release_$item
case $release in
"") set -- $item/$SHIPMENT
shift $#-1
case $1 in
"$item/$SHIPMENT") continue ;;
esac
release=${1#*/}
eval release_$item=$release
esac
if test ! -f $item/$release/items
then if test ! -f $item/$release/delete
then continue
fi
items=$item
else case $closure in
"") items=$item ;;
*) items=$(<$item/$release/items)" $item" ;;
esac
fi
eval items_$item=\"$items\"
;;
esac
dup="$dup $items"
done
old=$new
new=
for item in $dup
do eval seen_$item=
done
for item in $dup
do eval seen=\$seen_$item
case $seen in
"") eval seen_$item=1
new="$new $item"
esac
done
done
tools="$tools $new"
done
}
function undup # tools
{
tools=
for item
do eval seen_$item=
done
for item
do eval seen=\$seen_$item
case $seen in
"") eval seen_$item=1
tools="$tools $item"
esac
done
}
command=$0
integer dtime=0 i=0 nrecipient=0 first_time=1 delay=0
info= mark= list= logfile= message=1 nocopy= noexec= format=$SHIPMENT
shipinfo_test= force= shipper= closure=1 undo= date= basetoo= www=
paxformat= paxunformat= paxcompress= paxuncompress=
while :
do case $1 in
-b) basetoo=1 ;;
+b) basetoo= ;;
-c) closure= ;;
+c) closure=1 ;;
-d) format=base ;;
+d) format=$SHIPMENT ;;
-i) info=1 delay=0 ;;
-k) mark=1 delay=0 ;;
-l) shift; list=$1 ;;
+l) list= ;;
-m) message= ;;
+m) message=1 ;;
-n) noexec=1 delay=0 ;;
+n) noexec= ;;
-o) shipper=1 ;;
+o) shipper= ;;
-p) shift; recipient_list[nrecipient]=$1; nrecipient=nrecipient+1 ;;
+p) recipient= ;;
-s) SHIPFILES= ;;
-t) total=1 noexec=1 delay=0 ;;
-u) shift; undo=$1 ;;
+u) undo= ;;
-v) shift; date=$1 ;;
-w) www=1 ;;
+w) www= ;;
-x) shift
case $1 in
compress|gzip)
paxcompress=$1
;;
*) paxformat=$1
;;
esac
;;
-C) shift; CRATEFILES="$CRATEFILES $1" ;;
-D) shift; delay=$1 ;;
+D) delay=0 ;;
-F) force=1 ;;
+F) force= ;;
-L) shift; logfile=$1 ;;
-S) shift; SHIPFILES="$SHIPFILES $1" ;;
*[,:!%@]*)recipient_list[nrecipient]=$1;nrecipient=nrecipient+1 ;;
--) shift; break ;;
-*|+*) print -u2 "Usage: $command [-bcdikmnostfF] [-l recipient-list] [-p recipient] [-u [[yy]mm]dd] [-v yymmdd] [-x format] [-C crate-file] [-D delay] [-S support-file] [recipient ...] [tool ...]"; exit 2 ;;
*) break ;;
esac
shift
done
case $www in
?*) case $paxformat in
"") paxformat=tar ;;
esac
case $paxcompress in
"") paxcompress=gzip ;;
esac
;;
esac
case $paxcompress in
""|compress)
paxcompress=compress
paxuncompress="zcat <"
;;
gzip) paxuncompress="(gunzip || zcat) <"
;;
esac
case $paxformat in
"") paxformat=cpio ;;
esac
case $paxformat in
cpio) paxunformat="cpio -icdvmu" ;;
tar) paxunformat="tar xvf -" ;;
*) paxunformat="pax -rv" ;;
esac
case $paxformat in
?*) paxformat="-x $paxformat" ;;
esac
case $paxcompress in
?*) paxformat="-x $paxcompress $paxformat" ;;
esac
case $date in
$SHIPMENT) ;;
*) date=$(shipstamp) ;;
esac
($SHIPMM2HTML) >/dev/null 2>&1 || SHIPMM2HTML=cat
case $info in
"") if test 0 = "$nrecipient" -a ! -f "$list"
then errexit "no recipient(s)"
fi
trap 'cleanup $?' EXIT INT TERM
#
# generate the tools list
#
original=" $* "
case $# in
0) tools=
for tool in *
do set -- $tool/$SHIPMENT
case $1 in
"$tool/$SHIPMENT") ;;
*) tools="$tools $tool" ;;
esac
done
case $tools in
"") errexit "no tools" ;;
esac
set -- $tools
;;
esac
closure $*
case $tools in
"") errexit "no 'items' file(s)" ;;
esac
tools_usr=$tools
tools_pax=
case $closure:$format:$SHIPFILES in
:*|*:|*:base:*|*:delete:*)
;;
*) set -- pax/$SHIPMENT
case $1 in
"$tool/$SHIPMENT")
;;
*) closure pax
tools_pax=$tools
;;
esac
;;
esac
undup $tools_pax $tools_usr
set -- $tools
for tool in $tools_pax
do eval type_$tool=pax
done
for tool in $tools_usr
do eval type_$tool=usr
done
set -- $tools
for tool
do eval tool=$tool/\$release_$tool
item=
for f in delete "$format" base
do set -- $tool/$f
if test -f "$1"
then item=${1##*/}
break
fi
done
case $item in
"") if test ! -d ${tool%/*}
then case $original in
*" ${tool%/*} "*|*" $tool "*) warning "${tool%/*}: invalid tool" ;;
esac
continue
fi
case $format in
base) set -- $tool/$SHIPMENT
if test -f "$1"
then eval release_${tool%/*}=${1##*/}
tool=${tool%/*}/${1##*/}
item=base
warning "${tool}: latest base not crated"
else warning "${tool}: base not crated"
continue
fi
;;
*) continue
;;
esac
;;
esac
case $format in
"$SHIPMENT"|$item)
tool=$tool/$item
;;
*) tool=${tool%/*}/$item/base
if test ! -f $tool
then errexit "${tool%/*}: $item base not crated"
fi
;;
esac
tool_list[i]=$tool;i=i+1
done
;;
*) typeset -lL16 fixedname
typeset -L9 address project
typeset -R12 phone
typeset -L21 mail
typeset -L11 company
;;
esac
if test ! -d $SHIPSLOG
then mkdir $SHIPSLOG || errexit "$SHIPSLOG: cannot create log directory"
fi
SHIPID=$FROMSYS!$SHIPPER
case $SHIPFILES in
?*) SHIPFILES="$SHIPFILES $SHIPAUX"
for file in $SHIPFILES
do if test ! -r $file
then print -u2 "$file: cannot read"; exit 1
fi
done
;;
esac
while :
do case $undo in
""|??????*) break ;;
*) undo="?$undo" ;;
esac
done
nocopy=${nocopy+-c}
flag=1
case $list in
"") set -s -- "${recipient_list[@]}"
;;
?*) if test ! -r "$list"
then errexit "$list: cannot read"
else set -s -- "${recipient_list[@]}" $(sed -e '/^#/d' -e 's/[: ].*//' $list)
fi
;;
esac
for recipient
do if ((dtime))
then sleep $dtime
fi
if dosend "$recipient" $flag
then flag=
case $noexec$info in
"") print "$name" >> ${tool%/*}/list ;;
esac
else flag=1
fi
if ((delay > dtime))
then dtime=delay
fi
done
exit 0