#ifndef lint
static const char rcsid[] =
- "$Id: tape.c,v 1.22 2000/12/21 11:14:54 stelian Exp $";
+ "$Id: tape.c,v 1.25 2001/02/22 10:57:40 stelian Exp $";
#endif /* not lint */
#include <config.h>
#ifdef __linux__
#include <sys/time.h>
+#include <time.h>
#include <linux/ext2_fs.h>
#include <bsdcompat.h>
#else /* __linux__ */
#include <string.h>
#include <unistd.h>
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+#endif /* HAVE_ZLIB */
+
#ifdef __linux__
#include <ext2fs/ext2fs.h>
#endif
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 */
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));
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 */
}
/*
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;
{
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)
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.
/*
* Handle read error.
*/
+#ifdef HAVE_ZLIB
+readerror:
+#endif
if (i < 0) {
fprintf(stderr, "Tape read error while ");
switch (curfile.action) {
#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) {
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++;
}
(long)i, TP_BSIZE);
ntrec = i / TP_BSIZE;
numtrec = ntrec;
+ tbufptr = tapebuf;
Vprintf(stdout, "Tape block size is %ld\n", ntrec);
}
return (x);
}
+#if 0
static u_long
swabl(u_long x)
{
swabst((u_char *)"l", (u_char *)&x);
return (x);
}
+#endif