|
|
1.1 root 1: :
2: # @(#)shipout (ulysses!{dgk,gsf}) 01/31/91
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: # -C files add to default crate file list
25: # -D secs delay in seconds between sends
26: # -F force db override
27: # -S files add to default support file list
28: #
29: # name -- recipient address
30: #
31: # machine!user uucp address
32: # host:directory rcp address
33: # *%compress generates compressed cpio archive on stdout
34: # *%list generates shipment file list
35: # *%pull generates sh script with datakit pull's
36: # *%push generates sh script with datakit push's
37: #
38: # the message file is evaluated by the shell and the following variables
39: # are predefined by ship:
40: #
41: # f list of expanded file names
42: # name name of shipee
43: #
44:
45: umask 02
46: PATH=:$PATH
47:
48: SHIPSLOG=${SHIPSLOG:-shipslog}
49: SHIPINFO=${SHIPINFO:-$SHIPSLOG/info}
50: SHIPFILES="README shipin shipout"
51: SHIPMENT=*[0-9][0-9][0-9][0-9][0-9][0-9]
52: SHIPPER=${SHIPPER:-${USER:-${LOGNAME:-${HOME##*/}}}}
53: SHIPSPOOL=${SHIPSPOOL:-/usr/spool/uucppublic}
54: CRATEFILES="items message promo release report"
55: TMP=${TMPDIR:=/tmp}/ship$$
56: FROMSYS=$((uname -n || hostname || cat /etc/whoami) 2>/dev/null)
57:
58: test -f shipinit && . ./shipinit
59:
60: function errexit
61: {
62: # print out an error message on unit 2 and exit
63: print -u2 - "$command: $@"
64: exit 1
65: }
66:
67: function warning
68: {
69: print -u2 - "$command: warning: $@"
70: }
71:
72: function cleanup # exitcode
73: {
74: db_done
75: rm -f $TMP.?
76: exit $1
77: }
78:
79: db_data=
80: db_db=
81: db_key_base=
82: db_key_delta=
83: db_status=
84: db_style=
85:
86: #
87: # send request to dbm server
88: # status returned in db_status
89: # data returned in db_data
90: #
91:
92: function db_request # request
93: {
94: print -p "$@"
95: read -p db_status db_data
96: case $db_debug in
97: ?*) print -u2 DB: "$@": $db_status $db_data ;;
98: esac
99: case $db_status in
100: I) return 0 ;;
101: E) print -u2 $logfile: $db_data; return 1 ;;
102: *) return 1 ;;
103: esac
104: }
105:
106: #
107: # initialize db
108: #
109:
110: function db_init # machine user
111: {
112: case $db_debug in
113: grep) db_style=grep ;;
114: esac
115: case $db_style in
116: "") if (shipdbm) </dev/null >/dev/null 2>&1
117: then db_style=dbm
118: logfile=$SHIPSLOG/log
119: shipdbm |&
120: db_request om$logfile || db_request oc$logfile || errexit $logfile: cannot access log
121: db_db=$db_data
122: else db_style=grep
123: fi
124: ;;
125: esac
126: case $db_style in
127: dbm) first_time=0
128: db_request s$db_db
129: db_check - $1 $2 shipin "*" base || first_time=1
130: ;;
131: grep) typeset -L2 dir=$1
132: case $logfile in
133: ?*) mv $logfile $SHIPSLOG/.tmp.
134: sort -r < $SHIPSLOG/.tmp. | sort -m -u +0 -1 > $logfile
135: rm -f $SHIPSLOG/.tmp.
136: ;;
137: esac
138: logfile=$SHIPSLOG/$dir/$1/$2
139: if test "" = "$force" -a -r "$logfile"
140: then first_time=0
141: else first_time=1
142: case $noexec in
143: "") if test ! -d "$SHIPSLOG/$dir"
144: then mkdir "$SHIPSLOG/$dir" || logfile=$SHIPSLOG/log
145: fi
146: if test ! -d "$SHIPSLOG/$dir/$1"
147: then mkdir "$SHIPSLOG/$dir/$1" || logfile=$SHIPSLOG/log
148: fi
149: ;;
150: esac
151: fi
152: ;;
153: esac
154: }
155:
156: #
157: # end db interaction
158: #
159:
160: function db_done #
161: {
162: case $noexec in
163: "") case $db_style in
164: dbm) case $db_db in
165: ?*) db_request c$db_db && db_request q ;;
166: esac
167: ;;
168: grep) case $logfile in
169: ?*) mv $logfile $SHIPSLOG/.tmp.
170: sort -r < $SHIPSLOG/.tmp. | sort -m -u +0 -1 > $logfile
171: rm -f $SHIPSLOG/.tmp.
172: ;;
173: esac
174: ;;
175: esac
176: ;;
177: esac
178: }
179:
180: #
181: # check if < machine user tool version type > was sent
182: #
183:
184: function db_check # [ - ] machine user tool version type
185: {
186: typeset k key ks sav x nocheck=
187: case $first_time:$force in
188: 1:*|*:1) return 1 ;;
189: esac
190: case $1 in
191: -) shift; nocheck=1 ;;
192: esac
193: typeset a=$1!$2 n=$3 v=$4 t=$5 m
194: case $5 in
195: "*") ks="base delta" ;;
196: base) ks=base ;;
197: *) ks=delta ;;
198: esac
199: for k in $ks
200: do key=$a,$n,$k
201: eval sav=\$db_key_$k
202: case $key in
203: $sav) eval set -- \$db_val_$k
204: ;;
205: *) case $db_style in
206: dbm) if db_request g$db_db$key
207: then set -- $db_data
208: else continue
209: fi
210: ;;
211: grep) set -- `grep "^$key" $logfile`
212: case $# in
213: 0) continue ;;
214: esac
215: shift
216: ;;
217: esac
218: eval db_key_$k='$key' db_val_$k='$*'
219: ;;
220: esac
221: case $1/$2 in
222: $v/$t) case $undo:$nocheck in
223: :*|*:1) ;;
224: *) continue ;;
225: esac
226: case $3 in
227: $undo) continue ;;
228: *) ;;
229: esac
230: case $v in
231: "*") return 0 ;;
232: esac
233: ;;
234: *) case "$v" in
235: "*") return 0 ;;
236: esac
237: continue
238: ;;
239: esac
240: if test -d $n
241: then m=$(shipop time $n/$1/$2)
242: else m=$(shipop time $n)
243: fi
244: case $6 in
245: ""|$m) return 0 ;;
246: *) return 1 ;;
247: esac
248: done
249: return 1
250: }
251:
252: #
253: # note that < machine user tool version type > was sent
254: #
255:
256: function db_note # machine user tool version type name
257: {
258: typeset k v m
259: case $5 in
260: base) k=base ;;
261: *) k=delta ;;
262: esac
263: if test -d $3
264: then m=$(shipop time $3/$4/$5)
265: else m=$(shipop time $3)
266: fi
267: v="$1!$2,$3,$k $4 $5 $date $SHIPPER $6 $m"
268: case $db_style in
269: dbm) db_request p$db_db$v ;;
270: grep) print $v >> $logfile ;;
271: esac
272: }
273:
274: #
275: # output SHIPMENT stamp for file [current date]
276: #
277:
278: function shipstamp # file
279: {
280: typeset -Z2 day month
281: typeset -R2 year
282: integer mon Jan=1 Feb=2 Mar=3 Apr=4 May=5 Jun=6 \
283: Jul=7 Aug=8 Sep=9 Oct=10 Nov=11 Dec=12
284: case $# in
285: 0) set -- $(date)
286: shift 1
287: ;;
288: *) set -- $(ls -ld $1)
289: while :
290: do case $# in
291: [01]) break ;;
292: esac
293: case $1 in
294: Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
295: case $2 in
296: [1-9]|[0-3][0-9])
297: case $3 in
298: [0-9]*) break ;;
299: esac
300: ;;
301: esac
302: ;;
303:
304: esac
305: shift
306: done
307: ;;
308: esac
309: mon=$1
310: day=$2
311: month=$mon
312: case $3 in
313: *:*:*) year=$5
314: ;;
315: *:*) set -- $(date)
316: year=$6
317: if (($mon > $2))
318: then let year=year-1
319: fi
320: ;;
321: *) year=$3
322: ;;
323: esac
324: print $year$month$day
325: }
326:
327: #
328: # prepare $tool for shipping -- $tool.000 always created
329: #
330:
331: function package
332: {
333: typeset tool=$1
334: integer nblocks=${2-20}
335:
336: integer size i=0 skip=0
337: integer chunksize=nblocks*8*1024
338: typeset -RZ3 suffix
339: typeset fsize
340: print packaging $tool
341: rm -f "$tool".???
342: fsize=$(wc -c $tool)
343: size=${fsize%$tool}
344: if ((size <= chunksize))
345: then ln "$tool" "$tool".000
346: else while (( size > 0))
347: do suffix=$i
348: dd if="$tool" of="$tool.$suffix" bs=8k skip=$skip count=$nblocks 2> /dev/null
349: let i=i+1 skip=skip+nblocks size=size-chunksize
350: done
351: fi
352: set -- "$tool".???
353: case $1 in
354: *.\?\?\?) errexit "$tool: cannot package" ;;
355: esac
356: }
357:
358: function gencontrol # tool
359: {
360: typeset tool=${1%/*}
361: typeset format=${1#$tool/}
362: typeset init
363: if test -f $1
364: then if test $1 -nt $1.000
365: then package $1
366: fi
367: set -- $1.???
368: else # $SHIPFILES
369: print - "cp $date.$SHIPPER/${tool%/*} \$INSTALLROOT/ship" >> $TMP.u
370: return
371: fi
372: tooldir=${tool%%/*}
373: {
374: cat <<-!
375: if test ! -f "\$INSTALLROOT/ship/$tooldir/items"
376: then
377: !
378: case $format in
379: base) init= ;;
380: *) init=$basetoo ;;
381: esac
382: case $init in
383: "") cat <<-!
384: if test ! -d "\$INSTALLROOT/ship/$tooldir"
385: then mkdir "\$INSTALLROOT/ship/$tooldir"
386: fi
387: rm -rf "\$INSTALLROOT/ship/$tool"
388: mkdir "\$INSTALLROOT/ship/$tool"
389: !
390: ;;
391: esac
392: cat <<-!
393: if cat $tool/$format.??? > \$INSTALLROOT/ship/$tool/$format
394: then rm -f $tool/$format.???
395: fi
396: !
397: case $init in
398: "") for i in $CRATEFILES
399: do if test -s $tool/$i
400: then print - "echo \"$(cat $tool/$i 2>/dev/null)\" > \$INSTALLROOT/ship/$tool/$i"
401: elif test -f $tool/$i
402: then print - "> \$INSTALLROOT/ship/$tool/$i"
403: fi
404: done
405: if test "" = "$shipper" -a -s $tool/owner
406: then owner=$(<$tool/owner)
407: else owner=$SHIPPER
408: fi
409: case ${TOSYS##*!} in
410: ${owner%%!*}) owner=${TOSYS%!*}!$owner ;;
411: *) owner=$TOSYS!$owner ;;
412: esac
413: print - "echo \"$owner\" > \$INSTALLROOT/ship/$tool/owner"
414: ;;
415: esac
416: cat <<-!
417: fi
418: !
419: } >> $TMP.u
420: }
421:
422: function buildscript # machine user
423: {
424: # create mscript to execute as a . script
425: typeset tool format
426: integer delta=0 first=1 no_shipin
427: mscript=$TMP.s tfile=$TMP.f
428: case $message in
429: ?*) {
430: print "cat > $tfile <<!EOF!"
431: print "Subject: software shipment"
432: if test -f ship.body
433: then print
434: cat ship.body
435: else f=${name#*,}
436: l=${name%,*}
437: case $f in
438: $l) ;;
439: *) print "\
440:
441: Dear ${name#*,} ${name%,*}:" ;;
442: esac
443: if test -f ship.head
444: then cat ship.head
445: print
446: fi
447: if db_check $1 $2 shipin "*" base
448: then no_shipin=0
449: else no_shipin=1
450: fi
451: if ((first_time||no_shipin))
452: then print "\
453:
454: As a first time recipient:
455:
456: (1) Wait for a \\\`copy succeeded' message from uucp for the file:
457:
458: \$user/$FROMSYS/$date.$SHIPPER/manifest
459:
460: (2) For safety do not run as root. If you are not running as \$user then:
461:
462: RECIPIENT=\$user
463: export RECIPIENT
464:
465: (3) Create a shipment root directory under which all source and binaries
466: will be generated. This should not be a final installation directory.
467:
468: INSTALLROOT=<shipment-root-directory>
469: test -d \\\$INSTALLROOT || mkdir \\\$INSTALLROOT
470: cd \\\$INSTALLROOT
471: test -d ship || mkdir ship
472:
473: (4) Name the uucp shipment spool directory:
474:
475: SHIPSPOOL=$uuspool/\$user/$FROMSYS
476:
477: however if $uuspool/\$user/$FROMSYS was copied to \\\$SPOOLROOT then:
478:
479: SHIPSPOOL=\\\$SPOOLROOT
480:
481: (5) If your system has att and bsd/ucb universes then in general the tools
482: will have more functionality when built in the bsd/ucb universe. You
483: can set the C compiler name and/or flags by:
484:
485: CC='hackcc -systype bsd43' CCFLAGS='-g' # just an example #
486: export CC CCFLAGS
487:
488: (6) Execute the following commands to unpack and install the shipment:
489:
490: export SHIPSPOOL
491: cp \\\$SHIPSPOOL/$date.$SHIPPER/shipin ship/shipin
492: chmod 0755 ship/shipin
493: nohup ship/shipin &
494:
495: (7) Use shipout within \\\$INSTALLROOT/ship to ship to other machines.
496: \\\$INSTALLROOT/ship/README contains more detailed information.
497: "
498: else print "\
499:
500: As a repeat recipient:
501:
502: (1) Wait for a \\\`copy succeeded' message from uucp for the file:
503:
504: \$user/$FROMSYS/$date.$SHIPPER/manifest
505:
506: (2) For safety do not run as root. If you are not running as \$user then:
507:
508: RECIPIENT=\$user
509: export RECIPIENT
510:
511: (3) Name the directory under which previous shipments were installed:
512:
513: INSTALLROOT=<shipment-root-directory>
514:
515: (4) If $uuspool/\$user/$FROMSYS was copied to \\\$SPOOLROOT then:
516:
517: SHIPSPOOL=\\\$SPOOLROOT
518: export SHIPSPOOL
519:
520: (5) If your system has att and bsd/ucb universes then in general the tools
521: will have more functionality when built in the bsd/ucb universe. You
522: can set the C compiler name and/or flags by:
523:
524: CC='hackcc -systype bsd43' CCFLAGS='-g' # just an example #
525: export CC CCFLAGS
526:
527: (6) Execute the following commands to unpack and install the shipment:
528:
529: cd \\\$INSTALLROOT
530: nohup ship/shipin &
531:
532: (7) Use shipout within \\\$INSTALLROOT/ship to ship to other machines.
533: \\\$INSTALLROOT/ship/README contains more detailed information.
534: "
535: fi
536: fi
537: typeset -L n='tool ' d='release '
538: t='type'
539: print "\
540: This distribution contains:
541:
542: $n$d$t"
543: n=----
544: d=-------
545: t=----
546: print "\
547: $n$d$t"
548: for tool in "${ship_list[@]}"
549: do format=${tool##*/}
550: tool=${tool%/$format}
551: test -r $tool && eval _notes_${tool%%/*}=0
552: n=${tool%%/*}
553: d=${tool##*/}
554: case $format in
555: base) t="base" ;;
556: $SHIPMENT) t="$format delta" delta=1 ;;
557: *) errexit "$format: invalid format" ;;
558: esac
559: print " $n$d$t"
560: done
561: print
562: if ((delta))
563: then print "\
564: Unpacking delta shipments requires the new pax command.
565: "
566: fi
567: for tool in "${ship_list[@]}"
568: do if test ! -r $tool
569: then continue
570: fi
571: format=${tool##*/}
572: tool=${tool%/$format}
573: if test -s "$tool/message"
574: then item=${tool%%/*}
575: eval x='$'_notes_$item
576: case $x in
577: 0) print "\
578: $item notes:
579: "
580: eval _notes_$item=1
581: ;;
582: 1) if cmp -s "$tool/message" "$item/$format/message"
583: then continue
584: fi
585: ;;
586: esac
587: cat "$tool/message"
588: print
589: fi
590: done
591: if test -f ship.tail
592: then cat ship.tail
593: elif test -f $HOME/.signature
594: then cat $HOME/.signature
595: fi
596: print '!EOF!'
597: case $noexec in
598: "") print 'mail $mail < $tfile'
599: ;;
600: *) print 'print "mail $mail <<!EOF!"'
601: print "cat $tfile"
602: print 'echo !EOF!'
603: ;;
604: esac
605: } > $mscript
606: ;;
607: esac
608: }
609:
610: function tosys # machine
611: {
612: # construct return mail address
613: typeset IFS=!
614: TOSYS=
615: for i in $@
616: do TOSYS=$i!$TOSYS
617: done
618: case $TOSYS in
619: $FROMSYS!) TOSYS= ;;
620: esac
621: TOSYS=$TOSYS$FROMSYS
622: }
623:
624: function genshiplist # machine user mail
625: {
626: typeset tool file x n v t need_pax= missing=
627: integer i=0 j=0
628: lclfiles= rmtfiles=
629: db_init $1 $2
630: db_check - $1 $2 pax "*" base || need_pax=1
631: machine=$1
632: user=$2
633: mail=$3
634: unset ship_list
635: for file in $SHIPFILES
636: do if test ! -r "$file"
637: then continue
638: fi
639: v=$(shipstamp $file)
640: if db_check $machine $user $file $v base
641: then continue
642: fi
643: ship_list[i]=$file/$v/base
644: i=i+1
645: done
646: j=i
647: for tool in "${tool_list[@]}"
648: do n=${tool%%/*}
649: case $need_pax in
650: "") eval t=\$type_$n
651: case $t in
652: pax) continue ;;
653: esac
654: ;;
655: esac
656: v=${tool#*/}
657: v=${v%/*}
658: t=${tool##*/}
659: case $tool in
660: */*/$SHIPMENT)
661: if db_check $machine $user $n $t "*"
662: then case $basetoo in
663: ?*) if db_check $machine $user $n $v base
664: then :
665: elif test -f $n/$v/base
666: then ship_list[i]=$n/$v/base
667: i=i+1
668: else print -u2 "$n/$v/base: missing base archive"
669: missing=1
670: fi
671: ;;
672: *) case $noexec in
673: "") db_note $machine $user $n $t base $name ;;
674: esac
675: ;;
676: esac
677: elif test -f "$n/$v/base"
678: then if db_check $machine $user $n $v base
679: then case $basetoo in
680: "") continue ;;
681: esac
682: else ship_list[i]=$n/$v/base
683: i=i+1
684: case $basetoo in
685: "") continue ;;
686: esac
687: fi
688: elif test -f $n/$t/base
689: then ship_list[i]=$n/$t/base
690: i=i+1
691: else print -u2 "$n/$t/base: missing base archive"
692: missing=1
693: fi
694: ;;
695: esac
696: if db_check $machine $user $n $v $t
697: then continue
698: fi
699: ship_list[i]=$tool
700: eval clean_$n=
701: i=i+1
702: done
703: case $missing in
704: ?*) exit 1 ;;
705: esac
706: if ((j>=i))
707: then case $total in
708: "") print -u2 "$mail is up to date" ;;
709: *) print -u2 "\n$mail: up to date" ;;
710: esac
711: return 0
712: else case $mark in
713: ?*) case $user:$noexec in
714: ?*:) for tool in "${ship_list[@]}"
715: do x=${tool#*/}
716: x=${x%/*}
717: db_note $machine $user ${tool%%/*} $x ${tool##*/} $name
718: done
719: ;;
720: esac
721: return 0
722: ;;
723: esac
724: case $total in
725: ?*) print -u2 "\n$mail:"
726: PS3=''
727: select i in ${ship_list[*]}
728: do :
729: done </dev/null
730: return 0
731: ;;
732: esac
733: fi
734: return 1
735: }
736:
737: function sendcontrol # machine user
738: {
739: # $transport the control file to <user> on given <machine>
740: case $transport in
741: uucp) typeset dest=$1!$uupublic/$2/$FROMSYS/$date.$SHIPPER
742: print "$rmtfiles
743: $date.$SHIPPER/unspool
744: $date.$SHIPPER/manifest" > $TMP.m
745: print uucp -r -C $TMP.u $dest/unspool
746: case $noexec in
747: "") uucp -r -C $TMP.u $dest/unspool ;;
748: esac
749: case $SHIPID in
750: ?*) print $date.$SHIPPER/id >> $TMP.m
751: id="$SHIPPER SEAL $(date) $1!$2"
752: print "$1!$SHIPID $id" > $TMP.i
753: print uucp -r -C $TMP.i $dest/id
754: case $noexec in
755: "") uucp -r -C $TMP.i $dest/id ;;
756: esac
757: case $noexec in
758: "") print "$id\t$(shipop seal $lclfiles $TMP.u $TMP.m $TMP.i)" >> $SHIPSLOG/seals
759: ;;
760: esac
761: ;;
762: esac
763: print uucp -r -C -m -n"$2" $TMP.m $dest/manifest
764: case $noexec in
765: "") uucp -r -C -m -n"$2" $TMP.m $dest/manifest ;;
766: esac
767: ;;
768: uuto) print uuto -m $TMP.u $1!$2
769: case $noexec in
770: "") uuto -m $TMP.u $1!$2 ;;
771: esac
772: ;;
773: esac
774: case $noexec in
775: ?*) case $SHIPID in
776: ?*) print "ID:"
777: cat $TMP.i
778: ;;
779: esac
780: print "MANIFEST:"
781: cat $TMP.m
782: print "UNSPOOL:"
783: cat $TMP.u
784: ;;
785: esac
786: }
787:
788: function doship #
789: {
790: # ship the files
791: typeset i j tool file
792: integer d
793: case "$info" in
794: ?*) fixedname=${name%% *}
795: print "$fixedname $address $phone $mail $company $project $transport"
796: return
797: esac
798: user=${mail##*!} machine=${mail%!*}
799: user=${user%%@*} machine=${machine#*@}
800: target=$machine!~/$user/$FROMSYS
801: uuspool=$SHIPSPOOL
802: case $transport in
803: uucp) uupublic='~'
804: ;;
805: uuto) uuspool=$uuspoool/receive
806: uupublic=$uuspool
807: print -u2 $transport: transport not supported for $user
808: return
809: ;;
810: *) print -u2 $transport: unknown transport for $user
811: return
812: ;;
813: esac
814: if genshiplist $machine $user $mail
815: then return
816: fi
817: tosys $machine
818: > $TMP.u
819: for i in "${ship_list[@]}"
820: do gencontrol "$i"
821: done
822: buildscript $machine $user
823: dtime=0
824: for tool in "${ship_list[@]}"
825: do for i in $tool.???
826: do case $i in
827: *.\?\?\?)
828: d=50
829: if test -f $tool
830: then i=$tool j=$tool.000
831: else # here for $SHIPFILES
832: i=${tool%%/*}; j=$date.$SHIPPER/$i
833: fi;;
834: *.000) j=$i d=50;;
835: *) j=$i d=100;;
836: esac
837: dfile=$target/$j
838: if test -f "$i"
839: then lclfiles="$lclfiles $i"
840: case $rmtfiles in
841: "") rmtfiles=$j
842: ;;
843: *) rmtfiles="$rmtfiles
844: $j"
845: ;;
846: esac
847: print uucp -r $nocopy $PWD/"$i" "$dfile"
848: case $noexec in
849: "") uucp -r $nocopy $PWD/"$i" "$dfile"
850: dtime=dtime+d
851: ;;
852: esac
853: fi
854: done
855: i=${tool#*/}
856: i=${i%/*}
857: case $noexec in
858: "") db_note $machine $user ${tool%%/*} $i ${tool##*/} $name ;;
859: esac
860: done
861: if test -r $mscript
862: then . $mscript
863: fi
864: sendcontrol $machine $user
865: }
866:
867: function dosend # recipient open
868: {
869: # lookup <recipient> in database and transport software to them
870: # if <open> is given, the database is re-opened
871: addr=$1
872: case $addr in
873: *:*) transport=rcp
874: mail=$1
875: host=${addr%:*}
876: machine=$host
877: dir=${addr#*:}
878: user=${dir%%/*}
879: case $user in
880: '~'*) user=${user#~} ;;
881: *) user=$SHIPPER ;;
882: esac
883: ;;
884: *!*) name=${1##*!} transport=uucp
885: ;;
886: *@*) name=${1%%@*} transport=uucp
887: ;;
888: *%compress|*%list|*%pull|*%push)
889: mail=$addr
890: transport=${addr##*'%'}
891: machine=%$transport
892: user=${addr%$machine}
893: dir=.
894: ;;
895: *) transport=db
896: ;;
897: esac
898: case $transport in
899: uucp) address= phone= mail=$1 project=
900: doship
901: return 1
902: ;;
903: db) typeset -l given match
904: case $shipinfo_test in
905: "") if test ! -f "$SHIPINFO"
906: then errexit "$SHIPINFO: cannot find information file"
907: fi
908: shipinfo_test=1
909: ;;
910: esac
911: case $2 in
912: ?*) exec 3< $SHIPINFO ;;
913: esac
914: given=$1
915: while IFS=: read -ru3 name address phone mail company project unused transport comments
916: do match=$name
917: case $match in
918: \#*) ;;
919: $given*) doship
920: return 1
921: ;;
922: esac
923: done
924: ;;
925: *) typeset d i p s
926: if genshiplist $machine $user $mail
927: then return 1
928: fi
929: tosys $machine
930: {
931: case $transport in
932: compress|list|push)
933: ;;
934: *) print - "umask 02"
935: ;;
936: esac
937: for i in "${ship_list[@]}"
938: do if test -f $i
939: then d=$i/file
940: p=${d%%/*}
941: s=${d#${p}/}
942: t=$p
943: while test "$s" != file
944: do if test "" != "$p"
945: then case $transport in
946: compress|list)
947: print - "$dir/$p"
948: ;;
949: push) ;;
950: *) print - "if test ! -d $dir/$p"
951: print - "then mkdir $dir/$p"
952: print - "fi"
953: ;;
954: esac
955: fi
956: p=${p}/${s%%/*}
957: s=${d#${p}/}
958: done
959: i=${i%/*}
960: for f in $CRATEFILES
961: do if test -s $i/$f
962: then case $transport in
963: compress|list|push)
964: print - "$dir/$i/$f"
965: ;;
966: *) print - "echo \"$(cat $i/$f 2>/dev/null)\" > $dir/$i/$f"
967: ;;
968: esac
969: elif test -f $i/$f
970: then case $transport in
971: compress|list|push)
972: print - "$dir/$i/$f"
973: ;;
974:
975: *) print - "> $dir/$i/$f"
976: ;;
977: esac
978: fi
979: done
980: case $transport in
981: compress|list|push)
982: if test -s $i/owner
983: then print - "$dir/$i/owner"
984: fi
985: ;;
986: *) if test "" = "$shipper" -a -s $i/owner
987: then owner=$(<$i/owner)
988: else owner=$SHIPPER
989: fi
990: case ${TOSYS##*!} in
991: ${owner%%!*}) owner=${TOSYS%!*}!$owner ;;
992: *) owner=$TOSYS!$owner ;;
993: esac
994: print - "echo \"$owner\" > $dir/$i/owner"
995: ;;
996: esac
997: fi
998: done
999: case $transport in
1000: list|push)
1001: ;;
1002: *) print - "rm -f $dir/ship.$date"
1003: ;;
1004: esac
1005: } | case $transport:$noexec in
1006: compress:)
1007: cat
1008: ;;
1009: compress:*)
1010: print - "(pax -wv | compress${mail:+" > $mail"}) <<!"
1011: cat
1012: ;;
1013: list:*) cat
1014: ;;
1015: pull:*) print - ': pull shipment from remote dk host'
1016: print - 'case $# in'
1017: print - '1|2) ;;'
1018: print - '*) echo "Usage: $0 dk-address [remote-INSTALLROOT]" >&2; exit 1 ;;'
1019: print - 'esac'
1020: print - 'DK_ADDRESS=$1'
1021: print - 'DK_INSTALLROOT=${2-.}'
1022: cat
1023: ;;
1024: push:*) print - ': push shipment to remote dk host'
1025: print - 'case $# in'
1026: print - '1|2) ;;'
1027: print - '*) echo "Usage: $0 dk-address [remote-INSTALLROOT]" >&2; exit 1 ;;'
1028: print - 'esac'
1029: print - 'push $1 - ${2-ship} <<"!"'
1030: cat
1031: ;;
1032: *:) cat > $TMP.r
1033: rcp $TMP.r $host:$dir/ship.$date || exit
1034: rm -f $TMP.r
1035: case $rsh in
1036: "") for i in rcmd remsh
1037: do if ($i $host date) >/dev/null 2>&1
1038: then rsh=$i
1039: break
1040: fi
1041: done
1042: case $rsh in
1043: "") rsh=rsh ;;
1044: esac
1045: ;;
1046: esac
1047: $rsh $host sh $dir/ship.$date || exit
1048: ;;
1049: *) print - "cat '"
1050: cat
1051: print - "' > ship.$date"
1052: print - "rcp ship.$date $host:$dir"
1053: print - "rm ship.$date"
1054: print - "rsh $host sh $dir/ship.$date"
1055: ;;
1056: esac
1057: for tool in "${ship_list[@]}"
1058: do if test ! -f $tool
1059: then i=${tool%%/*}
1060: else i=$tool
1061: fi
1062: dfile=$mail/$i
1063: if test -f "$i"
1064: then case $transport in
1065: compress)
1066: print -u2 "oops: $i"
1067: ;;
1068: list|push)
1069: print - "$i"
1070: ;;
1071: pull) case $i in
1072: */*) t=${i%/*} ;;
1073: *) t=. ;;
1074: esac
1075: print - echo pull '$DK_ADDRESS' '$DK_INSTALLROOT'/ship/$i $t
1076: print - pull '$DK_ADDRESS' '$DK_INSTALLROOT'/ship/$i $t
1077: ;;
1078: rcp) print rcp "$i" "$dfile"
1079: case $noexec in
1080: "") rcp "$i" "$dfile" || exit ;;
1081: esac
1082: ;;
1083: esac
1084: fi
1085: i=${tool#*/}
1086: i=${i%/*}
1087: case $user:$noexec in
1088: ?*:) db_note $machine $user ${tool%%/*} $i ${tool##*/} $name ;;
1089: esac
1090: done
1091: case $transport in
1092: push) print - '!' ;;
1093: esac
1094: return 1
1095: ;;
1096: esac
1097: print -u2 "$command: address for $1 not found"
1098: return 1
1099: }
1100:
1101: function closure # tools
1102: {
1103: tools=
1104: for tool
1105: do if test ! -d $tool
1106: then case $original in
1107: *" ${tool%/*} "*|*" $tool "*) warning "${tool%/*}: invalid tool" ;;
1108: esac
1109: else case $tool in
1110: */?*) release=${tool#*/}
1111: tool=${tool#*/}
1112: ;;
1113: *) eval items=\"\$items_$item\"
1114: case $items in
1115: "") release= ;;
1116: *) eval release=\$release_$tool ;;
1117: esac
1118: ;;
1119: esac
1120: eval release_${tool%/*}=$release
1121: tools="$tools $tool"
1122: fi
1123: done
1124: set -- $tools
1125: #
1126: # now generate the closure of the top level tools and releases
1127: #
1128: tools=
1129: for tool
1130: do old=
1131: new=$tool
1132: while :
1133: do case $new in
1134: $old) break
1135: esac
1136: dup=
1137: for item in $new
1138: do # we assume items_* not in environment
1139: eval items=\"\$items_$item\"
1140: case $items in
1141: "") eval release=\$release_$item
1142: case $release in
1143: "") set -- $item/$SHIPMENT
1144: shift $#-1
1145: case $1 in
1146: "$item/$SHIPMENT") continue ;;
1147: esac
1148: release=${1#*/}
1149: eval release_$item=$release
1150: esac
1151: if test ! -f $item/$release/items
1152: then continue
1153: fi
1154: case $closure in
1155: "") items=$item ;;
1156: *) items=$(<$item/$release/items)" $item" ;;
1157: esac
1158: eval items_$item=\"$items\"
1159: ;;
1160: esac
1161: dup="$dup $items"
1162: done
1163: old=$new
1164: new=
1165: for item in $dup
1166: do eval seen_$item=
1167: done
1168: for item in $dup
1169: do eval seen=\$seen_$item
1170: case $seen in
1171: "") eval seen_$item=1
1172: new="$new $item"
1173: esac
1174: done
1175: done
1176: tools="$tools $new"
1177: done
1178: }
1179:
1180: function undup # tools
1181: {
1182: tools=
1183: for item
1184: do eval seen_$item=
1185: done
1186: for item
1187: do eval seen=\$seen_$item
1188: case $seen in
1189: "") eval seen_$item=1
1190: tools="$tools $item"
1191: esac
1192: done
1193: }
1194:
1195: command=$0
1196: integer dtime=0 i=0 nrecipient=0 first_time=1 delay=0
1197: info= mark= list= logfile= message=1 nocopy= noexec= format=$SHIPMENT
1198: shipinfo_test= force= shipper= closure=1 undo= date= basetoo=
1199: while :
1200: do case $1 in
1201: -b) basetoo=1 ;;
1202: +b) basetoo= ;;
1203: -c) closure= ;;
1204: +c) closure=1 ;;
1205: -d) format=base ;;
1206: +d) format=$SHIPMENT ;;
1207: -i) info=1 delay=0 ;;
1208: -k) mark=1 delay=0 ;;
1209: -l) shift; list=$1 ;;
1210: +l) list= ;;
1211: -m) message= ;;
1212: +m) message=1 ;;
1213: -n) noexec=1 delay=0 ;;
1214: +n) noexec= ;;
1215: -o) shipper=1 ;;
1216: +o) shipper= ;;
1217: -p) shift; recipient_list[nrecipient]=$1; nrecipient=nrecipient+1 ;;
1218: +p) recipient= ;;
1219: -s) SHIPFILES= ;;
1220: -t) total=1 noexec=1 delay=0 ;;
1221: -u) shift; undo=$1 ;;
1222: +u) undo= ;;
1223: -v) shift; date=$1 ;;
1224: -C) shift; CRATEFILES="$CRATEFILES $1" ;;
1225: -D) shift; delay=$1 ;;
1226: +D) delay=0 ;;
1227: -F) force=1 ;;
1228: +F) force= ;;
1229: -S) shift; SHIPFILES="$SHIPFILES $1" ;;
1230: *[,:!%@]*)recipient_list[nrecipient]=$1;nrecipient=nrecipient+1 ;;
1231: --) shift; break ;;
1232: -*|+*) print -u2 "Usage: $command [-bcdikmnostfF] [-l recipient-list] [-p recipient] [-u [[yy]mm]dd] [-v yymmdd] [-C crate-file] [-D delay] [-S support-file] [recipient ...] [tool ...]"; exit 2 ;;
1233: *) break ;;
1234: esac
1235: shift
1236: done
1237: case $date in
1238: $SHIPMENT) ;;
1239: *) date=$(shipstamp) ;;
1240: esac
1241: case $info in
1242: "") if test 0 = "$nrecipient" -a ! -f "$list"
1243: then errexit "no recipient(s)"
1244: fi
1245: trap 'cleanup $?' EXIT INT TERM
1246: #
1247: # generate the tools list
1248: #
1249: original=" $* "
1250: case $# in
1251: 0) tools=
1252: for tool in *
1253: do set -- $tool/$SHIPMENT
1254: case $1 in
1255: "$tool/$SHIPMENT") ;;
1256: *) tools="$tools $tool" ;;
1257: esac
1258: done
1259: case $tools in
1260: "") errexit "no tools" ;;
1261: esac
1262: set -- $tools
1263: ;;
1264: esac
1265: closure $*
1266: case $tools in
1267: "") errexit "no 'items' file(s)" ;;
1268: esac
1269: tools_usr=$tools
1270: tools_pax=
1271: case $closure:$format:$SHIPFILES in
1272: :*|*:|*:base:*)
1273: ;;
1274: *) set -- pax/$SHIPMENT
1275: case $1 in
1276: "$tool/$SHIPMENT")
1277: ;;
1278: *) closure pax
1279: tools_pax=$tools
1280: ;;
1281: esac
1282: ;;
1283: esac
1284: undup $tools_pax $tools_usr
1285: set -- $tools
1286: for tool in $tools_pax
1287: do eval type_$tool=pax
1288: done
1289: for tool in $tools_usr
1290: do eval type_$tool=usr
1291: done
1292: set -- $tools
1293: for tool
1294: do eval tool=$tool/\$release_$tool
1295: item=
1296: for f in "$format" base
1297: do set -- $tool/$f
1298: if test -f "$1"
1299: then item=${1##*/}
1300: break
1301: fi
1302: done
1303: case $item in
1304: "") if test ! -d ${tool%/*}
1305: then case $original in
1306: *" ${tool%/*} "*|*" $tool "*) warning "${tool%/*}: invalid tool" ;;
1307: esac
1308: continue
1309: fi
1310: case $format in
1311: base) set -- $tool/$SHIPMENT
1312: if test -f "$1"
1313: then eval release_${tool%/*}=${1##*/}
1314: tool=${tool%/*}/${1##*/}
1315: item=base
1316: warning "${tool}: latest base not crated"
1317: else warning "${tool}: base not crated"
1318: continue
1319: fi
1320: ;;
1321: *) continue
1322: ;;
1323: esac
1324: ;;
1325: esac
1326: case $format in
1327: "$SHIPMENT"|$item)
1328: tool=$tool/$item
1329: ;;
1330: *) tool=${tool%/*}/$item/base
1331: if test ! -f $tool
1332: then errexit "${tool%/*}: $item base not crated"
1333: fi
1334: ;;
1335: esac
1336: tool_list[i]=$tool;i=i+1
1337: done
1338: ;;
1339: *) typeset -lL16 fixedname
1340: typeset -L9 address project
1341: typeset -R12 phone
1342: typeset -L21 mail
1343: typeset -L11 company
1344: ;;
1345: esac
1346: if test ! -d $SHIPSLOG
1347: then mkdir $SHIPSLOG || errexit "$SHIPSLOG: cannot create log directory"
1348: fi
1349: if test -f shipop.c -a -x shipop
1350: then SHIPID=$FROMSYS!$SHIPPER
1351: case $SHIPFILES in
1352: ?*) SHIPFILES="$SHIPFILES shipop.c" ;;
1353: esac
1354: else SHIPID=
1355: fi
1356: while :
1357: do case $undo in
1358: ""|??????*) break ;;
1359: *) undo="?$undo" ;;
1360: esac
1361: done
1362: nocopy=${nocopy+-c}
1363: flag=1
1364: case $list in
1365: "") set -s -- "${recipient_list[@]}"
1366: ;;
1367: ?*) if test ! -r "$list"
1368: then errexit "$list: cannot read"
1369: else set -s -- "${recipient_list[@]}" $(sed -e '/^#/d' -e 's/[: ].*//' $list)
1370: fi
1371: ;;
1372: esac
1373: for recipient
1374: do if ((dtime))
1375: then sleep $dtime
1376: fi
1377: if dosend "$recipient" $flag
1378: then flag=
1379: case $noexec$info in
1380: "") print "$name" >> ${tool%/*}/list ;;
1381: esac
1382: else flag=1
1383: fi
1384: if ((delay > dtime))
1385: then dtime=delay
1386: fi
1387: done
1388: exit 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.