]> git.wh0rd.org - dump.git/blobdiff - restore/tape.c
Small missing \n
[dump.git] / restore / tape.c
index b4fa15d93c8cdc9882f6a112524253614c6ee1d2..77f84f08dbe441f6be9cf283b6293cc6926d1990 100644 (file)
@@ -42,7 +42,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.75 2003/10/26 16:05:48 stelian Exp $";
+       "$Id: tape.c,v 1.87 2005/01/24 10:37:58 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));
@@ -413,13 +415,19 @@ setup(void)
                dump_ino_t oldmaxino = maxino;
                maxino += (spcl.c_count * TP_BSIZE * NBBY) + 1;
                resizemaps(oldmaxino, maxino);
+               map = usedinomap;
 
                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)
+       if (spcl.c_type != TS_BITS) {
+               if (spcl.c_type == TS_END) {
+                       msg("Cannot find file dump list, assuming empty tape\n");
+                       exit(0);
+               }
                errx(1, "Cannot find file dump list");
+       }
        map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
        if (map == (char *)NULL)
                errx(1, "no memory for file dump list");
@@ -834,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:
        {
@@ -867,6 +880,7 @@ extractfile(struct entry *ep, int doremove)
 #ifdef HAVE_LCHOWN
                (void) lchown(name, luid, lgid);
 #endif
+               extractattr(name);
                return (GOOD);
        }
 
@@ -889,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
                        {
@@ -901,6 +915,7 @@ extractfile(struct entry *ep, int doremove)
 #endif
 #endif
                skipfile();
+               extractattr(name);
                utimes(name, timep);
                return (GOOD);
 
@@ -925,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
@@ -942,6 +957,7 @@ extractfile(struct entry *ep, int doremove)
 #endif
 #endif
                skipfile();
+               extractattr(name);
                utimes(name, timep);
                return (GOOD);
 
@@ -973,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
                        {
@@ -984,6 +1000,7 @@ extractfile(struct entry *ep, int doremove)
                        (void) chflags(name, flags);
 #endif
 #endif
+               extractattr(name);
                utimes(name, timep);
                return (GOOD);
        }
@@ -991,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)
@@ -1000,12 +1051,10 @@ extractfinderinfoufs(char *name)
        int flags;
        mode_t mode;
        struct timeval timep[2];
-       struct entry *ep;
-       int     sz;
-       attrinfo_block_t gABuf;
        u_int32_t       uid;
        u_int32_t       gid;
        char    path[MAXPATHLEN], fname[MAXPATHLEN];
+       int toto;
 
        curfile.name = name;
        curfile.action = USING;
@@ -1157,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);
        }
@@ -1187,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;
@@ -1313,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';
 }
 
 /*
@@ -1422,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];
@@ -1464,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);
@@ -1482,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;
        }
 
@@ -1532,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
@@ -1539,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);
@@ -1558,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;
@@ -1587,6 +1706,7 @@ comparefile(char *name)
 
        case IFDIR:
                skipfile();
+               compareattr(name);
                return;
 
        case IFLNK: {
@@ -1610,7 +1730,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;
                }
@@ -1622,6 +1742,7 @@ comparefile(char *name)
                        do_compare_error;
                        return;
                }
+               compareattr(name);
                return;
        }
 
@@ -1639,19 +1760,20 @@ comparefile(char *name)
                        fprintf(stderr,
                                "%s: device changed from %d,%d to %d,%d.\n",
                                name,
-                               ((int)curfile.dip->di_rdev >> 8) & 0xff,
-                               (int)curfile.dip->di_rdev & 0xff,
-                               ((int)sb.st_rdev >> 8) & 0xff,
-                               (int)sb.st_rdev & 0xff);
+                               major(curfile.dip->di_rdev),
+                               minor(curfile.dip->di_rdev),
+                               major(sb.st_rdev),
+                               minor(sb.st_rdev));
                        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;
                }
@@ -1694,6 +1816,7 @@ comparefile(char *name)
                unlink(tmpfile);
 #endif
 #endif /* COMPARE_ONTHEFLY */
+               compareattr(name);
                return;
        }
        /* NOTREACHED */
@@ -2059,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 */
@@ -2108,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);
@@ -2141,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:
@@ -2172,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);
@@ -2453,34 +2575,47 @@ converthead(struct s_spcl *buf)
                goto good;
        }
        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;
-       buf->c_ddate = u_ospcl.s_ospcl.c_ddate;
-       buf->c_volume = u_ospcl.s_ospcl.c_volume;
-       buf->c_tapea = u_ospcl.s_ospcl.c_tapea;
-       buf->c_inumber = u_ospcl.s_ospcl.c_inumber;
-       buf->c_checksum = u_ospcl.s_ospcl.c_checksum;
-       buf->c_magic = u_ospcl.s_ospcl.c_magic;
-       buf->c_dinode.di_mode = u_ospcl.s_ospcl.c_dinode.odi_mode;
-       buf->c_dinode.di_nlink = u_ospcl.s_ospcl.c_dinode.odi_nlink;
-       buf->c_dinode.di_uid = u_ospcl.s_ospcl.c_dinode.odi_uid;
-       buf->c_dinode.di_gid = u_ospcl.s_ospcl.c_dinode.odi_gid;
-       buf->c_dinode.di_size = u_ospcl.s_ospcl.c_dinode.odi_size;
-       buf->c_dinode.di_rdev = u_ospcl.s_ospcl.c_dinode.odi_rdev;
+       if (checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
+               return(FAIL);
+       if (u_ospcl.s_ospcl.c_magic == OFS_MAGIC) {
+               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;
+               buf->c_ddate = u_ospcl.s_ospcl.c_ddate;
+               buf->c_volume = u_ospcl.s_ospcl.c_volume;
+               buf->c_tapea = u_ospcl.s_ospcl.c_tapea;
+               buf->c_inumber = u_ospcl.s_ospcl.c_inumber;
+               buf->c_checksum = u_ospcl.s_ospcl.c_checksum;
+               buf->c_magic = u_ospcl.s_ospcl.c_magic;
+               buf->c_dinode.di_mode = u_ospcl.s_ospcl.c_dinode.odi_mode;
+               buf->c_dinode.di_nlink = u_ospcl.s_ospcl.c_dinode.odi_nlink;
+               buf->c_dinode.di_uid = u_ospcl.s_ospcl.c_dinode.odi_uid;
+               buf->c_dinode.di_gid = u_ospcl.s_ospcl.c_dinode.odi_gid;
+               buf->c_dinode.di_size = u_ospcl.s_ospcl.c_dinode.odi_size;
+               buf->c_dinode.di_rdev = u_ospcl.s_ospcl.c_dinode.odi_rdev;
 #if defined(__linux__) || defined(sunos)
-       buf->c_dinode.di_atime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_atime;
-       buf->c_dinode.di_mtime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_mtime;
-       buf->c_dinode.di_ctime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_ctime;
+               buf->c_dinode.di_atime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_atime;
+               buf->c_dinode.di_mtime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_mtime;
+               buf->c_dinode.di_ctime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_ctime;
 #else  /* __linux__ || sunos */
-       buf->c_dinode.di_atime = u_ospcl.s_ospcl.c_dinode.odi_atime;
-       buf->c_dinode.di_mtime = u_ospcl.s_ospcl.c_dinode.odi_mtime;
-       buf->c_dinode.di_ctime = u_ospcl.s_ospcl.c_dinode.odi_ctime;
+               buf->c_dinode.di_atime = u_ospcl.s_ospcl.c_dinode.odi_atime;
+               buf->c_dinode.di_mtime = u_ospcl.s_ospcl.c_dinode.odi_mtime;
+               buf->c_dinode.di_ctime = u_ospcl.s_ospcl.c_dinode.odi_ctime;
 #endif /* __linux__ || sunos */
-       buf->c_count = u_ospcl.s_ospcl.c_count;
-       memmove(buf->c_addr, u_ospcl.s_ospcl.c_fill, (long)256);
-       if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
-           checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
+               buf->c_count = u_ospcl.s_ospcl.c_count;
+               memmove(buf->c_addr, u_ospcl.s_ospcl.c_fill, (long)256);
+       }
+       else if (u_ospcl.s_ospcl.c_magic == FS_UFS2_MAGIC) {
+               buf->c_date = (int32_t)(*(int64_t *)&u_ospcl.dummy[896]);
+               buf->c_ddate = (int32_t)(*(int64_t *)&u_ospcl.dummy[904]);
+               buf->c_tapea = (int32_t)(*(int64_t *)&u_ospcl.dummy[912]);
+               buf->c_firstrec = (int32_t)(*(int64_t *)&u_ospcl.dummy[920]);
+               buf->c_ntrec = 0;
+               buf->c_extattributes = 0;
+               buf->c_flags |= DR_NEWINODEFMT;
+               ufs2flag = 1;
+       }
+       else
                return(FAIL);
        buf->c_magic = NFS_MAGIC;