dtksh/sfio: resolved a naming collision on FreeBSD 11
[oweals/cde.git] / cde / programs / dtksh / ksh93 / ship / shipout
1 :
2 # @(#)shipout (gsf@research.att.com) 07/17/95
3 #
4 # shipout [ options ... ] [ name ... ] [ tool ... ]
5 #
6 # ship software to recipient using system|user info in $SHIPINFO
7 #
8 # options -- + turns the corresponding option off
9 #
10 #       -b              ship bases with deltas
11 #       -c              don't generate tool closure
12 #       -d              don't ship deltas
13 #       -i              list info on specified recipient(s) only
14 #       -k              mark recipient(s) as having received tool(s)
15 #       -l file         list of people to ship to
16 #       -m              don't send shipment manifest mail message
17 #       -n              show but don't execute
18 #       -o              set shipment ownership to shipper
19 #       -p name         next argument is a recipient to ship to
20 #       -s              don't send shipment support files
21 #       -t              don't execute but show total shipment
22 #       -u [[yy]mm]dd   ignore db info for date pattern
23 #       -v yymmdd       override current date stamp
24 #       -w              shipment suitable for www
25 #       -x format       pax output format and compression
26 #       -C files        add to default crate file list
27 #       -D secs         delay in seconds between sends
28 #       -F              force db override
29 #       -S files        add to default support file list
30 #
31 # name -- recipient address
32 #
33 #       machine!user            uucp address
34 #       host:directory          rcp address
35 #       *%[beta.]bin[.arch]     compressed cpio binary archive in Z/*[.arch]
36 #       *%ftp                   sh script with ftp get's on stdout
37 #       *%[beta.]lib[.arch]     compressed cpio binary archive in Z/*[.arch]
38 #       *%list                  shipment file list on stdout
39 #       *%pull                  sh script with datakit pull's on stdout
40 #       *%push                  sh script with datakit push's on stdout
41 #       *%[beta.]src            compressed cpio src archive in Z/*
42 #
43 # the message file is evaluated by the shell and the following variables
44 # are predefined by ship:
45 #
46 #       f                       list of expanded file names
47 #       name                    name of shipee
48 #
49
50 umask 02
51 PATH=:$PATH
52
53 SHIPSLOG=${SHIPSLOG:-shipslog}
54 SHIPINFO=${SHIPINFO:-$SHIPSLOG/info}
55 SHIPFILES="README shipin shipout"
56 SHIPAUX="shipiffe.sh shipop.c shipproto.c"
57 SHIPMENT=*[0-9][0-9][0-9][0-9][0-9][0-9]
58 SHIPPER=${SHIPPER:-${USER:-${LOGNAME:-${HOME##*/}}}}
59 SHIPSPOOL=${SHIPSPOOL:-/usr/spool/uucppublic}
60 SHIPORG=${SHIPORG:-"Software and Systems Research"}
61 SHIPLOGO=${SHIPLOGO:-"http://www1126.research.att.com/logos/attbllogo.gif align=middle"}
62 SHIPMM2HTML=${SHIPMM2HTML:-mm2html}
63 CRATEFILES="copyright items message promo release report"
64 TMP=${TMPDIR:=/tmp}/ship$$
65 FROMSYS=$( (uname -n || hostname || cat /etc/whoami) 2>/dev/null )
66
67 test -f shipinit && . ./shipinit
68
69 function errexit
70 {
71         # print out an error message on unit 2 and exit
72         print -u2 - "$command: $@"
73         exit 1
74 }
75
76 function warning
77 {
78         print -u2 - "$command: warning: $@"
79 }
80
81 function cleanup # exitcode
82 {
83         trap - EXIT INT TERM
84         db_done
85         rm -f $TMP.?
86         exit $1
87 }
88
89 db_access=
90 db_data=
91 db_disable=
92 db_key_base=
93 db_key_delta=
94 db_pid=
95 db_status=
96
97 #
98 # send request to dbm server
99 # status returned in db_status
100 # data returned in db_data
101 #
102
103 function db_request # op args ...
104 {
105         print -p "$@"
106         read -p db_status db_data
107         case $db_debug in
108         ?*)     print -u2 DB: "$@": $db_status $db_data ;;
109         esac
110         case $db_status in
111         I)      return 0 ;;
112         E)      print -u2 $logfile: $db_data; return 1 ;;
113         *)      return 1 ;;
114         esac
115 }
116
117 #
118 # initialize db
119 #
120
121 function db_init # machine user
122 {
123         typeset log=$logfile machine=$1 user=$2 i j l
124
125         case $db_disable in
126         ?*)     return 0 ;;
127         esac
128         case $db_debug in
129         grep)   db_access=grep ;;
130         esac
131         case $db_access in
132         "")     case $log in
133                 "")     ifs=$IFS
134                         IFS=:
135                         set -- $PATH
136                         IFS=$ifs
137                         for i
138                         do      case $i in
139                                 */bin)  i=${i%/bin}
140                                         for j in /share/ /
141                                         do      l=${i}${j}lib/ship/log
142                                                 if      test -f $l.dir -a -r $l.dir -a -w $l.dir
143                                                 then    log=$l
144                                                         break 2
145                                                 fi
146                                         done
147                                         ;;
148                                 esac
149                         done
150                         case $log in
151                         "")     log=$SHIPSLOG/log ;;
152                         esac
153                         ;;
154                 esac
155                 case $log in
156                 /*)     ;;
157                 *)      log=$PWD/$log ;;
158                 esac
159                 db_access=grep
160                 if      cs </dev/null >/dev/null 2>&1
161                 then    cs -i /dev/tcp/share/dbm/group=ship |&
162                         db_pid=$!
163                         if      db_request version
164                         then    db_request open $log w || errexit $log: cannot access log
165                                 db_access=dbm
166                                 logfile=$log
167                         fi
168                 fi
169                 ;;
170         esac
171         case $db_debug in
172         ?*)     print -u2 DB: init: access=$db_access logfile=$logfile ;;
173         esac
174         case $db_access in
175         dbm)    first_time=0
176                 db_check - $machine $user shipin "*" base || first_time=1
177                 ;;
178         grep)   typeset -L2 dir=$machine
179                 case $logfile in
180                 ?*)     mv $logfile $SHIPSLOG/.tmp.
181                         sort -r < $SHIPSLOG/.tmp. | sort -m -u +0 -1 > $logfile
182                         rm -f $SHIPSLOG/.tmp.
183                         ;;
184                 esac
185                 logfile=$SHIPSLOG/$dir/$machine/$user
186                 if      test  "" = "$force" -a -r "$logfile"
187                 then    first_time=0
188                 else    first_time=1
189                         case $noexec in
190                         "")     if      test ! -d "$SHIPSLOG/$dir"
191                                 then    mkdir "$SHIPSLOG/$dir" || logfile=$SHIPSLOG/log
192                                 fi
193                                 if      test ! -d "$SHIPSLOG/$dir/$machine"
194                                 then    mkdir "$SHIPSLOG/$dir/$machine" || logfile=$SHIPSLOG/log
195                                 fi
196                                 ;;
197                         esac
198                 fi
199                 ;;
200         esac
201 }
202
203 #
204 # end db interaction
205 #
206
207 function db_done #
208 {
209         case $db_disable in
210         ?*)     return 0 ;;
211         esac
212         case $noexec in
213         "")     case $db_access in
214                 dbm)    db_request close
215                         db_request quit
216                         kill $db_pid
217                         ;;
218                 grep)   case $logfile in
219                         ?*)     mv $logfile $SHIPSLOG/.tmp.
220                                 sort -r < $SHIPSLOG/.tmp. | sort -m -u +0 -1 > $logfile
221                                 rm -f $SHIPSLOG/.tmp.
222                                 ;;
223                         esac
224                         ;;
225                 esac
226                 ;;
227         esac
228 }
229
230 #
231 # check if < machine user tool version type > was sent
232 #
233
234 function db_check # [ - ] machine user tool version type
235 {
236         typeset k key ks sav x nocheck=
237
238         case $db_disable:$first_time:$force in
239         1:*:*|*:1:*|*:*:1)      return 1 ;;
240         esac
241         case $1 in
242         -)      shift; nocheck=1 ;;
243         esac
244         typeset a=$1!$2 n=$3 v=$4 t=$5 m
245         case $5 in
246         "*")    ks="base delta" ;;
247         base)   ks=base ;;
248         *)      ks=delta ;;
249         esac
250         for k in $ks
251         do      key=$a,$n,$k
252                 eval sav=\$db_key_$k
253                 case $key in
254                 $sav)   eval set -- \$db_val_$k
255                         ;;
256                 *)      case $db_access in
257                         dbm)    if      db_request get $key
258                                 then    set -- $db_data
259                                 else    continue
260                                 fi
261                                 ;;
262                         grep)   set -- $(grep "^$key" $logfile)
263                                 case $# in
264                                 0)      continue ;;
265                                 esac
266                                 shift
267                                 ;;
268                         esac
269                         eval db_key_$k='$key' db_val_$k='$*'
270                         ;;
271                 esac
272                 case $1/$2 in
273                 $v/$t)  case $undo in
274                         "")     ;;
275                         *)      case $nocheck in
276                                 "")     case $3 in
277                                         $undo)  continue ;;
278                                         esac
279                                         ;;
280                                 esac
281                                 ;;
282                         esac
283                         case $v in
284                         "*")    return 0 ;;
285                         esac
286                         ;;
287                 *)      case "$v" in
288                         "*")    return 0 ;;
289                         esac
290                         continue
291                         ;;
292                 esac
293                 if      test -d $n
294                 then    m=$(shipop time $n/$1/$2)
295                 else    m=$(shipop time $n)
296                 fi
297                 case $6 in
298                 ""|$m)  return 0 ;;
299                 *)      return 1 ;;
300                 esac
301         done
302         return 1
303 }
304
305 #
306 # note that < machine user tool version type > was sent
307 #
308
309 function db_note # machine user tool version type name
310 {
311         typeset k v m
312
313         case $db_disable in
314         ?*)     return 0 ;;
315         esac
316         case $5 in
317         base)   k=base ;;
318         *)      k=delta ;;
319         esac
320         if      test -d $3
321         then    m=$(shipop time $3/$4/$5)
322         else    m=$(shipop time $3)
323         fi
324         v="$1!$2,$3,$k $4 $5 $date $SHIPPER $6 $m"
325         case $db_access in
326         dbm)    db_request put $v ;;
327         grep)   print $v >> $logfile ;;
328         esac
329 }
330
331 #
332 # output SHIPMENT stamp for file [current date]
333 #
334
335 function shipstamp # file
336 {
337         typeset -Z2 day month
338         typeset -R2 year
339         integer mon Jan=1 Feb=2 Mar=3 Apr=4 May=5 Jun=6 \
340                 Jul=7 Aug=8 Sep=9 Oct=10 Nov=11 Dec=12
341         case $# in
342         0)      set -- $(date)
343                 shift 1
344                 ;;
345         *)      set -- $(ls -ld $1 2>/dev/null)
346                 while   :
347                 do      case $# in
348                         [01])   break ;;
349                         esac
350                         case $1 in
351                         Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
352                                 case $2 in
353                                 [1-9]|[0-3][0-9])
354                                         case $3 in
355                                         [0-9]*) break ;;
356                                         esac
357                                         ;;
358                                 esac
359                                 ;;
360                                         
361                         esac
362                         shift
363                 done
364                 ;;
365         esac
366         mon=$1
367         day=$2
368         month=$mon
369         case $3 in
370         *:*:*)  year=$5
371                 ;;
372         *:*)    set -- $(date)
373                 year=$6
374                 if      (($mon > $2))
375                 then    let year=year-1
376                 fi
377                 ;;
378         *)      year=$3
379                 ;;
380         esac
381         print $year$month$day
382 }
383
384 #
385 # prepare $tool for shipping
386 #
387
388 function package # tool [blocks]
389 {
390         typeset tool=$1
391         integer package_blocks=${2-20}
392         integer package_chunk=package_blocks*8*1024
393         integer size i=0 skip=0
394         typeset -RZ3 suffix
395         typeset fsize
396
397         if      test $tool.000 -nt $tool
398         then    return 0
399         fi
400         fsize=$(wc -c $tool)
401         size=${fsize%$tool}
402         if      ((size <= package_chunk))
403         then    return 1
404         fi
405         print packaging $tool
406         rm -f $tool.???
407         while   (( size > 0))
408         do      suffix=$i
409                 dd if=$tool of=$tool.$suffix bs=8k skip=$skip count=$package_blocks 2> /dev/null
410                 let i=i+1 skip=skip+package_blocks size=size-package_chunk
411         done
412         set -- $tool.???
413         case $1 in
414         *.\?\?\?)       errexit "$tool: cannot package" ;;
415         esac
416         return 0
417 }
418
419 function gencontrol # tool
420 {
421         typeset tool=${1%/*}
422         typeset format=${1#$tool/}
423         typeset init
424         typeset parts
425
426         if      test -f $1
427         then    if      package $1
428                 then    parts='.???'
429                 else    parts=''
430                 fi
431         else    # $SHIPFILES
432                 print - "cp $date.$SHIPPER/${tool%/*} \$INSTALLROOT/ship" >> $TMP.u
433                 return
434         fi
435         tooldir=${tool%%/*}
436         {
437                 print - "if     test ! -f \$INSTALLROOT/ship/$tooldir/items"
438                 set -- $tool/$format$parts
439                 case $# in
440                 1)      print - "then   if      test -f $tool/$format$parts"
441                         prefix="then"
442                         ;;
443                 *)      print - "then   _unspool_nope=
444         for i in $*
445         do      if      test ! -f \$i
446                 then    _unspool_nope=1
447                         break
448                 fi
449         done
450         case \$_unspool_nope in"
451                         prefix='"")'
452                         ;;
453                 esac
454                 case $format in
455                 base|delete)    init= ;;
456                 *)              init=$basetoo ;;
457                 esac
458                 case $init in
459                 "")     print - "       $prefix if      test ! -d \$INSTALLROOT/ship/$tooldir
460                 then    mkdir \$INSTALLROOT/ship/$tooldir
461                 fi
462                 rm -rf \$INSTALLROOT/ship/$tool
463                 mkdir \$INSTALLROOT/ship/$tool"
464                         prefix=
465                         ;;
466                 esac
467                 print - "       $prefix cat $tool/$format$parts > \$INSTALLROOT/ship/$tool/$format"
468                 print - "               rm -f $tool/$format$parts"
469                 case $init in
470                 "")     for i in $CRATEFILES
471                         do      if      test -s $tool/$i
472                                 then    print - "               echo \"$(cat $tool/$i 2>/dev/null)\" > \$INSTALLROOT/ship/$tool/$i"
473                                 elif    test -f $tool/$i
474                                 then    print - "               : > \$INSTALLROOT/ship/$tool/$i"
475                                 fi
476                         done
477                         if      test "" != "$www"
478                         then    owner=
479                         else    if      test "" = "$shipper" -a -s $tool/owner
480                                 then    owner=$(<$tool/owner)
481                                 else    owner=$SHIPPER
482                                 fi
483                                 case ${TOSYS##*!} in
484                                 ${owner%%!*})   owner=${TOSYS%!*}!$owner ;;
485                                 *)              owner=$TOSYS!$owner ;;
486                                 esac
487                         fi
488                         print - "               echo \"$owner\" > \$INSTALLROOT/ship/$tool/owner"
489                         ;;
490                 esac
491                 case $# in
492                 1)      print - "       fi"
493                         ;;
494                 *)      print - "               ;;
495         esac"
496                         ;;
497                 esac
498                 print - "fi"
499          } >> $TMP.u
500 }
501
502 function instructions # first
503 {
504         integer item=0 first=$1
505         typeset tool pack packages omit main
506
507         case $first in
508         0)      print "
509 As a repeat recipient:"
510                 case $redo in
511                 1)      print "
512 ($((item=item+1))) This shipment includes an update to the installation support tools.
513     Any tools that failed to build previously will be attempted again."
514                         ;;
515                 esac
516                 ;;
517         1)      print "
518 As a first time recipient:"
519                 ;;
520         esac
521
522         print "
523 ($((item=item+1))) Wait for a \\\`copy succeeded' message from uucp for the file:
524
525         \$user/$FROMSYS/$date.$SHIPPER/manifest"
526
527         print "
528 ($((item=item+1))) For safety do not run as root.  If you are not running as \$user then:
529
530         RECIPIENT=\$user
531         export RECIPIENT"
532
533         packages=$(for tool in "${ship_list[@]}"
534         do      tool=${tool%%/*}
535                 if      test -f $tool/Mamfile
536                 then    sed -e '/^setv PACKAGE/!d' -e 's/^setv /        /' -e 's/ /=/' -e 's/\$/\\&/g' $tool/Mamfile
537                 fi
538         done | sort -t= -u +0 -1)
539         case $packages in
540         ?*)     omit=
541                 for tool in "${ship_list[@]}"
542                 do      case $tool in
543                         lib*)   tool=${tool%%/*}
544                                 tool=${tool#lib}
545                                 case $omit in
546                                 "")     omit="$tool" ;;
547                                 *)      omit="$omit|$tool" ;;
548                                 esac
549                                 ;;
550                         esac
551                 done
552                 case $omit in
553                 ?*)     main=$(echo "$packages" | egrep "PACKAGE_($omit)[=_]" | sed -e 's/^     PACKAGE_\([^_=]*\).*/\1/' | sort -u)
554                         packages=$(echo "$packages" | egrep -v "PACKAGE_($omit)[=_]")
555                         ;;
556                 esac
557         esac
558
559         case $first in
560         0)      print "
561 ($((item=item+1))) Name the directory under which previous shipments were installed:
562
563         INSTALLROOT=<shipment-root-directory>"
564                 ;;
565         1)      case $main in
566                 ""|*"
567 "*)     main= ;;
568                 *)      main="
569     A good final installation directory name would be /usr/add-on/$main." ;;
570                 esac
571                 print "
572 ($((item=item+1))) Create a shipment root directory under which all source and binaries
573     will be generated.  This should not be a final installation directory.$main
574
575         INSTALLROOT=<shipment-root-directory>
576         test -d \\\$INSTALLROOT || mkdir \\\$INSTALLROOT
577         cd \\\$INSTALLROOT
578         test -d ship || mkdir ship"
579                 ;;
580         esac
581
582         print "
583 ($((item=item+1))) If $uuspool/\$user/$FROMSYS was copied to \\\$SPOOLROOT then:
584
585         SHIPSPOOL=\\\$SPOOLROOT
586         export SHIPSPOOL"
587
588         print "
589 ($((item=item+1))) If your system has att and bsd/ucb universes then in general the tools
590     will have more functionality when built in the bsd/ucb universe.  The
591     exception is on solaris where /usr/ucb/cc is fubar.  Set cc by:
592
593         CC='hackcc -systype bsd43' CCFLAGS='-g'  # just an example #
594         export CC CCFLAGS"
595
596         case $packages in
597         ?*)     print "
598 ($((item=item+1))) This shipment refers to some installation dependent software packages.
599     Redefine and export any of the following definitions that are incorrect:
600
601 $packages"
602                 ;;
603         esac
604
605         print "
606 ($((item=item+1))) Execute the following commands to unpack and install the shipment:
607
608         cd \\\$INSTALLROOT"
609         case $first in
610         1)      print "\
611         cp \\\${SHIPSPOOL-$uuspool/\$user/$FROMSYS}/$date.$SHIPPER/shipin ship/shipin
612         chmod 0755 ship/shipin"
613                 ;;
614         esac
615         print "\
616         nohup ksh ship/shipin &"
617
618         print "
619 ($((item=item+1))) Use shipout within \\\$INSTALLROOT/ship to ship to other machines.
620     \\\$INSTALLROOT/ship/README contains more detailed information."
621
622 }
623
624 function buildscript # machine user
625 {
626         # create mscript to execute as a . script
627         typeset tool format
628         integer delta=0 first=1 no_shipin
629         mscript=$TMP.s tfile=$TMP.f
630         case $message in
631         ?*)     {
632                 print "cat > $tfile <<!EOF!"
633                 print "Subject: software shipment"
634                 if      test -f ship.body
635                 then    print
636                         cat ship.body
637                 else    f=${name#*,}
638                         l=${name%,*}
639                         case $f in
640                         $l)     ;;
641                         *)      print "\
642
643 Dear ${name#*,} ${name%,*}:" ;;
644                         esac
645                         if      test -f ship.head
646                         then    cat ship.head
647                                 print
648                         fi
649                         if      db_check $1 $2 shipin "*" base
650                         then    no_shipin=0
651                         else    no_shipin=1
652                         fi
653                         instructions $((first_time||no_shipin))
654                 fi
655                 print
656                 typeset -L n='tool           ' d='release     '
657                 t='type'
658                 print "\
659 This distribution contains:
660
661         $n$d$t"
662                 n=----
663                 d=-------
664                 t=----
665                 print "\
666         $n$d$t"
667                 for tool in "${ship_list[@]}"
668                 do      format=${tool##*/}
669                         tool=${tool%/$format}
670                         test -r $tool && eval _notes_${tool%%/*}=0
671                         n=${tool%%/*}
672                         d=${tool##*/}
673                         case $format in
674                         base|delete)
675                                 t=$format
676                                 ;;
677                         $SHIPMENT)
678                                 if      pax -f $tool/$format -z - 2>/dev/null | egrep 'DELTA!!!|!PAX!D!' >/dev/null
679                                 then    t="$format delta" delta=1
680                                 else    t="$format patch"
681                                 fi
682                                 ;;
683                         *)      errexit "$format: invalid format"
684                                 ;;
685                         esac
686                         print " $n$d$t"
687                 done
688                 print
689                 if      ((delta))
690                 then    print "\
691 Unpacking delta shipments requires the new pax command.
692 "
693                 fi
694                 for tool in "${ship_list[@]}"
695                 do      if      test ! -r $tool
696                         then    continue
697                         fi
698                         format=${tool##*/}
699                         tool=${tool%/$format}
700                         if      test -s "$tool/message"
701                         then    item=${tool%%/*}
702                                 eval x='$'_notes_$item
703                                 case $x in
704                                 0)      print "\
705 $item notes:
706 "
707                                         eval _notes_$item=1
708                                         ;;
709                                 1)      if      cmp -s "$tool/message" "$item/$format/message"
710                                         then    continue
711                                         fi
712                                         ;;
713                                 esac
714                                 cat "$tool/message"
715                                 print
716                         fi
717                 done
718                 if      test -f ship.tail
719                 then    cat ship.tail
720                 elif    test -f $HOME/.signature
721                 then    cat $HOME/.signature
722                 fi
723                 print  '!EOF!'
724                 case $noexec in
725                 "")     print 'mail $mail < $tfile'
726                         ;;
727                 *)      print 'print "mail $mail <<!EOF!"'
728                         print "cat $tfile"
729                         print  'echo !EOF!'
730                         ;;
731                 esac
732                 } > $mscript
733                 ;;
734         esac
735 }
736
737 function tosys # machine
738 {
739         # construct return mail address
740         typeset i IFS=!
741         TOSYS=
742         for i in $@
743         do      case $i in
744                 %*)     ;;
745                 *)      TOSYS=$i!$TOSYS ;;
746                 esac
747         done
748         case $TOSYS in
749         $FROMSYS!) TOSYS= ;;
750         esac
751         TOSYS=$TOSYS$FROMSYS
752 }
753
754 function genshiplist # machine user mail
755 {
756         typeset tool file x n v t need_pax= missing=
757         integer i=0 j=0
758
759         lclfiles= rmtfiles=
760         db_init $1 $2
761         db_check - $1 $2 pax "*" base || need_pax=1
762         machine=$1
763         user=$2
764         mail=$3
765         unset ship_list redo
766         for file in $SHIPFILES
767         do      v=$(shipstamp $file)
768                 if      db_check $machine $user $file $v base
769                 then    continue
770                 fi
771                 ship_list[i]=$file/$v/base
772                 i=i+1
773                 case " $SHIPAUX " in
774                 *" $file "*)    redo=1 ;;
775                 esac
776         done
777         j=i
778         for tool in "${tool_list[@]}"
779         do      n=${tool%%/*}
780                 case $need_pax in
781                 "")     eval t=\$type_$n
782                         case $t in
783                         pax)    continue ;;
784                         esac
785                         ;;
786                 esac
787                 v=${tool#*/}
788                 v=${v%/*}
789                 t=${tool##*/}
790                 case $tool in
791                 */*/$SHIPMENT)
792                         if      db_check $machine $user $n $t "*"
793                         then    case $basetoo in
794                                 "")     case $noexec in
795                                         "")     db_note $machine $user $n $t base $name ;;
796                                         esac
797                                         ;;
798                                 ?*)     if      db_check $machine $user $n $v base
799                                         then    :
800                                         elif    test -f $n/$v/base
801                                         then    ship_list[i]=$n/$v/base
802                                                 i=i+1
803                                         else    print -u2 "$n/$v/base: missing base archive"
804                                                 missing=1
805                                         fi
806                                         ;;
807                                 esac
808                         elif    test -f "$n/$v/base"
809                         then    if      db_check $machine $user $n $v base
810                                 then    :
811                                 else    ship_list[i]=$n/$v/base
812                                         i=i+1
813                                 fi
814                                 case $basetoo in
815                                 "")     continue ;;
816                                 esac
817                         elif    test -f $n/$t/base
818                         then    ship_list[i]=$n/$t/base
819                                 i=i+1
820                         else    print -u2 "$n/$t/base: missing base archive"
821                                 missing=1
822                         fi
823                         ;;
824                 esac
825                 if      db_check $machine $user $n $v $t
826                 then    :
827                 else    ship_list[i]=$tool
828                         eval clean_$n=
829                         i=i+1
830                 fi
831         done
832         case $missing in
833         ?*)     exit 1 ;;
834         esac
835         if      ((j>=i))
836         then    case $redo in
837                 "")     case $total in
838                         "")     print -u2 "$mail is up to date" ;;
839                         *)      print -u2 "\\n$mail: up to date" ;;
840                         esac
841                         return 0
842                         ;;
843                 esac
844         else    case $mark in
845                 ?*)     case $user:$noexec in
846                         ?*:)    for tool in "${ship_list[@]}"
847                                 do      x=${tool#*/}
848                                         x=${x%/*}
849                                         db_note $machine $user ${tool%%/*} $x ${tool##*/} $name
850                                 done
851                                 ;;
852                         esac
853                         return 0
854                         ;;
855                 esac
856         fi
857         case $total in
858         ?*)     print -u2 "\\n$mail:"
859                 PS3=''
860                 select i in ${ship_list[*]}
861                 do      :
862                 done </dev/null
863                 return 0
864                 ;;
865         esac
866         return 1
867 }
868
869 function sendcontrol # machine user
870 {
871         # $transport the control file to <user> on given <machine>
872         case $transport in
873         uucp)   typeset dest=$1!$uupublic/$2/$FROMSYS/$date.$SHIPPER
874                 print "$rmtfiles
875 $date.$SHIPPER/unspool
876 $date.$SHIPPER/manifest" > $TMP.m
877                 print uucp -r -C $TMP.u $dest/unspool
878                 case $noexec in
879                 "")     uucp -r -C $TMP.u $dest/unspool ;;
880                 esac
881                 case $SHIPID in
882                 ?*)     print $date.$SHIPPER/id >> $TMP.m
883                         id="$SHIPPER    SEAL    $(date) $1!$2"
884                         print "$1!$SHIPID $id" > $TMP.i
885                         print uucp -r -C $TMP.i $dest/id
886                         case $noexec in
887                         "")     uucp -r -C $TMP.i $dest/id ;;
888                         esac
889                         case $noexec in
890                         "")     print "$id\\t$(shipop seal $lclfiles $TMP.u $TMP.m $TMP.i)" >> $SHIPSLOG/seals
891                                 ;;
892                         esac
893                         ;;
894                 esac
895                 print uucp -r -C -m -n"$2" $TMP.m $dest/manifest
896                 case $noexec in
897                 "")     uucp -r -C -m -n"$2" $TMP.m $dest/manifest ;;
898                 esac
899                 ;;
900         uuto)   print uuto -m $TMP.u $1!$2
901                 case $noexec in
902                 "")     uuto -m $TMP.u $1!$2 ;;
903                 esac
904                 ;;
905         esac
906         case $noexec in
907         ?*)     case $SHIPID in
908                 ?*)     print "ID:"
909                         cat $TMP.i
910                         ;;
911                 esac
912                 print "MANIFEST:"
913                 cat $TMP.m
914                 print "UNSPOOL:"
915                 cat $TMP.u
916                 ;;
917         esac
918 }
919
920 function doship #
921 {
922         # ship the files
923         typeset i j tool file
924         integer d
925         case "$info" in
926         ?*)     fixedname=${name%% *}
927                 print "$fixedname $address $phone $mail $company $project $transport"
928                 return
929         esac
930         user=${mail##*!} machine=${mail%!*}
931         user=${user%%@*} machine=${machine#*@}
932         target=$machine!~/$user/$FROMSYS
933         uuspool=$SHIPSPOOL
934         case $transport in
935         uucp)   uupublic='~'
936                 ;;
937         uuto)   uuspool=$uuspoool/receive
938                 uupublic=$uuspool
939                 print -u2 $transport: transport not supported for $user
940                 return
941                 ;;
942         *)      print -u2 $transport: unknown transport for $user
943                 return
944                 ;;
945         esac
946         if      genshiplist $machine $user $mail
947         then    return
948         fi
949         tosys $machine
950         > $TMP.u
951         for i in "${ship_list[@]}"
952         do      gencontrol "$i"
953         done
954         case $redo in
955         ?*)     for i in $tools
956                 do      print - "for i in \$INSTALLROOT/ship/${i%/*}/*"
957                         print - "do     if      test -d \$i -a ! -f \$i/BUILT"
958                         print - "       then    rm -f \$i/[BEU]*"
959                         print - "       fi"
960                         print - "done"
961                 done >> $TMP.u
962                 ;;
963         esac
964         buildscript $machine $user
965         dtime=0
966         for tool in "${ship_list[@]}"
967         do      for i in $tool.???
968                 do      case $i in
969                         *.\?\?\?|*.000)
970                                 d=25
971                                 if      test -f $tool.001
972                                 then    j=$i
973                                 elif    test -f $tool
974                                 then    i=$tool j=$tool
975                                 else    # here for $SHIPFILES
976                                         i=${tool%%/*}; j=$date.$SHIPPER/$i
977                                 fi;;
978                         *)      j=$i d=50;;
979                         esac
980                         dfile=$target/$j
981                         if      test -f "$i"
982                         then    lclfiles="$lclfiles $i"
983                                 case $rmtfiles in
984                                 "")     rmtfiles=$j
985                                         ;;
986                                 *)      rmtfiles="$rmtfiles
987 $j"
988                                         ;;
989                                 esac
990                                 print   uucp -r $nocopy $PWD/"$i" "$dfile"
991                                 case $noexec in
992                                 "")     uucp -r $nocopy $PWD/"$i" "$dfile"
993                                         dtime=dtime+d
994                                         ;;
995                                 esac
996                         fi
997                 done
998                 i=${tool#*/}
999                 i=${i%/*}
1000                 case $noexec in
1001                 "")     db_note $machine $user ${tool%%/*} $i ${tool##*/} $name ;;
1002                 esac
1003         done
1004         if      test -r $mscript
1005         then    . $mscript
1006         fi
1007         sendcontrol $machine $user
1008 }
1009
1010 function dosend # recipient open
1011 {
1012         # lookup <recipient> in database and transport software to them
1013         # if <open> is given, the database is re-opened
1014         addr=$1
1015         db_disable=
1016         case $addr in
1017         *%beta.*|*%bin*|*%ftp|*%lib*|*%list|*%pull|*%push|*%src)
1018                 db_disable=1
1019                 mail=$addr
1020                 transport=${addr##*'%'}
1021                 machine=%$transport
1022                 user=${addr%"$machine"}
1023                 case $transport in
1024                 beta.*) beta=$SHIPPER transport=${transport#beta.} ;;
1025                 *)      beta= ;;
1026                 esac
1027                 case $transport in
1028                 bin*|lib*|src)
1029                         dir=ship
1030                         out=${user:-${transport%%.*}}
1031                         view=
1032                         case $transport in
1033                         bin)    arch=${PWD%/ship}
1034                                 case $arch in
1035                                 */arch/*)
1036                                         a=${arch##*/}
1037                                         ;;
1038                                 *)      a=${HOSTTYPE:-$(hostinfo type)}
1039                                         ;;
1040                                 esac
1041                                 out=$out.$a
1042                                 type="$a binary"
1043                                 type_H=".I $a
1044 .B binary"
1045                                 ;;
1046                         bin.*)  arch=${transport#bin.}
1047                                 out=$out.$arch
1048                                 transport=bin
1049                                 type="$arch binary"
1050                                 type_H=".I $arch
1051 .B binary"
1052                                 view=1
1053                                 ;;
1054                         lib)    arch=${PWD%/ship}
1055                                 case $arch in
1056                                 */arch/*)
1057                                         a=${arch##*/}
1058                                         ;;
1059                                 *)      a=${HOSTTYPE:-$(hostinfo type)}
1060                                         ;;
1061                                 esac
1062                                 out=$out.$a
1063                                 type="$a binary and library"
1064                                 type_H=".I $a
1065 .B binary
1066 and
1067 .B library"
1068                                 ;;
1069                         lib.*)  arch=${transport#lib.}
1070                                 out=$out.$arch
1071                                 transport=lib
1072                                 type="$arch binary and library"
1073                                 type_H=".I $arch
1074 .B binary
1075 and
1076 .B library"
1077                                 view=1
1078                                 ;;
1079                         *)      arch=..
1080                                 type="source"
1081                                 type_H=".B source"
1082                                 ;;
1083                         esac
1084                         ccprobe=
1085                         case $view in
1086                         ?*)     case $PWD in
1087                                 */arch/*)
1088                                         arch=${PWD%/arch/*}/arch/$arch
1089                                         export INSTALLROOT=$arch
1090                                         vpath $arch ${PWD%/arch/*} 2>/dev/null
1091                                         export VPATH=$arch:${PWD%/arch/*}
1092                                         for f in $arch/lib/probe/C/make/[!p]*bincc $arch/lib/probe/C/make/[!p]*cc $arch/lib/probe/C/make/[!p]*
1093                                         do      if      test -f $f
1094                                                 then    ccprobe=CC.PROBE=$f
1095                                                         break
1096                                                 fi
1097                                         done
1098                                         ;;
1099                                 esac
1100                                 ;;
1101                         esac
1102                         MAKE=$(whence nmake)
1103                         ;;
1104                 *)      dir=. 
1105                         ;;
1106                 esac
1107                 ;;
1108         *:*)    transport=rcp
1109                 mail=$1
1110                 host=${addr%:*}
1111                 dir=${addr#*:}
1112                 case $host in
1113                 *@*)    user=${host%@*}
1114                         host=${host#*@}
1115                         ;;
1116                 *)      user=${dir%%/*}
1117                         case $user in
1118                         '~'*)   user=${user#~} ;;
1119                         *)      user=$SHIPPER ;;
1120                         esac
1121                         ;;
1122                 esac
1123                 machine=$host
1124                 ;;
1125         *!*)    name=${1##*!} transport=uucp
1126                 ;;
1127         *@*)    name=${1%%@*} transport=uucp
1128                 ;;
1129         *)      transport=db
1130                 ;;
1131         esac
1132         case $transport in
1133         uucp)   address= phone= mail=$1 project=
1134                 doship
1135                 return 1
1136                 ;;
1137         db)     typeset -l given match
1138                 case $shipinfo_test in
1139                 "")     if      test ! -f "$SHIPINFO"
1140                         then    errexit "$SHIPINFO: cannot find information file"
1141                         fi
1142                         shipinfo_test=1
1143                         ;;
1144                 esac
1145                 case $2 in
1146                 ?*)     exec 3< $SHIPINFO ;;
1147                 esac
1148                 given=$1
1149                 while IFS=: read -ru3 name address phone mail company project unused transport comments
1150                 do      match=$name
1151                         case $match in
1152                         \#*)            ;;
1153                         $given*)        doship
1154                                         return 1
1155                                         ;;
1156                         esac
1157                 done
1158                 ;;
1159         *)      typeset d i p s
1160                 if      genshiplist $machine $user $mail
1161                 then    return 1
1162                 fi
1163                 tosys $machine
1164                 case $transport in
1165                 ftp)    ftp_address=$(cs -a addr $FROMSYS 2>/dev/null || print - $FROMSYS) ;;
1166                 esac
1167                 exec 9>&1
1168                 case $transport in
1169                 bin|lib);;
1170                 *)      case $transport in
1171                         list|push|src)
1172                                 ;;
1173                         *)      print - "umask 02"
1174                                 ;;
1175                         esac
1176                         case $transport in
1177                         ftp)    print - 'case $INSTALLROOT in'
1178                                 print - '?*)    if      test -d $INSTALLROOT'
1179                                 print - '       then    cd $INSTALLROOT'
1180                                 print - '       else    echo "$0: $INSTALLROOT: invalid INSTALLROOT" >&2'
1181                                 print - '               exit 1'
1182                                 print - '       fi'
1183                                 print - '       ;;'
1184                                 print - 'esac'
1185                                 print - 'if     test ! -d ship'
1186                                 print - 'then   mkdir ship || exit 1'
1187                                 print - 'fi'
1188                                 print - 'cd ship'
1189                                 print - 'if     test -r "$HOME/.netrc" && grep -c "machine[     ]*'$ftp_address'[       ]*" "$HOME/.netrc"'
1190                                 print - 'then   :'
1191                                 print - 'else   echo "machine '$ftp_address' login anonymous password '$user'" >> "$HOME/.netrc"'
1192                                 print - '       chmod 0600 "$HOME/.netrc"'
1193                                 print - 'fi'
1194                                 ;;
1195                         esac
1196                         for i in "${ship_list[@]}"
1197                         do      if      test -f $i
1198                                 then    d=$i/file
1199                                         p=${d%%/*}
1200                                         s=${d#${p}/}
1201                                         t=$p
1202                                         while   test "$s" != file
1203                                         do      if      test "" != "$p"
1204                                                 then    case $transport in
1205                                                         list|src)
1206                                                                 print - "$dir/$p"
1207                                                                 ;;
1208                                                         push)   ;;
1209                                                         *)      print - "if     test ! -d $dir/$p"
1210                                                                 print - "then   mkdir $dir/$p"
1211                                                                 print - "fi"
1212                                                                 ;;
1213                                                         esac
1214                                                 fi
1215                                                 p=${p}/${s%%/*}
1216                                                 s=${d#${p}/}
1217                                         done
1218                                         i=${i%/*}
1219                                         for f in $CRATEFILES
1220                                         do      if      test -s $i/$f
1221                                                 then    case $transport in
1222                                                         list|push|src)
1223                                                                 print - "$dir/$i/$f"
1224                                                                 ;;
1225                                                         *)      print - "echo \"$(cat $i/$f 2>/dev/null)\" > $dir/$i/$f"
1226                                                                 ;;
1227                                                         esac
1228                                                 elif    test -f $i/$f
1229                                                 then    case $transport in
1230                                                         list|push|src)
1231                                                                 print - "$dir/$i/$f"
1232                                                                 ;;
1233
1234                                                         *)      print - "> $dir/$i/$f"
1235                                                                 ;;
1236                                                         esac
1237                                                 fi
1238                                         done
1239                                         case $transport in
1240                                         list|push|src)
1241                                                 if      test "" = "$www" -a -s $i/owner
1242                                                 then    print - "$dir/$i/owner"
1243                                                 fi
1244                                                 ;;
1245                                         *)      if      test "" != "$www"
1246                                                 then    owner=
1247                                                 else    if      test "" = "$shipper" -a -s $i/owner
1248                                                         then    owner=$(<$i/owner)
1249                                                         else    owner=$SHIPPER
1250                                                         fi
1251                                                         case ${TOSYS##*!} in
1252                                                         ${owner%%!*})   owner=${TOSYS%!*}!$owner ;;
1253                                                         *)              owner=$TOSYS!$owner ;;
1254                                                         esac
1255                                                 fi
1256                                                 print - "echo \"$owner\" > $dir/$i/owner"
1257                                                 ;;
1258                                         esac
1259                                 fi
1260                         done
1261                         case $transport in
1262                         list|push|src)
1263                                 ;;
1264                         *)      print - "rm -f $dir/ship.$date"
1265                                 ;;
1266                         esac
1267                         case $transport in
1268                         ftp)    print - '${FTP-ftp} $FTP_ADDRESS <<!!!'
1269                                 print - 'user anonymous'
1270                                 print - 'type image'
1271                                 print - 'cd $FTP_INSTALLROOT/ship'
1272                                 ;;
1273                         esac
1274                         ;;
1275                 esac | case $transport:$noexec in
1276                 bin:|lib:|src:)
1277                         exec 1>$TMP.f
1278                         cat
1279                         test -d Z || mkdir Z
1280                         ;;
1281                 bin:*|lib:*|src:*)
1282                         print - "(cd $arch; pax -w $paxformat) > Z/$out.Z <<!!!"
1283                         cat
1284                         ;;
1285                 ftp:*)  print - ': get shipment from remote ftp host'
1286                         print - 'case $# in'
1287                         print - '0|1|2) ;;'
1288                         print - '*)     echo "Usage: $0 [ftp-address [remote-INSTALLROOT]]" >&2; exit 1 ;;'
1289                         print - 'esac'
1290                         print - 'FTP_ADDRESS=${1-'$ftp_address'}'
1291                         print - 'FTP_INSTALLROOT=${2-.}'
1292                         cat
1293                         ;;
1294                 list:*) cat
1295                         ;;
1296                 pull:*) print - ': pull shipment from remote dk host'
1297                         print - 'case $# in'
1298                         print - '1|2)   ;;'
1299                         print - '*)     echo "Usage: $0 dk-address [remote-INSTALLROOT]" >&2; exit 1 ;;'
1300                         print - 'esac'
1301                         print - 'DK_ADDRESS=$1'
1302                         print - 'DK_INSTALLROOT=${2-.}'
1303                         cat
1304                         ;;
1305                 push:*) print - ': push shipment to remote dk host'
1306                         print - 'case $# in'
1307                         print - '1|2)   ;;'
1308                         print - '*)     echo "Usage: $0 dk-address [remote-INSTALLROOT]" >&2; exit 1 ;;'
1309                         print - 'esac'
1310                         print - 'push $1 - ${2:+$2/}ship <<"!!!"'
1311                         cat
1312                         ;;
1313                 *:)     cat > $TMP.r
1314                         rcp $TMP.r $host:$dir/ship.$date || exit
1315                         rm -f $TMP.r
1316                         case $rsh in
1317                         "")     for i in rcmd remsh
1318                                 do      if      ($i $host date) >/dev/null 2>&1
1319                                         then    rsh=$i
1320                                                 break
1321                                         fi
1322                                 done
1323                                 case $rsh in
1324                                 "") rsh=rsh ;;
1325                                 esac
1326                                 ;;
1327                         esac
1328                         $rsh $host sh $dir/ship.$date || exit
1329                         ;;
1330                 *)      print - "cat '"
1331                         cat
1332                         print - "' > ship.$date"
1333                         print - "rcp ship.$date $host:$dir"
1334                         print - "rm ship.$date"
1335                         print - "rsh $host sh $dir/ship.$date"
1336                         ;;
1337                 esac
1338                 chmod=
1339                 items=
1340                 pwd=.
1341                 skip=
1342                 for tool in "${ship_list[@]}"
1343                 do      if      test ! -f $tool
1344                         then    i=${tool%%/*}
1345                         else    i=$tool
1346                         fi
1347                         dfile=$mail/$i
1348                         if      test -f "$i"
1349                         then    case $transport in
1350                                 bin|lib)case $i in
1351                                         */*)    case $i in
1352                                                 $tool)  i=${i%/*}
1353                                                         i=${i%/*}
1354                                                         case $i in
1355                                                         $skip)  ;;
1356                                                         *)      (
1357                                                                 cd $arch
1358                                                                 r=$PWD
1359                                                                 case $i in
1360                                                                 lib*)   cd src/lib/$i ;;
1361                                                                 *)      cd src/cmd/$i ;;
1362                                                                 esac
1363                                                                 list=list.ship
1364                                                                 case $transport in
1365                                                                 bin)    list=$list.$transport ;;
1366                                                                 esac
1367                                                                 INSTALLROOT=$r $MAKE -o 'accept noexec mismatch reread silent' $list $ccprobe
1368                                                                 )
1369                                                                 ;;
1370                                                         esac
1371                                                         ;;
1372                                                 esac
1373                                                 ;;
1374                                         README|shipout)
1375                                                 print - "ship/$i"
1376                                                 skip=${tool%%/*}
1377                                                 ;;
1378                                         *)      skip=${tool%%/*}
1379                                                 ;;
1380                                         esac
1381                                         ;;
1382                                 ftp)    case $i in
1383                                         */*)    t=${i%/*} ;;
1384                                         *)      t=. ;;
1385                                         esac
1386                                         case $t in
1387                                         $pwd)   ;;
1388                                         *)      print - cd '$FTP_INSTALLROOT'/ship/${i%/*}
1389                                                 case $pwd in
1390                                                 .)      print - lcd $t ;;
1391                                                 *)      print - lcd ../../$t ;;
1392                                                 esac
1393                                                 pwd=$t
1394                                                 ;;
1395                                         esac
1396                                         print - get ${i##*/}
1397                                         test -x $i && chmod="$chmod $i"
1398                                         ;;
1399                                 list|push)
1400                                         print - "$i"
1401                                         ;;
1402                                 pull)   case $i in
1403                                         */*)    t=${i%/*} ;;
1404                                         *)      t=. ;;
1405                                         esac
1406                                         print - echo pull '$DK_ADDRESS' '$DK_INSTALLROOT'/ship/$i $t
1407                                         print - pull '$DK_ADDRESS' '$DK_INSTALLROOT'/ship/$i $t
1408                                         ;;
1409                                 rcp)    print   rcp "$i" "$dfile"
1410                                         case $noexec in
1411                                         "")     rcp "$i" "$dfile" || exit ;;
1412                                         esac
1413                                         ;;
1414                                 src)    print - "ship/$i"
1415                                         case $i in
1416                                         */*)    ;;
1417                                         *)      skip=${tool%%/*} ;;
1418                                         esac
1419                                         ;;
1420                                 esac
1421                         fi
1422                         i=${tool#*/}
1423                         i=${i%/*}
1424                         case $user:$noexec in
1425                         ?*:)    db_note $machine $user ${tool%%/*} $i ${tool##*/} $name ;;
1426                         esac
1427                         i=${tool%%/*}
1428                         case $i in
1429                         $skip)  ;;
1430                         *)      skip=$i
1431                                 items="$items $i"
1432                                 ;;
1433                         esac
1434                 done
1435                 exec 1>&9 9>&-
1436                 case $transport:$noexec in
1437                 bin:|lib:|src:)
1438                         test "" != "$www" && {
1439                         case $type in
1440                         [aehiouAEHIOU]*)
1441                                 a=an
1442                                 ;;
1443                         *)      a=a
1444                                 ;;
1445                         esac
1446                         print - ".TL - - \"$SHIPORG\" \"$SHIPLOGO\"
1447 Software Shipment Contents
1448 This is $a
1449 $type_H
1450 shipment of
1451 .IR $out ."
1452                         if      test -f ship.${out%%.*}.promo
1453                         then    print - ".P"
1454                                 cat ship.${out%%.*}.promo
1455                                 print - ".P"
1456                         fi
1457                         print - "The shipment contains:
1458 .EX"
1459                         case $transport in
1460                         bin)    ls -Cd $(ls -d $items 2>/dev/null | grep -v '^lib') 2>/dev/null ;;
1461                         *)      ls -Cd $items 2>/dev/null ;;
1462                         esac
1463                         print - ".EE"
1464                         hit=" "
1465                         for tool in "${ship_list[@]}"
1466                         do      tool=${tool%/*}
1467                                 case $hit in
1468                                 *" $tool "*)
1469                                         ;;
1470                                 *)      hit="$hit$tool "
1471                                         if      test -f $tool/promo
1472                                         then    promo=1
1473                                                 cat $tool/promo
1474                                         else    promo=
1475                                         fi
1476                                         if      test -f $tool/release
1477                                         then    case $promo in
1478                                                 "")     print - ".H 1 ${tool%/*}"
1479                                                         ;;
1480                                                 esac
1481                                                 print - ".P"
1482                                                 print - ".DS"
1483                                                 cat $tool/release
1484                                                 print - ".DE"
1485                                         fi
1486                                         ;;
1487                                 esac
1488                         done
1489                         print - ".H 1
1490 If you have problems send mail to
1491 .I advsoft@attmail.att.com
1492 with
1493 .I $out
1494 in the subject field."
1495                         } | $SHIPMM2HTML >Z/$out.H
1496                         {
1497                         print - "#"
1498                         print - "# the following ${beta:+beta }$type shipment"
1499                         print - "# of $out has been sent"
1500                         case $beta in
1501                         ?*)     print - "# this beta shipment may only be interface compatible with itself"
1502                                 print - "# other shipments will be reconciled after beta testing"
1503                                 ;;
1504                         esac
1505                         print - "#"
1506                         case $transport in
1507                         bin)    ls -Cd $(ls -d $items 2>/dev/null | grep -v '^lib') 2>/dev/null ;;
1508                         *)      ls -Cd $items 2>/dev/null ;;
1509                         esac | sed 's/^/#   /'
1510                         print - "#"
1511                         print - "# to install:"
1512                         print - "#"
1513                         print - "INSTALLROOT=<installation-root-dir>${beta:+/beta.$beta}"
1514                         print - "SHIPMENT=<shipment-.Z-file>"
1515                         print - "cd \$INSTALLROOT"
1516                         print - "$paxuncompress \$SHIPMENT | $paxunformat"
1517                         case $transport in
1518                         bin|lib)(cd $arch; ls -ld $(<$TMP.f) 2>/dev/null) > $TMP.s
1519                                 for f in $(sed -e '/^-..s..s/!d' -e 's/.* //' $TMP.s)
1520                                 do      set x $(cd $arch; ls -ld $f 2>/dev/null)
1521                                         n=$#
1522                                         g=$5
1523                                         set x $(cd $arch; ls -ldg $f 2>/dev/null)
1524                                         n1=$#
1525                                         g1=$5
1526                                         if      test $n -lt $n1
1527                                         then    g=$g1
1528                                         fi
1529                                         print - "chgrp $g $f || echo ship: $f would be more efficient if owned by group $g >&2"
1530                                 done
1531                                 sed -e '/^-..s/!d' -e 's/^-..s..s.* /chmod ug+s /' -e 's/^-..s.* /chmod u+s /' $TMP.s
1532                                 rm $TMP.s
1533                                 for f in $items
1534                                 do      test -f $f/binary && cat $f/binary
1535                                 done
1536                                 ;;
1537                         src)    print - "nohup ksh ship/shipin &"
1538                                 ;;
1539                         esac
1540                         print - "#"
1541                         print - "# to use:"
1542                         print - "#"
1543                         print - "export LD_LIBRARY_PATH=\$INSTALLROOT/lib\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}"
1544                         print - "export PATH=\$INSTALLROOT/bin:\$PATH"
1545                         print - "export FPATH=\$INSTALLROOT/fun\${FPATH:+:\$FPATH}"
1546                         } >Z/$out.M
1547                         case $transport in
1548                         bin)    (cd $arch; sort -u $TMP.f | egrep -v '^(include/.*|lib/lib.*\.a)$' |  pax -Lw $paxformat; rm $TMP.f) > Z/$out.Z ;;
1549                         *)      (cd $arch; sort -u $TMP.f | pax -Lw $paxformat; rm $TMP.f) > Z/$out.Z ;;
1550                         esac
1551                         ;;
1552                 bin:*|ftp:*|lib:*|push:*|src:*)
1553                         case $transport in
1554                         ftp)    print - 'quit' ;;
1555                         esac
1556                         print - '!!!'
1557                         case $chmod in
1558                         ?*)     print - "chmod +x$chmod" ;;
1559                         esac
1560                         ;;
1561                 esac
1562                 return 1
1563                 ;;
1564         esac
1565         print -u2 "$command: address for $1 not found"
1566         return 1
1567 }
1568
1569 function closure # tools
1570 {
1571         tools=
1572         for tool
1573         do      if      test ! -d $tool
1574                 then    case $original in
1575                         *" ${tool%/*} "*|*" $tool "*)   warning "${tool%/*}: invalid tool" ;;
1576                         esac
1577                 else    case $tool in
1578                         */?*)   release=${tool#*/}
1579                                 tool=${tool#*/}
1580                                 ;;
1581                         *)      eval items=\"\$items_$item\"
1582                                 case $items in
1583                                 "")     release= ;;
1584                                 *)      eval release=\$release_$tool ;;
1585                                 esac
1586                                 ;;
1587                         esac
1588                         eval release_${tool%/*}=$release
1589                         tools="$tools $tool"
1590                 fi
1591         done
1592         set -- $tools
1593         #
1594         # now generate the closure of the top level tools and releases
1595         #
1596         tools=
1597         for tool
1598         do      old=
1599                 new=$tool
1600                 while :
1601                 do      case $new in
1602                         $old)   break
1603                         esac
1604                         dup=
1605                         for item in $new
1606                         do      # we assume items_* not in environment
1607                                 eval items=\"\$items_$item\"
1608                                 case $items in
1609                                 "")     eval release=\$release_$item
1610                                         case $release in
1611                                         "")     set -- $item/$SHIPMENT
1612                                                 shift $#-1
1613                                                 case $1 in
1614                                                 "$item/$SHIPMENT") continue ;;
1615                                                 esac
1616                                                 release=${1#*/}
1617                                                 eval release_$item=$release
1618                                         esac
1619                                         if      test ! -f $item/$release/items
1620                                         then    if      test ! -f $item/$release/delete
1621                                                 then    continue
1622                                                 fi
1623                                                 items=$item
1624                                         else    case $closure in
1625                                                 "")     items=$item ;;
1626                                                 *)      items=$(<$item/$release/items)" $item" ;;
1627                                                 esac
1628                                         fi
1629                                         eval items_$item=\"$items\"
1630                                         ;;
1631                                 esac
1632                                 dup="$dup $items"
1633                         done
1634                         old=$new
1635                         new=
1636                         for item in $dup
1637                         do      eval seen_$item=
1638                         done
1639                         for item in $dup
1640                         do      eval seen=\$seen_$item
1641                                 case $seen in
1642                                 "")     eval seen_$item=1
1643                                         new="$new $item"
1644                                 esac
1645                         done
1646                 done
1647                 tools="$tools $new"
1648         done
1649 }
1650
1651 function undup # tools
1652 {
1653         tools=
1654         for item
1655         do      eval seen_$item=
1656         done
1657         for item
1658         do      eval seen=\$seen_$item
1659                 case $seen in
1660                 "")     eval seen_$item=1
1661                         tools="$tools $item"
1662                 esac
1663         done
1664 }
1665
1666 command=$0
1667 integer dtime=0 i=0 nrecipient=0 first_time=1 delay=0
1668 info= mark= list= logfile= message=1 nocopy= noexec= format=$SHIPMENT
1669 shipinfo_test= force= shipper= closure=1 undo= date= basetoo= www=
1670 paxformat= paxunformat= paxcompress= paxuncompress=
1671 while   :
1672 do      case    $1 in
1673         -b)     basetoo=1 ;;
1674         +b)     basetoo= ;;
1675         -c)     closure= ;;
1676         +c)     closure=1 ;;
1677         -d)     format=base ;;
1678         +d)     format=$SHIPMENT ;;
1679         -i)     info=1 delay=0 ;;
1680         -k)     mark=1 delay=0 ;;
1681         -l)     shift; list=$1 ;;
1682         +l)     list= ;;
1683         -m)     message= ;;
1684         +m)     message=1 ;;
1685         -n)     noexec=1 delay=0 ;;
1686         +n)     noexec= ;;
1687         -o)     shipper=1 ;;
1688         +o)     shipper= ;;
1689         -p)     shift; recipient_list[nrecipient]=$1; nrecipient=nrecipient+1 ;;
1690         +p)     recipient= ;;
1691         -s)     SHIPFILES= ;;
1692         -t)     total=1 noexec=1 delay=0 ;;
1693         -u)     shift; undo=$1 ;;
1694         +u)     undo= ;;
1695         -v)     shift; date=$1 ;;
1696         -w)     www=1 ;;
1697         +w)     www= ;;
1698         -x)     shift
1699                 case $1 in
1700                 compress|gzip)
1701                         paxcompress=$1
1702                         ;;
1703                 *)      paxformat=$1
1704                         ;;
1705                 esac
1706                 ;;
1707         -C)     shift; CRATEFILES="$CRATEFILES $1" ;;
1708         -D)     shift;  delay=$1 ;;
1709         +D)     delay=0 ;;
1710         -F)     force=1 ;;
1711         +F)     force= ;;
1712         -L)     shift; logfile=$1 ;;
1713         -S)     shift; SHIPFILES="$SHIPFILES $1" ;;
1714         *[,:!%@]*)recipient_list[nrecipient]=$1;nrecipient=nrecipient+1 ;;
1715         --)     shift; break ;;
1716         -*|+*)  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 ;;
1717         *)      break ;;
1718         esac
1719         shift
1720 done
1721 case $www in
1722 ?*)     case $paxformat in
1723         "")     paxformat=tar ;;
1724         esac
1725         case $paxcompress in
1726         "")     paxcompress=gzip ;;
1727         esac
1728         ;;
1729 esac
1730 case $paxcompress in
1731 ""|compress)
1732         paxcompress=compress
1733         paxuncompress="zcat <"
1734         ;;
1735 gzip)   paxuncompress="(gunzip || zcat) <"
1736         ;;
1737 esac
1738 case $paxformat in
1739 "")     paxformat=cpio ;;
1740 esac
1741 case $paxformat in
1742 cpio)   paxunformat="cpio -icdvmu" ;;
1743 tar)    paxunformat="tar xvf -" ;;
1744 *)      paxunformat="pax -rv" ;;
1745 esac
1746 case $paxformat in
1747 ?*)     paxformat="-x $paxformat" ;;
1748 esac
1749 case $paxcompress in
1750 ?*)     paxformat="-x $paxcompress $paxformat" ;;
1751 esac
1752 case $date in
1753 $SHIPMENT)      ;;
1754 *)              date=$(shipstamp) ;;
1755 esac
1756 ($SHIPMM2HTML) >/dev/null 2>&1 || SHIPMM2HTML=cat
1757 case $info in
1758 "")     if      test 0 = "$nrecipient" -a ! -f "$list"
1759         then    errexit "no recipient(s)"
1760         fi
1761         trap 'cleanup $?' EXIT INT TERM
1762         #
1763         # generate the tools list
1764         #
1765         original=" $* "
1766         case $# in
1767         0)      tools=
1768                 for tool in *
1769                 do      set -- $tool/$SHIPMENT
1770                         case $1 in
1771                         "$tool/$SHIPMENT")      ;;
1772                         *)              tools="$tools $tool" ;;
1773                         esac
1774                 done
1775                 case $tools in
1776                 "")     errexit "no tools" ;;
1777                 esac
1778                 set -- $tools
1779                 ;;
1780         esac
1781         closure $*
1782         case $tools in
1783         "")     errexit "no 'items' file(s)" ;;
1784         esac
1785         tools_usr=$tools
1786         tools_pax=
1787         case $closure:$format:$SHIPFILES in
1788         :*|*:|*:base:*|*:delete:*)
1789                 ;;
1790         *)      set -- pax/$SHIPMENT
1791                 case $1 in
1792                 "$tool/$SHIPMENT")
1793                         ;;
1794                 *)      closure pax
1795                         tools_pax=$tools
1796                         ;;
1797                 esac
1798                 ;;
1799         esac
1800         undup $tools_pax $tools_usr
1801         set -- $tools
1802         for tool in $tools_pax
1803         do      eval type_$tool=pax
1804         done
1805         for tool in $tools_usr
1806         do      eval type_$tool=usr
1807         done
1808         set -- $tools
1809         for tool
1810         do      eval tool=$tool/\$release_$tool
1811                 item=
1812                 for f in delete "$format" base
1813                 do      set -- $tool/$f
1814                         if      test -f "$1"
1815                         then    item=${1##*/}
1816                                 break
1817                         fi
1818                 done
1819                 case $item in
1820                 "")     if      test ! -d ${tool%/*}
1821                         then    case $original in
1822                                 *" ${tool%/*} "*|*" $tool "*)   warning "${tool%/*}: invalid tool" ;;
1823                                 esac
1824                                 continue
1825                         fi
1826                         case $format in
1827                         base)   set -- $tool/$SHIPMENT
1828                                 if      test -f "$1"
1829                                 then    eval release_${tool%/*}=${1##*/}
1830                                         tool=${tool%/*}/${1##*/}
1831                                         item=base
1832                                         warning "${tool}: latest base not crated"
1833                                 else    warning "${tool}: base not crated"
1834                                         continue
1835                                 fi
1836                                 ;;
1837                         *)      continue
1838                                 ;;
1839                         esac
1840                         ;;
1841                 esac
1842                 case $format in
1843                 "$SHIPMENT"|$item)
1844                         tool=$tool/$item
1845                         ;;
1846                 *)      tool=${tool%/*}/$item/base
1847                         if      test ! -f $tool
1848                         then    errexit "${tool%/*}: $item base not crated"
1849                         fi
1850                         ;;
1851                 esac
1852                 tool_list[i]=$tool;i=i+1
1853         done
1854         ;;
1855 *)      typeset -lL16 fixedname
1856         typeset -L9 address project
1857         typeset -R12 phone
1858         typeset -L21 mail
1859         typeset -L11 company
1860         ;;
1861 esac
1862 if      test ! -d $SHIPSLOG
1863 then    mkdir $SHIPSLOG || errexit "$SHIPSLOG: cannot create log directory"
1864 fi
1865
1866 SHIPID=$FROMSYS!$SHIPPER
1867 case $SHIPFILES in
1868 ?*)     SHIPFILES="$SHIPFILES $SHIPAUX"
1869         for file in $SHIPFILES
1870         do      if      test ! -r $file
1871                 then    print -u2 "$file: cannot read"; exit 1
1872                 fi
1873         done
1874         ;;
1875 esac
1876 while   :
1877 do      case $undo in
1878         ""|??????*)     break ;;
1879         *)              undo="?$undo" ;;
1880         esac
1881 done
1882 nocopy=${nocopy+-c}
1883 flag=1
1884 case $list in
1885 "")     set -s -- "${recipient_list[@]}"
1886         ;;
1887 ?*)     if      test ! -r "$list"
1888         then    errexit "$list: cannot read"
1889         else    set -s -- "${recipient_list[@]}" $(sed -e '/^#/d' -e 's/[:      ].*//' $list)
1890         fi
1891         ;;
1892 esac
1893 for recipient
1894 do      if      ((dtime))
1895         then    sleep $dtime
1896         fi
1897         if      dosend "$recipient" $flag
1898         then    flag=
1899                 case $noexec$info in
1900                 "")     print "$name" >> ${tool%/*}/list ;;
1901                 esac
1902         else    flag=1
1903         fi
1904         if      ((delay > dtime))
1905         then    dtime=delay
1906         fi
1907 done
1908 exit 0