/********************************************************************** * Copyright (c) Digital Equipment Corporation 1984, 1985, 1986. * * All Rights Reserved. * * Reference "/usr/src/COPYRIGHT" for applicable restrictions. * **********************************************************************/ static char Sccsid[] = "@(#)volcopy.c 3.0 4/22/86"; /* * volcopy -- copy file systems w/label checking (from SYSTEM V) * * Changes for ULTRIX-11 * Removed 3b processor and RT dependencies. * John Dustin 7/25/84 */ /* Based on: (SYSTEM V) volcopy.c 4.9 */ #define LOG /* keep log of system copy activity */ #define AFLG 0 /* AFLG == 0 will ask: Ready to copy? */ #include <sys/param.h> #include <signal.h> #include <sys/types.h> #include <sys/filsys.h> #include <sys/stat.h> #include <sys/devmaj.h> #include <stdio.h> #include <signal.h> #include <sys/mount.h> #include <a.out.h> #include <errno.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 */ #define BLKSIZ 512 /* use physical blocks */ #define _2_DAYS 172800L #define V_MAX 1000000L #define Ft800x10 15L #define Ft1600x4 22L #define Ft1600x10 28L #define Ft6250x10 90L #define Ft6250x50 120L 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[470]; int t_type; /* does tape have nblocks field? (u3b) */ } Tape_hdr; int first = 0; char **args; int Nblocks = 0; long Reelblks = V_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; short magtape; #define NMNT 0 #define MNT 1 struct nlist nl[] = { { "_nmount" }, { "_mount" }, { "" }, }; int nmount; struct mount *mp; struct mount *mpp; char *coref = "/dev/mem"; /* 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 usual 5 second delay. This is default. -n - inverse of -a ( this used to be the '-s' option) 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 5 seconds to ^C if mistaken! With '-a' option, a positive user response is required to continue. With '-n' 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; int i,j,mem; struct stat statb; long tvec; int altflg = AFLG; FILE *popen(); char vol[12], dev[12], c; signal(SIGALRM, sigalrm); sync(); 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],"-n",2)) altflg++; else if(EQ(argv[1],"-a",2)) altflg = 0; else { fprintf(stderr, "<%s> invalid option\n", argv[1]); exit(1); } ++argv; --argc; } args = argv; if ((Devtty = fopen("/dev/tty", "r")) < 0) { fprintf(stderr,"Cannot open terminal!\n"); exit(1); } time(&tvec); /* get mandatory inputs */ if(argc!=6){ fprintf(stderr,"Usage: volcopy [options] fsname"); fprintf(stderr," /devfrom volfrom /devto volto\n"); exit (9); } if(!magtape) { if ((stat(argv[DEV_TO],&statb)) < 0) { fprintf(stderr,"volcopy: cannot stat %s\n",argv[DEV_TO]); exit(2); } nlist("/unix", nl); if((nl[NMNT].n_value==0) || (nl[MNT].n_value==0)) { fprintf(stderr, "volcopy: cannot access /unix namelist\n"); exit(2); } mem = open(coref, 0); if(mem < 0 ) { fprintf(stderr, "volcopy: cannot open %s\n", coref); exit(2); } lseek(mem, (long)nl[NMNT].n_value, 0); read(mem, (char *)&nmount, sizeof(nmount)); mp = malloc(sizeof(struct mount) * nmount); lseek(mem, (long)nl[MNT].n_value, 0); read(mem, (char *)mp, sizeof(struct mount) * nmount); mpp = mp; for(i=0; i<nmount; i++, mpp++) { j = (statb.st_rdev >> 8) & 0377; j -= RK_RMAJ; /* convert to block major */ j <<= 8; j |= (statb.st_rdev & 0377); if((mpp->m_bufp == 0) || (mpp->m_dev != j)) continue; fprintf(stderr, "\7\7volcopy: SORRY - output file system is mounted!\n"); exit(2); } } 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"); if(fstat(fsi, &statb)<0 || (statb.st_mode&S_IFMT)!=S_IFCHR) err("From device not RAW !");/* was "character-special" */ if(fstat(fso, &statb)<0 || (statb.st_mode&S_IFMT)!=S_IFCHR) err("To device not RAW !"); 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) { fprintf(stderr,"Use dd(1) command to copy tapes\n"); exit(1); } Nblocks = ((Totape||Fromtape)&&(Bpi!=6250))? 10:88; if(Bpi == 6250) Nblocks = 50; Buf = -1; /* * Check if enough space, if not, scale down... */ if (!((BLKSIZ*Nblocks) <= 0)) Buf = (short *)sbrk(BLKSIZ*Nblocks); if((int)Buf == -1 && Nblocks == 88) { Nblocks = 22; if (!((BLKSIZ*Nblocks) <= 0)) Buf = (short *)sbrk(BLKSIZ*Nblocks); } if((int)Buf == -1) { fprintf(stderr, "Not enough memory--get help\n"); exit(1); } #ifdef UCB_NKB Sptr = (struct filsys *)&Buf[BLKSIZ]; #else Sptr = (struct filsys *)&Buf[BLKSIZ/2]; #endif if(!Fromtape && !Totape) reel = 1; if((reel == 1) || !Fromtape){ #ifdef UCB_NKB if(read(fsi, Buf, 4*BLKSIZ) != 4*BLKSIZ) #else if(read(fsi, Buf, 2*BLKSIZ) != 2*BLKSIZ) #endif { fprintf(stderr, "read error on input (ERR %d)",errno); err(); } 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"); } ***/ #ifdef UCB_NKB Fstype = 2; /* 1024 byte block filesystem */ Fs = Sptr->s_fsize * 2; #else Fstype = 1; /* 512 byte block filesystem */ Fs = Sptr->s_fsize; #endif Superi.s_fsize = Sptr->s_fsize; Superi.s_time = Sptr->s_time; } #ifdef UCB_NKB if(read(fso, Buf, 4*BLKSIZ) != 4*BLKSIZ){ #else if(read(fso, Buf, 2*BLKSIZ) != 2*BLKSIZ){ #endif fprintf(stderr,"read error on output (ERR = %d)\n", errno); 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 reel", Reels); Reels>1 ? printf("s.\n(The same size and density is expected for all reels)\n") : printf(".\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(); } printf("From: %s To: %s",argv[DEV_FROM],argv[DEV_TO]); if(altflg){ /* user entered -n flag... he's on his own. */ /* printf("(DEL if wrong)\n"); */ printf("\nCopying...\n"); sleep(5); /* But really give him 5 seconds to ^C... */ } else if(!asks(" Ready? (y or n): ")) { printf("volcopy: STOP\n"); exit(9); } 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; if (write(fso, &Tape_hdr, sizeof Tape_hdr) != sizeof Tape_hdr) { fprintf(stderr, "volcopy: cannot write tape label (ERR %d)", errno); err(); } if (read(fsi, Buf, 2048) != 2048) { fprintf(stderr, "volcopy: cannot read superblock (ERR %d)", errno); err(); } if (write(fso, Buf, 2048) != 2048) { fprintf(stderr, "volcopy: cannot write superblock (ERR %d)", errno); err(); } strcpy(vol,argv[TO_VOL]); } else if(Fromtape) { if (read(fsi, &Tape_hdr, sizeof Tape_hdr) != sizeof Tape_hdr) { fprintf(stderr, "volcopy: cannot read tape label (ERR %d)", errno); err(); } if (read(fsi, Buf, 2048) != 2048) { fprintf(stderr, "volcopy: cannot read superblock (ERR %d)", errno); err(); } if (write(fso, Buf, 2048) != 2048) { fprintf(stderr, "volcopy: cannot write superblock (ERR %d)", errno); err(); } } 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("DONE: %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; { return(atoi(inp)); } char *tapeck(dev, vol, fd) char *dev, *vol; { struct stat statb; int i; char resp[16]; if(stat(dev, &statb) < 0) { fprintf(stderr, "volcopy: cannot stat %s\n",dev); exit(2); } i = (statb.st_rdev >> 8) & 0377; switch(i) { case HT_RMAJ: case TS_RMAJ: case TM_RMAJ: case TK_RMAJ: magtape = 1; break; default: magtape = 0; break; } if (!magtape) /* the real tape check */ 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) fprintf(stderr,"Tape read error: (ERR %d)\n",errno); alarm(0); if(!EQ(Tape_hdr.t_magic, "Volcopy", 7)){ fprintf(stderr,"Not a labeled tape.\n"); 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; } else{ Reels = 0; } if(Reelsize == 0) { printf("Enter size of reel in feet for <%s>: ", vol); fgets(resp, 10, Devtty); Reelsize = atoi(resp); } if(Reelsize <= 0 || Reelsize > 2400) { fprintf(stderr, "Size of reel must be > 0, <= 2400\n"); 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) { Reelblks = Ft1600x10 * Reelsize; } else if(Bpi == 6250) Reelblks = Ft6250x50 * Reelsize; 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 tape header (ERR %d)\n", errno); 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("Writing REEL %d of %d, VOL = %.6s\n", reel,Reels,vol); if(Fromtape) printf("Reading 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) < 0) { 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 -n \"%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("date >> /etc/log/filesave.log"); system("rm /tmp/FSJUNK"); exit(0); } #endif copy(fsi,fso) int fsi,fso; { int i, cnt; int p1[2], p2[2]; char buf[20]; pid = -1; if(bufflg && (Bpi < 1600)) fprintf(stderr,"Not using double buffered i/o. (tape density not >= 1600 BPI)\n"); 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) { /* * From tape? then always an error; otherwise, * From disk? then only an error if not errno == 6 */ if((Fromtape) || ((!Fromtape) && (errno != ENXIO))) printf("Read error %d block %ld...\n", errno, 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) { /* * To tape? then always an error; otherwise, * To disk? then only an error if not errno == 6 */ if((Totape) || ((!Totape) && (errno != ENXIO))) printf("Write error %d, block %ld...\n", errno,Block); if(Totape) { if(pid == 1) { write(p_out,"Tape error",10); exit(1); } if(asks("Want to try another tape? ")) { asks("Mount the new tape. Type `y' when ready: "); --reel; Block = reeloff; Fs = saveFs; lseek(fsi, (long)reeloff*BLKSIZ, 0); return(1); } } else { if(errno != ENXIO) 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) { 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]; struct stat statb; rblock = 0; reeloff = Block; saveFs = Fs; ++reel; again: if((sts = close(fs)) < 0) printf("Close failed: (ERR %d). (warning only)\n",errno); printf("Changing drives? (type RETURN for no),\n"); printf("enter device name, ie: /dev/rmt? for yes: "); fgets(ctemp, 20, Devtty); ctemp[strlen(ctemp) -1] = '\0'; if(ctemp[0] != '\0') while(strncmp(ctemp,"/dev/r",6)){ /* should do a magtape check here ! */ printf("%s is not a RAW tape!\n",ctemp); /* /dev/rmt check: %s not a valid device */ printf("enter device name, ie: /dev/rmt? : "); fgets(ctemp, 20, Devtty); ctemp[strlen(ctemp) -1] = '\0'; if(ctemp[0] == '\0') { strcpy(dev, Tape_nm); /* assume old drive */ break; } else strcpy(dev,ctemp); } printf("Mount tape %d\nEnter volume-ID: ", 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) { printf("Cannot open %s for reading. ( ERR %d )\n",Tape_nm,errno); goto again; } if(fstat(fs, &statb)<0 || (statb.st_mode&S_IFMT)!=S_IFCHR) { printf("output device (%s) not RAW tape!\n",Tape_nm); goto again; } /* if(fs > 10) printf("\nERR %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) { printf("Cannot open %s for writing. ( ERR %d )\n",Tape_nm,errno); goto again; } /* if (fs > 10) printf("\nERR %d\n",errno); */ if(write(fs, &Tape_hdr, sizeof Tape_hdr) < 0) { fprintf(stderr,"The tape doesn't seem to be labeled!\n"); fprintf(stderr, "Cannot re-write header!"); fprintf(stderr," Dismount tape and try another.\n"); goto again; } } else { fs = open(Tape_nm, 0); if(fs < 0) { printf("Cannot open %s for reading. (ERR %d )\n",Tape_nm,errno); goto again; } if(fstat(fs, &statb)<0 || (statb.st_mode&S_IFMT)!=S_IFCHR) { printf("input device (%s) not RAW tape!\n",Tape_nm); goto again; } /* if(fs > 10) printf("\nERR %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); }