]> git.wh0rd.org - dump.git/blobdiff - restore/tape.c
Emit warnings not panic() when comparing a file and we don't have enough priviledges...
[dump.git] / restore / tape.c
index 560a6c96c5f220d00e04eaefc427a1011a7106d4..76bdb4cb7d7def62ef1bd319b870421f86beb065 100644 (file)
@@ -42,7 +42,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.79 2004/04/13 13:04:33 stelian Exp $";
+       "$Id: tape.c,v 1.86 2005/01/24 10:32:14 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -168,6 +168,8 @@ static void  xtrmap __P((char *, size_t));
 static void     xtrmapskip __P((char *, size_t));
 static void     xtrskip __P((char *, size_t));
 static void     setmagtapein __P((void));
+static int      extractattr __P((char *));
+static void     compareattr __P((char *));
 
 #if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
 static void    newcomprbuf __P((int));
@@ -840,14 +842,19 @@ extractfile(struct entry *ep, int doremove)
                return (GOOD);
 
        case IFDIR:
+       {
+               int ret;
                if (mflag) {
                        if (ep == NULL || ep->e_flags & EXTRACT)
                                panic("unextracted directory %s\n", name);
                        skipfile();
                        return (GOOD);
                }
-               Vprintf(stdout, "extract file %s\n", name);
-               return (genliteraldir(name, curfile.ino));
+               Vprintf(stdout, "extract dir %s\n", name);
+               ret = genliteraldir(name, curfile.ino);
+               extractattr(name);
+               return ret;
+       }
 
        case IFLNK:
        {
@@ -873,6 +880,7 @@ extractfile(struct entry *ep, int doremove)
 #ifdef HAVE_LCHOWN
                (void) lchown(name, luid, lgid);
 #endif
+               extractattr(name);
                return (GOOD);
        }
 
@@ -895,7 +903,7 @@ extractfile(struct entry *ep, int doremove)
                (void) chmod(name, mode);
                if (flags)
 #ifdef  __linux__
-                       (void) fsetflags(name, flags);
+                       (void) lsetflags(name, flags);
 #else
 #ifdef sunos
                        {
@@ -907,6 +915,7 @@ extractfile(struct entry *ep, int doremove)
 #endif
 #endif
                skipfile();
+               extractattr(name);
                utimes(name, timep);
                return (GOOD);
 
@@ -931,8 +940,8 @@ extractfile(struct entry *ep, int doremove)
                if (flags)
 #ifdef __linux__
                        {
-                       warn("%s: fsetflags called on a special file", name);
-                       (void) fsetflags(name, flags);
+                       warn("%s: lsetflags called on a special file", name);
+                       (void) lsetflags(name, flags);
                        }
 #else
 #ifdef sunos
@@ -948,6 +957,7 @@ extractfile(struct entry *ep, int doremove)
 #endif
 #endif
                skipfile();
+               extractattr(name);
                utimes(name, timep);
                return (GOOD);
 
@@ -979,7 +989,7 @@ extractfile(struct entry *ep, int doremove)
                (void) chmod(name, mode);
                if (flags)
 #ifdef __linux__
-                       (void) fsetflags(name, flags);
+                       (void) lsetflags(name, flags);
 #else
 #ifdef sunos
                        {
@@ -990,6 +1000,7 @@ extractfile(struct entry *ep, int doremove)
                        (void) chflags(name, flags);
 #endif
 #endif
+               extractattr(name);
                utimes(name, timep);
                return (GOOD);
        }
@@ -997,6 +1008,40 @@ extractfile(struct entry *ep, int doremove)
        /* NOTREACHED */
 }
 
+static int
+extractattr(char *path)
+{
+       while (spcl.c_flags & DR_EXTATTRIBUTES) {
+               switch (spcl.c_extattributes) {
+               case EXT_MACOSFNDRINFO:
+#ifdef DUMP_MACOSX
+                       (void)extractfinderinfoufs(path);
+#else
+                       msg("MacOSX not supported in this version, skipping\n");
+                       skipfile();
+#endif
+                       break;
+               case EXT_MACOSRESFORK:
+#ifdef DUMP_MACOSX
+                       (void)extractresourceufs(path);
+#else
+                       msg("MacOSX not supported in this version, skipping\n");
+                       skipfile();
+#endif
+                       break;
+               case EXT_XATTR:
+                       msg("EA/ACLs not supported in this version, skipping\n");
+                       skipfile();
+                       break;
+               default:
+                       msg("unexpected inode extension %ld, skipping\n", spcl.c_extattributes);
+                       skipfile();
+                       break;
+               }
+       }
+       return GOOD;
+}
+
 #ifdef DUMP_MACOSX
 int
 extractfinderinfoufs(char *name)
@@ -1161,7 +1206,7 @@ extractresourceufs(char *name)
                (void) fchown(ofile, uid, gid);
                (void) fchmod(ofile, mode);
                (void) close(ofile);
-               (void) fsetflags(oFileRsrc, flags);
+               (void) lsetflags(oFileRsrc, flags);
                utimes(oFileRsrc, timep);
                return (GOOD);
        }
@@ -1191,6 +1236,17 @@ skipfile(void)
        getfile(xtrnull, xtrnull);
 }
 
+/*
+ * skip over any extended attributes.
+ */
+void
+skipxattr(void)
+{
+
+       while (spcl.c_flags & DR_EXTATTRIBUTES)
+               skipfile();
+}
+
 /*
  * Extract a file from the tape.
  * When an allocated block is found it is passed to the fill function;
@@ -1317,10 +1373,13 @@ xtrlnkfile(char *buf, size_t size)
 {
 
        pathlen += size;
-       if (pathlen > MAXPATHLEN)
+       if (pathlen > MAXPATHLEN) {
+               buf[size - 1] = '\0';
                errx(1, "symbolic link name: %s->%s%s; too long %d",
                    curfile.name, lnkbuf, buf, pathlen);
+       }
        (void) strcat(lnkbuf, buf);
+       lnkbuf[pathlen] = '\0';
 }
 
 /*
@@ -1426,7 +1485,7 @@ xtrcmpskip(UNUSED(char *buf), size_t size)
 
 #if !COMPARE_ONTHEFLY
 static int
-do_cmpfiles(int fd_tape, int fd_disk, long size)
+do_cmpfiles(int fd_tape, int fd_disk, OFF_T size)
 {
        static char buf_tape[BUFSIZ];
        static char buf_disk[BUFSIZ];
@@ -1468,15 +1527,15 @@ 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;
        }
 
        if (sbuf_disk->st_size != sbuf_tape.st_size) {
                fprintf(stderr,
-                       "%s: size changed from %ld to %ld.\n",
-                       diskfile, (long)sbuf_tape.st_size, (long)sbuf_disk->st_size);
+                       "%s: size changed from %lld to %lld.\n",
+                       diskfile, (long long)sbuf_tape.st_size, (long long)sbuf_disk->st_size);
                do_compare_error;
 #ifdef COMPARE_FAIL_KEEP_FILE
                return (0);
@@ -1486,12 +1545,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;
        }
 
@@ -1536,6 +1595,31 @@ cmpfiles(char *tapefile, char *diskfile, struct STAT *sbuf_disk)
 }
 #endif /* !COMPARE_ONTHEFLY */
 
+static void
+compareattr(char *name)
+{
+       while (spcl.c_flags & DR_EXTATTRIBUTES) {
+               switch (spcl.c_extattributes) {
+               case EXT_MACOSFNDRINFO:
+                       msg("MacOSX not supported for comparision in this version, skipping\n");
+                       skipfile();
+                       break;
+               case EXT_MACOSRESFORK:
+                       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();
+                       break;
+               default:
+                       msg("unexpected inode extension %ld, skipping\n", spcl.c_extattributes);
+                       skipfile();
+                       break;
+               }
+       }
+}
+
 #if !COMPARE_ONTHEFLY
 static char tmpfilename[MAXPATHLEN];
 #endif
@@ -1543,17 +1627,23 @@ static char tmpfilename[MAXPATHLEN];
 void
 comparefile(char *name)
 {
-       unsigned int mode;
+       mode_t mode;
+       uid_t uid;
+       uid_t gid;
+       unsigned int flags;
+       unsigned long newflags;
        struct STAT sb;
        int r;
 #if !COMPARE_ONTHEFLY
        static char *tmpfile = NULL;
        struct STAT stemp;
 #endif
-
        curfile.name = name;
        curfile.action = USING;
        mode = curfile.dip->di_mode;
+       flags = curfile.dip->di_flags;
+       uid = curfile.dip->di_uid;
+       gid =  curfile.dip->di_gid;
 
        if ((mode & IFMT) == IFSOCK) {
                Vprintf(stdout, "skipped socket %s\n", name);
@@ -1562,20 +1652,45 @@ 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;
        }
 
-       Vprintf(stdout, "comparing %s (size: %ld, mode: 0%o)\n", name,
-               (long)sb.st_size, mode);
+       Vprintf(stdout, "comparing %s (size: %lld, mode: 0%o)\n", name,
+               (long long)sb.st_size, mode);
 
        if (sb.st_mode != mode) {
                fprintf(stderr, "%s: mode changed from 0%o to 0%o.\n",
                        name, mode & 07777, sb.st_mode & 07777);
                do_compare_error;
        }
+       if (sb.st_uid != uid) {
+               fprintf(stderr, "%s: uid changed from %d to %d.\n",
+                       name, uid, sb.st_uid);
+               do_compare_error;
+       }
+       if (sb.st_gid != gid) {
+               fprintf(stderr, "%s: gid changed from %d to %d.\n",
+                       name, gid, sb.st_gid);
+               do_compare_error;
+       }
+#ifdef  __linux__
+       if (lgetflags(name, &newflags) < 0) {
+               if (flags != 0) {
+                       warn("%s: lgetflags failed", name);
+                       do_compare_error;
+               }
+       }
+       else {
+               if (newflags != flags) {
+                       fprintf(stderr, "%s: flags changed from 0x%08x to 0x%08lx.\n",
+                               name, flags, newflags);
+                       do_compare_error;
+               }
+       }
+#endif
        if (spcl.c_flags & DR_METAONLY) {
                skipfile();
                return;
@@ -1591,6 +1706,7 @@ comparefile(char *name)
 
        case IFDIR:
                skipfile();
+               compareattr(name);
                return;
 
        case IFLNK: {
@@ -1626,6 +1742,7 @@ comparefile(char *name)
                        do_compare_error;
                        return;
                }
+               compareattr(name);
                return;
        }
 
@@ -1650,12 +1767,13 @@ comparefile(char *name)
                        do_compare_error;
                }
                skipfile();
+               compareattr(name);
                return;
 
        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;
                }
@@ -1698,6 +1816,7 @@ comparefile(char *name)
                unlink(tmpfile);
 #endif
 #endif /* COMPARE_ONTHEFLY */
+               compareattr(name);
                return;
        }
        /* NOTREACHED */
@@ -2063,9 +2182,6 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize)
        /* zflag gets set in setup() from the dump header          */
        int cresult, blocklen;        
        unsigned long worklen;
-#ifdef HAVE_BZLIB
-       unsigned int worklen2;
-#endif
        char *output = NULL,*reason = NULL, *lengtherr = NULL;              
        
        /* build a length error message */
@@ -2112,7 +2228,7 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize)
 #ifndef HAVE_BZLIB
                        errx(1,"This restore version doesn't support bzlib decompression");
 #else
-                       worklen2 = worklen;
+                       unsigned int worklen2 = worklen;
                        cresult = BZ2_bzBuffToBuffDecompress(
                                        comprbuf, &worklen2, 
                                        tpbin->buf, blocklen, 0, 0);
@@ -2145,8 +2261,10 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize)
 #ifndef HAVE_LZO
                        errx(1,"This restore version doesn't support lzo decompression");
 #else
+                       lzo_uint worklen2 = worklen;
                        cresult = lzo1x_decompress(tpbin->buf, blocklen,
-                                                   comprbuf, (lzo_uintp) &worklen,NULL);
+                                                   comprbuf, &worklen2, NULL);
+                       worklen = worklen2;
                        output = comprbuf;
                        switch (cresult) {
                                case LZO_E_OK:
@@ -2176,7 +2294,7 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize)
        }
        if (reason) {
                if (lengtherr)
-                       fprintf(stderr, "%s compressed block: %d expected: %d\n",
+                       fprintf(stderr, "%s compressed block: %d expected: %u\n",
                                lengtherr, readsize, tpbin->length + PREFIXSIZE);
                fprintf(stderr, "decompression error, block %ld: %s\n",
                        tpblksread+1, reason);