X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Ftape.c;h=9bfb4c5051e74098d6cfa38670cf84d8fcf36ce9;hp=453b7eb276e533f694cfc73bfdd7d2ae0b8c32c1;hb=2d32c89c9844547c83ef7a9ca97308da29e280cc;hpb=0cedbda5e645e6a30ef47fa3e0fae683160d4431 diff --git a/restore/tape.c b/restore/tape.c index 453b7eb..9bfb4c5 100644 --- a/restore/tape.c +++ b/restore/tape.c @@ -46,7 +46,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.60 2002/04/04 08:20:23 stelian Exp $"; + "$Id: tape.c,v 1.69 2003/02/11 12:43:45 stelian Exp $"; #endif /* not lint */ #include @@ -134,6 +134,8 @@ static int checksum __P((int *)); static void findinode __P((struct s_spcl *)); static void findtapeblksize __P((void)); static int gethead __P((struct s_spcl *)); +static int converthead __P((struct s_spcl *)); +static void converttapebuf __P((struct tapebuf *)); static void readtape __P((char *)); static void setdumpnum __P((void)); static u_int swabi __P((u_int)); @@ -284,8 +286,8 @@ setup(void) temptape = magtape; #ifdef RRESTORE - if (host) - mt = rmtopen(temptape, 0); + if (!Afile && host) + mt = rmtopen(temptape, O_RDONLY); else #endif if (pipein) @@ -293,7 +295,7 @@ setup(void) else mt = OPEN(temptape, O_RDONLY, 0); if (mt < 0) - err(1, "%s", magtape); + err(1, "%s", temptape); if (!Afile) { volno = 1; setmagtapein(); @@ -334,7 +336,7 @@ setup(void) if (vflag || command == 't' || command == 'C') printdumpinfo(); #ifdef USE_QFA - if (tapeposflag && spcl.c_date != qfadumpdate) + if (tapeposflag && (unsigned long)spcl.c_date != qfadumpdate) errx(1, "different QFA/dumpdates detected\n"); #endif if (filesys[0] == '\0') { @@ -374,15 +376,9 @@ setup(void) getfile(xtrmap, xtrmapskip); while (spcl.c_type == TS_ADDR) { /* Recompute maxino and the map */ - char *oldmap = usedinomap; dump_ino_t oldmaxino = maxino; maxino += (spcl.c_count * TP_BSIZE * NBBY) + 1; - map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY)); - if (map == NULL) - errx(1, "no memory for active inode map"); - usedinomap = map; - memcpy(usedinomap, oldmap, howmany(oldmaxino, NBBY)); - free(oldmap); + resizemaps(oldmaxino, maxino); spcl.c_dinode.di_size = spcl.c_count * TP_BSIZE; getfile(xtrmap, xtrmapskip); @@ -431,6 +427,8 @@ getvol(long nextvol) if (nextvol == 1) { tapesread = 0; gettingfile = 0; + tpblksread = 0; + blksread = 0; } if (pipein) { if (nextvol != 1) @@ -504,6 +502,13 @@ again: return; } closemt(); + + /* + * if using an archive file, reset its name so readtape() + * could properly use remote access. + */ + Afile = NULL; + if (Mflag) { snprintf(magtape, MAXPATHLEN, "%s%03ld", magtapeprefix, newvol); magtape[MAXPATHLEN - 1] = '\0'; @@ -539,7 +544,7 @@ again: } #ifdef RRESTORE if (host) - mt = rmtopen(magtape, 0); + mt = rmtopen(magtape, O_RDONLY); else #endif mt = OPEN(magtape, O_RDONLY, 0); @@ -587,8 +592,6 @@ gethdr: goto again; } tapesread |= 1 << volno; - blksread = saved_blksread; - tpblksread = saved_tpblksread; /* * If continuing from the previous volume, skip over any * blocks read already at the end of the previous volume. @@ -603,10 +606,10 @@ gethdr: #endif /* !HAVE_ZLIB && !HAVE_BZLIB */ } Dprintf(stdout, "read %ld recs, tape starts with %ld\n", - tpblksread, (long)tmpbuf.c_firstrec); + tpblksread - 1, (long)tmpbuf.c_firstrec); if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) { if (!wantnext) { - tpblksread = tmpbuf.c_firstrec; + tpblksread = tmpbuf.c_firstrec + 1; for (i = tmpbuf.c_count; i > 0; i--) readtape(buf); } else if (tmpbuf.c_firstrec > 0 && @@ -705,7 +708,7 @@ printvolinfo(void) if (volinfo[1] == ROOTINO) { printf("Starting inode numbers by volume:\n"); - for (i = 1; i < TP_NINOS && volinfo[i] != 0; ++i) + for (i = 1; i < (int)TP_NINOS && volinfo[i] != 0; ++i) printf("\tVolume %d: %lu\n", i, (unsigned long)volinfo[i]); } } @@ -1020,10 +1023,10 @@ xtrfile(char *buf, size_t size) */ /* ARGSUSED */ static void -xtrskip(char *buf, size_t size) +xtrskip(UNUSED(char *buf), size_t size) { - if (LSEEK(ofile, (off_t)size, SEEK_CUR) == -1) + if (LSEEK(ofile, (OFF_T)size, SEEK_CUR) == -1) err(1, "seek error extracting inode %lu, name %s\nlseek", (unsigned long)curfile.ino, curfile.name); } @@ -1047,7 +1050,7 @@ xtrlnkfile(char *buf, size_t size) */ /* ARGSUSED */ static void -xtrlnkskip(char *buf, size_t size) +xtrlnkskip(UNUSED(char *buf), UNUSED(size_t size)) { errx(1, "unallocated block in symbolic link %s", curfile.name); @@ -1069,7 +1072,7 @@ xtrmap(char *buf, size_t size) */ /* ARGSUSED */ static void -xtrmapskip(char *buf, size_t size) +xtrmapskip(UNUSED(char *buf), size_t size) { panic("hole in map\n"); @@ -1081,7 +1084,7 @@ xtrmapskip(char *buf, size_t size) */ /* ARGSUSED */ void -xtrnull(char *buf, size_t size) +xtrnull(UNUSED(char *buf), UNUSED(size_t size)) { return; @@ -1099,7 +1102,7 @@ xtrcmpfile(char *buf, size_t size) if (cmperror) return; - if (read(ifile, cmpbuf, size) != size) { + if (read(ifile, cmpbuf, size) != (ssize_t)size) { fprintf(stderr, "%s: size has changed.\n", curfile.name); cmperror = 1; @@ -1118,7 +1121,7 @@ xtrcmpfile(char *buf, size_t size) * Skip over a hole in a file. */ static void -xtrcmpskip(char *buf, size_t size) +xtrcmpskip(UNUSED(char *buf), size_t size) { static char cmpbuf[MAXBSIZE]; int i; @@ -1126,14 +1129,14 @@ xtrcmpskip(char *buf, size_t size) if (cmperror) return; - if (read(ifile, cmpbuf, size) != size) { + if (read(ifile, cmpbuf, size) != (ssize_t)size) { fprintf(stderr, "%s: size has changed.\n", curfile.name); cmperror = 1; return; } - for (i = 0; i < size; ++i) + for (i = 0; i < (int)size; ++i) if (cmpbuf[i] != '\0') { fprintf(stderr, "%s: tape and disk copies are different\n", curfile.name); @@ -1262,7 +1265,7 @@ static char tmpfilename[MAXPATHLEN]; void comparefile(char *name) { - int mode; + unsigned int mode; struct STAT sb; int r; #if !COMPARE_ONTHEFLY @@ -1270,6 +1273,16 @@ comparefile(char *name) struct STAT stemp; #endif + curfile.name = name; + curfile.action = USING; + mode = curfile.dip->di_mode; + + if ((mode & IFMT) == IFSOCK) { + Vprintf(stdout, "skipped socket %s\n", name); + skipfile(); + return; + } + if ((r = LSTAT(name, &sb)) != 0) { warn("%s: does not exist (%d)", name, r); do_compare_error; @@ -1277,10 +1290,6 @@ comparefile(char *name) return; } - curfile.name = name; - curfile.action = USING; - mode = curfile.dip->di_mode; - Vprintf(stdout, "comparing %s (size: %ld, mode: 0%o)\n", name, (long)sb.st_size, mode); @@ -1352,7 +1361,7 @@ comparefile(char *name) return; } - if (sb.st_rdev != (int)curfile.dip->di_rdev) { + if (sb.st_rdev != (dev_t)curfile.dip->di_rdev) { fprintf(stderr, "%s: device changed from %d,%d to %d,%d.\n", name, @@ -1485,7 +1494,7 @@ readtape(char *buf) #endif getmore: #ifdef RRESTORE - if (host) + if (!Afile && host) i = rmtread(&tapebuf[rd], cnt); else #endif @@ -1547,11 +1556,11 @@ getmore: i = ntrec * TP_BSIZE; memset(tapebuf, 0, (size_t)i); #ifdef RRESTORE - if (host) + if (!Afile && host) seek_failed = (rmtseek(i, 1) < 0); else #endif - seek_failed = (LSEEK(mt, i, SEEK_CUR) == (off_t)-1); + seek_failed = (LSEEK(mt, i, SEEK_CUR) == (OFF_T)-1); if (seek_failed) { warn("continuation failed"); @@ -1613,8 +1622,9 @@ readtape_comprfile(char *buf) /* read the block prefix */ ret = read_a_block(mt, tapebuf, PREFIXSIZE, &rl); + converttapebuf(tpb); - if (Vflag && (ret == 0 || rl < PREFIXSIZE || tpb->length == 0)) + if (Vflag && (ret == 0 || rl < (int)PREFIXSIZE || tpb->length == 0)) ret = 0; if (ret <= 0) goto readerr; @@ -1705,6 +1715,7 @@ readtape_comprtape(char *buf) if (ret <= 0) goto readerr; + converttapebuf(tpb); tbufptr = decompress_tapebuf(tpb, rl); if (tbufptr == NULL) { msg_read_error("Tape decompression error while"); @@ -1781,10 +1792,10 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize) /* build a length error message */ blocklen = tpbin->length; - if (readsize < blocklen + PREFIXSIZE) + if (readsize < blocklen + (int)PREFIXSIZE) lengtherr = "short"; else - if (readsize > blocklen + PREFIXSIZE) + if (readsize > blocklen + (int)PREFIXSIZE) lengtherr = "long"; worklen = comprlen; @@ -1915,7 +1926,7 @@ findtapeblksize(void) long i; size_t len; struct tapebuf *tpb = (struct tapebuf *) tapebuf; - struct s_spcl *spclpt = (struct s_spcl *) tapebuf; + struct s_spcl spclpt; for (i = 0; i < ntrec; i++) ((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0; @@ -1930,6 +1941,17 @@ findtapeblksize(void) if (read_a_block(mt, tapebuf, len, &i) <= 0) errx(1, "Tape read error on first record"); + memcpy(&spclpt, tapebuf, TP_BSIZE); + if (converthead(&spclpt) == FAIL) { + cvtflag++; + if (converthead(&spclpt) == FAIL) { + /* Special case for old compressed tapes with prefix */ + if (magtapein && (i % TP_BSIZE != 0)) + goto oldformat; + errx(1, "Tape is not a dump tape"); + } + fprintf(stderr, "Converting to new file system format.\n"); + } /* * If the input is from a file or a pipe, we read TP_BSIZE * bytes looking for a dump header. If the dump is compressed @@ -1938,14 +1960,14 @@ findtapeblksize(void) * dump is not compressed and does not have a prefix. */ if (!magtapein) { - if (spclpt->c_type == TS_TAPE - && spclpt->c_flags & DR_COMPRESSED) { + if (spclpt.c_type == TS_TAPE + && spclpt.c_flags & DR_COMPRESSED) { /* It's a compressed dump file, read in the */ - /* rest of the block based on spclpt->c_ntrec. */ - if (spclpt->c_ntrec > ntrec) + /* rest of the block based on spclpt.c_ntrec. */ + if (spclpt.c_ntrec > ntrec) errx(1, "Tape blocksize is too large, use " - "\'-b %d\' ", spclpt->c_ntrec); - ntrec = spclpt->c_ntrec; + "\'-b %d\' ", spclpt.c_ntrec); + ntrec = spclpt.c_ntrec; len = (ntrec - 1) * TP_BSIZE; zflag = 1; } @@ -1954,7 +1976,7 @@ findtapeblksize(void) len = bufsize - TP_BSIZE; } if (read_a_block(mt, tapebuf+TP_BSIZE, len, &i) < 0 - || (i != len && i % TP_BSIZE != 0)) + || (i != (long)len && i % TP_BSIZE != 0)) errx(1,"Error reading dump file header"); tbufptr = tapebuf; numtrec = ntrec; @@ -1968,14 +1990,21 @@ findtapeblksize(void) * what we asked for; adjust the value of ntrec and test for * a compressed dump tape. */ - if (i % TP_BSIZE != 0) { +oldformat: /* may be old format compressed dump tape with a prefix */ - spclpt = (struct s_spcl *) tpb->buf; + memcpy(&spclpt, tpb->buf, TP_BSIZE); + cvtflag = 0; + if (converthead(&spclpt) == FAIL) { + cvtflag++; + if (converthead(&spclpt) == FAIL) + errx(1, "Tape is not a dump tape"); + fprintf(stderr, "Converting to new file system format.\n"); + } if (i % TP_BSIZE == PREFIXSIZE && tpb->compressed == 0 - && spclpt->c_type == TS_TAPE - && spclpt->c_flags & DR_COMPRESSED) { + && spclpt.c_type == TS_TAPE + && spclpt.c_flags & DR_COMPRESSED) { zflag = 1; tbufptr = tpb->buf; if (tpb->length > bufsize) @@ -1987,12 +2016,12 @@ findtapeblksize(void) i, TP_BSIZE); } ntrec = i / TP_BSIZE; - if (spclpt->c_type == TS_TAPE) { - if (spclpt->c_flags & DR_COMPRESSED) + if (spclpt.c_type == TS_TAPE) { + if (spclpt.c_flags & DR_COMPRESSED) zflag = 1; - if (spclpt->c_ntrec > ntrec) + if (spclpt.c_ntrec > ntrec) errx(1, "Tape blocksize is too large, use " - "\'-b %d\' ", spclpt->c_ntrec); + "\'-b %d\' ", spclpt.c_ntrec); } numtrec = ntrec; Vprintf(stdout, "Tape block size is %ld\n", ntrec); @@ -2008,7 +2037,7 @@ static int read_a_block(int fd, char *buf, size_t len, long *lengthread) size = len; while (size > 0) { #ifdef RRESTORE - if (host) + if (!Afile && host) i = rmtread(buf, size); else #endif @@ -2032,7 +2061,7 @@ closemt(void) if (mt < 0) return; #ifdef RRESTORE - if (host) + if (!Afile && host) rmtclose(); else #endif @@ -2069,6 +2098,13 @@ setmagtapein(void) { */ static int gethead(struct s_spcl *buf) +{ + readtape((char *)buf); + return converthead(buf); +} + +static int +converthead(struct s_spcl *buf) { int32_t i; union { @@ -2104,7 +2140,6 @@ gethead(struct s_spcl *buf) } u_ospcl; if (!cvtflag) { - readtape((char *)buf); if (buf->c_magic != NFS_MAGIC) { if (swabi(buf->c_magic) != NFS_MAGIC) return (FAIL); @@ -2116,10 +2151,10 @@ gethead(struct s_spcl *buf) if (checksum((int *)buf) == FAIL) return (FAIL); if (Bcvt) - swabst((u_char *)"8i4s31i528bi192b2i", (u_char *)buf); + swabst((u_char *)"8i4s31i528bi192b3i", (u_char *)buf); goto good; } - readtape((char *)(&u_ospcl.s_ospcl)); + memcpy(&u_ospcl.s_ospcl, buf, TP_BSIZE); memset((char *)buf, 0, (long)TP_BSIZE); buf->c_type = u_ospcl.s_ospcl.c_type; buf->c_date = u_ospcl.s_ospcl.c_date; @@ -2219,6 +2254,23 @@ good: return(GOOD); } +static void +converttapebuf(struct tapebuf *tpb) +{ + if (Bcvt) { + struct tb { + unsigned int length:28; + unsigned int flags:3; + unsigned int compressed:1; + } tb; + swabst((u_char *)"i", (u_char *)tpb); + memcpy(&tb, tpb, 4); + tpb->length = tb.length; + tpb->flags = tb.flags; + tpb->compressed = tb.compressed; + } +} + /* * Check that a header is where it belongs and predict the next header */ @@ -2550,7 +2602,7 @@ GotoTapePos(long long pos) #ifdef RDUMP if (host) - err = (rmtseek((long)pos, SEEK_SET) < 0); + err = (rmtseek(pos, SEEK_SET) < 0); else #endif {