X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=restore%2Ftape.c;h=f5a8d556b9f2299d7b34057aa2dd5ea4c55715f6;hb=95c74f382492999827000f544fcb6844150cda81;hp=63eae65ef23cf95a29dd747bed9f3e0a08496bd2;hpb=816bf0d9a643ed425d9677064d58b626d7df7b70;p=dump.git diff --git a/restore/tape.c b/restore/tape.c index 63eae65..f5a8d55 100644 --- a/restore/tape.c +++ b/restore/tape.c @@ -46,10 +46,11 @@ #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.37 2001/04/27 15:22:47 stelian Exp $"; #endif /* not lint */ #include +#include #include #include #include @@ -82,6 +83,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 +151,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 @@ -248,7 +252,7 @@ void setup(void) { int i, j, *ip; - struct stat stbuf; + struct STAT stbuf; struct mtget mt_stat; Vprintf(stdout, "Verify tape and initialize maps\n"); @@ -260,7 +264,7 @@ setup(void) if (pipein) mt = 0; else - mt = open(magtape, O_RDONLY, 0); + mt = OPEN(magtape, O_RDONLY, 0); if (mt < 0) err(1, "%s", magtape); volno = 1; @@ -271,7 +275,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"); @@ -319,7 +328,7 @@ setup(void) } dumptime = spcl.c_ddate; dumpdate = spcl.c_date; - if (stat(".", &stbuf) < 0) + if (STAT(".", &stbuf) < 0) err(1, "cannot stat ."); if (stbuf.st_blksize > 0 && stbuf.st_blksize < TP_BSIZE ) fssize = TP_BSIZE; @@ -462,7 +471,7 @@ again: mt = rmtopen(magtape, 0); else #endif - mt = open(magtape, O_RDONLY, 0); + mt = OPEN(magtape, O_RDONLY, 0); if (mt == -1) { fprintf(stderr, "Cannot open %s\n", magtape); @@ -730,7 +739,7 @@ extractfile(char *name) } if (uflag) (void)unlink(name); - if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC, + if ((ofile = OPEN(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { warn("%s: cannot create file", name); skipfile(); @@ -838,8 +847,17 @@ 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); + while (size > 0) { + size_t skp = size > TP_BSIZE ? TP_BSIZE : size; + (*skip)(clearedbuf, skp); + size -= skp; + } + last_write_was_hole = 1; + } if (last_write_was_hole) { - ftruncate(ofile, origsize); + FTRUNCATE(ofile, origsize); } findinode(&spcl); gettingfile = 0; @@ -867,7 +885,7 @@ static void xtrskip(char *buf, size_t size) { - if (lseek(ofile, (off_t)size, SEEK_CUR) == -1) + if (LSEEK(ofile, (off_t)size, SEEK_CUR) == -1) err(1, "seek error extracting inode %lu, name %s\nlseek", (unsigned long)curfile.ino, curfile.name); } @@ -1025,12 +1043,12 @@ int #else void #endif -cmpfiles(char *tapefile, char *diskfile, struct stat *sbuf_disk) +cmpfiles(char *tapefile, char *diskfile, struct STAT *sbuf_disk) { - struct stat sbuf_tape; + struct STAT sbuf_tape; int fd_tape, fd_disk; - if (stat(tapefile, &sbuf_tape) != 0) { + if (STAT(tapefile, &sbuf_tape) != 0) { panic("Can't lstat tmp file %s: %s\n", tapefile, strerror(errno)); compare_errors = 1; @@ -1048,11 +1066,11 @@ cmpfiles(char *tapefile, char *diskfile, struct stat *sbuf_disk) #endif } - if ((fd_tape = open(tapefile, O_RDONLY)) < 0) { + if ((fd_tape = OPEN(tapefile, O_RDONLY)) < 0) { panic("Can't open %s: %s\n", tapefile, strerror(errno)); compare_errors = 1; } - if ((fd_disk = open(diskfile, O_RDONLY)) < 0) { + if ((fd_disk = OPEN(diskfile, O_RDONLY)) < 0) { close(fd_tape); panic("Can't open %s: %s\n", diskfile, strerror(errno)); compare_errors = 1; @@ -1107,14 +1125,14 @@ void comparefile(char *name) { int mode; - struct stat sb; + struct STAT sb; int r; #if !COMPARE_ONTHEFLY static char *tmpfile = NULL; - struct stat stemp; + struct STAT stemp; #endif - if ((r = lstat(name, &sb)) != 0) { + if ((r = LSTAT(name, &sb)) != 0) { warn("%s: does not exist (%d)", name, r); compare_errors = 1; skipfile(); @@ -1207,7 +1225,7 @@ comparefile(char *name) case IFREG: #if COMPARE_ONTHEFLY - if ((ifile = open(name, O_RDONLY)) < 0) { + if ((ifile = OPEN(name, O_RDONLY)) < 0) { panic("Can't open %s: %s\n", name, strerror(errno)); skipfile(); compare_errors = 1; @@ -1233,11 +1251,11 @@ comparefile(char *name) snprintf(tmpfilename, sizeof(tmpfilename), "%s/restoreCXXXXXX", tmpdir); tmpfile = mktemp(&tmpfilename[0]); } - if ((stat(tmpfile, &stemp) == 0) && (unlink(tmpfile) != 0)) { + if ((STAT(tmpfile, &stemp) == 0) && (unlink(tmpfile) != 0)) { panic("cannot delete tmp file %s: %s\n", tmpfile, strerror(errno)); } - if ((ofile = open(tmpfile, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) { + if ((ofile = OPEN(tmpfile, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) { panic("cannot create file temp file %s: %s\n", name, strerror(errno)); } @@ -1317,8 +1335,6 @@ readtape(char *buf) if (numtrec == 0) numtrec = ntrec; cnt = ntrec * TP_BSIZE; - if (zflag) - cnt += PREFIXSIZE; rd = 0; getmore: #ifdef RRESTORE @@ -1388,7 +1404,7 @@ getmore: seek_failed = (rmtseek(i, 1) < 0); else #endif - seek_failed = (lseek(mt, i, SEEK_CUR) == (off_t)-1); + seek_failed = (LSEEK(mt, i, SEEK_CUR) == (off_t)-1); if (seek_failed) { warn("continuation failed"); @@ -1631,12 +1647,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 +1724,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 +1771,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 +1803,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 +2114,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 +2272,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 */