#ifndef lint
static const char rcsid[] =
- "$Id: tape.c,v 1.30 2001/03/20 20:39:36 stelian Exp $";
+ "$Id: tape.c,v 1.36 2001/04/27 12:23:23 stelian Exp $";
#endif /* not lint */
#include <config.h>
#include "extern.h"
#include "pathnames.h"
+#ifdef USE_QFA
+int noresyncmesg = 0;
+#endif /* USE_QFA */
static long fssize = MAXBSIZE;
static int mt = -1;
static int pipein = 0;
static char *decompress_tapebuf __P((struct tapebuf *, int));
static void msg_read_error __P((char *));
#endif
-static int read_a_block __P((int, void *, size_t, long *));
+static int read_a_block __P((int, char *, size_t, long *));
#define PREFIXSIZE sizeof(struct tapebuf)
#define COMPARE_ONTHEFLY 1
magtapein = rmtioctl(MTNOP, 1) != -1;
else
#endif
- magtapein = ioctl(mt, MTIOCGET, (char *) &mt_stat) == 0;
+ if (ioctl(mt, MTIOCGET, (char *) &mt_stat) == 0) {
+ if (mt_stat.mt_dsreg & 0xffff)
+ magtapein = 1; /* fixed blocksize */
+ else
+ magtapein = 2; /* variable blocksize */
+ }
}
Vprintf(stdout,"Input is from %s\n", magtapein? "tape": "file/pipe");
(*fill)((char *)buf, (size_t)(curblk * TP_BSIZE) + size);
last_write_was_hole = 0;
}
+ if (size > 0) {
+ fprintf(stderr, "Missing blocks at the end of %s, assuming hole\n", curfile.name);
+ (*skip)(clearedbuf, size);
+ last_write_was_hole = 1;
+ }
if (last_write_was_hole) {
ftruncate(ofile, origsize);
}
if (numtrec == 0)
numtrec = ntrec;
cnt = ntrec * TP_BSIZE;
- if (zflag)
- cnt += PREFIXSIZE;
rd = 0;
getmore:
#ifdef RRESTORE
}
switch (cresult) {
case Z_OK:
- if (worklen != ntrec * TP_BSIZE) {
- /* short block, shouldn't happen, but... */
+ numtrec = worklen / TP_BSIZE;
+ if (worklen % TP_BSIZE != 0)
reason = "length mismatch";
- if (worklen % TP_BSIZE == 0)
- numtrec = worklen / TP_BSIZE;
- }
break;
case Z_MEM_ERROR:
reason = "not enough memory";
* For a pipe or file, read in the first record. For a tape, read
* the first block.
*/
- len = magtapein ? bufsize + PREFIXSIZE: TP_BSIZE;
+ if (magtapein == 1) /* fixed blocksize tape, not compressed */
+ len = ntrec * TP_BSIZE;
+ else if (magtapein == 2)/* variable blocksize tape */
+ len = bufsize + PREFIXSIZE;
+ else /* not mag tape */
+ len = TP_BSIZE;
if (read_a_block(mt, tapebuf, len, &i) <= 0)
errx(1, "Tape read error on first record");
else {
/* read in the rest of the block based on bufsize */
len = bufsize - TP_BSIZE;
- if (read_a_block(mt, tapebuf+TP_BSIZE, len, &i) <= 0
- || i != len)
+ if (read_a_block(mt, tapebuf+TP_BSIZE, len, &i) < 0
+ || (i != len && i % TP_BSIZE != 0))
errx(1,"Error reading dump file header");
tbufptr = tapebuf;
numtrec = ntrec;
}
/*
- * If the input is a tape, we tried to read PREFIXSIZE +
- * ntrec * TP_BSIZE bytes. If it's not a compressed dump tape
- * or the value of ntrec is too large, we have read less than
- * what we asked for; adjust the value of ntrec and test for
- * a compressed dump tape prefix.
+ * If the input is a variable block size tape, we tried to
+ * read PREFIXSIZE + ntrec * TP_BSIZE bytes.
+ * If it's not a compressed dump tape or the value of ntrec is
+ * too large, we have read less than * what we asked for;
+ * adjust the value of ntrec and test for * a compressed dump
+ * tape prefix.
*/
if (i % TP_BSIZE != 0) {
/*
* Read a block of data handling all of the messy details.
*/
-static int read_a_block(int fd, void *buf, size_t len, long *lengthread)
+static int read_a_block(int fd, char *buf, size_t len, long *lengthread)
{
long i = 1, size;
}
} while (header->c_type == TS_ADDR);
if (skipcnt > 0)
- fprintf(stderr, "resync restore, skipped %ld blocks\n",
- skipcnt);
+#ifdef USE_QFA
+ if (!noresyncmesg)
+#endif
+ fprintf(stderr, "resync restore, skipped %ld blocks\n",
+ skipcnt);
skipcnt = 0;
}
return (x);
}
#endif
+
+#ifdef USE_QFA
+/*
+ * get the current position of the tape
+ */
+int
+GetTapePos(long *pos)
+{
+ int err = 0;
+
+ *pos = 0;
+ if (ioctl(mt, MTIOCPOS, pos) == -1) {
+ err = errno;
+ fprintf(stdout, "[%ld] error: %d (getting tapepos: %ld)\n",
+ (unsigned long)getpid(), err, *pos);
+ return err;
+ }
+ return err;
+}
+
+typedef struct mt_pos {
+ short mt_op;
+ int mt_count;
+} MTPosRec, *MTPosPtr;
+
+/*
+ * go to specified position on tape
+ */
+int
+GotoTapePos(long pos)
+{
+ int err = 0;
+ struct mt_pos buf;
+
+ buf.mt_op = MTSEEK;
+ buf.mt_count = pos;
+ if (ioctl(mt, MTIOCTOP, &buf) == -1) {
+ err = errno;
+ fprintf(stdout, "[%ld] error: %d (setting tapepos: %ld)\n",
+ (unsigned long)getpid(), err, pos);
+ return err;
+ }
+ return err;
+}
+
+/*
+ * read next data from tape to re-sync
+ */
+void
+ReReadFromTape(void)
+{
+ FLUSHTAPEBUF();
+ noresyncmesg = 1;
+ if (gethead(&spcl) == FAIL) {
+#ifdef DEBUG_QFA
+ fprintf(stdout, "DEBUG 1 gethead failed\n");
+#endif
+ }
+ findinode(&spcl);
+ noresyncmesg = 0;
+}
+
+void
+RequestVol(long tnum)
+{
+ FLUSHTAPEBUF();
+ getvol(tnum);
+}
+#endif /* USE_QFA */