X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Ftape.c;h=1b6b1d9d52578436d8fd6c1cfa6baf712359fe11;hp=b6d27f7a691060a9656337bcab4c1e6ca6da353c;hb=ff9e45da1a0be7807fb18401ca7e5ee28d0e1007;hpb=fe0e02857a1ff7db4bf8cb28780de7ecf2f24234 diff --git a/restore/tape.c b/restore/tape.c index b6d27f7..1b6b1d9 100644 --- a/restore/tape.c +++ b/restore/tape.c @@ -46,7 +46,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.58 2002/02/04 11:18:46 stelian Exp $"; + "$Id: tape.c,v 1.61 2002/05/06 08:45:41 stelian Exp $"; #endif /* not lint */ #include @@ -175,6 +175,7 @@ static void xtrcmpskip __P((char *, size_t)); #endif static int readmapflag; +static int readingmaps; /* set to 1 while reading the maps */ /* * Set up an input source. This is called from main.c before setup() is. @@ -360,18 +361,33 @@ setup(void) Dprintf(stdout, "header read failed at %ld blocks\n", (long)blksread); panic("no header after volume mark!\n"); } + readingmaps = 1; findinode(&spcl); if (spcl.c_type != TS_CLRI) errx(1, "Cannot find file removal list"); maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1; - Dprintf(stdout, "maxino = %ld\n", (long)maxino); map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY)); if (map == NULL) errx(1, "no memory for active inode map"); usedinomap = map; curfile.action = USING; getfile(xtrmap, xtrmapskip); - findinode(&spcl); + 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); + + spcl.c_dinode.di_size = spcl.c_count * TP_BSIZE; + getfile(xtrmap, xtrmapskip); + } + Dprintf(stdout, "maxino = %lu\n", (unsigned long)maxino); if (spcl.c_type != TS_BITS) errx(1, "Cannot find file dump list"); map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY)); @@ -380,6 +396,10 @@ setup(void) dumpmap = map; curfile.action = USING; getfile(xtrmap, xtrmapskip); + while (spcl.c_type == TS_ADDR) { + spcl.c_dinode.di_size = spcl.c_count * TP_BSIZE; + getfile(xtrmap, xtrmapskip); + } /* * If there may be whiteout entries on the tape, pretend that the * whiteout inode exists, so that the whiteout entries can be @@ -387,6 +407,7 @@ setup(void) */ if (oldinofmt == 0) SETINO(WINO, dumpmap); + readingmaps = 0; findinode(&spcl); } @@ -410,6 +431,8 @@ getvol(long nextvol) if (nextvol == 1) { tapesread = 0; gettingfile = 0; + tpblksread = 0; + blksread = 0; } if (pipein) { if (nextvol != 1) @@ -566,8 +589,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. @@ -582,10 +603,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 && @@ -697,12 +718,24 @@ struct timeval #endif int -extractfile(char *name) +extractfile(struct entry *ep, int doremove) { unsigned int flags; mode_t mode; struct timeval timep[2]; - struct entry *ep; + char *name = myname(ep); + + /* If removal is requested (-r mode) do remove it unless + * we are extracting a metadata only inode */ + if (spcl.c_flags & DR_METAONLY) { + Vprintf(stdout, "file %s is metadata only\n", name); + } + else { + if (doremove) { + removeleaf(ep); + ep->e_flags &= ~REMOVED; + } + } curfile.name = name; curfile.action = USING; @@ -733,7 +766,6 @@ extractfile(char *name) case IFDIR: if (mflag) { - ep = lookupname(name); if (ep == NULL || ep->e_flags & EXTRACT) panic("unextracted directory %s\n", name); skipfile(); @@ -748,16 +780,21 @@ extractfile(char *name) uid_t luid = curfile.dip->di_uid; gid_t lgid = curfile.dip->di_gid; #endif - lnkbuf[0] = '\0'; - pathlen = 0; - getfile(xtrlnkfile, xtrlnkskip); - if (pathlen == 0) { - Vprintf(stdout, - "%s: zero length symbolic link (ignored)\n", name); - return (GOOD); + if (! (spcl.c_flags & DR_METAONLY)) { + lnkbuf[0] = '\0'; + pathlen = 0; + getfile(xtrlnkfile, xtrlnkskip); + if (pathlen == 0) { + Vprintf(stdout, + "%s: zero length symbolic link (ignored)\n", name); + return (GOOD); + } + if (linkit(lnkbuf, name, SYMLINK) == FAIL) + return (FAIL); } - if (linkit(lnkbuf, name, SYMLINK) == FAIL) - return (FAIL); + else + skipfile(); + #ifdef HAVE_LCHOWN (void) lchown(name, luid, lgid); #endif @@ -770,12 +807,14 @@ extractfile(char *name) skipfile(); return (GOOD); } - if (uflag && !Nflag) - (void)unlink(name); - if (mkfifo(name, mode) < 0) { - warn("%s: cannot create fifo", name); - skipfile(); - return (FAIL); + if (! (spcl.c_flags & DR_METAONLY)) { + if (uflag && !Nflag) + (void)unlink(name); + if (mkfifo(name, mode) < 0) { + warn("%s: cannot create fifo", name); + skipfile(); + return (FAIL); + } } (void) chown(name, curfile.dip->di_uid, curfile.dip->di_gid); (void) chmod(name, mode); @@ -796,12 +835,14 @@ extractfile(char *name) skipfile(); return (GOOD); } - if (uflag) - (void)unlink(name); - if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) { - warn("%s: cannot create special file", name); - skipfile(); - return (FAIL); + if (! (spcl.c_flags & DR_METAONLY)) { + if (uflag) + (void)unlink(name); + if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) { + warn("%s: cannot create special file", name); + skipfile(); + return (FAIL); + } } (void) chown(name, curfile.dip->di_uid, curfile.dip->di_gid); (void) chmod(name, mode); @@ -819,32 +860,41 @@ extractfile(char *name) return (GOOD); case IFREG: + { + uid_t luid = curfile.dip->di_uid; + gid_t lgid = curfile.dip->di_gid; + Vprintf(stdout, "extract file %s\n", name); if (Nflag) { skipfile(); return (GOOD); } - if (uflag) - (void)unlink(name); - if ((ofile = OPEN(name, O_WRONLY | O_CREAT | O_TRUNC, - 0666)) < 0) { - warn("%s: cannot create file", name); - skipfile(); - return (FAIL); + if (! (spcl.c_flags & DR_METAONLY)) { + if (uflag) + (void)unlink(name); + if ((ofile = OPEN(name, O_WRONLY | O_CREAT | O_TRUNC, + 0666)) < 0) { + warn("%s: cannot create file", name); + skipfile(); + return (FAIL); + } + getfile(xtrfile, xtrskip); + (void) close(ofile); } - (void) fchown(ofile, curfile.dip->di_uid, curfile.dip->di_gid); - (void) fchmod(ofile, mode); + else + skipfile(); + (void) chown(name, luid, lgid); + (void) chmod(name, mode); if (flags) #ifdef __linux__ - (void) setflags(ofile, flags); + (void) fsetflags(name, flags); #else - (void) fchflags(ofile, flags); + (void) chflags(name, flags); #endif - getfile(xtrfile, xtrskip); - (void) close(ofile); utimes(name, timep); return (GOOD); } + } /* NOTREACHED */ } @@ -946,7 +996,8 @@ loop: if (last_write_was_hole) { FTRUNCATE(ofile, origsize); } - findinode(&spcl); + if (!readingmaps) + findinode(&spcl); gettingfile = 0; } @@ -1238,6 +1289,10 @@ comparefile(char *name) name, mode & 07777, sb.st_mode & 07777); do_compare_error; } + if (spcl.c_flags & DR_METAONLY) { + skipfile(); + return; + } switch (mode & IFMT) { default: skipfile();