]> git.wh0rd.org - dump.git/blobdiff - restore/tape.c
LFS fixes (explicit use of open64/etc)
[dump.git] / restore / tape.c
index 1bb6d8c2d45192a6e023e85fed08b2f6962bebc7..f5a8d556b9f2299d7b34057aa2dd5ea4c55715f6 100644 (file)
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.28 2001/03/20 09:14:58 stelian Exp $";
+       "$Id: tape.c,v 1.37 2001/04/27 15:22:47 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
+#include <compatlfs.h>
 #include <errno.h>
 #include <compaterr.h>
 #include <setjmp.h>
@@ -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 = creat(tmpfile, 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");
@@ -1742,8 +1760,8 @@ findtapeblksize(void)
                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;
@@ -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;
 
@@ -1981,7 +2000,7 @@ good:
 static void
 accthdr(struct s_spcl *header)
 {
-       static ino_t previno = 0x7fffffff;
+       static dump_ino_t previno = 0x7fffffff;
        static int prevtype;
        static long predict;
        long blks, i;
@@ -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 */