X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Ftape.c;h=fa4a9618f3a8323ef7f5ea3ea0e18ab46c6dea57;hp=aa0dbd7021a711c2192da6c4646fcb64dc7f6993;hb=2e555f4100de1ce92bb01d09fd4b635fb0e133f4;hpb=a55ce9149e3f4a5f848a20b7593dbe8cd7b0bbd1 diff --git a/restore/tape.c b/restore/tape.c index aa0dbd7..fa4a961 100644 --- a/restore/tape.c +++ b/restore/tape.c @@ -42,7 +42,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.84 2004/12/15 11:00:01 stelian Exp $"; + "$Id: tape.c,v 1.94 2009/12/03 12:46:30 stelian Exp $"; #endif /* not lint */ #include @@ -167,6 +167,7 @@ static void xtrlnkskip __P((char *, size_t)); static void xtrmap __P((char *, size_t)); static void xtrmapskip __P((char *, size_t)); static void xtrskip __P((char *, size_t)); +static void xtrxattr __P((char *, size_t)); static void setmagtapein __P((void)); static int extractattr __P((char *)); static void compareattr __P((char *)); @@ -196,6 +197,9 @@ static void xtrcmpskip __P((char *, size_t)); static int readmapflag; static int readingmaps; /* set to 1 while reading the maps */ +static char xattrbuf[XATTR_MAXSIZE]; +static int xattrlen; + #ifdef DUMP_MACOSX static DumpFinderInfo gFndrInfo; #endif @@ -342,6 +346,7 @@ setup(void) #endif FLUSHTAPEBUF(); findtapeblksize(); + cvtflag = 0; if (gethead(&spcl) == FAIL) { blkcnt--; /* push back this block */ blksread--; @@ -469,7 +474,6 @@ getvol(long nextvol) if (nextvol == 1) { tapesread = 0; gettingfile = 0; - tpblksread = 0; blksread = 0; } if (pipein) { @@ -565,6 +569,8 @@ again: } if (haderror || (bot_code && !Mflag)) { haderror = 0; + if (compare_errors) + fprintf(stderr, "%d compare errors so far\n", compare_errors); #ifdef sunos fprintf(stderr, "Mount volume %ld\n", (long)newvol); #else @@ -886,21 +892,21 @@ extractfile(struct entry *ep, int doremove) case IFIFO: Vprintf(stdout, "extract fifo %s\n", name); - if (Nflag) { - skipfile(); + skipfile(); + if (Nflag) return (GOOD); - } 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); + extractattr(name); + utimes(name, timep); if (flags) #ifdef __linux__ (void) lsetflags(name, flags); @@ -914,29 +920,26 @@ extractfile(struct entry *ep, int doremove) (void) chflags(name, flags); #endif #endif - skipfile(); - extractattr(name); - utimes(name, timep); return (GOOD); case IFCHR: case IFBLK: Vprintf(stdout, "extract special file %s\n", name); - if (Nflag) { - skipfile(); + skipfile(); + if (Nflag) return (GOOD); - } 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); + extractattr(name); + utimes(name, timep); if (flags) #ifdef __linux__ { @@ -956,9 +959,6 @@ extractfile(struct entry *ep, int doremove) } #endif #endif - skipfile(); - extractattr(name); - utimes(name, timep); return (GOOD); case IFREG: @@ -987,6 +987,8 @@ extractfile(struct entry *ep, int doremove) skipfile(); (void) chown(name, luid, lgid); (void) chmod(name, mode); + extractattr(name); + utimes(name, timep); if (flags) #ifdef __linux__ (void) lsetflags(name, flags); @@ -1000,8 +1002,6 @@ extractfile(struct entry *ep, int doremove) (void) chflags(name, flags); #endif #endif - extractattr(name); - utimes(name, timep); return (GOOD); } } @@ -1029,10 +1029,14 @@ extractattr(char *path) skipfile(); #endif break; - case EXT_XATTR: - msg("EA/ACLs not supported in this version, skipping\n"); - skipfile(); - break; + case EXT_XATTR: { + char xattr[XATTR_MAXSIZE]; + + if (readxattr(xattr) == GOOD) { + xattr_extract(path, xattr); + break; + } + } default: msg("unexpected inode extension %ld, skipping\n", spcl.c_extattributes); skipfile(); @@ -1054,7 +1058,6 @@ extractfinderinfoufs(char *name) u_int32_t uid; u_int32_t gid; char path[MAXPATHLEN], fname[MAXPATHLEN]; - int toto; curfile.name = name; curfile.action = USING; @@ -1206,14 +1209,37 @@ extractresourceufs(char *name) (void) fchown(ofile, uid, gid); (void) fchmod(ofile, mode); (void) close(ofile); - (void) lsetflags(oFileRsrc, flags); utimes(oFileRsrc, timep); + (void) lsetflags(oFileRsrc, flags); return (GOOD); } /* NOTREACHED */ } #endif /* DUMP_MACOSX */ +int +readxattr(char *buffer) +{ + if (dflag) + msg("reading EA data for inode %lu\n", curfile.ino); + + curfile.name = "EA block"; + if (curfile.dip->di_size > XATTR_MAXSIZE) { + fprintf(stderr, "EA size too big (%ld)", (long)curfile.dip->di_size); + skipfile(); + return (FAIL); + } + + memset(xattrbuf, 0, XATTR_MAXSIZE); + xattrlen = 0; + + getfile(xtrxattr, xtrnull); + + memcpy(buffer, xattrbuf, XATTR_MAXSIZE); + + return (GOOD); +} + /* * skip over bit maps on the tape */ @@ -1300,7 +1326,11 @@ loop: break; } } - if (gethead(&spcl) == GOOD && size > 0) { + while (gethead(&spcl) != GOOD) { + fprintf(stderr, "Incorrect block for %s at %ld blocks\n", + curfile.name, (long)blksread); + } + if (size > 0) { if (spcl.c_type == TS_ADDR) goto loop; Dprintf(stdout, @@ -1346,8 +1376,6 @@ xtrfile(char *buf, size_t size) static void xtrfilefinderinfo(char *buf, size_t size) { - if (Nflag) - return; bcopy(buf, &gFndrInfo, size); } #endif /* DUMP_MACOSX */ @@ -1483,6 +1511,17 @@ xtrcmpskip(UNUSED(char *buf), size_t size) } #endif /* COMPARE_ONTHEFLY */ +static void +xtrxattr(char *buf, size_t size) +{ + if (xattrlen + size > XATTR_MAXSIZE) { + fprintf(stderr, "EA size too big (%ld)", (long)xattrlen + size); + return; + } + memcpy(xattrbuf + xattrlen, buf, size); + xattrlen += size; +} + #if !COMPARE_ONTHEFLY static int do_cmpfiles(int fd_tape, int fd_disk, OFF_T size) @@ -1527,7 +1566,7 @@ cmpfiles(char *tapefile, char *diskfile, struct STAT *sbuf_disk) int fd_tape, fd_disk; if (STAT(tapefile, &sbuf_tape) != 0) { - panic("Can't lstat tmp file %s: %s\n", tapefile, + panic("can't lstat tmp file %s: %s\n", tapefile, strerror(errno)); do_compare_error; } @@ -1545,12 +1584,12 @@ cmpfiles(char *tapefile, char *diskfile, struct STAT *sbuf_disk) } if ((fd_tape = OPEN(tapefile, O_RDONLY)) < 0) { - panic("Can't open %s: %s\n", tapefile, strerror(errno)); + panic("can't open %s: %s\n", tapefile, strerror(errno)); do_compare_error; } if ((fd_disk = OPEN(diskfile, O_RDONLY)) < 0) { close(fd_tape); - panic("Can't open %s: %s\n", diskfile, strerror(errno)); + panic("can't open %s: %s\n", diskfile, strerror(errno)); do_compare_error; } @@ -1598,6 +1637,8 @@ cmpfiles(char *tapefile, char *diskfile, struct STAT *sbuf_disk) static void compareattr(char *name) { + int xattr_done = 0; + while (spcl.c_flags & DR_EXTATTRIBUTES) { switch (spcl.c_extattributes) { case EXT_MACOSFNDRINFO: @@ -1608,16 +1649,26 @@ compareattr(char *name) msg("MacOSX not supported for comparision in this version, skipping\n"); skipfile(); break; - case EXT_XATTR: - msg("EA/ACLs not supported for comparision in this version, skipping\n"); - skipxattr(); + case EXT_XATTR: { + char xattr[XATTR_MAXSIZE]; + + if (readxattr(xattr) == GOOD) { + if (xattr_compare(name, xattr) == FAIL) + do_compare_error; + xattr_done = 1; + } + else + do_compare_error; break; + } default: msg("unexpected inode extension %ld, skipping\n", spcl.c_extattributes); skipfile(); break; } } + if (!xattr_done && xattr_compare(name, NULL) == FAIL) + do_compare_error; } #if !COMPARE_ONTHEFLY @@ -1652,7 +1703,7 @@ comparefile(char *name) } if ((r = LSTAT(name, &sb)) != 0) { - warn("%s: does not exist (%d)", name, r); + warn("unable to stat %s", name); do_compare_error; skipfile(); return; @@ -1678,8 +1729,10 @@ comparefile(char *name) } #ifdef __linux__ if (lgetflags(name, &newflags) < 0) { - warn("%s: lgetflags failed", name); - do_compare_error; + if (flags != 0) { + warn("%s: lgetflags failed", name); + do_compare_error; + } } else { if (newflags != flags) { @@ -1728,7 +1781,7 @@ comparefile(char *name) return; } if ((lsize = readlink(name, lbuf, MAXPATHLEN)) < 0) { - panic("readlink of %s failed: %s", name, + panic("readlink of %s failed: %s\n", name, strerror(errno)); do_compare_error; } @@ -1771,7 +1824,7 @@ comparefile(char *name) case IFREG: #if COMPARE_ONTHEFLY if ((ifile = OPEN(name, O_RDONLY)) < 0) { - panic("Can't open %s: %s\n", name, strerror(errno)); + warn("can't open %s", name); skipfile(); do_compare_error; } @@ -2359,6 +2412,7 @@ findtapeblksize(void) errx(1, "Tape read error on first record"); memcpy(&spclpt, tapebuf, TP_BSIZE); + cvtflag = 0; if (converthead(&spclpt) == FAIL) { cvtflag++; if (converthead(&spclpt) == FAIL) { @@ -2569,7 +2623,7 @@ converthead(struct s_spcl *buf) if (checksum((int *)buf) == FAIL) return (FAIL); if (Bcvt) - swabst((u_char *)"8i4s31i528bi192b3i", (u_char *)buf); + swabst((u_char *)"8i4s1l29i528bi192b4i", (u_char *)buf); goto good; } memcpy(&u_ospcl.s_ospcl, buf, TP_BSIZE);