pdp11v/usr/src/cmd/volcopy.c
/* volcopy COMPILE: cc -O volcopy.c -s -i -o volcopy */
/* u370 COMPILE: cc -O -b1,1 volcopy.c -s -i -o volcopy */
/* @(#)volcopy.c 4.9 */
#define LOG
#define AFLG 0
#ifdef RT
#include <rt/types.h>
#include <rt/param.h>
#include <rt/fmgr/filsys.h>
#include <rt/stat.h>
#else
#include <sys/param.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <sys/filsys.h>
#include <sys/stat.h>
#endif
#include <stdio.h>
#include <signal.h>
#define FILE_SYS 1
#define DEV_FROM 2
#define FROM_VOL 3
#define DEV_TO 4
#define TO_VOL 5
#define T_TYPE 0xfd187e20 /* like FsMAGIC */
#ifdef RT
#define IFTAPE(s) (EQ(s,"/dev/mt",7)||EQ(s,"mt",2))
#else
#define IFTAPE(s) (EQ(s,"/dev/rmt",8)||EQ(s,"rmt",3)||EQ(s,"/dev/rtp",8)||EQ(s,"rtp",3))
#endif
#ifdef u370
#define BLKSIZ 4096
#else
#define BLKSIZ 512 /* use physical blocks */
#endif
#define _2_DAYS 172800L
#define MAX 1000000L
#ifdef u370
#define Ft800x10 2L /* u370 */
#define Ft1600x10 4L /* u370 */
#define Ft6250x50 15L /* u370 */
#else
#define Ft800x10 15L
#define Ft1600x4 22L
#define Ft1600x10 28L
#define Ft6250x10 90L
#define Ft6250x50 120L
#endif
struct Tphdr {
char t_magic[8];
char t_volume[6];
char t_reels,
t_reel;
long t_time;
long t_length;
long t_dens;
long t_reelblks; /* u370 added field */
long t_blksize; /* u370 added field */
long t_nblocks; /* u370 added field */
char t_fill[468];
int t_type; /* does tape have nblocks field? (u3b) */
} Tape_hdr;
int K_drive = 0; /* Kennedy tape drive? (4 blks/rec max) */
int first = 0;
char **args;
int Nblocks = 0;
long Reelblks = MAX;
int Reels = 1;
int reel = 1;
int Reelsize = 0;
long rblock = 0, reeloff = 0;
long saveFs;
int Bpi = 0;
int bufflg = 0;
long Fs;
short *Buf;
long Fstype;
int sts;
int p_in, p_out;
extern int errno;
/*
filesystem copy with propagation of volume ID and filesystem name:
volcopy [-options] filesystem /dev/from from_vol /dev/to to_vol
options are:
-feet - length of tape
-bpi - recording density
-reel - reel number (if not starting from beginning)
-buf - use double buffered i/o (if dens >= 1600 bpi)
-a - ask "y or n" instead of "DEL if wrong"
-s - inverse of -a
Examples:
volcopy root /dev/rrp2 pk5 /dev/rrp12 pk12
volcopy u3 /dev/rrp15 pk1 /dev/rmt0 tp123
volcopy u5 /dev/rmt0 - /dev/rrp15 -
In the last example, dashed volume args mean "use label that's there."
From/to devices are printed followed by `?'.
User has 10 seconds to DEL if mistaken!
With '-a' option, a positive user response is required to continue.
With '-s' option, -a is cancelled, some override questions are bypassed.
*/
long Block;
char *Totape, *Fromtape;
FILE *Devtty;
char *Tape_nm;
int pid;
struct filsys Superi, Supero, *Sptr;
extern int read(), write();
sigalrm()
{
signal(SIGALRM, sigalrm);
}
sigint()
{
if(pid != 1){
if(asks("Want Shell? "))
system("sh");
else if(asks("Want to quit? ")) {
if(pid) kilchld();
exit(2);
}
}
signal(SIGINT, sigint);
}
char kilcmd[] = "kill -9 000000";
kilchld()
{
sprintf(&kilcmd[8],"%d",pid -1);
system(kilcmd);
}
char *tapeck();
main(argc, argv) char **argv;
{
int fsi, fso;
struct stat statb;
long tvec;
int i, altflg = AFLG;
FILE *fb, *popen();
char vol[12], dev[12], c;
signal(SIGALRM, sigalrm);
while(argv[1][0] == '-') {
if(EQ(argv[1], "-bpi", 4))
if((c = argv[1][4]) >= '0' & c <= '9')
Bpi = getbpi(&argv[1][4]);
else {
++argv;
--argc;
Bpi = getbpi(&argv[1][0]);
}
else if(EQ(argv[1], "-feet", 5))
if((c = argv[1][5]) >= '0' & c <= '9')
Reelsize = atoi(&argv[1][5]);
else {
++argv;
--argc;
Reelsize = atoi(&argv[1][0]);
}
else if(EQ(argv[1],"-reel",5))
if((c = argv[1][5]) >= '0' & c <= '9')
reel = atoi(&argv[1][5]);
else {
++argv;
--argc;
reel = atoi(&argv[1][0]);
}
else if(EQ(argv[1],"-buf",4))
bufflg++;
else if(EQ(argv[1],"-a",2))
altflg++;
else if(EQ(argv[1],"-s",2))
altflg = 0;
else {
fprintf(stderr, "<%s> invalid option\n",
argv[1]);
exit(1);
}
++argv;
--argc;
}
args = argv;
Devtty = fopen("/dev/tty", "r");
time(&tvec);
/* get mandatory inputs */
if(argc!=6){
fprintf(stderr,"Usage: volcopy [options] fsname");
fprintf(stderr,"/devfrom volfrom /devto volto\n");
exit (9);
}
if((fsi = open(argv[DEV_FROM],0)) < 1)
fprintf(stderr, "%s: ",argv[DEV_FROM]), err("cannot open");
if((fso = open(argv[DEV_TO],0)) < 1)
fprintf(stderr, "%s: ",argv[DEV_TO]), err("cannot open");
#ifdef RT
if((fstat(fsi, &statb)<0) || (((statb.st_mode&S_IFMT)!=S_IFBLK)
&& ((statb.st_mode & S_IFMT) != S_IFREC)
&& ((statb.st_mode & S_IFMT) != S_IFCHR)))
err("From device not character, block, or record special");
if(fstat(fso, &statb)<0 || (((statb.st_mode&S_IFMT)!=S_IFBLK)
&& ((statb.st_mode & S_IFMT) != S_IFREC)
&& ((statb.st_mode & S_IFMT) != S_IFCHR)))
err("To device not character, block, or record special");
#else
if(fstat(fsi, &statb)<0 || (statb.st_mode&S_IFMT)!=S_IFCHR)
err("From device not character-special");
if(fstat(fso, &statb)<0 || (statb.st_mode&S_IFMT)!=S_IFCHR)
err("To device not character-special");
#endif
Fromtape = argv[DEV_FROM]; /* this will get reset if not appropriate
but is needed by tapeck's label processing */
Fromtape = tapeck(argv[DEV_FROM], argv[FROM_VOL], fsi);
Totape = tapeck(argv[DEV_TO], argv[TO_VOL], fso);
if(Totape && Fromtape)
err("Use dd(1) command to copy tapes");
#ifdef RT
setio(-1,1); /* use physical io */
#endif
#ifdef u370
Nblocks = (Totape||Fromtape)? 8:8; /* disk-disk can even be > 8 */
Buf = (short *)malloc(BLKSIZ*(Nblocks+1));
/* Force buffer to page boundary */
Buf = (short *)((int)((char *)Buf+BLKSIZ) & ~(BLKSIZ-1));
if ((int)Buf <= 1) {
fprintf(stderr, "Not enough memory--get help\n");
exit(1);
}
#else
#ifdef u3b
if (K_drive)
Nblocks = 4;
else
Nblocks = ((Totape||Fromtape)&&(Bpi!=6250))? 10:152;
#else
Nblocks = ((Totape||Fromtape)&&(Bpi!=6250))? 10:88;
#endif
#ifdef u3b
if(Bpi == 6250) Nblocks = 10;
#else
if(Bpi == 6250) Nblocks = 50;
#endif
Buf = (short *)sbrk(BLKSIZ*Nblocks);
#ifdef u3b
if((int)Buf == -1 && Nblocks ==152) {
Nblocks = 32;
#else
if((int)Buf == -1 && Nblocks ==88) {
Nblocks = 22;
#endif
Buf = (short *)sbrk(BLKSIZ*Nblocks);
}
if((int)Buf == -1) {
fprintf(stderr, "Not enough memory--get help\n");
exit(1);
}
#endif
Sptr = (struct filsys *)&Buf[BLKSIZ/2];
if(!Fromtape && !Totape) reel = 1;
if((reel == 1) || !Fromtape){
if(read(fsi, Buf, 2*BLKSIZ) < 2*BLKSIZ)
err("read error on input");
strncpy(Superi.s_fname, Sptr->s_fname,6);
strncpy(Superi.s_fpack, Sptr->s_fpack,6);
if (Sptr->s_magic != FsMAGIC)
Sptr->s_type = Fs1b;
switch ((int)Sptr->s_type) {
case Fs1b:
Fstype = 1;
Fs = Sptr->s_fsize;
break;
case Fs2b:
Fstype = 2;
Fs = Sptr->s_fsize * 2;
break;
default:
err("File System type unknown--get help");
}
Superi.s_fsize = Sptr->s_fsize;
Superi.s_time = Sptr->s_time;
}
if(read(fso, Buf, 2*BLKSIZ) < 2*BLKSIZ){
fprintf(stderr,"Read error on output\n");
if(!Totape | !altflg) ask();
}
strncpy(Supero.s_fname, Sptr->s_fname,6);
strncpy(Supero.s_fpack, Sptr->s_fpack,6);
Supero.s_fsize = Sptr->s_fsize;
Supero.s_time = Sptr->s_time;
if((reel != 1) && Fromtape){ /* if this isn't reel 1,
the TO_FS better have been initialized */
printf("\volcopy: IF REEL 1 HAS NOT BEEN RESTORED,");
printf(" STOP NOW AND START OVER ***\n");
if(!asks(" Continue? ")) exit(9);
strncpy(Superi.s_fname,argv[FILE_SYS],6);
strncpy(Superi.s_fpack,argv[FROM_VOL],6);
}
if(Totape){
Reels = Fs / Reelblks + ((Fs % Reelblks) && 1);
printf("You will need %d reels.\n", Reels);
printf("(\tThe same size and density");
printf(" is expected for all reels)\n");
/* output vol name was validated already */
strncpy(Tape_hdr.t_volume,argv[TO_VOL],6);
strncpy(Supero.s_fpack,argv[TO_VOL],6);
strncpy(vol,argv[TO_VOL],6);
strncpy(Supero.s_fname,argv[FILE_SYS],6);
}
if(Fromtape){
if((Tape_hdr.t_reel != reel
|| Tape_hdr.t_reels!=Reels)){
fprintf(stderr, "Tape disagrees: Reel %d of %d",
Tape_hdr.t_reel, Tape_hdr.t_reels);
fprintf(stderr," : looking for %d of %d\n",
reel,Reels);
ask();
}
strncpy(vol,Tape_hdr.t_volume,6);
}
if(!EQ(argv[FILE_SYS],Superi.s_fname, 6)) {
printf("arg. (%.6s) doesn't agree with from fs. (%.6s)\n",
argv[FILE_SYS],Superi.s_fname);
if(!Totape | !altflg) ask();
}
if(!EQ(argv[FROM_VOL],"-", 6) &
!EQ(argv[FROM_VOL],Superi.s_fpack, 6)) {
printf("arg. (%.6s) doesn't agree with from vol.(%.6s)\n",
argv[FROM_VOL],Superi.s_fpack);
if(!Totape | !altflg) ask();
}
if(argv[FROM_VOL][0]=='-') argv[FROM_VOL] = Superi.s_fpack;
if(argv[TO_VOL][0]=='-') argv[TO_VOL] = Supero.s_fpack;
if((reel == 1) & (Supero.s_time+_2_DAYS > Superi.s_time)) {
printf("%s less than 48 hours older than %s\n",
argv[DEV_TO], argv[DEV_FROM]);
printf("To filesystem dated: %s", ctime(&Supero.s_time));
if(!altflg) ask();
}
if(!EQ(argv[TO_VOL],Supero.s_fpack, 6)) {
printf("arg.(%.6s) doesn't agree with to vol.(%.6s)\n",
argv[TO_VOL],Supero.s_fpack);
ask();
strncpy(Supero.s_fpack, argv[TO_VOL],6);
}
if(Superi.s_fsize > Supero.s_fsize && !Totape) {
printf("from fs larger than to fs\n");
ask();
}
if(!Totape && !EQ(Superi.s_fname,Supero.s_fname, 6)) {
printf("warning! from fs(%.6s) differs from to fs(%.6s)\n",
Superi.s_fname,Supero.s_fname);
if(!altflg) ask();
}
COPY:
printf("From: %s, to: %s? ",
argv[DEV_FROM], argv[DEV_TO]);
if(altflg){
if(!asks("(y or n) ")) {
printf("\nvolcopy: STOP\n");
exit(9);
}
}
else {
printf("(DEL if wrong)\n");
sleep(10); /* 10 seconds to DEL */
}
close(fso); close(fsi);
sync();
fsi = open(argv[DEV_FROM], 0);
fso = open(argv[DEV_TO], 1);
if(Totape) {
Tape_hdr.t_reels = Reels;
Tape_hdr.t_reel = reel;
Tape_hdr.t_time = tvec;
Tape_hdr.t_reelblks = Reelblks;
Tape_hdr.t_blksize = BLKSIZ*Nblocks;
Tape_hdr.t_nblocks = Nblocks;
Tape_hdr.t_type = T_TYPE;
write(fso, &Tape_hdr, sizeof Tape_hdr);
strcpy(vol,argv[TO_VOL]);
} else if(Fromtape) {
read(fsi, &Tape_hdr, sizeof Tape_hdr);
}
if(reel > 1) {
Fs = (reel -1) * Reelblks + Nblocks;
lseek(Totape ? fsi : fso,(unsigned)(Fs * BLKSIZ),0);
Sptr = Totape? &Superi: &Supero;
Fs = (Sptr->s_fsize * Fstype) - Fs;
}
rprt(vol);
signal(SIGINT, sigint);
while(copy(fsi,fso))
chgreel(Totape ? fso : fsi, dev,vol);
printf(" END: %ld blocks.\n", Block);
#ifdef LOG
fslog(argv);
#endif
exit(0);
}
err(s) char *s; {
printf("%s\n\t%d reel(s) completed\n",s,--reel);
exit(9);
}
EQ(s1, s2, ct)
char *s1, *s2;
int ct;
{
register i;
for(i=0; i<ct; ++i) {
if(*s1 == *s2) {;
if(*s1 == '\0') return(1);
s1++; s2++;
continue;
} else return(0);
}
return(1);
}
ask() {
char ans[12];
printf("Type `y' to override: ");
fgets(ans, 10, Devtty);
if(EQ(ans,"y", 1))
return;
if(EQ(ans,"a",1))
abort();
exit(9);
}
asks(s)
char *s;
{
char ans[12];
printf(s);
ans[0] = '\0';
fgets(ans, 10, Devtty);
for(;;){
switch(ans[0]) {
case 'a':
if(pid == 1) {
write(p_out,"ABORT",1);
exit(1);
}
if(pid) kilchld();
abort();
case 'y':
return(1);
case 'n':
return(0);
default:
printf("\n(y or n)?");
fgets(ans, 10, Devtty);
}
}
}
getbpi(inp)
char *inp;
{
#ifdef u3b
if (inp[4] == 'k' || inp[4] == 'K') {
K_drive++;
inp[4] = '\0';
}
#endif
return(atoi(inp));
}
char *tapeck(dev, vol, fd)
char *dev, *vol;
{
char resp[16];
if(!IFTAPE(dev))
return 0;
Tape_nm = dev;
Tape_hdr.t_magic[0] = '\0'; /* scribble on old data */
alarm(5);
if(read(fd, &Tape_hdr, sizeof Tape_hdr) <= 0)
printf("\n ERR %d\n",errno);
alarm(0);
if(!EQ(Tape_hdr.t_magic, "Volcopy", 7)){
fprintf(stderr,"Not a labeled tape");
if(!Fromtape){
ask();
makelab();
strncpy(Tape_hdr.t_volume, vol, 6);
Supero.s_time = 0;
}
else err();
}
else if(Tape_hdr.t_reel == (char)0)
if(Fromtape){
fprintf(stderr,"Input tape is empty\n");
exit(9);
}
if((vol[0] != '-') && (!EQ(Tape_hdr.t_volume, vol, 6))) {
fprintf(stderr, "Header volume(%.6s) does not match %s\n",
Tape_hdr.t_volume, vol);
ask();
strncpy(Tape_hdr.t_volume, vol, 6);
}
tapein:
if(Fromtape){
Reels = Tape_hdr.t_reels;
Reelsize = Tape_hdr.t_length;
Bpi = Tape_hdr.t_dens;
#ifdef u3b
if (Tape_hdr.t_type == T_TYPE)
if (Tape_hdr.t_nblocks == 4)
K_drive++; /* use Kennedy tapedrive limit */
#endif
}
else{
Reels = 0;
}
if(Reelsize == 0) {
printf("Enter size of reel in feet for <%s>: ", vol);
fgets(resp, 10, Devtty);
Reelsize = atoi(resp);
}
#ifdef u370
if(Reelsize <= 0 || Reelsize > 3600) {
fprintf(stderr, "Size of reel must be > 0, <= 3600\n");
#else
if(Reelsize <= 0 || Reelsize > 2400) {
fprintf(stderr, "Size of reel must be > 0, <= 2400\n");
#endif
Reelsize = 0;
goto tapein;
}
if(!Bpi) {
printf("Tape density? (i.e., 800 | 1600 | 6250)? ");
fgets(resp, 10, Devtty);
Bpi = getbpi(resp);
}
if(Bpi == 800)
Reelblks = Ft800x10 * Reelsize;
else if(Bpi == 1600) {
#ifdef u3b
if (K_drive)
Reelblks = Ft1600x4 * Reelsize;
else
#endif
Reelblks = Ft1600x10 * Reelsize;
}
else if(Bpi == 6250)
#ifdef u3b
Reelblks = Ft6250x10 * Reelsize;
#else
Reelblks = Ft6250x50 * Reelsize;
#endif
else {
fprintf(stderr, "Bpi must be 800, 1600, or 6250\n");
Bpi = 0;
goto tapein;
}
printf("\nReel %.6s",Tape_hdr.t_volume);
Tape_hdr.t_length = Reelsize;
printf(", %d feet",Reelsize);
Tape_hdr.t_dens = Bpi;
printf(", %d BPI\n",Bpi);
return dev;
}
hdrck(fd, tvol)
char *tvol;
{
struct Tphdr *thdr;
int siz;
thdr = (struct Tphdr *) Buf;
alarm(15); /* dont scan whole tape for label */
if((siz = read(fd, thdr, sizeof Tape_hdr)) != sizeof Tape_hdr) {
alarm(0);
fprintf(stderr, "Cannot read header\n");
if(Totape){
ask();
strncpy(Tape_hdr.t_volume, tvol, 6);
return(1);
}
else{
close(fd);
return 0;
}
}
alarm(0);
Tape_hdr.t_reel = thdr->t_reel;
if(!EQ(thdr->t_volume, tvol, 6)) {
fprintf(stderr, "Volume is <%.6s>, not <%s>.\n",
thdr->t_volume, tvol);
if(asks("Want to override? ")) {
if(Totape) {
strncpy(Tape_hdr.t_volume, tvol, 6);
}
else{
strncpy(tvol,thdr->t_volume,6);
}
return 1;
}
return 0;
}
return 1;
}
makelab()
{
int i;
for(i = 0; i < sizeof Tape_hdr; i++)
Tape_hdr.t_magic[i] = '\0';
strncpy(Tape_hdr.t_magic,"Volcopy\0",8);
}
rprt(vol)
char *vol;
{
if(Totape)
printf("\nWriting REEL %d of %d, VOL = %.6s\n",
reel,Reels,vol);
if(Fromtape)
printf("\nReading REEL %d of %d, VOL = %.6s\n",
reel,Reels,vol);
}
#ifdef LOG
fslog(argv)
char *argv[];
{
char cmd[100];
if(access("/etc/log/filesave.log", 6) == -1) {
fprintf(stderr,
"volcopy: cannot access /etc/log/filesave.log\n");
exit(0);
}
system("tail -200 /etc/log/filesave.log >/tmp/FSJUNK");
system("cp /tmp/FSJUNK /etc/log/filesave.log");
sprintf(cmd,"echo \"%s;%.6s;%.6s -> %s;%.6s;%.6s\n\" >>/etc/log/filesave.log",
argv[DEV_FROM], Superi.s_fname, Superi.s_fpack,
argv[DEV_TO], Supero.s_fname,
Supero.s_fpack);
system(cmd);
system("rm /tmp/FSJUNK");
exit(0);
}
copy(fsi,fso)
int fsi,fso;
{
int i, cnt, pos;
int p1[2], p2[2];
char buf[20];
pid = -1;
if(bufflg && (Bpi >= 1600)) {
if( pipe(p1) | pipe(p2)) {
printf("\volcopy: cannot open pipe, err = %d\n",errno);
exit(1);
}
pid = fork();
if(pid) {
close(p1[0]);
close(p2[1]);
p_in = p2[0];
p_out = p1[1];
}
else {
close(p1[1]);
close(p2[0]);
p_in = p1[0];
p_out = p2[1];
write(p_out,"rw",2); /* prime the pipe */
}
}
pid++; /* pid is >0 if we forked */
/* child has pid == 1 */
/* copy from fsi to fso */
while((Fs > 0) && (rblock < Reelblks)) {
Nblocks = Fs > Nblocks ? Nblocks : Fs;
if(pid) {
if(pid == 1) {
Fs -= Nblocks;
if(Fs <= 0) goto cfin;
Block += Nblocks;
rblock += Nblocks;
Nblocks = Fs > Nblocks ? Nblocks : Fs;
}
cnt = read(p_in,buf,1);
if(cnt < 0 | buf[0] != 'r') {
if(pid == 1) {
write(p_out,"R",1);
exit(1);
}
else {
piperr(buf);
}
}
}
if((sts = read(fsi, Buf, BLKSIZ * Nblocks)) != BLKSIZ * Nblocks) {
printf("Read error %d block %ld...\n", sts, Block);
for(i=0; i != Nblocks * (BLKSIZ/2); ++i) Buf[i] = 0;
if(!Fromtape)
lseek(fsi,(long)((Block+Nblocks) * BLKSIZ), 0);
}
/*
* This code was moved out of main (which did the
* first read & write) so that the same number of
* blocks would be written on each tape--a change
* required for finc, frec, and ff compatibility.
*/
if(!first && pid != 1 && reel == 1){
first++;
strncpy(Sptr->s_fpack, args[TO_VOL],6);
strncpy(Sptr->s_fname, args[FILE_SYS],6);
}
if(pid) {
write(p_out,"r",1); /* signal read complete */
cnt = read(p_in,buf,1);
if(cnt < 0 | buf[0] != 'w') {
if(pid == 1) {
write(p_out,"W",1);
exit(1);
}
piperr(buf);
}
}
if((sts = write(fso, Buf, BLKSIZ*Nblocks)) != BLKSIZ*Nblocks) {
printf("Write error %d, block %ld...\n",
errno,Block);
if(Totape) {
if(pid == 1) {
write(p_out,"Tape error",10);
exit(1);
}
oterr: if(asks("Want to try another tape? ")) {
asks("Type `y' when ready: ");
--reel;
Block = reeloff;
Fs = saveFs;
lseek(fsi, (long)reeloff*BLKSIZ, 0);
return(1);
}
} else {
exit(9);
}
}
if(pid) {
write(p_out,"w",1); /* signal write complete */
if(pid != 1) {
Fs -= Nblocks;
Block += Nblocks;
rblock += Nblocks;
Nblocks = Fs > Nblocks ? Nblocks : Fs;
}
}
Fs -= Nblocks;
Block += Nblocks;
rblock += Nblocks;
}
if(pid == 1) {
cfin: write(p_out,"Done",4);
while (cnt < 0 | buf[0] != 'D') {
cnt = read(p_in,buf,1);
}
exit(0);
}
else if(pid) {
pfin: cnt = read(p_in,buf,1);
/*
* Ihcc code debugs some end condition problems
*/
if ((Fs + Nblocks) > 0) {
if (cnt < 0 | buf[0] != 'r') piperr(buf);
cnt = read(p_in, buf, 1);
if (cnt < 0 | buf[0] != 'w') piperr(buf);
cnt = read(p_in, buf, 1);
}
/***/
if(cnt < 0 | buf[0] != 'D') piperr(buf);
write(p_out,"Done",4);
close(p_in);
close(p_out);
}
return((Fs > 0) ? 1 : 0);
}
chgreel(fs,dev,vol)
int fs;
char *dev, *vol;
{
char ctemp[21];
rblock = 0;
reeloff = Block;
saveFs = Fs;
++reel;
again:
if((sts = close(fs)) < 0)
printf("\n ERR %d\n",errno);
printf("Changing drives? (type RETURN for no, ");
#ifdef RT
printf("`/dev/mt_' for yes: ");
#else
printf("`/dev/rmt_' for yes: ");
#endif
fgets(ctemp, 20, Devtty);
ctemp[strlen(ctemp) -1] = '\0';
if(ctemp[0] != '\0')
while(strncmp(ctemp,"/dev/rmt",8)){
printf("\n'%s' is not a valid device",ctemp);
printf("\nenter device name `/dev/rmt?' : ");
fgets(ctemp, 20, Devtty);
ctemp[strlen(ctemp) -1] = '\0';
}
strcpy(dev,ctemp);
printf("Mount tape %d\nType volume-ID when ready: ",
reel);
fgets(ctemp, 10, Devtty);
ctemp[strlen(ctemp) -1] = '\0';
if(ctemp[0] != '\0') /*if only <cr> - use old vol-id */
strcpy(vol,ctemp);
if(*dev)
Tape_nm = dev;
if(Totape) {
fs = open(Tape_nm, 0);
if(fs <= 0 || fs > 10)
printf("\n ERR %d\n",errno);
if(!hdrck(fs, vol))
goto again;
Tape_hdr.t_reel = reel;
close(fs);
sleep(2);
fs = open(Tape_nm, 1);
if(fs <= 0 || fs > 10)
printf("\n ERR %d\n",errno);
if(write(fs, &Tape_hdr, sizeof Tape_hdr) < 0) {
fprintf(stderr, "Cannot re-write header");
fprintf(stderr,"-%s\n","Try again!");
goto again;
}
} else {
fs = open(Tape_nm, 0);
if(fs <= 0 || fs > 10)
printf("\n ERR %d\n",errno);
if(!hdrck(fs, vol))
goto again;
if(Tape_hdr.t_reel != reel) {
fprintf(stderr,"Need reel %d,",reel);
fprintf(stderr," label says reel %d\n",
Tape_hdr.t_reel);
goto again;
}
}
rprt(vol);
}
piperr(pbuff)
char pbuff[];
{
if(pbuff[0] == 'R')
printf("\volcopy: read sequence error");
else if(pbuff[0] == 'W')
printf("\volcopy: write sequence error");
else
printf("\nvolcopy: pipe error = %d",errno);
printf(" pipe buffer: %.10s\n",pbuff);
printf(" reel %d, %d blocks\n",reel, Block);
kilchld();
/* if(pbuff[0] == 'A') */
abort();
exit(1);
}