cliffb@isavax.isa.com (cliff bedore*) (01/13/91)
In article <422@opus.NMSU.Edu> sberger@nmsu.edu ( Steve Berger ) writes: >I'm trying to copy the boot tape that I have for Ultrix. > >We had our original TK50 get trashed in the tape drive, >now I have a new one and I want to make a backup copy of it >so I can use the copy and save my original. > >Could someone kindly send me the correct command sequence >to copy a bootable TK50 tape? > >I imagine it can be done with dd but I can't figure out >which parameters to use. > >Thanks, > >Steve Berger > >sberger@nmsu.edu I had the same problem with a different tape but the logic below should work. The distr tapes have a variety of file lengths and block sizes so you need the program tape map supplied below by a kind gentleman. I use it to create a tape log of block sizes using tapemap and then read the tape using the shell script readtape naming all the files sequentially (1, 2 etc). I then used the shell program writetape to write the files back out in numerical order and voila a copy of the tape. I lay no claim to originality but it does work on any arbitrary tape thanks almost completely to the tapemap program supplied to me by the gentleman whose name i'v forgotten but his mail address is included below. Cliff readtape #!/bin/csh -f set count=1 foreach filedes (`cat filedata | cut -f3`) #foreach filedes (`cat filedata `) /bin/echo " $count $filedes" dd if=/dev/nrmt0h of=/e/cliffb/brad/$count bs=$filedes @ count++ end writetape #!/bin/csh -f set count=1 foreach filedes (`cat filedata | cut -f3`) #foreach filedes (`cat filedata `) /bin/echo " $count $filedes" dd if=/e/cliffb/brad/$count of=/dev/nrmt0h bs=$filedes @ count++ end From uunet!sbphy!hbo Fri Dec 21 22:27:05 1990 Received: by isavax.ISA.COM (5.57/UUCP-Project/02.16.86) id AA16773; Fri, 21 Dec 90 22:26:59 EST From: uunet!sbphy!hbo Received: from sbphy.ucsb.edu by uunet.uu.net (5.61/1.14) with SMTP id AA13276; Fri, 21 Dec 90 19:35:58 -0500 Received: from localhost by sbphy with SMTP (5.61/PCS-v1.0-eef) id AA01014; Fri, 21 Dec 90 16:38:29 -0800 Message-Id: <9012220038.AA01014@sbphy> To: wdg@gatech.edu, isavax!cliffb, rtc@westford.ccur.com, jmoore@ecn.purdue.edu, jrr%beta@LANL.GOV Subject: Tapemap Date: Fri, 21 Dec 90 16:38:28 PST Status: OR #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -s ./tapemap.c` then echo "writing ./tapemap.c" cat > ./tapemap.c << '\End\Of\Shar\' /* * Constraints on MAX_BLKSIZE: * - MAX_BLKSIZE % 512 == 0 * - MAX_BLKSIZE <= 65536 * - (int)MAX_BLKSIZE > 0 */ #define MAX_BLKSIZE 64512 #include <stdio.h> extern int optind; #define ERROR (-1) main(argc, argv) int argc; char **argv; { int fd; int opt; int verbose = 0; while ((opt = getopt(argc, argv, "v")) != EOF) { switch (opt) { case 'v': verbose = 1; break; default: (void) printf("Usage: %s [ -v ] device\n", argv[0]); exit(1); } } if (argv[optind] == NULL) { (void) printf("Usage: %s [ -v ] device\n", argv[0]); exit(1); } fd = open(argv[optind], 0); if (fd == ERROR) { perror(argv[optind]); exit(1); } setlinebuf(stdout); exit(tapemap(fd, verbose)); } tapemap(fd, verbose) int fd; register int verbose; { register int blk; /* last successful block # */ register int blksize; /* current block size */ char buf[MAX_BLKSIZE]; /* read buffer */ int file; /* current file # */ int maxsize; /* max block size */ int minsize; /* min block size */ register int eofcount; /* # consecutive EOF's read */ if (verbose) { (void) printf("file\tblock\tsize\n"); (void) printf("----\t-----\t-----\n"); } else { (void) printf("file\tblocks\tsize range\n"); (void) printf("----\t------\t----------\n"); } for (eofcount = 0, file = 1;; ++file) { if (!verbose) { maxsize = 0; minsize = sizeof(buf); } for (blk = 0; (blksize = read(fd, buf, sizeof(buf))) > 0;) { ++blk; eofcount = 0; if (verbose) { (void) printf("%d\t%d\t%d\n", file, blk, blksize); } else { if (blksize > maxsize) { maxsize = blksize; } if (blksize < minsize) { minsize = blksize; } } } if (blksize < 0) { (void) printf("read error: file %d block %d\n", file, blk + 1); return (1); } /* * if we get here, we just read an EOF */ if (++eofcount > 1) { break; /* end of tape */ } if (!verbose) { (void) printf("%d\t%d\t%d", file, blk, minsize); if (maxsize > minsize) { (void) printf("\t%d", maxsize); } putchar('\n'); } } return (0); } \End\Of\Shar\ else echo "will not over write ./tapemap.c" fi if `test ! -s ./tapemap.1` then echo "writing ./tapemap.1" cat > ./tapemap.1 << '\End\Of\Shar\' .TH TAPEMAP 1 "20 January 1988" "UCSB CSL" .SH NAME tapemap \- map a mystery tape .SH SYNOPSIS .B tapemap [ .B \-v ] device .SH DESCRIPTION .I Tapemap reads the tape mounted on .IR device , producing one line of output for each file on the tape. The output format is: .IP file#<tab>#blocks<tab>max-blocksize<tab>min-blocksize .PP File and block numbers start at 1. Block sizes are given in bytes. .SH OPTIONS .TP .B \-v verbose mode. Superseding the default output, one line of output is printed for each block on the tape. The output format is: .IP file#<tab>record#<tab>blocksize .\".SH FILES .\".SH SEE ALSO .SH DIAGNOSTICS .B read error: file .I f .B block .I b .PP Plus the usual \*(lqcan't open ...\*(rq\-type stuff. .SH AUTHOR J. Frew, Computer Systems Laboratory, UCSB .SH BUGS Tape blocks longer than 64512 bytes will cause read errors. .PP .IR Tapemap 's output is silly (but harmless) if .I device is not a tape drive. \End\Of\Shar\ else echo "will not over write ./tapemap.1" fi echo "Finished archive 1 of 1" exit