ts and tcp - tape utilities
Lyle McElhaney
lmc at denelvx.UUCP
Sun Dec 2 16:04:25 AEST 1984
Well, it seems that there was a bug in the posting of ts.c and tcp.c that
I made about a month ago. Soooo...
ts.c - reads in a tape and outputs a synopsis of files and block sizes.
tcp.c - allows an exact tape copy of any tape to be made with only one tape
drive.
Manual pages went out the first time; I'll not repeat them here. (I'll mail
them on request).
: - - - - - - - - - - - - - cut here - - - - - - - - - - - - - - - - -
: This is a shar archieve. Extract with sh, not csh.
: The rest of this file will extract:
: ts.c tcp.c
echo extracting - ts.c
sed 's/^X//' > ts.c << 'FUNKYSTUFF'
X/*
X * ts - This program outputs a file/record description of a tape's
X * structure.
X *
X * Exits: 0 - normal.
X * 1 - usage error.
X * 2 - tape read error.
X * 3 - SIGINT received.
X *
X * Copyright (C) 1983, 1984 Lyle McElhaney
X * Permission to copy for non-commercial use granted under condition
X * that this notice remains intact in the copy.
X *
X * Address: 2489 W. Ridge Rd., Littleton, CO 80120
X * ....denelcor!lmc
X */
X#include <stdio.h>
X#include <signal.h>
X
X#define MAXBUF=32767
X/* This can be whatever maximum the machine/os will take.
X * 16000 is allowed on an 11/44 running System 3 Unix (tm).
X */
X
X#ifndef YES
X#define YES 1
X#define NO 0
X#endif
X
Xchar tape[]="/dev/rmt0\0\0";
Xchar buff[MAXBUF];
XFILE *tapedev;
Xlong recno, nrec, fsize, filen;
Xextern void sig();
X
Xmain (argc, argv)
X int argc;
X char **argv;
X{
X char *p;
X int n;
X
X argv++;
X if (argc > 1) {
X p = *argv;
X if (*p == '-') {
X p++;
X while (*p != '\0') {
X switch (*p++) {
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':
X case '8':
X case '9':
X case '0':
X tape[8] = *(p-1);
X break;
X case '1':
X tape[8] = '1';
X if (*p >= '0' && *p <= '5')
X tape[9] = *p++;
X break;
X default:
XUsage:
X fprintf (stderr, "Usage: ts [-0...15]\n");
X exit (2);
X }
X }
X argc--;
X argv++;
X }
X else goto Usage;
X }
X
X signal (SIGINT, sig);
X if ((tapedev = fopen (tape, "r")) == NULL) {
X fprintf (stderr, "ts: cannot open %s\n", tape);
X exit (2);
X }
X
X filen = 0;
X for (;;) {
X recno = nrec = 0;
X for (;;) {
X n = read (fileno (tapedev), buff, sizeof buff);
X if (n > 0) {
X if (recno == 0) {
X printf ("File %ld:\n", filen);
X fsize = n;
X }
X if (n != fsize) {
X printf (" Records %ld through %ld (%ld records), length = %ld bytes\n",
X nrec, recno - 1, recno - nrec, fsize);
X fsize = n;
X nrec = recno;
X }
X recno ++;
X } else goto Out;
X }
XOut: if (n == 0) {
X if (recno != 0)
X printf (" Records %ld through %ld (%ld records), length = %ld bytes\n",
X nrec, recno - 1, recno - nrec, fsize);
X } else {
X printf ("Tape read error %d in record %ld\n", n, recno);
X exit (1);
X }
X if (recno == 0) break;
X filen ++;
X }
X printf ("End of tape reached.\n");
X fclose (tapedev);
X exit (0);
X}
X
Xvoid sig ()
X{
X printf (" Records %ld through %ld (%ld records), length = %ld bytes\n",
X nrec, recno-1, recno - nrec, fsize);
X printf ("ts: aborted by interrupt at that point.\n");
X close (tapedev);
X exit (3);
X}
FUNKYSTUFF
echo extracting - tcp.c
sed 's/^X//' > tcp.c << 'FUNKYSTUFF'
X/*
X * tcp - this routine runs in input (-i) and output (-o) modes. On
X * input, it reads a tape's contents (out to the double tape-marks)
X * and writes that data to files in a the current directory, along
X * with a file of data which will allow reconstruction of the tape
X * in the output mode.
X *
X * Copyright (C) 1983, 1984 Lyle McElhaney
X * Permission to copy for non-commercial use granted under condition
X * that this notice remains intact in the copy.
X *
X * Address: 2489 W. Ridge Rd., Littleton, CO 80120
X * ....denelcor!lmc
X *
X */
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/ioctl.h>
X#ifdef MTIO
X#include <sys/mtio.h>
X#endif
X#define MAXBUF 32768 /* maximum tape physical record size */
X#ifndef YES
X#define NO 0
X#define YES 1
X#endif
X#define NYU 2
X
Xextern char *index();
Xextern int errno;
Xchar nrtape[]="/dev/nrmt8\0\0";
Xchar tape[]="/dev/rmt8\0\0";
Xchar ffh[]="tcp,f"; /* headers for temp filenames */
Xchar nfh[]="tcp,n";
Xchar format[]="%s%02d%05d"; /* format of filenames. args: [fcn]fh, tapen, nfile */
X#define FMTSIZ 13 /* limit on size of filenames created + 1 */
Xchar ffile[FMTSIZ], cfile[FMTSIZ];
Xchar buff[MAXBUF];
Xchar buf[10];
Xint nfile;
Xint tapen=0;
Xint inmode=NYU; /* input mode - not yet set. User must choose. */
XFILE *tapedev, *filedev, *ctldev;
Xlong recno, nrec, fsize, filen;
X#ifdef MTIO
Xint convmode=NO; /* conversational mode default to no */
Xstruct mtop mtop;
X#endif
X
Xmain (argc, argv)
X int argc;
X char **argv;
X{
X char *p;
X int n;
X
X argv++;
X if (argc > 1) {
X p = *argv;
X if (*p == '-') {
X p++;
X while (*p != '\0') {
X switch (*p++) {
X#ifdef MTIO
X case 'c':
X convmode = YES;
X break;
X#endif
X case 'i':
X if (inmode != NYU) goto Usage;
X inmode = YES;
X break;
X case 'o':
X if (inmode != NYU) goto Usage;
X inmode = NO;
X break;
X case 'n':
X tapen = atoi (p);
X break;
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':
X case '8':
X case '9':
X case '0':
X tape[8] = nrtape[9] = *(p-1);
X break;
X case '1':
X tape[8] = nrtape[9] = '1';
X if (*p >= '0' && *p <= '5')
X tape[9] = nrtape[10] = *p++;
X break;
X default:
XUsage:
X fprintf (stderr, "Usage: tcp [-i] [-o] [-nxx] [-1...15]\n");
X exit (2);
X }
X }
X argc--;
X argv++;
X }
X } else goto Usage;
X if (inmode == NYU) goto Usage;
X
X if (inmode) {
X/*
X * input mode - read tape into files.
X */
X sprintf (cfile, format, nfh, tapen, 0);
X if ((ctldev = fopen (cfile, "w+")) == NULL) {
X fprintf (stderr, "tcp: cannot open %s\n", cfile);
X exit (2);
X }
X if ((tapedev = fopen (tape, "r")) == NULL) {
X fprintf (stderr, "tcp: cannot open %s\n", tape);
X exit (2);
X }
X filen = 0;
X for (;;) {
X recno = nrec = 0;
Xreread: while ((n = read (fileno (tapedev), buff, sizeof buff)) > 0) {
X if (recno == 0) {
X fsize = n;
X sprintf (ffile, format, ffh, tapen, filen);
X if ((filedev = fopen (ffile, "w+")) == NULL) {
X fprintf (stderr, "tcp: cannot open %s\n", ffile);
X exit (2);
X }
X }
X if (write (fileno (filedev), buff, n) <= 0) {
X fprintf (stderr, "tcp: file write error #%d in %s\n",
X errno, ffile);
X exit (2);
X }
X if (fsize != n) {
X fprintf (ctldev, "%d,%d\n", recno - nrec, fsize);
X fsize = n;
X nrec = recno;
X }
X recno ++;
X }
X if (n == 0)
X if (recno == 0)
X break;
X else {
X fprintf (ctldev, "%d,%d\n0,0\n", recno - nrec, fsize);
X filen ++;
X fclose (filedev);
X }
X else {
X printf ("Tape read error %d in record %ld\n", n, recno);
X#ifdef MTIO
X for (;;) {
X if (convmode) {
X printf ("Abort, Retry, or Ignore? ");
X if (gets (buf) != NULL) {
X if (*buf == 'R' || *buf == 'r') {
X mtop.mt_count = 1;
X mtop.mt_op = MTBSR;
X if (ioctl (fileno (tapedev), MTIOCTOP, &mtop) < 0) {
X printf ("error %d in ioctl; ignoring prev error.\n", errno);
X recno ++;
X }
X goto reread;
X } else if (*buf == 'I' || *buf == 'i') {
X recno ++;
X goto reread;
X } else if (*buf == 'A' || *buf == 'a')
X exit (1);
X }
X } else
X exit (1);
X }
X#else
X exit (1);
X#endif MTIO
X }
X }
X fclose (tapedev);
X fprintf (ctldev, "0,1\n");
X fclose (ctldev);
X } else {
X/*
X * output mode - copy files back out to tape.
X */
X sprintf (cfile, format, nfh, tapen, 0);
X if ((ctldev = fopen (cfile, "r")) == NULL) {
X fprintf (stderr, "tcp: cannot open %s\n", cfile);
X exit (2);
X }
X recno = 0;
X for (;;) {
X if (fgets (buf, sizeof(buf), ctldev) == NULL) {
X fprintf (stderr, "tcp: file %s malformed.\n", cfile);
X exit (2);
X }
X nrec = atoi (buf);
X n = atoi (index (buf, ',') + 1);
X if (nrec != 0) {
X if (recno == 0) {
X if ((tapedev = fopen (nrtape, "a")) == NULL) {
X fprintf (stderr, "tcp: cannot open %s\n", nrtape);
X exit (2);
X }
X sprintf (ffile, format, ffh, tapen, filen);
X if ((filedev = fopen (ffile, "r")) == NULL) {
X fprintf (stderr, "tcp: cannot open %s\n", ffile);
X exit (2);
X }
X }
X for (; nrec > 0; nrec--) {
X if (read (fileno (filedev), buff, n) <= 0) {
X fprintf (stderr, "tcp: file read error #%d in %s\n",
X errno, ffile);
X exit (2);
X }
X if (write (fileno (tapedev), buff, n) <= 0) {
X fprintf (stderr, "tcp: tape write error #%d in %s\n",
X errno, nrtape);
X exit (2);
X }
X recno ++;
X }
X } else if (n == 0) {
X fclose (filedev);
X fclose (tapedev);
X filen ++;
X recno = 0;
X } else
X break;
X }
X fclose (ctldev);
X }
X exit (0);
X}
FUNKYSTUFF
More information about the Comp.sources.unix
mailing list