X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=restore%2Ftape.c;h=e5e995d71bfe9fbe7d98521a3b8744efea60f7c2;hb=871ede100ce41d967ebbb4e2d67c6b7587e16f76;hp=63eae65ef23cf95a29dd747bed9f3e0a08496bd2;hpb=816bf0d9a643ed425d9677064d58b626d7df7b70;p=dump.git diff --git a/restore/tape.c b/restore/tape.c index 63eae65..e5e995d 100644 --- a/restore/tape.c +++ b/restore/tape.c @@ -46,7 +46,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.31 2001/03/27 08:09:21 stelian Exp $"; + "$Id: tape.c,v 1.36 2001/04/27 12:23:23 stelian Exp $"; #endif /* not lint */ #include @@ -82,6 +82,9 @@ static const char rcsid[] = #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; @@ -147,7 +150,7 @@ static void readtape_comprtape __P((char *)); 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 @@ -271,7 +274,12 @@ setup(void) 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"); @@ -838,6 +846,11 @@ loop: (*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); } @@ -1317,8 +1330,6 @@ readtape(char *buf) if (numtrec == 0) numtrec = ntrec; cnt = ntrec * TP_BSIZE; - if (zflag) - cnt += PREFIXSIZE; rd = 0; getmore: #ifdef RRESTORE @@ -1631,12 +1642,9 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize) } 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"; @@ -1711,7 +1719,12 @@ findtapeblksize(void) * 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"); @@ -1753,11 +1766,12 @@ findtapeblksize(void) } /* - * 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) { @@ -1784,7 +1798,7 @@ findtapeblksize(void) /* * 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; @@ -2095,8 +2109,11 @@ findinode(struct s_spcl *header) } } 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; } @@ -2250,3 +2267,72 @@ swabl(u_long x) 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 */