X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Ftape.c;h=4710f889d1cdae269f1c3c586eb594cdc401c650;hp=c74e3909f10e46cf1f1ae026573f5d9cfab56bde;hb=2359fe7e917ea8a52c5d523c77d29bddf6f82fce;hpb=cb6d3f79501e3c03637ca49f4b980288771eabd3 diff --git a/restore/tape.c b/restore/tape.c index c74e390..4710f88 100644 --- a/restore/tape.c +++ b/restore/tape.c @@ -42,7 +42,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.90 2005/06/08 13:24:11 stelian Exp $"; + "$Id: tape.c,v 1.100 2010/12/06 14:26:51 stelian Exp $"; #endif /* not lint */ #include @@ -61,6 +61,8 @@ static const char rcsid[] = #include #include #include +#include +#include #ifdef __linux__ #include @@ -474,7 +476,6 @@ getvol(long nextvol) if (nextvol == 1) { tapesread = 0; gettingfile = 0; - tpblksread = 0; blksread = 0; } if (pipein) { @@ -521,7 +522,8 @@ again: do { fprintf(stderr, "Specify next volume # (none if no more volumes): "); (void) fflush(stderr); - (void) fgets(buf, TP_BSIZE, terminal); + if (!fgets(buf, TP_BSIZE, terminal)) + break; } while (!feof(terminal) && buf[0] == '\n'); if (feof(terminal)) exit(1); @@ -570,6 +572,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 @@ -582,7 +586,8 @@ again: fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape); #endif (void) fflush(stderr); - (void) fgets(buf, TP_BSIZE, terminal); + if (fgets(buf, TP_BSIZE, terminal)) + exit(1); if (feof(terminal)) exit(1); if (!strcmp(buf, "none\n")) { @@ -842,9 +847,54 @@ extractfile(struct entry *ep, int doremove) return (FAIL); case IFSOCK: - Vprintf(stdout, "skipped socket %s\n", name); + { + uid_t luid = curfile.dip->di_uid; + gid_t lgid = curfile.dip->di_gid; + + Vprintf(stdout, "extract socket %s\n", name); skipfile(); + if (Nflag) + return (GOOD); + if (! (spcl.c_flags & DR_METAONLY)) { + int sk; + struct sockaddr_un addr; + + if (uflag) + (void)unlink(name); + + if ((sk = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { + warn("%s: cannot create socket", name); + return (FAIL); + } + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, name); + if (bind(sk, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) { + warn("%s: cannot create socket", name); + return (FAIL); + } + close(sk); + } + if (chown(name, luid, lgid) < 0) + warn("%s: chown", name); + if (chmod(name, mode) < 0) + warn("%s: chmod", name); + extractattr(name); + utimes(name, timep); + if (flags) +#ifdef __linux__ + (void) lsetflags(name, flags); +#else +#ifdef sunos + { + warn("%s: cannot call chflags", name); + /* (void) chflags(name, flags); */ + } +#else + (void) chflags(name, flags); +#endif +#endif return (GOOD); + } case IFDIR: { @@ -883,29 +933,36 @@ extractfile(struct entry *ep, int doremove) skipfile(); #ifdef HAVE_LCHOWN - (void) lchown(name, luid, lgid); + if (lchown(name, luid, lgid) < 0) + warn("%s: lchown", name); #endif extractattr(name); return (GOOD); } case IFIFO: + { + uid_t luid = curfile.dip->di_uid; + gid_t lgid = curfile.dip->di_gid; + 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); + if (chown(name, luid, lgid) < 0) + warn("%s: chown", name); + if (chmod(name, mode) < 0) + warn("%s: chmod", name); + extractattr(name); + utimes(name, timep); if (flags) #ifdef __linux__ (void) lsetflags(name, flags); @@ -919,29 +976,33 @@ extractfile(struct entry *ep, int doremove) (void) chflags(name, flags); #endif #endif - skipfile(); - extractattr(name); - utimes(name, timep); return (GOOD); - + } case IFCHR: case IFBLK: + { + uid_t luid = curfile.dip->di_uid; + gid_t lgid = curfile.dip->di_gid; + int lrdev = (int)curfile.dip->di_rdev; + 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) { + if (mknod(name, mode, lrdev) < 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); + if (chown(name, luid, lgid) < 0) + warn("%s: chown", name); + if (chmod(name, mode) < 0) + warn("%s: chmod", name); + extractattr(name); + utimes(name, timep); if (flags) #ifdef __linux__ { @@ -961,11 +1022,8 @@ extractfile(struct entry *ep, int doremove) } #endif #endif - skipfile(); - extractattr(name); - utimes(name, timep); return (GOOD); - + } case IFREG: { uid_t luid = curfile.dip->di_uid; @@ -990,8 +1048,12 @@ extractfile(struct entry *ep, int doremove) } else skipfile(); - (void) chown(name, luid, lgid); - (void) chmod(name, mode); + if (chown(name, luid, lgid) < 0) + warn("%s: chown", name); + if (chmod(name, mode) < 0) + warn("%s: chmod", name); + extractattr(name); + utimes(name, timep); if (flags) #ifdef __linux__ (void) lsetflags(name, flags); @@ -1005,8 +1067,6 @@ extractfile(struct entry *ep, int doremove) (void) chflags(name, flags); #endif #endif - extractattr(name); - utimes(name, timep); return (GOOD); } } @@ -1211,11 +1271,13 @@ extractresourceufs(char *name) /* and add the resource data from tape */ getfile(xtrfile, xtrskip); - (void) fchown(ofile, uid, gid); - (void) fchmod(ofile, mode); + if (fchown(ofile, uid, gid) < 0) + warn("%s: fchown", name); + if (fchmod(ofile, mode) < 0) + warn("%s: fchmod", name); (void) close(ofile); - (void) lsetflags(oFileRsrc, flags); utimes(oFileRsrc, timep); + (void) lsetflags(oFileRsrc, flags); return (GOOD); } /* NOTREACHED */ @@ -1234,12 +1296,20 @@ readxattr(char *buffer) skipfile(); return (FAIL); } - + memset(xattrbuf, 0, XATTR_MAXSIZE); xattrlen = 0; + /* + * ugly hack: cope with invalid spcl.c_addr[] records written by + * old versions of dump. + */ + readmapflag = 1; + getfile(xtrxattr, xtrnull); + readmapflag = 0; + memcpy(buffer, xattrbuf, XATTR_MAXSIZE); return (GOOD); @@ -1331,7 +1401,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, @@ -1352,7 +1426,8 @@ loop: last_write_was_hole = 1; } if (last_write_was_hole) { - FTRUNCATE(ofile, origsize); + if (FTRUNCATE(ofile, origsize) < 0) + warn("%s: ftruncate", curfile.name); } if (!readingmaps) findinode(&spcl); @@ -2346,8 +2421,8 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize) } if (reason) { if (lengtherr) - fprintf(stderr, "%s compressed block: %d expected: %u\n", - lengtherr, readsize, tpbin->length + PREFIXSIZE); + fprintf(stderr, "%s compressed block: %d expected: %lu\n", + lengtherr, readsize, (unsigned long)tpbin->length + PREFIXSIZE); fprintf(stderr, "decompression error, block %ld: %s\n", tpblksread+1, reason); if (!cresult) @@ -3261,11 +3336,14 @@ ReReadInodeFromTape(dump_ino_t theino) cntloop++; gethead(&spcl); } while (!(spcl.c_inumber == theino && spcl.c_type == TS_INODE && spcl.c_date == dumpdate)); + + tpblksread = spcl.c_tapea + spcl.c_volume; #ifdef DEBUG_QFA fprintf(stderr, "DEBUG: %ld reads\n", cntloop); fprintf(stderr, "DEBUG: bufsize %ld\n", bufsize); fprintf(stderr, "DEBUG: ntrec %ld\n", ntrec); - fprintf(stderr, "DEBUG: %ld reads\n", cntloop); + fprintf(stderr, "DEBUG: tapea %d\n", spcl.c_tapea); + fprintf(stderr, "DEBUG: tpblksread %ld\n", tpblksread); #endif findinode(&spcl); noresyncmesg = 0;