lmc@denelvx.UUCP (Lyle McElhaney) (12/02/84)
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