]> git.wh0rd.org - dump.git/blobdiff - restore/tape.c
64bit and glibc 2.2.2 fixes.
[dump.git] / restore / tape.c
index c5d9a661adccdf0fdadb72b2ec31a6446e58c689..45d19d22aa8234a12480f424459aeb8e5a513961 100644 (file)
@@ -2,7 +2,8 @@
  *     Ported to Linux's Second Extended File System as part of the
  *     dump and restore backup suit
  *     Remy Card <card@Linux.EU.Org>, 1994-1997
- *     Stelian Pop <pop@cybercable.fr>, 1999-2000
+ *     Stelian Pop <pop@noos.fr>, 1999-2000
+ *     Stelian Pop <pop@noos.fr> - AlcĂ´ve <www.alcove.fr>, 2000
  */
 
 /*
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.17 2000/06/03 22:24:18 stelian Exp $";
+       "$Id: tape.c,v 1.25 2001/02/22 10:57:40 stelian Exp $";
 #endif /* not lint */
 
+#include <config.h>
 #include <sys/param.h>
 #include <sys/file.h>
 #include <sys/mtio.h>
@@ -55,6 +57,7 @@ static const char rcsid[] =
 
 #ifdef __linux__
 #include <sys/time.h>
+#include <time.h>
 #include <linux/ext2_fs.h>
 #include <bsdcompat.h>
 #else  /* __linux__ */
@@ -70,6 +73,10 @@ static const char rcsid[] =
 #include <string.h>
 #include <unistd.h>
 
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+#endif /* HAVE_ZLIB */
+
 #ifdef __linux__
 #include <ext2fs/ext2fs.h>
 #endif
@@ -86,6 +93,11 @@ static char  magtapeprefix[MAXPATHLEN];
 static int     blkcnt;
 static int     numtrec;
 static char    *tapebuf;
+static char    *tbufptr = NULL;        /* active tape buffer */
+#ifdef HAVE_ZLIB
+static char    *comprbuf;              /* uncompress work buf */
+static size_t  comprlen;
+#endif
 static union   u_spcl endoftapemark;
 static long    blksread;               /* blocks read since last header */
 static long    tpblksread = 0;         /* TP_BSIZE blocks read */
@@ -113,7 +125,9 @@ static int   gethead __P((struct s_spcl *));
 static void     readtape __P((char *));
 static void     setdumpnum __P((void));
 static u_int    swabi __P((u_int));
+#if 0
 static u_long   swabl __P((u_long));
+#endif
 static u_char  *swab64 __P((u_char *, int));
 static u_char  *swab32 __P((u_char *, int));
 static u_char  *swab16 __P((u_char *, int));
@@ -197,6 +211,14 @@ newtapebuf(long size)
        if (tapebuf == NULL)
                errx(1, "Cannot allocate space for tape buffer");
        tapebufsize = size;
+#ifdef HAVE_ZLIB
+       if (comprbuf != NULL)
+               free(comprbuf);
+       comprlen = size * TP_BSIZE;
+       comprbuf = malloc(comprlen);
+       if (comprbuf == NULL)
+               errx(1, "Cannot allocate space for uncompress buffer");
+#endif /* HAVE_ZLIB */
 }
 
 /*
@@ -235,6 +257,15 @@ setup(void)
                        errx(1, "Tape is not a dump tape");
                fprintf(stderr, "Converting to new file system format.\n");
        }
+
+       if (spcl.c_flags & DR_COMPRESSED) {
+               fprintf(stderr, "Dump tape is compressed.\n");
+#ifdef HAVE_ZLIB
+               zflag = 1;
+#else
+               errx(1,"This restore version doesn't support decompression");
+#endif /* HAVE_ZLIB */
+       }
        if (pipein) {
                endoftapemark.s_spcl.c_magic = cvtflag ? OFS_MAGIC : NFS_MAGIC;
                endoftapemark.s_spcl.c_type = TS_END;
@@ -279,7 +310,7 @@ setup(void)
        Dprintf(stdout, "maxino = %ld\n", (long)maxino);
        map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
        if (map == NULL)
-               panic("no memory for active inode map\n");
+               errx(1, "no memory for active inode map");
        usedinomap = map;
        curfile.action = USING;
        getfile(xtrmap, xtrmapskip);
@@ -287,7 +318,7 @@ setup(void)
                errx(1, "Cannot find file dump list");
        map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
        if (map == (char *)NULL)
-               panic("no memory for file dump list\n");
+               errx(1, "no memory for file dump list");
        dumpmap = map;
        curfile.action = USING;
        getfile(xtrmap, xtrmapskip);
@@ -546,9 +577,9 @@ printdumpinfo(void)
 #endif
        if (spcl.c_host[0] == '\0')
                return;
-       fprintf(stderr, "Level %d dump of %s on %s:%s\n",
+       fprintf(stdout, "Level %d dump of %s on %s:%s\n",
                spcl.c_level, spcl.c_filesys, spcl.c_host, spcl.c_dev);
-       fprintf(stderr, "Label: %s\n", spcl.c_label);
+       fprintf(stdout, "Label: %s\n", spcl.c_label);
 }
 
 int
@@ -1216,13 +1247,19 @@ readtape(char *buf)
 {
        ssize_t rd, newvol, i;
        int cnt, seek_failed;
+#ifdef HAVE_ZLIB
+       int cresult;
+       struct tapebuf* tpb;
+       unsigned long worklen;
+#endif
 
        if (blkcnt < numtrec) {
-               memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], TP_BSIZE);
+               memmove(buf, &tbufptr[(blkcnt++ * TP_BSIZE)], TP_BSIZE);
                blksread++;
                tpblksread++;
                return;
        }
+       tbufptr = tapebuf;
        for (i = 0; i < ntrec; i++)
                ((struct s_spcl *)&tapebuf[i * TP_BSIZE])->c_magic = 0;
        if (numtrec == 0)
@@ -1236,6 +1273,28 @@ getmore:
        else
 #endif
                i = read(mt, &tapebuf[rd], cnt);
+
+#ifdef HAVE_ZLIB
+       if (i < 0)
+               goto readerror;
+       if (i == 0 && !pipein)
+               goto endoftape;
+
+       if (zflag  && i != ntrec * TP_BSIZE) {
+               tpb = (struct tapebuf *) tapebuf;
+               if (i != tpb->clen + sizeof(struct tapebuf))
+                       errx(1,"tape is not a compressed dump tape");
+               worklen = comprlen;
+               cresult = uncompress(comprbuf, &worklen, tpb->buf, tpb->clen);
+               if (cresult != Z_OK)
+                       errx(1,"tape is not a compressed dump tape");
+               if (worklen != tpb->unclen)
+                       errx(1,"decompression error, length mismatch");
+               i = worklen;
+               tbufptr = comprbuf;
+       }
+#endif /* HAVE_ZLIB */
+
        /*
         * Check for mid-tape short read error.
         * If found, skip rest of buffer and start with the next.
@@ -1270,6 +1329,9 @@ getmore:
        /*
         * Handle read error.
         */
+#ifdef HAVE_ZLIB
+readerror:
+#endif
        if (i < 0) {
                fprintf(stderr, "Tape read error while ");
                switch (curfile.action) {
@@ -1298,12 +1360,19 @@ getmore:
 #endif
                        seek_failed = (lseek(mt, i, SEEK_CUR) == (off_t)-1);
 
-               if (seek_failed)
-                       err(1, "continuation failed");
+               if (seek_failed) {
+                       warn("continuation failed");
+                       if (!yflag && !reply("assume end-of-tape and continue"))
+                               exit(1);
+                       i = 0;
+               }
        }
        /*
         * Handle end of tape.
         */
+#ifdef HAVE_ZLIB
+endoftape:
+#endif
        if (i == 0) {
                Vprintf(stdout, "End-of-tape encountered\n");
                if (!pipein) {
@@ -1321,7 +1390,7 @@ getmore:
                memmove(&tapebuf[rd], &endoftapemark, TP_BSIZE);
        }
        blkcnt = 0;
-       memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], TP_BSIZE);
+       memmove(buf, &tbufptr[(blkcnt++ * TP_BSIZE)], TP_BSIZE);
        blksread++;
        tpblksread++;
 }
@@ -1348,6 +1417,7 @@ findtapeblksize(void)
                                (long)i, TP_BSIZE);
        ntrec = i / TP_BSIZE;
        numtrec = ntrec;
+       tbufptr = tapebuf;
        Vprintf(stdout, "Tape block size is %ld\n", ntrec);
 }
 
@@ -1785,9 +1855,11 @@ swabi(u_int x)
        return (x);
 }
 
+#if 0
 static u_long
 swabl(u_long x)
 {
        swabst((u_char *)"l", (u_char *)&x);
        return (x);
 }
+#endif