[net.sources] trw - Tape program which handles ANSI standard and IBM labeled tapes

david@ukma.UUCP (David Herron, NPR Lover) (05/15/85)

:	This is a shell archive.
:	Remove everything above and including the cut line.
:	Then run the rest of the file through sh.
: -----cut here-----cut here-----cut here-----cut here-----
:  shar:	Shell Archiver
:	Run the following text with /bin/sh to create:
:	'README'
:	'Makefile'
:	'dec.h'
:	'dec.orig'
:	'main.c'
:	'dsrep.c'
:	'err.c'
:	'convutil.c'
:	'readtp.c'
:	'gutil.c'
:	'writetp.c'
: This archive created: Tue May 14 20:10:46 1985

: By:	David Herron, NPR Lover '()'
echo shar: extracting README '(791 characters)'
sed 's/^X//' > README << '/*EOF' 
XAs it says in the manual page, this program was written by Karen Cross
Xand Rosemarie Maruskan.  Neither of them attend UK any longer.  Karen
Xworks at IBM so is unreachable by Unix mail.  Rosemarie however is on
XUsenet as: hplabs!hpfcla!hpfcrj!rose.
X
XIt's been tested with both IBM labeled tapes and ANSI tapes.  (Though,
Xnote the qualification in the manual page).
X
XQuestions can be sent to Rose at the above address, or me (David Herron,
Xcbosgd!ukma!david).
X
XBy The Way.  The options are of the form name=value because Karen
Xlikes IBM operating systems, not because they'd been using dd(1) a lot.
XThough, they HAD been doing some of that also.
X
X	David Herron
X	University of Kentucky, Department of Computer Science
X	915 Patterson Office Tower
X	Lexington, KY  40506-0027
X
X	cbosgd!ukma!david
/*EOF
if test 791 -ne "`wc -c README`"
then
echo shar: error transmitting README '(should have been 791 characters)'
fi
echo shar: extracting Makefile '(694 characters)'
sed 's/^X//' > Makefile << '/*EOF' 
X
X# This is the makefile for the IBM/EBCDIC-ANSI standard tape handler.
X
XOBJECTS = main.o dsrep.o err.o convutil.o readtp.o gutil.o writetp.o
XSOURCES = main.c dsrep.c err.c convutil.c readtp.c gutil.c writetp.c
XINSDIR	= /usr/local
XOWNER	= bin
XGROUP	= bin
X
Xtrw: $(OBJECTS)             
X	cc $(OBJECTS) -o trw
X
Xinstall: $(INSDIR)/trw
X	:
X$(INSDIR)/trw: trw
X	mv trw $(INSDIR)/trw
X	chmod 755 $(INSDIR)/trw
X	chown $(OWNER) $(INSDIR)/trw
X	chgrp $(GROUP) $(INSDIR)/trw
X
Xclean:
X	rm -f $(OBJECTS) core a.out
X
Xshar:
X	shar -a README Makefile dec.h dec.orig $(SOURCES) >trw.shar
X
Xmain.o:     dec.h
Xdsrep.o:    dec.h
Xerr.o:      dec.h
Xgutil.o:    dec.h
Xconvutil.o: tables.h
Xreadtp.o:   dec.h
Xwritetp.o:  dec.h
/*EOF
if test 694 -ne "`wc -c Makefile`"
then
echo shar: error transmitting Makefile '(should have been 694 characters)'
fi
echo shar: extracting dec.h '(2554 characters)'
sed 's/^X//' > dec.h << '/*EOF' 
X
X#include	<stdio.h>
X
X#define	MAXBUF	32760		/* maximum buffer size                */
X#define MAXFILES   32		/* maximum number of files on tape    */
X#define BLKSIZE    80           /* label size and default blocksize   */
X
X/* error codes */
X#define VIDERR	0
X#define SECERR	1
X#define REDERR  2
X#define CMDERR  3
X#define OPNERR  4
X#define FLGERR  5
X#define EOVERR  6
X#define FPRERR	7
X#define CLOERR	8
X#define TECERR	9  
X#define FCLERR  10
X#define FOPERR  11
X#define VOLERR  12
X#define WRTERR  13
X#define FMTERR	14
X#define BLKERR  15
X#define MAXERR  16
X#define RECERR  17
X#define FNMERR  18
X#define RFMERR  19
X
X/* labels to check */
X# define	L_VOL1		1
X# define	L_HDR1		2
X# define	L_HDR2		3
X# define	L_EOF1		4
X# define	L_EOF2		5
X# define	L_EOV1		6
X# define	L_UTL		7
X# define	L_UHL		8
X
X/* record types */
X# define	F	0
X# define	FB	1
X# define	V	2
X# define	VB	3
X
X/* miscellaneous constants */
X#define SPACE   ' '
X#define SPACES  "  "
X#define ZERO    '0'
X#define VOL1    "VOL1"
X#define HDR1    "HDR1"
X#define HDR2    "HDR2"
X#define EOF1    "EOF1"
X#define EOF2    "EOF2"
X#define SYSCD   "OS36000000000" 
X#define DEVRMT  "/dev/rmt"
X#define DEVNRMT "/dev/nrmt"
X
X#define MIN(x, y)	(((x) > (y)) ? (y) : (x))
X
X/* miscellaneous variables */
Xchar	inptbuf[MAXBUF+1];	/* input-output buffer		     */	
Xchar	fname[18];		/* file name for tape labels         */
Xchar	ufname[257];		/* UNIX file name		     */
Xchar	vid[7];			/* volume serial number		     */
Xint	reclen;			/* logical record length             */
Xint	recode;			/* record format for writing	     */
Xint	blklen;			/* block length			     */
Xint	blkct;			/* block count for a single data set */
Xint	vblen;			/* variable block length	     */
Xint	tfd;			/* mag tape file descriptor  	     */
Xchar	*tpdr;			/* rewinding tape drive              */
Xchar	ntpdr[12];		/* non-rewinding tape                */
Xint	filectr; 		/* count of files processed	     */
Xextern  int   errno;		/* return code for errors	     */
X
X/* flags */
Xint	ansi;			/* ansi label tape                   */
Xint	stdl;			/* stdl tape               	     */
Xint	flags;			/* required parameters     	     */
Xint	files;			/* files to be read       	     */
Xint	wrtflag;		/* write parameters        	     */
Xint	eov;			/* count of tapemarks for eov        */
Xint	p;			/* padding or no padding  	     */
Xint	keep;			/* keeping same file names 	     */
Xint	firstrec;		/* set until 1st record read   	     */
Xint	ok_vol_label;		/* set for valid volume label  	     */
Xint	complete;		/* for write parameters	    	     */
Xint	devflag;		/* for tape device		     */
/*EOF
if test 2554 -ne "`wc -c dec.h`"
then
echo shar: error transmitting dec.h '(should have been 2554 characters)'
fi
echo shar: extracting dec.orig '(4854 characters)'
sed 's/^X//' > dec.orig << '/*EOF' 
X
X#include	<stdio.h>
X
X#define	MAXBUF	32760		/* maximum buffer size                */
X#define BLKSIZE    80           /* label size and default blocksize   */
X
X#define VOLERR	0
X#define SECERR	1
X#define REDERR  2
X#define CMDERR  3
X#define OPNERR  4
X#define FLGERR  5
X#define EOVERR  6
X#define FPRERR	7
X#define CLOERR	8
X#define TECERR	9  
X#define FCLERR  10
X#define FOPERR  11
X
X#define SPACE   ' '
X#define SPACES  "  "
X
Xstruct	vol_sl			/* sl standard volume label (VOL1)   */
X   {
X	char	id[4];		/* label identifier (VOL1)           */
X	char	volid[6];	/* volume serial number	             */
X	char	resv1;  	/* reserved for future use (0)       */
X	char	vtocptr[10];	/* VTOC pointer (' ''s)              */
X	char	resv2[20];	/* reserved for future use (' ''s)   */
X	char	ownid[10];	/* owner name and address	     */
X	char	resv3[29];      /* reserved for future use (' ''s)   */
X   };
X
Xstruct	vol_al			/* ansi standard volume label (VOL1) */
X   {
X	char	id[4];		/* label identifier (VOL1)           */
X	char	volid[6];	/* volume serial number              */
X	char	volsec;  	/* volume accessibility code (' ')   */
X	char	resv1[26];	/* reserved for future use (' ''s)   */
X	char	ownid[14];	/* owner name and address            */
X	char	resv2[28];	/* reserved for future use (' ''s)   */
X	char	stlev;  	/* ansi standards used (1)           */
X   };           	
X
Xstruct	ds_lab1			/* data set label 1 (HDR1/EOV1/EOF1) */
X   {
X	char	id[4];		/* label identifier (HDR1/EOV1/EOF1) */
X	char	dsid[17];	/* data set or file name 	     */
X	char	volid[6];	/* volume serial number              */ 
X	char	vseqno[4];	/* volume sequence number (1)        */
X	char	dseqno[4];	/* data set sequence number (1)      */
X	char	genno[4];	/* generation number for gdg         */
X	char	verno[2];	/* version number for gdg            */
X	char	crdate[6];	/* creation date (byyddd)	     */
X	char	exdate[6];	/* expiration date (byyddd)          */
X	char	dssec;  	/* data set security (sl:'0',al:' ') */
X	char	blkct[6];     	/* number of data blocks in data set */
X	char	syscd[13];	/* system code (OS36000000000)       */
X	char	resv1[7];	/* reserved for future use (' ''s)   */
X   };
X
Xstruct	ds_lab2			/* data set label (HDR2/EOV2/EOF2)   */
X  {
X	char	id[4];		/* label identifier (HDR2/EOV2/EOF1) */
X	char	recfm;  	/* record format (F/V/D/U)           */
X	char	blklen[5];	/* block length in bytes             */
X	char	reclen[5];	/* record length in bytes	     */
X	char 	tpden;  	/* tape density code (3)	     */
X	char	dspos;   	/* volume switch code (0)            */
X	char	jobid[17];	/* creation job and job step id      */
X	char	tprec[2];	/* tape recording technique (' ')    */
X	char	ctrlch; 	/* ctrl code for char set (A/M/' ')  */
X	char	resv1;  	/* reserved for future use (' ''s)   */
X	char	blkatr;   	/* blocking type (B/S/R/' ')         */
X	char	resv2[11];	/* reserved for future use (' ''s)   */
X	char	bufos[2];	/* length of block prefix            */
X	char   	resv3[28];	/* reserved for future use (' ''s)   */
X   };
X
Xstruct	user_lab		/* user header or trailer label      */
X   {
X	char	id[4];		/* label identifier (UHLn/UTLn)      */
X	char	info[76];	/* user specified information        */
X   };
X
Xstruct	any_lab			/* any label identifier              */
X   {
X	char	id[4];		/* label identifier	             */
X	char	info[76];	/* rest of the record	             */
X   };
X
Xunion buffer			/* 80 byte buffer for labels         */
X   {
X	struct	vol_sl   sl;	/* sl standard volume label          */
X	struct	vol_al   al;    /* ansi standard volume label        */
X	struct	ds_lab1  dl1;	/* data set label1                   */
X	struct	ds_lab2  dl2; 	/* data set label2                   */
X	struct	user_lab ul; 	/* user header or trailer label      */
X	struct	any_lab  gl;    /* general label identifier          */
X	char    ibuf[BLKSIZE];  /* 80 byte buffer                    */ 
X   };
X
X
X
Xtypedef	union buffer	BUF; 	/* identifier for buffer             */
Xtypedef	BUF     	*BPTR;  /* identifier for buffer pointer     */
X
XBUF	buf;			/* label buffer                      */
X
Xchar	inptbuf[MAXBUF];            
Xchar	fname[17];		/* UNIX file name                    */
Xchar	dsname[17];             /* file name on tape                 */
Xchar	*vid;			/* volume serial number		     */
Xint	ifd;			/* input file (tape) descriptor      */
XFILE	*ofp;			/* output file pointer		     */
Xint	filectr;
X
Xextern  int   errno;
Xint	ansi;			/* flag for ansi label tape          */
Xint	stdl;			/* flag for stdl tape                */
Xint	flags;			/* flag for required parameters      */
Xint	files;			/* flag for files to be read         */
Xint	eov;			/* count of tapemarks for eov        */
Xint	p;			/* flag for padding or no padding    */
X
X/* labels to check */
X# define	L_VOL1		1
X# define	L_HDR1		2
X# define	L_HDR2		3
X# define	L_EOF1		4
X# define	L_EOF2		5
X# define	L_EOV1		6
X# define	L_UTL		7
X# define	L_UHL		8
/*EOF
if test 4854 -ne "`wc -c dec.orig`"
then
echo shar: error transmitting dec.orig '(should have been 4854 characters)'
fi
echo shar: extracting main.c '(5234 characters)'
sed 's/^X//' > main.c << '/*EOF' 
X#include	"dec.h"
X
Xmain(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	         int	c, i;   
X	         char   **str;
X	         char   option;		        /* read, write, or dir      */
X		 char	sv[80];			/* numeric char string      */
X		 int	n1;			/* M of files=M-N or M      */
X		 int 	n2;			/* N of files=M-N           */
X		 int	fstart;			/* [] of 1st file to write  */
X		 int	fend;			/* [] of last file to write */
X		 int    setflag();
X		 int    match();
X	extern int	readtp();
X	extern int	dsrep();
X	extern int	err();
X	extern int	writetp();
X
X	fstart = fend = 0;
X	keep = 1;
X	if (argc < 2)
X		err(CMDERR);
X	option = *argv[1];
X	if (option != 'r' && option != 'w' && option != 'd')
X		err(CMDERR);
X	for (c = 2; c < argc; ++c)
X	{
X		str = argv + c;
X		if (match("blklen=", str))
X		{
X			setflag(&wrtflag, 2);
X			blklen = atoi(*str);
X			if (blklen > MAXBUF)
X				err(MAXERR);
X			if (fend < fstart)
X				fend = c;	
X			continue;
X		}
X		if (match("dev=", str))
X		{
X			setflag(&flags, 0);
X			tpdr = *str;
X			if (match(DEVRMT, str))
X			{		
X				devflag = 1; 
X				strcat(strcat(ntpdr, DEVNRMT), *str);
X			}
X			if (fend < fstart)
X				fend = c;
X			continue;
X		}
X		if (match("files=", str))
X		{
X			while (**str)
X			{
X				if (**str == ',')
X					(*str)++;
X				else if (**str == '-')
X				{
X					(*str)++;
X					for (sv[0]='\0';**str != ',' && 
X						        **str != '\0'; (*str)++)
X						strncat(sv, *str, 1);
X					sscanf(sv, "%d", &n2);  
X					for (i = ++n1; i <= n2; i++)
X						setflag(&files, i-1);
X				}
X				else      
X				{
X					for (sv[0]='\0';**str != ',' &&
X						        **str != '-' &&
X					                **str != '\0';(*str)++)
X					       strncat(sv, *str, 1);
X					sscanf(sv, "%d", &n1);
X					setflag(&files, n1-1);
X				}
X			}
X			if (fend < fstart) 
X				fend = c;
X			continue;
X		}
X		if (match("fn=", str)) 
X		{
X			setflag(&wrtflag, 3);
X			*(argv+c) = *str;  
X			fstart = c;	
X			if (**str == '\0')
X				fstart++;      	
X			continue;
X		}
X		if (match("keep=", str))
X		{
X			if (match("n", str) || match("N", str))
X			   	keep = 0;
X			if (fend < fstart)
X			 	fend = c;
X			continue;
X		}
X		if (match("pad=", str))
X		{
X			if (match("y", str) || match("Y", str))
X				p = 1; 
X			if (fend < fstart)
X				fend = c;
X			continue;
X		}
X		if (match("recfm=",str))
X		{
X			if (fend < fstart) 
X				fend = c;
X			if (strcmp(*str, "F") == 0)
X			{ 
X				setflag(&wrtflag, 0);
X				recode = F;
X			}
X			else if (strcmp(*str, "FB") == 0)
X			{	
X				setflag(&wrtflag, 0);	
X				recode = FB;
X			}	
X			else if (strcmp(*str, "V") == 0)
X			{
X				setflag(&wrtflag, 0);	
X				recode = V;
X			}	
X			else if (strcmp(*str, "VB") == 0)
X			{
X				setflag(&wrtflag, 0);
X				recode = VB;
X			}
X			else
X				err(FMTERR);
X			continue;
X		}
X		if (match("reclen=", str))
X		{
X			setflag(&wrtflag, 1);
X			reclen = atoi(*str);
X		 	if (fend < fstart)
X				fend = c;		
X			continue;
X		}
X		if (match("tf=ansi", str))
X		{
X			setflag(&flags, 1);
X			ansi = 1;
X			if (fend < fstart)
X				fend = c;
X			continue;
X		}
X		if (match("tf=stdl", str))
X		{
X			setflag(&flags, 1);
X			stdl = 1;
X			if (fend < fstart)
X				fend = c;
X			continue;
X		}
X		if (match("vol=", str))
X		{
X			setflag(&flags, 2);
X			strncpy(vid, *str, MIN(strlen(*str), 6));
X			if (strlen(vid) < 6)           
X				strncat(vid, "      ", 6-strlen(vid));
X			if (fend < fstart)
X				fend = c;
X			continue;
X		}	
X	}
X	
X	if (fend)
X		fend--;        
X	else
X		fend = argc - 1;
X
X	switch (wrtflag)
X	{
X		case 15:
X			complete = 1;
X			if (recode == F && reclen != blklen)
X				err(BLKERR);
X			else if (recode == FB && blklen % reclen != 0)
X				err(BLKERR);
X			else if (recode == V && blklen != reclen)
X				err(BLKERR);
X			else if (recode == VB && blklen % reclen != 4)          
X				err(BLKERR);
X			else if (ansi && (recode == V || recode == VB))
X				err(RFMERR);
X			break;
X
X		case  9:
X			if (recode == F || recode == FB)
X			{
X				complete = 1;
X				recode = F;
X				reclen = 80;
X				blklen = 80;
X			}
X			else
X				err(RECERR);
X			break;
X
X	}
X
X	switch (option)
X	{
X		case 'r':     
X			if (flags == 7)
X			{
X				if ((tfd = open(tpdr, 0)) >= 0)
X				{
X					if (!files)
X						files = ~files;
X					readtp();	
X				}
X				else
X					err(OPNERR);
X			}
X			else
X				err(FLGERR);
X			break;
X
X		case 'w':
X			if (flags == 7)
X			{
X				if ((wrtflag & 8) == 8)
X					if (devflag)
X						if ((tfd = open(ntpdr, 1)) >= 0)
X							writetp(argv,fstart,fend);	
X						else
X							err(OPNERR);
X					else
X						if ((tfd = open(tpdr, 1)) >= 0)
X							writetp(argv,fstart,fend);
X			 			else
X							err(OPNERR);
X				else
X					err(FNMERR);
X			}
X			else
X				err(FLGERR);
X			break;
X
X		case 'd':
X			if (flags == 7)
X			{
X				if ((tfd = open(tpdr, 0)) >= 0)   
X					dsrep();
X				else
X					err(OPNERR);	
X			}
X			else
X				err(FLGERR);
X			break;
X	}
X	if (close(tfd) != 0)
X		err(CLOERR);
X}
X
X
X
Xmatch(s, cs)
X/*
X**  match returns a 1 if the strings, pointed to by s and cs,
X**  are identical and advances the cs pointer the strlen(s),
X**  otherwise it returns a 0.
X*/
X
Xregister char	*s;
Xregister char	**cs;
X{
X	register char	*ls;
X
X	ls = *cs;
X	for (; **cs == *s; ++(*cs))
X	{
X		if (*++s == '\0')
X		{
X			++*cs;
X			return(1);
X		}
X	}
X	*cs = ls;
X	return(0);
X}
X
X
X
Xsetflag(flg, n)
X/*
X** Sets the (n + 1)st bit in flg to 1.
X*/
Xregister int	*flg;
Xregister int	n;
X{
X	register int	f;
X
X	if (n < MAXFILES)
X	{
X		f = 1;
X		f <<= n;
X		*flg |= f;
X	}
X	    
X}
/*EOF
if test 5234 -ne "`wc -c main.c`"
then
echo shar: error transmitting main.c '(should have been 5234 characters)'
fi
echo shar: extracting dsrep.c '(1539 characters)'
sed 's/^X//' > dsrep.c << '/*EOF' 
X
X# include	"dec.h"
X 
Xdsrep() 
X/*
X**  Prints to stdout a list of all tape filenames,
X**  file numbers, and record formats.
X**  This function is entered when given 'd' option,
X**  required parameters (dev=, vol=, tf=ansi or tf=stdl),
X**  and successful open of tpdr.
X*/
X{
X	extern int	ibmtoa();
X	extern int	check_id();
X	extern int	user_exit();
X	extern int 	err();
X	int	nb;			/* number of bytes read or -1 */
X	 
X	firstrec = eov = 1;
X	while (((nb = read(tfd, inptbuf, MAXBUF)) >= 0) &&
X		(nb || !(eov && (++eov == 3))))
X	{
X		if (nb == 0)
X			continue;
X		if (stdl)
X			ibmtoa(inptbuf, nb);
X		if (!ok_vol_label && !firstrec)
X			err(VOLERR);
X		if (firstrec)
X			firstrec = 0;
X		switch (check_id(inptbuf))
X		{
X			case L_VOL1:
X				process_dvol();
X				continue;
X
X			case L_HDR1:
X				process_dhdr1();
X				continue;
X
X			case L_HDR2:
X				process_dhdr2();
X				continue;
X
X			case L_EOF1:
X				++eov;
X				continue;
X
X			case L_EOF2:
X				continue;
X
X			case L_EOV1:
X				err(EOVERR);
X
X			case L_UTL:
X				user_exit();
X				continue;
X
X			case L_UHL:
X				user_exit();
X				continue;
X
X		}
X	}
X	if (nb == -1)
X		err(REDERR);
X	else
X		printf("\nProcessing Complete\n");		
X}
X  
Xprocess_dvol() 
X{
X	ok_vol_label = 1;
X	if (strncmp(inptbuf+4, vid, 6)) 
X		err(VIDERR);
X	if (ansi && (*(inptbuf+10) != SPACE))
X		err(SECERR);
X}
X		
X	
Xprocess_dhdr1()
X{
X        strncpy(fname, inptbuf+4, 17);
X}
X 
Xprocess_dhdr2() 
X{
X	if (!filectr)
X		printf("\t\tFILE NO\t\tFILE NAME\t\tFILE FORMAT\n\n");
X	printf("\t\t%d\t\t%s\t\t%c%c\n", ++filectr, fname, 
X			*(inptbuf+4), *(inptbuf+38));
X	eov = 0;	
X}
/*EOF
if test 1539 -ne "`wc -c dsrep.c`"
then
echo shar: error transmitting dsrep.c '(should have been 1539 characters)'
fi
echo shar: extracting err.c '(2798 characters)'
sed 's/^X//' > err.c << '/*EOF' 
X
X#include	"dec.h"  
X
Xerr(code)
X/*
X**  Prints error message to stderr based
X**  on code and then exits.
X*/
Xint	code;
X{
X	int i;
X
X	switch (code)
X	{
X		case VIDERR:
X			fprintf(stderr, "Volume ids do not match\n");
X			fprintf(stderr, "Volume specified: %s\n", vid);
X			fprintf(stderr, "Tape volume: ");
X			for (i=4; i<10; i++)
X				fputc(*(inptbuf+i), stderr);
X			break;
X
X		case SECERR:
X			fprintf(stderr, "Volume protected - Unable to read\n");
X			break;  
X
X		case REDERR:
X			fprintf(stderr, "Error Code %d - Unable to read tape\n",
X                                errno);
X			break;
X
X		case CMDERR:
X			fprintf(stderr, "Command Error - Valid options: r, w, or d\n");
X			break;
X
X		case OPNERR:
X			fprintf(stderr, "Error Code %d - Unable to open file\n",
X				errno);
X			break;
X
X		case FLGERR:
X			fprintf(stderr, "Required input parameters missing:\n");
X			if (!(flags & 1))
X				fprintf(stderr, "\tdev=\n");
X			if (!(flags & 2))
X				fprintf(stderr, "\ttf=ansi or tf=stdl\n");
X			if (!(flags & 4))
X				fprintf(stderr, "\tvol=\n");
X			break;
X
X		case EOVERR:
X			fprintf(stderr, "Error - Multiple volume file\n");
X			break;
X
X		case FPRERR:
X			fprintf(stderr, "File protected - Unable to read\n");
X			break;
X
X		case CLOERR:
X			fprintf(stderr,"Error Code %d - Unable to close file\n",
X                           	errno);
X			break;
X
X		case TECERR:
X			fprintf(stderr, "Tape recording technique error\n");
X			break;
X
X		case FCLERR:
X			fprintf(stderr, "Error - Unable to close output file\n");
X			break;
X
X		case FOPERR:
X			fprintf(stderr,"Error - Output filename cannot be accessed\n");
X			break;
X
X		case VOLERR:
X			if (ansi)
X				fprintf(stderr, "Error - Not ansi label tape\n");
X			else if (stdl)
X				fprintf(stderr, "Error - Not standard label tape\n");
X			break;
X                case WRTERR:
X                        fprintf(stderr, "Error code %d - Unable to write tape\n", errno);
X                        break;
X		case FMTERR:
X			fprintf(stderr, "Error - Invalid record format specified\n");
X			break;
X
X		case RECERR:
X			fprintf(stderr, "Error - Variable length records require blklen and reclen\n");
X			break;
X
X		case MAXERR:
X			fprintf(stderr, "Error - Blklen must be less than %d\n", MAXBUF);
X			break;
X
X		case BLKERR:
X			switch (recode)
X			{
X				case F:
X				case V:
X					fprintf(stderr, "Error - Blklen must equal reclen\n");
X					break;
X
X				case FB:
X					fprintf(stderr, "Error - Blklen must be a multiple of reclen\n");
X					break;
X
X				case VB:
X					fprintf(stderr, "Error - Blklen must be four more than a multiple of reclen\n");
X					break;
X	
X			}
X
X		case FNMERR:
X			fprintf(stderr, "Error - Option fn must be specified with 'w' option\n");
X			break;
X  
X		case RFMERR:
X			fprintf(stderr, "Error - Invalid record format specified for ansi label tape\n");
X			break;
X
X	}
X	fprintf(stderr, "\n");
X	exit(0);
X}
/*EOF
if test 2798 -ne "`wc -c err.c`"
then
echo shar: error transmitting err.c '(should have been 2798 characters)'
fi
echo shar: extracting convutil.c '(673 characters)'
sed 's/^X//' > convutil.c << '/*EOF' 
X# include	"tables.h"	/* IBM_ASCII conversion tables */
X
Xibmtoa(cp, n)
Xchar	*cp;
Xint	n;
X/*
X**  Converts n IBM characters of cp to their ASCII equivalent.
X*/
X{
X	for (; n--; cp++)
X		*cp = ibm_a[*cp & 255];
X}
X	
X
X
Xatoibm(cp, n)
Xchar	*cp;
Xint	n;
X/*
X**  Converts n ASCII characters of cp to their IBM-EBCDIC equivalent.
X*/
X{
X	for (; n--; cp++)
X		*cp = a_ibm[*cp & 255];
X}
X
X
Xatoe(cp, n)
Xchar	*cp;
Xint	n;
X/*   
X**  Converts n EBCDIC characters of cp to their ASCII equivalent.
X*/
X{
X	for (; n--; cp++)
X		*cp = a_ebc[*cp & 255];
X}
X
X
X
Xetoa(cp, n)
Xchar	*cp;
Xint	n;
X/*
X**  Converts n ASCII characters of cp to their EBCDIC equivalent.
X*/
X{
X	for (; n--; cp++)
X		*cp = ebc_a[*cp & 255];
X}
/*EOF
if test 673 -ne "`wc -c convutil.c`"
then
echo shar: error transmitting convutil.c '(should have been 673 characters)'
fi
echo shar: extracting readtp.c '(4742 characters)'
sed 's/^X//' > readtp.c << '/*EOF' 
X#include	"dec.h"
X#include	<ctype.h>
X 
Xint	nb;				/* number of bytes read or -1 */
Xint	vrlen;
Xchar	recfm;
Xchar	blkatr;
XFILE	*ofp;
X
Xreadtp()
X/*
X**  Reads user-specified files from tape to the
X**  current directory.
X**  This function is entered when given 'r' option,
X**  required parameters (dev=, vol=, tf=ansi or tf=stdl),
X**  and successful open of tpdr.
X*/
X{
X	extern int	ibmtoa();      
X	extern int	check_id();
X	extern int	eread();
X	extern int	err();
X	extern int	user_exit();
X	extern int	wrtrec();
X
X	firstrec = 1;
X	blkct = 0;
X	while (files && ((nb = read(tfd, inptbuf, MAXBUF)) >= 0 &&
X	       		(nb || !(eov && (++eov == 3)))))
X	{
X		if (nb == 0)
X			continue;
X		if (stdl)
X			ibmtoa(inptbuf, nb);
X		if (!ok_vol_label && !firstrec)
X			err(VOLERR);
X		if (firstrec)
X			firstrec = 0;
X		switch (check_id(inptbuf))
X		{
X			case L_VOL1:
X				process_rvol();
X				continue;
X
X			case L_HDR1:
X				if (files & 1)
X					process_rhdr1();
X				continue;
X
X			case L_HDR2:
X				if (files & 1)
X					process_rhdr2();
X				blkct = 0;
X				continue;
X
X			case L_EOF1:
X				process_reof1();
X				continue;
X		
X			case L_EOF2:
X				continue;
X
X			case L_EOV1:
X				err(EOVERR);
X				continue;
X
X			case L_UTL:
X				user_exit();
X				continue;
X
X			case L_UHL:
X				user_exit();	
X				continue;
X
X			default:
X				if (files & 1)
X				{
X					if (stdl)
X						atoibm(inptbuf, nb);
X					process_rfile();
X				}
X		}
X	}
X	if (nb == -1)
X		err(REDERR);
X	else
X		printf("\nProcessing complete\n");
X}
X
X
X
Xprocess_rvol()
X/*
X** check volid (volume serial number)
X** check accessibility if ansi
X*/
X{
X
X	ok_vol_label = 1;
X	if (strncmp(inptbuf+4, vid, 6))
X		err(VIDERR);
X	if (ansi && (*(inptbuf+10) != SPACE))
X			err(SECERR);
X}
X
X
X
Xprocess_rhdr1()
X/*
X** check security status and establish
X** the UNIX file name to be used
X*/
X{
X	int	i, j;
X
X	if (ansi && (*(inptbuf+53) != SPACE))
X		err(FPRERR);
X	if (stdl && (*(inptbuf+53) != '0'))
X		err(FPRERR);
X
X	if (keep == 0)
X	{
X		printf("Current File Name:  ");
X		putline(inptbuf+4, 17);
X		printf("\n\nNew File Name:  ");
X		eread(ufname);
X	}
X	if ((fname[0] == 0) || keep)
X		for (i=4, j=0; j<17; ++i, ++j)
X			fname[j] = isupper(inptbuf[i]) ? tolower(inptbuf[i]) : inptbuf[i];
X	if ((ofp = fopen(ufname, "w")) == NULL)
X		err(FOPERR);
X	eov = 0;
X}
X
X
X
X
Xprocess_rhdr2()
X/*
X** check tape recording technique
X*/
X{
X	if (strncmp(inptbuf+34, SPACES, 2))
X		err(TECERR);
X	printf("recfm is :   ");
X	putchar(*(inptbuf+4));
X	recfm = inptbuf[4];   
X	printf("\nblkatr is :  ");
X	putchar(*(inptbuf+38));
X	printf("\n");
X	blkatr = *(inptbuf+38);
X	if (blkatr == 'B')
X		blklen = convert(inptbuf+5, 5);
X	reclen = convert(inptbuf+10, 5);
X}
X
X
X
Xprocess_reof1()
X{
X	eov++;
X	if (blkct != convert(inptbuf+54, 6))
X		printf("Block count discrepancy - Processing continues\n");
X	if ((files & 1) && (fclose(ofp) == EOF))
X		err(FCLERR);
X	files >>= 1;
X}
X
X
X
Xprocess_rfile()
X/*
X** A data record has been read and converted if stdl 
X*/
X{
X	int	i;
X
X	do
X	{
X		printf("nb is %d\n", nb);
X		if (stdl)
X			ibmtoa(inptbuf, nb);
X		switch (blkatr)
X		{
X			case ' ':		/* unblocked records */
X				switch (recfm)
X				{
X					case 'F':
X						wrtrec(inptbuf, ofp, reclen, reclen);
X						blkct++;
X						break;
X
X					case 'V':
X						vrlen = convert(inptbuf, 4);
X						wrtrec(inptbuf+4, ofp, vrlen-4, reclen-4);
X						blkct++;
X						break;
X				}
X				break;
X
X			case 'B':		/* blocked records */
X				switch (recfm)
X				{
X					case 'F':
X						for (i=0; i<blklen; i += reclen)
X						{
X							printf("i is %d\n", i);
X							printf("blklen is %d\n", blklen);
X							printf("reclen is %d\n", reclen);
X							wrtrec(inptbuf+i, ofp, reclen, reclen);
X						}
X						blkct++;
X						break;
X
X					case 'V':
X						vblen = convert(inptbuf, 4);
X						for (i=4; i<vblen; i += vrlen)
X						{
X							vrlen = convert(inptbuf+i, 4);
X							wrtrec(inptbuf+(i+4), ofp, vrlen-4, reclen-4);
X						}
X						blkct++;
X						break;
X				}
X				break;
X
X			default:		/* copy as is */
X				wrtrec(inptbuf, ofp, nb, nb);
X		}
X	} while ((nb = read(tfd, inptbuf, MAXBUF)) > 0);
X	if (nb == -1)
X		err(REDERR);
X}
X
X
X
X
Xwrtrec(ibuf, ofp, irs, ors)
X/*
X**  Writes ors bytes of ibuf to
X**  pointed to by ofp.
X*/
Xchar	*ibuf;
XFILE	*ofp;
Xint	irs,ors;
X{
X	int	i;
X
X	if (p)
X	{
X		for (i=0; i<irs; i++, ibuf++)
X			putc(*ibuf, ofp);
X		if (irs < ors)
X			for (i=ors-irs; i--; )
X				putc(SPACE, ofp);
X		putc('\n', ofp);
X	}
X	else
X	{
X		/* strip blanks */
X		for (i=irs-1; *(ibuf+i) == SPACE && i>=0; irs--, i--)   
X			;
X		for (; irs>0; ibuf++, irs--)
X			putc(*ibuf, ofp);
X		putc('\n', ofp);
X	}
X}
X
X 
X
Xputline(cp, n)
X/*
X**  Prints n character of cp to stdout.
X*/
Xregister char	*cp;
Xregister int	n;
X{
X	while(n--)
X		putchar(*cp++);
X	putchar('\n');
X}
X
X
X
Xconvert(s, n)
X/*
X**  Converts n characters of s to an integer
X*/
Xchar	*s;
Xint	n;
X{
X	char	t[10];
X	int	l;
X
X	strncpy(t, s, n);
X	l = atoi(t);
X	return(l);
X}
/*EOF
if test 4742 -ne "`wc -c readtp.c`"
then
echo shar: error transmitting readtp.c '(should have been 4742 characters)'
fi
echo shar: extracting gutil.c '(1372 characters)'
sed 's/^X//' > gutil.c << '/*EOF' 
X# include	"dec.h"
X
X/*
X** Header Label Table
X*/
X
Xstruct labid
X{
X	char	*name;
X	int	code;
X};
X
Xstruct labid	Labelids[] =
X{
X	"VOL",		L_VOL1,
X	"HDR",		L_HDR1,
X	"EOF",		L_EOF1,
X	"EOV",		L_EOV1,
X	"UTL",		L_UTL,
X	"UHL",		L_UHL,
X	0                
X};
X
Xcheck_id(s)
X/*
X**  Searches Labelids for name s and
X**  returns numeric code or 0 if not
X**  found.
X*/
Xregister char	*s;
X{
X	register struct labid	*cw;
X
X	for (cw = Labelids; cw->name; cw++)
X	{
X		if (!strncmp(s, cw->name, 3))
X		{
X			if (cw->code == L_HDR1)
X				if (*(s+3) == '2')
X					return(L_HDR2);
X			if (cw->code == L_EOF1)
X				if (*(s+3) == '2')
X					return(L_EOF2);
X			return(cw->code);
X		}
X	}
X
X	return(0);
X}
X
X
X
Xuser_exit()
X{
X}
X
X
X
Xitoa(i, a, n)
X/*
X**  ITOA -- integer to ascii conversion
X**	    converts the integer i to  
X**	    an ascii character string 
X**	    n digits in length. a is the
X**	    position of the rightmost digit.    
X*/
Xregister int	i;
Xregister char	*a;
Xregister int	n;
X{
X	register int	k;
X	register char  *j;
X
X	j = a;
X	for (k=0; k<n; k++)	/* zeros out the field */
X		*j-- = '0';
X	j = a;
X	k = 0;
X	do
X	{
X		*j-- = i%10 + '0';
X		i /= 10;
X		k++;
X	} while (i > 0 && k < n);
X}
X
X
X
Xeread(s)
Xchar	*s;
X/*
X** The sizeof(string to be read) < length(s).
X** s will be a null-terminated string.
X*/
X{
X	int	c;
X	
X	while ((c=getchar()) != EOF)
X	{
X		if (c == '\n')
X		{
X			*s = 0;
X			return(0);
X		}
X		*s++ = c;
X	}
X	return(1);
X}
/*EOF
if test 1372 -ne "`wc -c gutil.c`"
then
echo shar: error transmitting gutil.c '(should have been 1372 characters)'
fi
echo shar: extracting writetp.c '(8140 characters)'
sed 's/^X//' > writetp.c << '/*EOF' 
X# include	"dec.h"
X# include	<ctype.h>
X
Xchar	fmtab[] = {'F',		/* recfm based on defines for recode  */
X		   'F',
X		   'V',
X		   'V' };
X
Xchar	blktab[] = {' ',	/* blocking attribute based on recode */
X		    'B',
X		    ' ',
X		    'B' };
X
Xwritetp(argv,fstart,fend)
X/*
X**  Writes user-specified UNIX files to tape
X**  according to user-specified format.
X**  This function is entered when given 'w' option,
X**  required parameters (dev=, vol=, fn=, tf=ansi or tf=stdl),
X**  and successful open of tpdr or ntpdr.
X*/
Xchar	**argv;			/* command line argument list         */
Xint	fstart;			/* index in argv of first file name   */
Xint	fend;			/* index in argv of last file name    */
X{
X	int	valid;		/* valid input flag                   */
X	char	s[256];		/* input string			      */
X	int	i, j, nb;
X	extern int	itoa();
X	extern int	atoibm();
X	extern int	err();
X	extern int	eread();
X	extern int	readrec();
X        
X	process_wvol();
X	for (j=1; fstart<=fend && j<MAXFILES; fstart++, j++)
X	{
X		if (!complete)
X		{
X			valid = 0;
X			printf("\nEnter input parameters for %s\n",argv[fstart]);
X			printf("\nPlease enter recfm:  ");
X			while (!valid)
X			{
X			eread(s);
X			if (strncmp(s,"F",2) == 0 || strncmp(s,"F ",2) == 0)
X			{
X				recode = F;
X				valid = 1;
X			}
X			else if ((strncmp(s,"V",2) == 0 || strncmp(s,"V ",2) == 0) && !ansi)
X			{	
X				recode = V;
X				valid = 1;
X			}
X			else if (strncmp(s,"FB",2) == 0)
X			{
X				recode = FB;
X				valid = 1;
X			}
X			else if ((strncmp(s, "VB",2) == 0) && !ansi)
X			{
X				recode = VB;
X				valid = 1;
X			}
X			else
X				printf("\nInvalid recfm - Please reenter:  ");
X			}
X			valid = 0;
X			printf("\nPlease enter reclen:  ");
X			while (!valid)
X			{
X			eread(s);
X			reclen = atoi(s);
X			if (reclen < MAXBUF)
X			 	valid = 1;
X			else
X				printf("\nInvalid reclen - Please reenter:  ");
X			}
X			if (recode == F || recode == V)
X				blklen = reclen;
X			else               
X			{
X				valid = 0;
X				printf("\nPlease enter blklen:  ");
X				while (!valid)
X				{
X				eread(s);
X				blklen = atoi(s);
X				if (blklen < MAXBUF)
X				{	
X					if (recode == FB && blklen%reclen == 0)
X						valid = 1;
X					else if (blklen%reclen == 4)
X						valid = 1; 
X				}
X				if (!valid)
X					printf("\nInvalid blklen - Please reenter: ");
X				}
X			}
X			
X		}
X
X		printf("\n");
X		strcpy(ufname, argv[fstart]);
X		if (keep == 0)
X		{
X			printf("Current File Name:  ");
X			printf("%s", argv[fstart]);
X			printf("\n\nNew File Name:  ");
X			eread(s);
X		}
X		for (i=0; i<17; i++)
X			fname[i] = SPACE;
X		if (s[0] == 0 || keep)
X			strncpy(fname, argv[fstart], MIN(strlen(argv[fstart]), 17));
X		else
X			strncpy(fname, s, MIN(strlen(s), 17));
X		if (strlen(fname) < 17)
X			strncat(fname, "                 ", 
X					(17 - strlen(fname)));
X		for (i=0; i < 17; ++i)
X			fname[i] = islower(fname[i]) ? toupper(fname[i]) : fname[i];
X		process_whdr1();
X 		process_whdr2();
X		wrteof();
X		process_wfile();
X		wrteof();
X		process_weof1();
X		process_weof2();
X		wrteof();
X	}
X	wrtfinaleof();
X}
X
Xprocess_wvol()
X{
X        int i;
X 
X        strncpy(inptbuf+0, VOL1, 4);
X        strncpy(inptbuf+4, vid, 6);
X        if (stdl) 
X           *(inptbuf+10) = ZERO;
X        else
X           *(inptbuf+10) = SPACE;
X        for (i=11; i<79; i++)
X           *(inptbuf+i) = SPACE;
X        if (stdl) 
X           *(inptbuf+79) = SPACE;
X        else
X           *(inptbuf+79) = '1';
X        if (stdl)
X           atoibm(inptbuf, 80);
X        if (write(tfd, inptbuf, 80) < 0)
X           err(WRTERR);
X}
X
Xprocess_whdr1()
X{
X    	int i;
X 
X	strncpy(inptbuf+0, HDR1, 4);
X     	strncpy(inptbuf+4, fname, 17);
X	strncpy(inptbuf+21, vid, 6);
X 	strncpy(inptbuf+27, "0001", 4);
X	strncpy(inptbuf+31, "0001",4);
X	for (i=35; i<42; i++)
X		*(inptbuf+i) = SPACE;
X	for (i=42; i<47; i++)
X		*(inptbuf+i) = ZERO;
X        *(inptbuf+47) = SPACE;
X 	for (i=48; i<53; i++)
X		*(inptbuf+i) = ZERO;
X	if (stdl)
X		*(inptbuf+53) = ZERO;
X        else
X		*(inptbuf+53) = SPACE;
X	for (i=54; i<60; i++)
X		*(inptbuf+i) = ZERO;
X	strncpy(inptbuf+60, SYSCD, 13);
X	for (i=73; i<80; i++)
X		*(inptbuf+i) = SPACE;
X	if (stdl)
X		atoibm(inptbuf, 80);
X	if (write(tfd, inptbuf, 80) < 0)
X	{
X		err(WRTERR);
X	}
X	
X}
X 
Xprocess_whdr2()
X{
X	int	i;
X 
X	strncpy(inptbuf+0, HDR2, 4);
X	*(inptbuf+4) = fmtab[recode];
X	itoa(blklen, inptbuf+9, 5);
X	itoa(reclen, inptbuf+14, 5);
X	*(inptbuf+15) = '3';
X	*(inptbuf+16) = ZERO;
X	for (i=17; i<38; i++)
X		*(inptbuf+i) = SPACE;
X	*(inptbuf+38) = blktab[recode];
X	for (i=39; i<80; i++)
X		*(inptbuf+i) = SPACE;
X	if (stdl)
X		atoibm(inptbuf, 80);
X	if (write(tfd, inptbuf, 80) < 0)
X		err(WRTERR);
X}
X
Xprocess_wfile()
X{
X	FILE	*fp;			/* UNIX file to be written to tape  */
X	int	more;			/* flag for reading blocked records */
X	int	nb;			/* number of bytes read or -1       */
X	int	i;
X	extern int	atoibm();
X
X	more = 1;
X	blkct = 0;
X	if ((fp = fopen(ufname, "r")) == NULL)
X		err(FOPERR);
X	for (i=MAXBUF; --i >= 0;)
X		*(inptbuf+i) = SPACE;
X
X	switch (recode)
X	{
X		case F:
X			while ((nb = readrec(fp,inptbuf)) >= 0)
X			{
X				if (stdl)
X					atoibm(inptbuf, nb);
X				write(tfd,inptbuf,reclen);
X				blkct += 1;
X				for (i=nb; --i >= 0;)
X					*(inptbuf+i) = SPACE;
X			}
X			break;
X
X		case FB:
X			while (more && (nb = readrec(fp,inptbuf)) >= 0)
X			{
X				for (i=reclen; i < blklen; i += reclen)
X					if ((nb = readrec(fp,inptbuf+i)) < 0)
X					{
X						more = 0;
X						break;
X					}
X				if (stdl)
X					atoibm(inptbuf, blklen);
X				write(tfd,inptbuf,blklen);
X				blkct += 1;
X				for (i=blklen; --i >= 0;)
X					*(inptbuf+i) = SPACE;
X			}
X
X		case V:
X			while ((nb = readrec(fp, inptbuf+4)) >= 0)
X			{
X				itoa(nb+4, inptbuf+3, 4);
X				if (stdl)
X					atoibm(inptbuf, nb+4);
X				write(tfd, inptbuf, nb+4);
X				blkct += 1;
X				for (i=nb+4; --i >= 0;)
X					*(inptbuf+i) = SPACE;
X			}
X			break;
X
X		case VB:
X			nb = readrec(fp, inptbuf+8);
X			while (more && nb >= 0)
X			{
X				itoa(nb+4, inptbuf+7, 4);
X				vblen = nb + 8;
X				for (i=nb+8;			
X			             i+(nb = readrec(fp,inptbuf+i+4)) < blklen;
X		                     i += nb+4)
X					if (nb < 0)
X					{
X						more = 0;
X						break;
X					}
X					else
X					{
X						itoa(nb+4, inptbuf+i+3, 4);
X						vblen += nb + 4;
X					}
X				itoa(vblen, inptbuf+3, 4);
X				if (stdl)
X					atoibm(inptbuf, vblen);
X				write(tfd, inptbuf, vblen);
X				blkct++;
X				if (nb > 0)
X					bufcpy(inptbuf+8, inptbuf+i+4, nb);
X				for (i=vblen-(nb+8); --i >= 0;)
X					*(inptbuf+i+nb+8) = SPACE;
X			}
X			break;
X
X
X	}
X	if (fclose(fp) == EOF)
X		err(FCLERR);
X}
X
Xprocess_weof1()
X{
X	int i;
X	 
X	strncpy(inptbuf+0, EOF1, 4);
X	strncpy(inptbuf+4, fname, 17);
X	strncpy(inptbuf+21, vid, 6);
X	strncpy(inptbuf+27, "0001", 4);
X	strncpy(inptbuf+31, "0001", 4);
X	for (i=35; i<42; i++)
X		*(inptbuf+i) = SPACE;
X	for (i=42; i<47; i++)
X		*(inptbuf+i) = ZERO;
X	*(inptbuf+47) = SPACE;
X	for (i=48; i<53; i++)
X		*(inptbuf+i) = ZERO;
X	if (stdl)
X		*(inptbuf+53) = ZERO;
X	else
X		*(inptbuf+53) = SPACE;
X	itoa(blkct, inptbuf+59, 6);
X	strncpy(inptbuf+60, SYSCD, 13);
X	for (i=73; i<80; i++)
X		*(inptbuf+i) = SPACE;
X	if (stdl)
X		atoibm(inptbuf, 80);
X	if (write(tfd, inptbuf, 80) < 0)
X		err(WRTERR);
X}
X 
Xprocess_weof2()
X{
X	int	i;
X	 
X	strncpy(inptbuf+0, EOF2, 4);
X	*(inptbuf+4) = fmtab[recode];
X	itoa(blklen, inptbuf+9, 5);
X	itoa(reclen, inptbuf+14, 5);
X	*(inptbuf+15) = '3';
X	*(inptbuf+16) = ZERO;
X	for (i=17; i<38; i++)
X		*(inptbuf+i) = SPACE;
X	*(inptbuf+38) = blktab[recode];
X	for (i=39; i<80; i++)
X		*(inptbuf+i) = SPACE;
X	if (stdl) 
X		atoibm(inptbuf, 80);
X	if (write(tfd, inptbuf, 80) < 0)
X		err(WRTERR);
X}
X 
Xwrteof()
X{
X	if (close(tfd) != 0)
X		err(CLOERR);
X	if (devflag)
X	{
X		if ((tfd = open(ntpdr, 1)) < 0)
X			err(OPNERR);
X	}
X	else
X		if ((tfd = open(tpdr, 1)) < 0)
X			err(OPNERR);
X}
X
Xwrtfinaleof()
X{
X	if (devflag)
X	{
X		close(tfd);
X		if ((tfd = open(tpdr, 1)) < 0)
X			err(OPNERR);
X	}
X}
X
X
Xreadrec(fp,buf)
X/*
X**  	Readrec reads a record from the designated file
X**	and returns the number of bytes read.
X*/
XFILE	*fp;
Xchar	*buf;
X{
X	int	i;
X	int	c;
X
X	for (i=0; (c = getc(fp)) != '\n'; i++)
X	{
X		if (c == EOF)
X		{
X			if (i == 0)
X				return(--i);
X			else 
X				return(i);
X		}
X		else 
X			*(buf+i) = c;
X	}
X	return(i);
X}
X		
X
X 
Xbufcpy(b, i, n)  
X/*
X**  Copies i[0] ... i[n-1] to b[0] ... b[n-1].
X*/
Xregister char	*b;
Xregister char	*i;
Xregister int	n;
X{
X	while(n--) 
X	{
X		*b++ = *i++;
X	}
X}
/*EOF
if test 8140 -ne "`wc -c writetp.c`"
then
echo shar: error transmitting writetp.c '(should have been 8140 characters)'
fi
:	End of shell archive
exit 0