X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=restore%2Ftape.c;h=2bb447239bed286d20afbe0de2cb57f2afdf7215;hb=dbb649e870428cffea2583ed34233d0239b80992;hp=b9d0b02635f2c9d3629083a38ce4d3e2bfb30c07;hpb=a18d599791e977f3e3d26123031e6ed4e64d6d08;p=dump.git diff --git a/restore/tape.c b/restore/tape.c index b9d0b02..2bb4472 100644 --- a/restore/tape.c +++ b/restore/tape.c @@ -46,7 +46,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.63 2002/07/19 14:57:40 stelian Exp $"; + "$Id: tape.c,v 1.67 2003/01/10 14:42:51 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)); @@ -285,7 +287,7 @@ setup(void) #ifdef RRESTORE if (host) - mt = rmtopen(temptape, "O_RDONLY"); + mt = rmtopen(temptape, O_RDONLY); else #endif if (pipein) @@ -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); @@ -541,7 +537,7 @@ again: } #ifdef RRESTORE if (host) - mt = rmtopen(magtape, "O_RDONLY"); + mt = rmtopen(magtape, O_RDONLY); else #endif mt = OPEN(magtape, O_RDONLY, 0); @@ -1023,7 +1019,7 @@ static void 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); } @@ -1551,7 +1547,7 @@ getmore: 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,6 +1609,7 @@ readtape_comprfile(char *buf) /* read the block prefix */ ret = read_a_block(mt, tapebuf, PREFIXSIZE, &rl); + converttapebuf(tpb); if (Vflag && (ret == 0 || rl < (int)PREFIXSIZE || tpb->length == 0)) ret = 0; @@ -1705,6 +1702,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"); @@ -1915,7 +1913,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 +1928,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 +1947,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; } @@ -1968,14 +1977,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 +2003,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); @@ -2069,6 +2085,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 +2127,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 +2138,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 +2241,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 +2589,7 @@ GotoTapePos(long long pos) #ifdef RDUMP if (host) - err = (rmtseek((long)pos, SEEK_SET) < 0); + err = (rmtseek(pos, SEEK_SET) < 0); else #endif {