[comp.sources.misc] Read tape and print format program

root@qetzal.UUCP (07/15/87)

Brandon - here is a little utility program for USG systems; it may
very well work on BSD as well. Please post to comp.sources.misc.

Submitted by qetzal!rcw; Thanks to rochester!ken

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	taprd.1
#	taprd.c
# This archive created: Fri Jul  3 13:46:03 1987
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'taprd.1'
then
	echo shar: "will not over-write existing file 'taprd.1'"
else
cat << \SHAR_EOF > 'taprd.1'
.TH TAPRD 1 AUS
.SH NAME
taprd  \-  read tape and print its format
.SH SYNOPSIS
.B taprd
raw_special_file
.SH DESCRIPTION
.I Taprd
is used to read a tape
and list the format of records and tape marks.
It will print a message describing the last set of
identical records encountered
every time the record type changes.
On receiving an interrupt,
.I taprd
prints a summary before terminating.
.SH EXAMPLES
taprd /dev/rmt0
.SH SEE ALSO
mt (4)
SHAR_EOF
fi
if test -f 'taprd.c'
then
	echo shar: "will not over-write existing file 'taprd.c'"
else
cat << \SHAR_EOF > 'taprd.c'
/*
**	this creation just reads raw tape file specified as
**	1st argument.  it then reports on record size etc.  on
**	double tapemark it stops.
*/ 

#include	<sys/types.h>
#include	<sys/stat.h>
#include	<signal.h>
#include	<stdio.h>
#include	<fcntl.h>


#define		NBUF	44	/* Maximum size tape block likely to be encountered */
#define		NERR	10	/* NERR consecutive ==> giveup */

char		buf[NBUF*BUFSIZ];
int		flag;
int		err;



catch(s)
	int	s;
{
	signal(s, SIG_IGN);
	flag = 1;
}



main(argc, argv)
	int		argc;
	char **		argv;
{
	register	iold;
	register	i;
	register	nrec;
	register	infd;
	struct stat	sbuf;

	signal(SIGHUP, catch);
	if ( signal(SIGINT, SIG_IGN) == SIG_DFL )
		signal(SIGINT, catch);
	if ( signal(SIGQUIT, SIG_IGN) == SIG_DFL )
		signal(SIGQUIT, catch);

	if(argc != 2)
	{
		fprintf(stderr, "Usage: %s file\n", argv[0]);
		return 2;
	}

	if((infd = open(argv[1], O_RDONLY)) == -1)
	{
		perror(argv[1]);
		return 2;
	}

	fstat(infd, &sbuf);
	if((sbuf.st_mode&S_IFMT) != S_IFCHR)
	{
		fprintf(stderr, "%s not a raw device !!\n", argv[1]);
		return 2;
	}

	nrec = 0;
	iold = read(infd, buf, sizeof buf);
	for(;;)
	{
		nrec++;
		i = read(infd, buf, sizeof buf);
		if(i == iold && i == 0)
			goto fini;	/* considered end-of-tape */
		if ( (i==iold) && (i==-1) && (nrec==NERR) )
		{
			printf("%d consecutive errors: EOT assumed\n",NERR);
			return 1;
		}
		if((i == iold) && !flag)
			continue;
		if(iold)
		{
			if(iold != -1)
			{
				printf("%6d. * %6o(%6d.)\n",
					nrec, iold, iold);
			}
			else
			{
				printf("%6d. *  ERR  \n", nrec);
				err++;
				if(nrec > 1)
					return err;
			}
		}
		else
		{
			printf("\tTM\n");
		}
		nrec = 0;
		iold = i;
		if(flag)
		{
			printf("Interrupted\n");
			return 1;
		}
	}
fini:
	printf("\tEOT\n");
	return err;
}
SHAR_EOF
fi
exit 0
#	End of shell archive