Article 2679 of comp.sources.unix:
Path: nntpd.lkg.dec.com!crl.dec.com!crl.dec.com!caen!usenet.cis.ufl.edu!usenet.eel.ufl.edu!news.mathworks.com!uunet!in2.uu.net!news1.digital.com!vixie!vixie!not-for-mail
From: nmm1@cus.cam.ac.uk (Nick Maclaren)
Newsgroups: comp.sources.unix
Subject: v29i021: mvstape - suite of utilities for handling IBM MVS tapes, Part02/09
Date: 4 Aug 1995 15:04:03 -0700
Organization: Vixie Enterprises
Lines: 1321
Sender: vixie@vix.com
Approved: vixie@gw.home.vix.com
Message-ID: <3vu5gj$gja@gw.home.vix.com>
References: <1.807573809.16947@gw.home.vix.com>
NNTP-Posting-Host: gw.home.vix.com

Submitted-By: nmm1@cus.cam.ac.uk (Nick Maclaren)
Posting-Number: Volume 29, Issue 21
Archive-Name: mvstape/part02

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 9)."
# Contents:  Copyright Makefile convdata.uue externs.h ioerrs.h
#   scantape.1 uniextra.h unifudge.h weeble.c
# Wrapped by nmm1@ursa.cus.cam.ac.uk on Fri Aug  4 15:43:57 1995
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Copyright' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Copyright'\"
else
echo shar: Extracting \"'Copyright'\" \(3676 characters\)
sed "s/^X//" >'Copyright' <<'END_OF_FILE'
X      General Public Licence for the software known as MVSTAPE
X      --------------------------------------------------------
X
X	  (c) Copyright, N.M. Maclaren, 1993, 1994, 1995
X	  (c) Copyright, University of Cambridge, 1993, 1994, 1995
X
X
X
XFree use of MVSTAPE in source and binary forms is permitted, provided that this
Xentire licence is duplicated in all copies, and that any documentation,
Xannouncements, and other materials related to use acknowledge that the software
Xwas developed by N.M. Maclaren (hereafter refered to as the Author) at the
XUniversity of Cambridge.  Neither the name of the Author nor the University of
XCambridge may be used to endorse or promote products derived from this material
Xwithout specific prior written permission.
X
XThe Author and the University of Cambridge retain the copyright and all other
Xlegal rights to the software and make it available non-exclusively.  All users
Xmust ensure that the software in all its derivations carries a copyright notice
Xin the form:
X	  (c) Copyright N.M. Maclaren,
X	  (c) Copyright University of Cambridge.
X
X
X
X                           NO WARRANTY
X
XBecause the MVSTAPE software is licensed free of charge, the Author and the
XUniversity of Cambridge provide absolutely no warranty, either expressed or
Ximplied, including, but not limited to, the implied warranties of
Xmerchantability and fitness for a particular purpose.  The entire risk as to the
Xquality and performance of the MVSTAPE software is with you.  Should MVSTAPE
Xprove defective, you assume the cost of all necessary servicing or repair.
X
XIn no event, unless required by law, will the Author or the University of
XCambridge, or any other party who may modify and redistribute this software as
Xpermitted in accordance with the provisions below, be liable for damages for
Xany losses whatsoever, including but not limited to lost profits, lost monies,
Xlost or corrupted data, or other special, incidental or consequential losses
Xthat may arise out of the use or inability to use the MVSTAPE software.
X
X
X
X                         COPYING POLICY
X
XPermission is hereby granted for copying and distribution of copies of the
XMVSTAPE source and binary files, and of any part thereof, subject to the
Xfollowing licence conditions:
X
X1. You may distribute MVSTAPE or components of MVSTAPE, with or without
Xadditions developed by you or by others.  No charge, other than an "at-cost"
Xdistribution fee, may be charged for copies, derivations, or distributions of
Xthis material without the express written consent of the copyright holders.
X
X2. You may also distribute MVSTAPE along with any other product for sale,
Xprovided that the cost of the bundled package is the same regardless of whether
XMVSTAPE is included or not, and provided that those interested only in MVSTAPE
Xmust be notified that it is a product freely available from the University of
XCambridge.
X
X3. If you distribute MVSTAPE software or parts of MVSTAPE, with or without
Xadditions developed by you or others, then you must either make available the
Xsource to all portions of the MVSTAPE system (exclusive of any additions made
Xby you or by others) upon request, or instead you may notify anyone requesting
Xsource that it is freely available from the University of Cambridge.
X
X4. You may not omit any of the copyright notices on either the source files,
Xthe executable files, or the documentation.
X
X5. You may not omit transmission of this License agreement with whatever
Xportions of MVSTAPE that are distributed.
X
X6. Any users of this software must be notified that it is without warranty or
Xguarantee of any nature, express or implied, nor is there any fitness for use
Xrepresented.
X
X
XJuly 1994
END_OF_FILE
if test 3676 -ne `wc -c <'Copyright'`; then
    echo shar: \"'Copyright'\" unpacked with wrong size!
fi
# end of 'Copyright'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(6144 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Makefile for mvstape and related commands.
X# N.M. Maclaren, May 1995.
X
X# The headers will try and guess that a UNIX system is UNIX, but there is no
X# reliable way to do this, and it is safer to set SYSTEM=UNIX directly for
X# other UNIX systems.  Yes, I could build this by some obscene configuration
X# script, but a simple makefile is much easier to port to completely new
X# systems.  Note that SYSTEM=UNIX is triggered by _POSIX_SOURCE, as well as
X# several other symbols, though this is not assumed in the scripts that follow.
X
X# Setting _POSIX_SOURCE is not critical, and can be omitted without harm in
X# all of the following scripts, but everything except tapeio.c and weeble.c
X# should compile with it on any reasonable UNIX system.  On serious systems
X# (like HP-UX and DEC OSF/1), even they compile with it.  Unfortunately, enough
X# systems are broken that I cannot set it in the source.  It is also COMPLETELY
X# broken by gcc 2.5.7 fixincludes on many systems, so watch out!
X
X# The following settings can be used under SunOS 4.1
XCC = gcc -ansi -D_POSIX_SOURCE
XCFLAGS = -O
XTAPE_FLAGS = -U_POSIX_SOURCE -D__sun
XLDFLAGS =
XLIBS =
XRANLIB = ranlib
X
X# The following settings can be used under Solaris 2; ignore the drivelling
X# about changes in semantics, which is due to bugs in Sun's compiler
X# CC = cc -Xc -D_POSIX_SOURCE -DSYSTEM=UNIX
X# CFLAGS = -O -v
X# TAPE_FLAGS = -U_POSIX_SOURCE -D__sun
X# LDFLAGS =
X# LIBS =
X# RANLIB = /bin/true
X
X# The following settings can be used under HP-UX
X# CC = cc -Aa -D_POSIX_SOURCE
X# CFLAGS = -O
X# TAPE_FLAGS = -D_HPUX_SOURCE
X# LDFLAGS =
X# LIBS =
X# RANLIB = /bin/true
X
X# The following settings can be used under DEC OSF/1
X# CC = cc -std1 -D_POSIX_SOURCE
X# CFLAGS = -O
X# TAPE_FLAGS =
X# LDFLAGS =
X# LIBS =
X# RANLIB = /bin/true
X
X# The following settings can be used under DEC Ultrix 4.3 on a MIPS
X# CC = gcc -ansi -D_POSIX_SOURCE
X# CFLAGS = -O
X# TAPE_FLAGS = -U_POSIX_SOURCE
X# LDFLAGS =
X# LIBS =
X# RANLIB = ranlib
X
X# The following settings can be used under SGI Irix; -D_POSIX_SOURCE is
X# defined automatically by -ansiposix
X# CC = cc -ansiposix
X# CFLAGS = -O
X# TAPE_FLAGS = -xansi
X# LDFLAGS =
X# LIBS =            
X# RANLIB = /bin/true
X
X# It has been compiled with the following options, though with quite a lot of
X# warnings (mostly due to gcc and system header bugs!)
X# CC = gcc -ansi -D_POSIX_SOURCE
X# CFLAGS = -O -pedantic -Wall -Wtraditional -Wshadow -Wpointer-arith \
X# -Wcast-qual -Wwrite-strings -Waggregate-return -Wstrict-prototypes \
X# -Wmissing-prototypes -Wredundant-decls -Wnested-externs
X# TAPE_FLAGS = -U_POSIX_SOURCE
X# LDFLAGS =
X# LIBS =
X# RANLIB = /bin/true
X
X# Except for weeble.c and wibble.c, it also compiles cleanly under OS/2 with
X# CSet/2 version 1.  This needs uniextra.h replacing by unifudge.h and tapeio.c
X# replacing by os2.c.  Naturally, the make file is nothing like this one.  It
X# needs KNOTTED_SIGNALS setting if ibmconv.c is to work, for reasons that may
X# be deduced!
X
X# Many systems will need either NO_IEEE_OVERFLOW or KNOTTED_SIGNALS setting
X# when compiling convtest.c, depending on how sick their compiler and signal
X# handling are.
X
XLIBRARY = ibmconv.a
X
X
X
Xall: check loadtape mvstape readtape scantape $(LIBRARY)
X
Xclean:
X	rm -f check loadtape mvstape readtape scantape ibmconv.a *~ *.o core \
Xweeble wibble
X
Xtar:
X	tar -cvf tar Copyright READ_ME Makefile \
Xcommand.h control.h ebcdic.h externs.h globals.h ibmconv.h iebcopy.h ioerrs.h \
Xlabels.h loadtape.h mvstape.h system.h tarpit.h tlsdict.h tlspds.h uniextra.h \
Xunifudge.h version.h \
Xcheck.c command.c control.c ebcdic.c ibmconv.c iebcopy.c labels.c loadtape.c \
Xmisc.c mvstape.c os2.c recover.c scanning.c tapeio.c tlspds.c unpick.c \
Xcheck.1 loadtape.1 mvstape.1 readtape.1 scantape.1 ibmconv.3c ibmconv.3f \
Xweeble.c wibble.c convtest.c convtest.f convdata
X	compress tar
X
Xinstall:
X	@echo "This does not actually install anything; to do so, do something like:"
X	@echo "cp loadtape mvstape /usr/local/bin"
X	@echo "chmod a=rx /usr/local/bin/loadtape /usr/local/bin/mvstape"
X	@echo "ln -s /usr/local/bin/mvstape /usr/local/bin/scantape"
X	@echo "ln -s /usr/local/bin/mvstape /usr/local/bin/readtape"
X	@echo "cp loadtape.1 mvstape.1 readtape.1 scantape.1 \
X/usr/local/man/man1"
X	@echo "cp ibmconv.a /usr/local/"
X	@echo "chmod a=r /usr/local/lib/ibmconv.a"
X	@echo "cp ibmconv.3c /usr/local/man/man3c"
X	@echo "cp ibmconv.3f /usr/local/man/man3f"
X
X
X
XLOADTAPE_O = ebcdic.o loadtape.o tapeio.o
X
XMVSTAPE_O = command.o control.o ebcdic.o iebcopy.o labels.o misc.o mvstape.o \
Xrecover.o scanning.o tapeio.o tlspds.o unpick.o
X
X$(LIBRARY): ibmconv.o
X	rm -f $(LIBRARY)
X	ar cr $(LIBRARY) ibmconv.o
X	$(RANLIB) $(LIBRARY)
X
Xcheck: check.o ebcdic.o
X	$(CC) $(LDFLAGS) -o check check.o ebcdic.o $(LIBS)
X
Xloadtape: $(LOADTAPE_O)
X	$(CC) $(LDFLAGS) -o loadtape $(LOADTAPE_O) $(LIBS)
X
Xmvstape: $(MVSTAPE_O)
X	$(CC) $(LDFLAGS) -o mvstape $(MVSTAPE_O) $(LIBS)
X
Xreadtape:
X	ln -s mvstape readtape
X
Xscantape:
X	ln -s mvstape scantape
X
Xweeble: weeble.o
X	$(CC) $(LDFLAGS) -o weeble weeble.o $(LIBS)
X
Xwibble: wibble.o
X	$(CC) $(LDFLAGS) -o wibble wibble.o $(LIBS)
X
Xlibrary: $(LIBRARY)
X
X
X
XMVSTAPE_H = externs.h globals.h mvstape.h system.h uniextra.h
X
Xcheck.o:  check.c ebcdic.h
X
Xcommand.o:  command.c $(MVSTAPE_H) command.h
X
Xcontrol.o:  control.c $(MVSTAPE_H) command.h control.h
X
Xebcdic.o:  ebcdic.c ebcdic.h
X
Xibmconv.o:  ibmconv.c ebcdic.c ebcdic.h ibmconv.h
X
Xiebcopy.o:  iebcopy.c $(MVSTAPE_H) control.h ebcdic.h tlspds.h tlsdict.h \
Xiebcopy.h
X
Xlabels.o:  labels.c $(MVSTAPE_H) control.h ebcdic.h labels.h tlsdict.h
X
Xloadtape.o:  loadtape.c ebcdic.h labels.h loadtape.h system.h tlsdict.h \
Xversion.h
X
Xmisc.o:  misc.c $(MVSTAPE_H) control.h ebcdic.h tarpit.h
X
Xmvstape.o:  mvstape.c $(MVSTAPE_H) ebcdic.h ioerrs.h version.h
X
Xrecover.o:  recover.c $(MVSTAPE_H) control.h ebcdic.h labels.h tlsdict.h
X
Xscanning.o:  scanning.c $(MVSTAPE_H) control.h
X
Xtapeio.o:  tapeio.c
X	$(CC) $(CCFLAGS) $(TAPE_FLAGS) -c -o tapeio.o tapeio.c
X
Xtlspds.o:  tlspds.c $(MVSTAPE_H) control.h ebcdic.h tlspds.h
X
Xunpick.o:  unpick.c $(MVSTAPE_H) command.h control.h ebcdic.h
X
Xweeble.o:  weeble.c
X	$(CC) $(CCFLAGS) $(TAPE_FLAGS) -c -o weeble.o weeble.c
X
Xwibble.o:  wibble.c
END_OF_FILE
if test 6144 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'convdata.uue' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'convdata.uue'\"
else
echo shar: Extracting \"'convdata.uue'\" \(4907 characters\)
sed "s/^X//" >'convdata.uue' <<'END_OF_FILE'
Xbegin 644 convdata
XM    7T!:?WM;;%!]35U<3FM@2V'P\?+S]/7V]_CY>EY,?FYO?,'"P\3%QL?(
XMR='2T]35UM?8V>+CY.7FY^CIK>"]<6UY@8*#A(6&AXB)D9*3E)66EYB9HJ.D
XMI::GJ*G 3]!?    7P   ,B  ( !__\    !?_Y___E3=^7^%AGPM7L&VIL!
XM*%LW"/4@<VNYY 0*1I%PENVG0R7)RKFO4BX;882+XY$=,SR.C,'(FO=&GQ[<
XM5NYDTG.-Q,AE';JT$>]OOO"Y"ZDR:,(%;0^]&._$(?*(R&WP]M+^"M8D)-(+
XMM>1$/6&MYI-).H%9!G^*M=MS(W-&\0%DZIT /57#V!VM8062W6_0<&I]%KRK
XM;L@"T2F"@2P8-N)$XYV*99OE;$X1\<N(4"J4DNH!C1)&50D:SP   ,@   &0
XM@    (    '_____          %____^?____^-TMI0K8C,TJQ3TM,^="**.
XMMH;N]ZA<P"A2%AW!U#V4B!GRWX%(%#0]D:\BU^N"B$R*OX5>8E_N1_X2^W'A
XM15&RXC]Z1!"[=\1]ACTVQ&)F?D&X JQ 4*+4$UF)[,+C)DU05 \2P!%RVT!P
XM>'*?3RXII)"-"S(V+C93 \<B/+7.!$V+:7C@B+1# :;=IUWO:SXFM#2YK?W$
XMIA'JC0N]_OZMF@(?MM5\U+?"*E/KGXG0$-;5WCCC(&TQ6VY^4/$P8](^U$"_
XMI2'0!%P?C*QX#7D<.1)B#)3L^??CVLQ]]PG\22#VNW;MD0W.[/.$BU&4HE:;
XM1/W7L\WH>TU?[-1A7^,Y-?R;GR8BD$X0FR,^8NN[PSY%(4(6G-$<%:" L@I0
XM7B&BJ*#7^(79IIEX4IBMU8G^W@,5A>8E^O** 0\6IDVM #;5A3!!M7_L<Y0J
XMLH8P]QAKX4P!4(3IV0:$76V'>1U0&?TU**F\)9%B O;;IQF%AY@B;0   9  
XM  &0____\^$0 #;@__ CH4 '#*$_^1R $ !-       0 $TA/_D<(4 '#&#_
XM\"-A$  V?___\\LBMK76YD:.2F'@A3>)T.=3-9&_I!P-A#HI3X[&(&$I-"P^
XM'+828H3--AA]58?&+CH5=^7=Q)7X8!J%E3*WP:U),!_2/Y$!E[ 8KQ@N2EF5
XMJT<I$+L?G:<H*"\91"I3J;2F3.#5D%PQ7<^;?;RN1Y*FLH'3T_HKEC,\VYTZ
XM$%S),&M.OR>Q0>)<PHWG/_.JL#Y4J!8L(,42J477CS6CLYE+&B9^(GN.,B'D
XM]V-80?D7L2U4N*U?;)73A.]")NV@]K(4L'U!?5Q</!S$Q$LNRL:C%K8V*1>7
XM)+0[J=6\?H8=38W8,:G'?BQ'M\;+-WB0%=$O$_<Q)&*SN$_Y<<--S%O(2#$:
XM/AVU3B,H".)%+T'DV[E@8*=?SQ])$^03P\%I D4<EK52-*_WK!,X -AJ!!.W
XM5)1R(2UGG2]K/8Q3%F$>1!][5#<3#LU9&;BD)34K0U[""FF]-N$B.WX3>0  
XM 9    ,@____\Q(!!,3A$  V5@OU->#_\"+_3(P$H4 '##=P+L6A/_D<&.HU
XMLH 0 $RK Y6P            $ !,JP.5L"$_^1P8ZC6R(4 '##=P+L5@__ B
XM_TR,!&$0 #96"_4U?___\Q(!!,0V)1F?$BKJ@+9IL['28HX C4!LNI(MED &
XM*ZZ&N3_%(+$?XXHJ&Y4P5C0/X",GH>"+4I^76HA90$I,*^J<05< NF0+Q?W=
XM$  0&W*\>$^1P.85-2W80H.0#3 &R6"QW0!HS?]L<"I* /DY& I_.+J@8Q=&
XMPFN0=L!F%S.$>AE% .'VX@PA-#V O!KVH\QRUD#''.'"LVS4$ A1<O0MFF, 
XM:SUQJ24!AN#[TW AH#64 )XI MJIY2> 3A);GU%@:E#/&@T?.$1/4'"V[=I9
XM!G  4E(WYIA<0(!EXH03XZ'H ",A.*@92A$@>/,*!'&<M(",*M#"AG?A %$J
XM@Q$K,$6 >1(K@.,CII"/&*?40=QKT*I%:6:(6L[ U&$PA=%^D,#B[QE ^+K+
XM@([B <9EUX8 (1++K3K#\M O/7^>H2]&@))32N@-H0< 8*P7ZG1>:  /TO?,
XM2F4U /XT[QO.Z?* >DTE'=2R9@"5=D.O-9M?P,E'2UZMDEX 7I_-E&71L8#5
XM05# <OK. ((OS,F5\L% ?"*9)4Z7$*"#^/\(/[Q( %P:>IFY&]7 >R')(4XN
XMW@!"J&0*P7K0 +(D$PSWOFL ^5R0V6M9X0"2$C9Y)9G3P =>:2"@V12 O#(X
XMB?I,\\ \%T&:_*X2<&8EK.?]7Y2@A!,*+AFV'V"J.'?3U?++8(@T3@!(?9A@
XMQBON'IR;E@!\%#X>]N%,0*4=F]\B+M& FS#\=NBH-4"Q/_ <LT5# $,:K"NZ
XMZD<@KA&S+5-'J-!)%%@T.X5ZP&,0O2"L:J2P%,D3W'*>' #\*L-E4=\V@&J<
XM8$]WB?2 \EJ*1".BY,"8;I.U2UP: )(85"1IE<E 8QEVO/5'<>!8. W*>7-S
XM -0G6X3R&4! TQ\/J!AL@< +C;47Y.+: '3JOX:<R-$ ,N@IY*IRE@    ,@
XM   &0/____,2 03$\0XL/6::NC_A$  V5@OU-=,5BC!?#X  X/_P(O],C /2
XMUG=^81   *% !PPW<"[$D_EK5Y98]9VA/_D<&.HULI,5\2#?E(>Q@!  3*L#
XME;#R?GH1M7TBX@                      $ !,JP.5L')^>A&U?2+B(3_Y
XM'!CJ-;(3%?$@WY2'L2% !PPW<"[$$_EK5Y98]9U@__ B_TR, U+6=WYA$   
XM81  -E8+]353%8HP7P^  '____,2 03$<0XL/6::NC^*7OV6GREE%?S-QA)B
XMP   2#_#6A]M;ZTZ4;+P*O.  // ;* *H:-3Y=>-^;8WX "#2&/Q!:)/_/5X
XM/"+7;   ?F@H</T<G;APUL6;/K0  #) Y#RKT"3>)#FA;0L:  ! 0)WMO2'I
XM3S)A8O_1(P  J1'^%EF07R.;D/U4@@4  #<7I@RUD>B]*0^@(_;Q4 #0^L&G
XMW8SH[,(#+-08V   ZC0=MT8I1[K<R6_F. >  "8P*//+&AZ)&%H(_QT@  #@
XM)V8H/U/]7](!%6HQ<X  DQK^AAB]-ZV%]J(TK .@  VLQ:XLDSFV?VWUD9Q[
XM0 #F9MXALJ1:--A&93&4;4  Y;?LOOZJ[V?7B Y.@8   $8O7',ZS16E. 2.
XM/0,I( "3-'M\R54B8X5=#HH78D  [1F%A>^ERI??5S!;20K  #X3F^S 9TV+
XM,-2 BX5^T #72KK*Z(J&DLFGT+O-W0  ]A*9\$B@47WHL:5P1U6P  -4$HT'
XMMD=<=:HVD4@5@  ['I];V)Z'-BT'_A&'SB  WA%$F3 Y"YK0B#H8.1[  "T2
XM5U!A0[^]'W502MO*& "I9CM92*WMSIMK6][CR   +2:"Z%W7P4<?M\92.FF 
XM ,$\;34<206,L\<9'GST  ##'!L[V/#J7K75 06L%:  M[C1)G 84FJIKF&3
XMQ:P   <1)]V)WZ^*>3 ?,^)R  "\(N&OW%U#6*Y5AC.9W   ^Q\B5FE#EV3M
XMR-A3:&   %,UL\YPK+]417Z5GYG-H "R6V8(5C4/0*0,(PN/N'  QCG'E]X6
XM2KJX];!>+39  "4B.NHP4#=W%Q,3L"BW@ "=@_C>1I0)OX]>DE]VSP  9B2<
XM?\'#(HE873GZJU+@ #T2]T^"0,\R+]G5$F3[@ !.JY6W@H9X[T SSIZI>   
XMB,=94@?&LI;Z]@E%&40  (Q5DML@HO%-_O;"YF$Z0  T2%F%"['"@"8T9*<+
XM,@  6B3;U0]SWSE,48J1E(   *WZA=Z@]S20GT&L#P_H  !)%UHE9==TSSN^
XM]/GC+@  %4Z<JB- ZQ$'9AJ;]!T  .$3JK6T%R4KTW-> N>,*  [T?>6%GD'
XM@RVZ0/#YZP  7"Y#:1#B%]I.YR?-1%?  "L7J0SL(XKT'30ADK#'T  9'+J$
XM> <LN0M9CB2OM>   VF6+1#T-(EU(5V:,B=  "] UF\:/?4$(7K_E7-P  "D
XM$4SMJ/)X$9;&\P8+<@  YH!B)7V-B'?8_BMS;&*  "\UE^@(/]X#(;\[H)B2
XM   4BEG"-,@M+P:K<<Z1W   Z!,;ND3$Q,_:EBCSG[7P '5RG[&W<5Y19_9S
XM=OB4  !1FR184@NJM$.CJ5@=I@  #RW%9V$B=L0!&A^HGN6  ,F=]:5]YN[&
XMNRHEF@!\   T%!]LR;=&H":\ _Y+<Y@ YX%7%T0^9IC9](VK6IB  $#G9-V(
XM?)Y2,DV+Y>>(   E]'L:Q%@E.!>U$9$\    >WK5@*C)VAEM+D!A7&   #6O
XM7>SWQ19.)Q2,-1>W  "OO.H_[7Q4^J%Q14D%#,  B"<5P9JD'2CZYWU-G-@ 
XM  1J[^!JH>DI=@84S!G.  #)4<IR.Z 55+N]FT4O'D  [A2C-__N[-+@LY#>
XM"AZ8 &7_"W/AU]C/5Q?U74O   #=/6,UX:OWGL_(S+=Q7P  MWPKJ$GW&Q2I
XM5]GU4V*  !%R0O\X(0M0 S7MR>J<  !8W^;PRN=2QDJA?:>PM   FG1SN5;Z
XM<AR,:I<S!]@  -4]>.#LT2"<Q^Q"5V<_  !/'6'TZ'OFD$&>6)<#%:  TB";
XAJ;DF3PG$N9"5X3P  "H:[,#%I>J='$>,D3[Q      9 
X 
Xend
END_OF_FILE
if test 4907 -ne `wc -c <'convdata.uue'`; then
    echo shar: \"'convdata.uue'\" unpacked with wrong size!
fi
# end of 'convdata.uue'
fi
if test -f 'externs.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'externs.h'\"
else
echo shar: Extracting \"'externs.h'\" \(4230 characters\)
sed "s/^X//" >'externs.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xexterns.h  -  all of the functions called across module boundaries, except
Xfor the code page converters (in ebcdic.h), one that relies upon a definition in
Xcommand.h and the error message functions (in system.h).  Note that the POSIX
Xemulation functions are in unifudge.h and not here. */
X
X
X
X/* command.c external functions. */
X
Xextern void read_commands (void);
X
X
X/* control.c external functions. */
X
Xextern void process_commands (void);
X
X
X/* ebcdic.c external functions and an array. */
X
X/* extern void initialize_code_pages (void);                 in ebcdic.h */
X/* extern CODE_PAGE *select_code_page (const char *name);    in ebcdic.h */
X/* extern CODE_PAGE code_pages;                              in ebcdic.h */
X/* extern const short *ebcdic_to_ascii;                      in ebcdic.h */
X
X
X/* iebcopy.c external functions. */
X
Xextern int read_IEB_block (void);
Xextern int check_IEB_unloaded (void);
Xextern void read_IEB_directory (void);
Xextern int next_IEB_member (int skip);
X
X
X/* labels.c external functions. */
X
Xextern void check_compiled_code (void);
Xextern int read_volume_labels (int disk_dict);
Xextern void unpick_DCB (int dsorg, int recfm);
Xextern void get_comments (char *target, const unsigned char *data, int length);
Xextern int read_header_labels (int operation);
Xextern void read_trailer_labels (int block_count);
X
X
X/* misc.c external functions. */
X
Xextern void get_string (char *target, const char *data, int length);
Xextern int reset_disk_file (int block);
Xextern int read_disk_block (void);
Xextern int read_simple_block (void);
Xextern void skip_file (int labels);
X/* extern void fatal (const char *message, int errtype, ...);    in system.h */
X/* extern void warn (const char *message, int errtype, ...);     in system.h */
X/* extern void comment (const char *message, ...);               in system.h */
Xextern void save_tape_block (const char *buffer, int in_length);
Xextern void write_TLS_dictionary (const char *filename);
Xextern int write_tar_file (int size);
Xextern int write_tar_alias (const char *name);
Xextern const char *format_recfm (int recfm);
Xextern void display_buffer (FILE *file, const char *buffer, int text, int hex);
Xextern void open_tape (const char *name);
Xextern void close_tape (void);
Xextern void rewind_tape (void);
Xextern void diagnose_tape (void);
Xextern void skip_tape_file (int labels);
Xextern int read_tape_block (void);
X
X
X/* mvstape.c external functions. */
X
Xextern int main (int argc, char *argv[]);
Xextern void stop (int code);
X
X
X/* recover.c external functions. */
X
Xextern void check_TLS_dictionary (int in_buffer);
Xextern void recover_TLS_dictionary (void);
Xextern void display_TLS_dictionary (void);
Xextern int find_good_header (void);
X
X
X/* scanning.c external functions. */
X
Xextern void print_volume (void);
Xextern void print_headers (void);
Xextern void display_tape_globals (void);
Xextern void display_label_globals (void);
Xextern void process_scanning (void);
Xextern void IO_error(const char *message, int fatality, int errtype);
X
X
X/* tapeio.c external functions, which are in <opsys.c> for non-UNIX systems. */
X
X/* extern int basic_tape_open (const char *name);         in system.h */
X/* extern int basic_tape_close (int fileno);              in system.h */
X/* extern int basic_tape_rewind (int fileno);             in system.h */
X/* extern const char * basic_tape_status (int fileno);    in system.h */
X/* extern int basic_tape_skip (int fileno, int labels, int data);
X                                                          in system.h */
X/* extern int basic_tape_read (int fileno, char *buffer, int length);
X                                                          in system.h */
X/* extern void basic_tape_signal (void (*receiver)(const char *));
X                                                          in system.h */
X
X
X/* tlspds.c external functions. */
X
Xextern int read_TLS_block (void);
Xextern void read_TLS_directory (void);
Xextern int next_TLS_member (int skip);
X
X
X/* unpick.c external functions. */
X
X/* extern int copy_file (int fileno, const command *cmdptr, int block_in_hand);
X                        in command.h */
END_OF_FILE
if test 4230 -ne `wc -c <'externs.h'`; then
    echo shar: \"'externs.h'\" unpacked with wrong size!
fi
# end of 'externs.h'
fi
if test -f 'ioerrs.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ioerrs.h'\"
else
echo shar: Extracting \"'ioerrs.h'\" \(7617 characters\)
sed "s/^X//" >'ioerrs.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993, 1994, 1995
X   (C) Copyright the University of Cambridge 1993, 1994, 1995
X   ALL RIGHTS RESERVED
X
Xioerrs.h  -  a message about the I/O error recovery logic.  There is no
Xcompilable code.  Yes, I know this is a kludge, but I thought that saving this
Xwould be useful. */
X
X
X
X/*
X
XThe normal commands in the Phoenix utility suite rely upon the existence of
Xother commands to handle broken tapes.  It is clearly not possible to provide
Xall of the Phoenix function, nor reasonable to provide no error recovery.
XUNIX provides no support whatsoever for tape handling, and traditionally UNIX
Xdevice drivers have a tendency to misposition with respect to file marks when
Xin stop/start mode.  This is because the 'normal' UNIX use is to read or write
Xa single large tar file per run (though possibly more than one per tape).  I
Xalso don't entirely trust the driver not to get confused upon real I/O errors.
X
XThe solution that I have adopted is as follows:
X
X
XMiscellaneous
X-------------
X
X    The default is that the first serious I/O error is fatal.  There is an
Xoption to control whether bad blocks in the data are ignored or cause the file
Xto be skipped, and one to control how many I/O errors are allowed.  No
Xdistinction is made between hardware and software I/O errors in this count, nor
Xbetween I/O errors in headers and I/O errors in the data, though some
Xinconvenient I/O errors are always fatal.
X
X    I try to print as much useful information as possible after an I/O error,
Xincluding the file name and real block number within the file.  However, until
XI hack the ioctl() calls directly, I am not certain whether I shall be able to
Xproduce useful hardware I/O error messages, and even then I am limited by the
Xappalling documentation, not to say its near-total absence.
X
X    Unlabelled tapes are not handled specially, and recovery consists of
Xassuming that no I/O error hides or creates a tape mark!  Tough.
X
X
XNon-tape errors
X---------------
X
X    Almost all non-tape errors are fatal, which simplifies things no end.  This
Xincludes any failure on any work file, even if needed for only a few datasets.
XThe main exception is that failure to open or write an output file merely
Xcauses the transfer of that file to be skipped.  This is the only case that
Xwill be common because of user error - the other non-fatal, non-tape errors are
Xall rather obscure.
X
X    There are also some warnings, where failure involves only ignoring or
Xresetting an option.  These include some tape-related errors, such as specifying
XTLS processing for a non-TLS tape, matching on NL tapes by name or ignoring
Xjunk after a TLS dictionary.  Their common property is that they need no
Xspecial recovery code, and I ignore them in this discussion.
X
X
XVolume and TLS dictionary errors
X--------------------------------
X
X    Errors while reading the volume label, first dataset header label and TLS
Xdictionary are fatal unless (a) the user has specified the type of processing
X(NL, SL or TLS) explicitly and (b) it is compatible with the evidence that
Xcould be extracted from the tape.  This applies even to NL tapes, but does not
Xapply to TLS tapes if a disk dictionary is being used.
X
X    The label checks are solely that the labels are of length 80 and start with
Xthe right identifier.  The TLS dictionary check is that it contains an EBCDIC
X'3' or '4' in the correct location and is an appropriate length (i.e. a
Xmultiple of 70 or 100).  The dataset name chain is also checked for values
Xoutside the dictionary, to avoid having to check later.
X
X    If a disk dictionary is being used, it checks that the VOL1 and first HDR1
Xmatch (i.e. checking the tape name, date and name TLS.DICTIONARY plus less
Xrelevant grobble), and gives a warning (counted as an I/O error) if there is
Xany mismatch.  No other cross-checking is performed at this stage, because
Xthere is some done at the dataset level.
X
X
XTLS dictionary recovery
X-----------------------
X
XThis involves searching for the trailer labels, checking that they have the
Xcorrect sequence number, and copying the data from the UTLn labels into the
Xdictionary.  This is then sorted in EBCDIC order, and the first entry has the
Xessential fields filled in.  No attempt is made to set any of the other fields,
Xeven though it would be possible to do so.
X
XThe code to search for the trailer labels is copied from the code to skip to
Xthe next header label (see below), but does not produce I/O error messages on
Xskipped blocks.  If it misses a set of trailer labels, or cannot make sense of
Xthem, it stops.  However, it does not check that they make sense.
X
X
XDataset label errors
X--------------------
X
X    Errors while reading dataset header labels (whether HDR1, HDR2 or the file
Xmark) cause a skip to the next recognisable HDR1 label that immediately follows
Xa file mark.  This is then used to set the dataset sequence number and there is
Xno backtracking.  The header labels are not used for matching on TLS tapes, but
Xare read and checked for matching files.  Checking for end-of-tape during this
Xskipping is a pretty chancy business, but there is no good solution.
X
X    HDR labels are checked to be of length 80, starting with the right
Xidentifier, and to have the correct sequence number.  If the latter differs
Xfrom what is expected, the tape version is used (this provides an implicit
Xcheck on the TLS dictionary).  User labels are just skipped, except when
Xrecovering a TLS dictionary.
X
X    If the sequence number matches, but the TLS dictionary name does not match
Xthe label name, I have no idea what recovery (if any) is plausible, so I just
Xstop.  This probably indicates a seriously corrupted tape.
X
X    Errors while reading trailer labels are non-fatal, but are counted as I/O
Xerrors, and the TLS information in the UTLs is not cross-checked.  The block
Xcount is checked for other than TLS PDSs, but only if the file is actually
Xread.
X
X
XPDS errors
X----------
X
X    Any significant error while reading the PDS directory causes the whole PDS
Xto be skipped.  There is code to use the second copy of the segments if the
Xfirst causes an I/O error, but I doubt that it will have much effect.  End of
Xfile in a PDS directory always causes the file to be skipped.
X
X    PDS members are handled by reading the member marker and then the data;
Xany error while reading a PDS marker causes a skip to the next good one.  If
Xa second PDS marker is found when a first one is expected, it is used for
Xrecovery.  An I/O error while reading a second marker is ignored with a
Xmessage, when it follows a good first one.  If the name on the marker is not
Xfound in the PDS directory, the whole file is skipped.
X
X
XI/O errors in the data
X----------------------
X
X    Software I/O errors cause the rest of the file to be skipped, but hardware
Xones may cause only the block to be skipped (under option control).  Files are
Xchecked fairly thoroughly, except that FBS files are not checked for early
Xshort blocks and VBS files are not checked for long records (in both cases,
Xbecause of broken MVS utilities).  I may need to allow 4-byte VBA records, too,
Xbut I don't at present.
X
X    The BLOCKS transfer method allows an escape, because it does no checking
Xand produces a disk file from which the block structure can be recreated.  My
Xguess is that no users will want to use it, but it was easy to provide.
X
X    No attempt is made to clean up any output file after an error, or to do
Xanything except get back into a standard state for the next one.  It does close
Xfiles properly and things like that, but some output may be lost unnecessarily.
XSkipping is always to the next file mark.
X
X*/
END_OF_FILE
if test 7617 -ne `wc -c <'ioerrs.h'`; then
    echo shar: \"'ioerrs.h'\" unpacked with wrong size!
fi
# end of 'ioerrs.h'
fi
if test -f 'scantape.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'scantape.1'\"
else
echo shar: Extracting \"'scantape.1'\" \(6901 characters\)
sed "s/^X//" >'scantape.1' <<'END_OF_FILE'
X.TH SCANTAPE 1L
X.SH NAME
Xscantape \- scan a 1/2" magnetic tape or `diskized' tape file
X.SH SYNOPSIS
X.B scantape
X.BI \-t " tape"
X[
X.BI \-d " disk"
X]
X[
X.BI \-l " type"
X]
X[
X.BI \-m " EOFs"
X]
X[
X.BI \-c " codepage"
X]
X[
X.B \-v
X]
X[
X.BI \-p " lines"
X]
X[
X.B \-D
X|
X.B \-E
X]
X[
X.BI \-F " errfile"
X]
X[
X.BI \-X " errors"
X]
X.SH DESCRIPTION
XThe
X.I scantape
Xcommand is used to print some information about a TLS, other IBM standard
Xlabelled or unlabelled tape or `diskized' tape file, which is assumed to have
Xbeen written on an IBM MVS system, but need not have been.  Other tapes can be
Xhandled, but their contents may have to be converted by a separate utility, as
Xwill any files with unusual formats.  The command normally determines the type
Xof tape automatically, but there is an option to force a particular assumption.
X[TLS is the Tape Library System using IBM standard labelled tapes that was
Xdeveloped as part of the Phoenix user-friendly front end to MVS by the
XUniversity of Cambridge Computing Service.]
X.PP
XIEBCOPY unloaded PDSs on non-TLS tapes will be detected if the record format
X.I VS
Xand the record length is 4 bytes less than the blocksize.  They will then be
Xhandled much like TLS PDSs.
X.PP
XThere is some recovery from I/O errors, but the command is not designed for
Xdecoding badly corrupted tapes. It may also be used to scan a TLS dictionary on
Xdisk, or a `diskized' copy of the tape created by the the Phoenix command
XDISCTLS or the
X.I loadtape
Xcommand.
X.SS Options
X.I scantape
Xrecognises the following arguments:
X.TP
X.B \-c
Xspecifies the code page to use for EBCDIC to ASCII conversion:
X.I phx
X(the one used in Phoenix, and the default),
X.I phx8
X(the 8-bit Phoenix one),
X.I phxmvt
X(the one used when Phoenix ran under MVT),
X.I ibmmvs
X(`standard' IBM MVS),
X.I ibm037
X(IBM code page 37) or
X.I ibm500
X(IBM code page 500).  The case of the code page name is ignored.
X.TP
X.B \-d
Xspecifies a disk copy of the header labels and TLS dictionary, which will be
Xread if it exists and created if it does not.
X.TP
X.B \-l
Xspecifies the tape type (with case ignored):
X.I TLS
X(Phoenix Tape Library System),
X.I SL
X(IBM Standard Label) or
X.I NL
X(unlabelled or something else).  This can be used to handle a TLS tape as SL or
XNL and a SL tape as NL.  The default is to determine the type from the tape.
X.TP
X.B \-m
Xspecifies which double tape mark means end of tape on unlabelled tapes (default
X1, maximum 1000); this is ignored for labelled tapes and `diskized' tape files.
X.TP
X.B \-p
Xspecifies how many lines of output to print, giving the contents of their
Xdirectories for PDSs or the first block for other files, in much the same was
Xas the Phoenix command TAPESCAN (default 0, maximum 100).
X.TP
X.B \-t
Xspecifies the tape device file on which the magnetic tape is mounted.
X.TP
X.B \-v
Xwrite the dataset name and other label information for each file on the tape;
Xthe default is to print just the volume information.  Note that it uses the TLS
Xdictionary information for TLS tapes; set the
X.B \-w
Xoption instead of
X.B \-v
Xto check that each file is present.
X.TP
X.B \-w
Xscan the files and write some statistics on their block sizes and counts; this
Xis also done when -v is specified for unlabelled tapes.
X.TP
X.B \-D
Xprint debugging information on stderr (not useful for most users).
X.TP
X.B \-E
Xprint an excessive amount of debugging information (not recommended for most
Xusers, even in desperation).
X.TP
X.B \-F
Xspecifies the name of a file containing block numbers to emulate I/O errors in
X`diskized' files (not useful for most users).
X.TP
X.B \-X
Xspecifies how many I/O errors occur before the command stops (default 100,
Xmaximum 10000).
X.PP
XNormally the
X.B \-t
Xargument is compulsory, but there is an exception for `diskized' tape files.  If
X.B \-d
Xis specified and
X.B \-t
Xis not, the disk copy of the header labels etc. is assumed to be a `diskized'
Xtape file and will be read as if it were the tape.  Such a `diskized' tape file
Xmay be created by the Phoenix command DISCTLS or the
X.I loadtape
Xcommand.
X.PP
XThe
X.B \-d
Xargument may use
X.B \-
Xinstead of a filename, in which case
X.I stdin
Xwill be used, so that the command can be used in a pipe.  Note that the
X.B \-t
Xargument must refer to a real tape device, because positioning operations are
Xneeded.
X.PP
XIf the
X.B \-d
Xoption refers to a disk file that was created by the
X.I loadtape
Xcommand with a dummy block in place of the TLS dictionary, an attempt will be
Xmade to replace the block with a valid TLS dictionary recovered from the 
Xtrailer labels.  This is likely only on tape decks that cannot read blocks of
Xbetween 32K and 64K.
X.PP
XFor labelled tapes, the
X.B \-v
Xoption writes the dataset name, creation date, record format, blocksize and
Xrecord length plus (for non-TLS tapes) the job/step identification or (for TLS
Xtapes) the dataset organisation, size in kilobytes and PDS directory blocks and
Xcomments.  For TLS tapes, deleted and replaced files have their name in square
Xbrackets.  For unlabelled tapes, the
X.B \-v
Xoption writes the byte count, block count, I/O error count, maximum block size,
Xminimum block size, whether the last block is the only short one and (for
Xunloaded PDSs) the number of members.  The
X.B \-w
Xoption specifies this for all types of tape.
X.PP
XThe
X.IR phx ,
X.I phxmvt
Xand
X.I ibmmvs
Xcode pages map EBCDIC to 7-bit ASCII with both EBCDIC
X.I NL
Xand
X.I LF
Xmapped to ASCII
X.IR LF ,
Xand EBCDIC
X.I NUL
Xmapped to ASCII
X.I SUB
X(to avoid confusing UNIX utilities); the first two also map pound sterling to
XISO Latin 1.  The remainder map all 256 EBCDIC characters to ISO Latin 1.
X.PP
XUnlike most UNIX utilities, incompatible or impossible options are an error.  A
Xfew non-fatal warnings are given when the options are incompatible with the
Xtape, or with the commands provided, but most errors are fatal.  The exit code
Xwill be non-zero if some function cannot be performed, whether or not
Xprocessing continued.
X.SH BUGS
XThe handling of I/O errors is crude, but this is as much a restriction of UNIX
Xas the program.
X.PP
XBlocks up to 65535 can be handled, provided the device driver and tape deck
Xhandle them correctly, but longer ones are rejected.
X.PP
XThe tape device must be a raw device, on systems that support both raw and
Xblock magnetic tape devices, though this is not checked.
X.PP
XThe directories of IEBCOPY PDSs are printed in TTR order of main name and ASCII
Xorder of aliases, and those of TLS PDSs in ASCII order of main name and in an
Xundefined order of aliases (not even EBCDIC).  It is in the tradition of UNIX
Xto describe coding accidents as the specification, so there!
X.PP
XSee
X.I readtape
Xfor warnings about the unreliability of programs as complex as this.  These
Xwarnings apply to
X.I scantape
Xas well, but are unlikely to cause more than mild confusion.
X.SH AUTHOR
X.I scantape
Xwas developed by N.M. Maclaren of the University of Cambridge Computing
XService.
X.SH SEE ALSO
Xloadtape(1L), mvstape(1L), readtape(1L).
END_OF_FILE
if test 6901 -ne `wc -c <'scantape.1'`; then
    echo shar: \"'scantape.1'\" unpacked with wrong size!
fi
# end of 'scantape.1'
fi
if test -f 'uniextra.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uniextra.h'\"
else
echo shar: Extracting \"'uniextra.h'\" \(3770 characters\)
sed "s/^X//" >'uniextra.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1994, 1995
X   (C) Copyright the University of Cambridge 1994, 1995
X   ALL RIGHTS RESERVED
X
Xuniextra.h  -  a header that is needed by UNIX-like systems only; it is 
Xreplaced by unifudge.h for systems that need to emulate POSIX calls.  It is
Xincluded from mvstape.h, but is needed mainly by mvstape.c and misc.c, with
Xsome use from control.c.  It also includes macros for the system-dependent
Xdefinitions that are external functions and data for other systems. */
X
X
X
X#include <unistd.h>
X#include <fcntl.h>
X#include <sys/stat.h>
X#include <sys/types.h>
X
X
X
X/* Define various flag bits in convenient forms, to avoid imposing the more
Xrevolting UNIX specifications on the program. */
X
X#define O_READ (O_RDONLY)          /* A sensible read-only */
X#define O_WRITE (O_WRONLY|O_CREAT|O_TRUNC) /* A sensible write-only */
X#define O_EXTEND (O_WRONLY|O_CREAT|O_APPEND) /* A sensible write-only append */
X#define O_UPDATE (O_RDWR)          /* A sensible read-write */
X#define O_SCRATCH (O_RDWR|O_CREAT|O_EXCL) /* A new scratch file */
X
X#define O_RDMODE (0)               /* Unused input and update mode */
X#define O_WRMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) /* Default creation mode */
X#define O_DIRMODE (O_WRMODE|S_IXUSR|S_IXGRP|S_IXOTH) /* Directory default */
X
X#define RD_OK (R_OK)               /* Read access is permitted */
X#define WR_OK (W_OK)               /* Write access is permitted */
X
X#define S_ALLRDWR (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) /* Umask */
X#define S_ALLBITS (S_ALLRDWR|S_IXUSR|S_IXGRP|S_IXOTH) /* Used in umask */
X
X#define E_EXISTS EEXIST            /* A directory/link already exists */
X#define E_NODIR ENOENT             /* A component directory does not exist */
X
X
X
X/* Declare the macros to allow other systems to call the ANSI C and POSIX
Xemulation functions; their proformas SHOULD be specified by the system headers.
XNote that using the POSIX names directly is asking for trouble on non-UNIX
Xsystems (and gets it, too).  perror() is treated as POSIX to allow for some
Xkludging up of systems with broken diagnostics, like OS/2. */
X
X#define Perror(a) perror((a))
X
X#define Access(a,b) access((a),(b))
X#define Open(a,b,c) open((a),(b),(c))
X#define Close(a) close((a))
X#define Mkdir(a,b) mkdir((a),(b))
X#define Link(a,b) link((a),(b))
X#define Unlink(a) unlink((a))
X#define Read(a,b,c) read((a),(b),(c))
X#define Write(a,b,c) write((a),(b),(c))
X#define Lseek(a,b,c) lseek((a),(b),(c))
X#define Getlogin() getlogin()
X#define Umask(a) umask((a))
X#define Getuid() getuid()
X#define Getgid() getgid()
X
X
X/* System-dependent definitions used by command.c and control.c.  See 
Xunifudge.h for their descriptions. */
X
X#define NAME_DIR_SEP     '/'       /* UNIX directory separator */
X#define NAME_CHAR_VETO   ""        /* No special forbidden characters */
X#define NAME_CHAR_SUB    ""        /* Therefore we don't need substitutes */
X#define CHECK_FILE_NAME(name)      /* Do not check the file name for validity */
Xextern void (CHECK_FILE_NAME) (char *name);
X#define FUDGE_FILE_NAME(name)      /* Do not kludge up default file names */
Xextern void (FUDGE_FILE_NAME) (char *name);
X#define SET_NO_NAME_CHECK()        /* No paranoia to be switched off */
Xextern void (SET_NO_NAME_CHECK) (void);
X
X
X/* System-dependent definitions used by unpick.c.  See unifudge.h for their
Xdescriptions. */
X
X#define GOOD_EBCDIC_CCS  "\n\r\f\v" /* EBCDIC CCs that can be handled */
X#define BAD_EBCDIC_CCS   ""         /* EBCDIC CCs that cannot be handled */
X#define SUB_CHAR         0x1a       /* Used for non-ASCII characters */
Xtypedef const char *ANSI_CC_TABLE_TYPE[2][6];
X#define ANSI_CC_TABLE {                                \
X    {"\r", "\n\f", "\n\n\n", "\n\n", "\n", "\n\v"},    \
X    {"", "\f", "\n\n", "\n", "", "\v"}                 \
X}
END_OF_FILE
if test 3770 -ne `wc -c <'uniextra.h'`; then
    echo shar: \"'uniextra.h'\" unpacked with wrong size!
fi
# end of 'uniextra.h'
fi
if test -f 'unifudge.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'unifudge.h'\"
else
echo shar: Extracting \"'unifudge.h'\" \(4048 characters\)
sed "s/^X//" >'unifudge.h' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1994, 1995
X   (C) Copyright the University of Cambridge 1994, 1995
X   ALL RIGHTS RESERVED
X
Xunifudge.h  -  this is the equivalent of uniextra.h for systems where POSIX 
Xcalls must be emulated (like OS/2).  See uniextra.h for more comments.  Note
Xthat this needs stddef.h, but this will not yet have been included by system.h,
Xso it is repeated here. */
X
X
X
X#include <stddef.h>
X
X
X
X/* The definitions to civilize POSIX are useful for portability. */
X
X#define STDOUT_FILENO    -1            /* -1 for non-POSIX systems */
X
X#define O_READ            1            /* A sensible read-only */
X#define O_WRITE           2            /* A sensible write-only */
X#define O_EXTEND          3            /* A sensible write-only append */
X#define O_UPDATE          4            /* A sensible read-write */
X#define O_SCRATCH         5            /* A new scratch file */
X
X#define O_RDMODE          0            /* Unused input mode */
X#define O_WRMODE          0            /* Default output mode (UNIX only) */
X#define O_DIRMODE         0            /* Directory default (UNIX only) */
X
X#define RD_OK             1            /* Read access is permitted */
X#define WR_OK             2            /* Write access is permitted */
X
X#define S_ALLRDWR         0            /* Used for umask (UNIX only) */
X#define S_ALLBITS         0            /* Used for umask (UNIX only) */
X
X#define E_EXISTS          -123        /* errno value for file existing */
X#define E_NODIR           -456        /* errno value for no directory */
X#define E_OTHER           -789        /* errno value for other error */
X
X
X
X/* Declare the ANSI C and POSIX emulation functions, to avoid yet another
Xheader.  perror() is treated as POSIX to allow for some kludging up of systems
Xwith broken diagnostics, like OS/2.  These are in <opsys>.c, together with the
Xdummy tape-handling functions. */
X
Xextern void Perror (const char *string);
X
Xextern int Access (const char *path, int amode);
Xextern int Open (const char *path, int flag, int mode);
Xextern int Close (int fildes);
Xextern int Mkdir (const char *path, int mode);
Xextern int (Link) (const char *path1, const char *path2);
Xextern int (Unlink) (const char *path);
Xextern ptrdiff_t Read (int fildes, void *buf, size_t nbyte);
Xextern ptrdiff_t Write (int fildes, const void *buf, size_t nbyte);
Xextern long Lseek (int filedes, long offset, int whence);
Xextern char *(Getlogin) (void);
Xextern unsigned int (Umask) (unsigned int cmask);
Xextern unsigned int (Getuid) (void);
Xextern unsigned int (Getgid) (void);
X
X
X
X/* System-dependent definitions used by command.c and control.c.  NAME_DIR_SEP
Xis changed to '/' by the parsing in command.c and NAME_CHAR_VETO are other
Xcharacters that either cause parsing problems or must be mapped (to
XNAME_CHAR_SUB) if they occur in MVS file names (note that ':' can be created by
Xthe parsing).  Note that full file name checking is currently provided (and
Xneeded!) only for MS-DOS derivatives. */
X
Xextern const char NAME_DIR_SEP;    /* Directory separator in file names */
Xextern const char *NAME_CHAR_VETO; /* Special forbidden characters */
Xextern const char *NAME_CHAR_SUB;  /* Substitutes for the above */
Xextern void CHECK_FILE_NAME (char *name); /* Check the name for validity */
Xextern void FUDGE_FILE_NAME (char *name); /* Kludge up default names */
Xextern void SET_NO_NAME_CHECK (void); /* Switch off the MS-DOS paranoia */
X
X
X
X/* System-dependent definitions used by unpick.c.  The ANSI control character
Xtranslation table is in the order '+', '1', '-', '0', ' ' and other, for all
Xlines but the first and the first line.  Note that unpick.c tests whether 
XANSI_CC_TABLE is a macro or not, to bypass a C restriction - do NOT shield the
Xname by a macro here! */
X
Xextern const char *GOOD_EBCDIC_CCS; /* EBCDIC CCs that can be handled */
Xextern const char *BAD_EBCDIC_CCS; /* EBCDIC CCs that cannot be handled */
Xextern const char SUB_CHAR;        /* Used for non-ASCII characters */
Xtypedef const char *ANSI_CC_TABLE_TYPE[2][6];
Xextern ANSI_CC_TABLE_TYPE ANSI_CC_TABLE;
END_OF_FILE
if test 4048 -ne `wc -c <'unifudge.h'`; then
    echo shar: \"'unifudge.h'\" unpacked with wrong size!
fi
# end of 'unifudge.h'
fi
if test -f 'weeble.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'weeble.c'\"
else
echo shar: Extracting \"'weeble.c'\" \(4474 characters\)
sed "s/^X//" >'weeble.c' <<'END_OF_FILE'
X/* (C) Copyright N.M. Maclaren 1993
X   (C) Copyright the University of Cambridge 1993
X   ALL RIGHTS RESERVED
X
Xweeble.c - an auxiliary that times the difference between reading blocks and
Xskipping files, so that tuning is possible.  Note that a non-rewinding raw
Xdevice must be used.  Note also that it assumes UNIX, because it is not
Xintended for release to users. */
X
X
X
X#include <errno.h>
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#include <time.h>
X
X#include <unistd.h>
X#include <fcntl.h>
X#include <sys/stat.h>
X#include <sys/types.h>
X#include <sys/ioctl.h>
X#include <sys/mtio.h>
X
X
X#define TOTAL 1000000
X#define COUNT 1000
X
X
Xvoid fail (const char *message) {
X    fprintf(stderr,"Failed:  %s\n",message);
X    perror("");
X    exit(1);
X}
X
X
X
Xint main (int argc, char *argv[]) {
X
X    struct mtop mt_command;
X    char *buffer;
X    int sizes[] = {80,6000,32760}, counts[] = {1,10,100},
X        tape, files, writing, reading, skipping, rewinding, count, total,
X        check_count, check_total, check_files, last_tm, k, l, m, n;
X
X
X    if (argc != 2) fail("invalid number of arguments");
X    if ((tape = open(argv[1],O_RDWR)) < 0) fail("unable to open tape device");
X    if ((buffer = malloc(32768)) == NULL) fail("unable to get buffer");
X    memset(buffer,0,32768);
X    printf("Writing    reading   skipping   rewinding\n");
X    for (n = 0; n < 3; ++n) {
X        for (m = 0; m < 3; ++m) {
X            printf("Files are %d blocks of %d\n",counts[m],sizes[n]);
X            rewinding = 0;
X
X/* Create the tape files to scan. */
X
X            writing = time(NULL);
X            files = count = total = 0;
X            for (l = 0; l < 100; ++l) {
X                ++files;
X                for (k = 0; k < counts[m]; ++k) {
X                    if (count >= COUNT || total >= TOTAL) goto stop;
X                    if (write(tape,buffer,sizes[n]) != sizes[n])
X                        fail("unable to write block");
X                    ++count;
X                    total += sizes[n];
X                }
X                if (close(tape) || (tape = open(argv[1],O_RDWR)) < 0)
X                    fail("unable to write file mark");
X            }
Xstop:       if (close(tape) || (tape = open(argv[1],O_RDWR)) < 0)
X                fail("unable to write double tape mark");
X            writing = time(NULL)-writing;
X
X            rewinding -= time(NULL);
X            errno = 0;
X            mt_command.mt_op = MTREW;
X            mt_command.mt_count = 1;
X            if (ioctl(tape,MTIOCTOP,&mt_command) < 0)
X                fail("unable to rewind tape");
X            rewinding += time(NULL);
X
X/* Read the blocks and time the process. */
X
X            reading = time(NULL);
X            check_files = check_count = check_total = 0;
X            last_tm = 0;
X            while (1) {
X                if ((k = read(tape,buffer,32768)) < 0)
X                      fail("unable to read tape block");
X                if (k == 0) {
X                    if (last_tm) break;
X                    ++check_files;
X                    last_tm = 1;
X                } else {
X                    ++check_count;
X                    check_total += k;
X                    last_tm = 0;
X                }
X            }
X            reading = time(NULL)-reading;
X/*          fprintf(stderr,"%d  %d  %d    %d  %d  %d\n",files,count,total,
X                check_files,check_count,check_total);    */
X
X            rewinding -= time(NULL);
X            errno = 0;
X            mt_command.mt_op = MTREW;
X            mt_command.mt_count = 1;
X            if (ioctl(tape,MTIOCTOP,&mt_command) < 0)
X                fail("unable to rewind tape");
X            rewinding += time(NULL);
X
X/* Skip the files and time the process. */
X
X            skipping = time(NULL);
X            for (l = 0; l < files; ++l) {
X                errno = 0;
X                mt_command.mt_op = MTFSF;
X                mt_command.mt_count = 1;
X                if (ioctl(tape,MTIOCTOP,&mt_command) < 0)
X                    fail("unable to skip file");
X            }
X            skipping = time(NULL)-skipping;
X
X            rewinding -= time(NULL);
X            errno = 0;
X            mt_command.mt_op = MTREW;
X            mt_command.mt_count = 1;
X            if (ioctl(tape,MTIOCTOP,&mt_command) < 0)
X                fail("unable to rewind tape");
X            rewinding += time(NULL);
X
X/* Print the times and repeat. */
X
X            printf("%5d      %5d      %5d      %5d\n",
X                writing,reading,skipping,rewinding/3);
X        }
X    }
X    exit(0);
X}
END_OF_FILE
if test 4474 -ne `wc -c <'weeble.c'`; then
    echo shar: \"'weeble.c'\" unpacked with wrong size!
fi
# end of 'weeble.c'
fi
echo shar: End of archive 2 \(of 9\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 9 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0


