386BSD 0.1 development
[unix-history] / usr / src / sbin / restore / tape.c
index 2895710..f8694e5 100644 (file)
@@ -1,22 +1,55 @@
-#ifndef lint
-static char sccsid[] = "@(#)tape.c     3.28    (Berkeley)      85/04/23";
-#endif
+/*
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
 
-/* Copyright (c) 1983 Regents of the University of California */
+#ifndef lint
+static char sccsid[] = "@(#)tape.c     5.21 (Berkeley) 2/22/91";
+#endif /* not lint */
 
 #include "restore.h"
 
 #include "restore.h"
-#include <dumprestor.h>
+#include <protocols/dumprestore.h>
 #include <sys/ioctl.h>
 #include <sys/mtio.h>
 #include <sys/file.h>
 #include <setjmp.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/mtio.h>
 #include <sys/file.h>
 #include <setjmp.h>
 #include <sys/stat.h>
+#include "pathnames.h"
 
 static long    fssize = MAXBSIZE;
 static int     mt = -1;
 static int     pipein = 0;
 static char    magtape[BUFSIZ];
 static int     bct;
 
 static long    fssize = MAXBSIZE;
 static int     mt = -1;
 static int     pipein = 0;
 static char    magtape[BUFSIZ];
 static int     bct;
+static int     numtrec;
 static char    *tbf;
 static union   u_spcl endoftapemark;
 static long    blksread;
 static char    *tbf;
 static union   u_spcl endoftapemark;
 static long    blksread;
@@ -29,15 +62,20 @@ static char *map;
 static char    lnkbuf[MAXPATHLEN + 1];
 static int     pathlen;
 
 static char    lnkbuf[MAXPATHLEN + 1];
 static int     pathlen;
 
+int            Bcvt;           /* Swap Bytes (for CCI or sun) */
+static int     Qcvt;           /* Swap quads (for sun) */
+u_long         swabl();
 /*
  * Set up an input source
  */
 setinput(source)
        char *source;
 {
 /*
  * Set up an input source
  */
 setinput(source)
        char *source;
 {
+       extern int errno;
 #ifdef RRESTORE
        char *host, *tape;
 #endif RRESTORE
 #ifdef RRESTORE
        char *host, *tape;
 #endif RRESTORE
+       char *strerror();
 
        flsht();
        if (bflag)
 
        flsht();
        if (bflag)
@@ -64,12 +102,14 @@ nohost:
                 * Since input is coming from a pipe we must establish
                 * our own connection to the terminal.
                 */
                 * Since input is coming from a pipe we must establish
                 * our own connection to the terminal.
                 */
-               terminal = fopen("/dev/tty", "r");
+               terminal = fopen(_PATH_TTY, "r");
                if (terminal == NULL) {
                if (terminal == NULL) {
-                       perror("Cannot open(\"/dev/tty\")");
-                       terminal = fopen("/dev/null", "r");
+                       (void)fprintf(stderr, "Cannot open %s: %s\n",
+                           _PATH_TTY, strerror(errno));
+                       terminal = fopen(_PATH_DEVNULL, "r");
                        if (terminal == NULL) {
                        if (terminal == NULL) {
-                               perror("Cannot open(\"/dev/null\")");
+                           (void)fprintf(stderr, "Cannot open %s: %s\n",
+                               _PATH_DEVNULL, strerror(errno));
                                done(1);
                        }
                }
                                done(1);
                        }
                }
@@ -105,7 +145,6 @@ setup()
 {
        int i, j, *ip;
        struct stat stbuf;
 {
        int i, j, *ip;
        struct stat stbuf;
-       extern char *ctime();
        extern int xtrmap(), xtrmapskip();
 
        vprintf(stdout, "Verify tape and initialize maps\n");
        extern int xtrmap(), xtrmapskip();
 
        vprintf(stdout, "Verify tape and initialize maps\n");
@@ -145,10 +184,8 @@ setup()
                while (--j);
                endoftapemark.s_spcl.c_checksum = CHECKSUM - i;
        }
                while (--j);
                endoftapemark.s_spcl.c_checksum = CHECKSUM - i;
        }
-       if (vflag || command == 't') {
-               fprintf(stdout, "Dump   date: %s", ctime(&spcl.c_date));
-               fprintf(stdout, "Dumped from: %s", ctime(&spcl.c_ddate));
-       }
+       if (vflag || command == 't')
+               printdumpinfo();
        dumptime = spcl.c_ddate;
        dumpdate = spcl.c_date;
        if (stat(".", &stbuf) < 0) {
        dumptime = spcl.c_ddate;
        dumpdate = spcl.c_date;
        if (stat(".", &stbuf) < 0) {
@@ -167,7 +204,7 @@ setup()
        }
        if (readhdr(&spcl) == FAIL)
                panic("no header after volume mark!\n");
        }
        if (readhdr(&spcl) == FAIL)
                panic("no header after volume mark!\n");
-       findinode(&spcl, 1);
+       findinode(&spcl);
        if (checktype(&spcl, TS_CLRI) == FAIL) {
                fprintf(stderr, "Cannot find file removal list\n");
                done(1);
        if (checktype(&spcl, TS_CLRI) == FAIL) {
                fprintf(stderr, "Cannot find file removal list\n");
                done(1);
@@ -206,6 +243,8 @@ getvol(nextvol)
        long savecnt, i;
        union u_spcl tmpspcl;
 #      define tmpbuf tmpspcl.s_spcl
        long savecnt, i;
        union u_spcl tmpspcl;
 #      define tmpbuf tmpspcl.s_spcl
+       char buf[TP_BSIZE];
+       extern char *ctime();
 
        if (nextvol == 1) {
                tapesread = 0;
 
        if (nextvol == 1) {
                tapesread = 0;
@@ -263,11 +302,22 @@ again:
        }
        closemt();
        fprintf(stderr, "Mount tape volume %d\n", newvol);
        }
        closemt();
        fprintf(stderr, "Mount tape volume %d\n", newvol);
-       fprintf(stderr, "then enter tape name (default: %s) ", magtape);
+       fprintf(stderr, "Enter ``none'' if there are no more tapes\n");
+       fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape);
        (void) fflush(stderr);
        (void) fgets(tbf, BUFSIZ, terminal);
        if (feof(terminal))
                done(1);
        (void) fflush(stderr);
        (void) fgets(tbf, BUFSIZ, terminal);
        if (feof(terminal))
                done(1);
+       if (!strcmp(tbf, "none\n")) {
+               curfile.name = "<name unknown>";
+               curfile.action = UNKNOWN;
+               curfile.dip = (struct dinode *)NIL;
+               curfile.ino = maxino;
+               if (gettingfile) {
+                       gettingfile = 0;
+                       longjmp(restart, 1);
+               }
+       }
        if (tbf[0] != '\n') {
                (void) strcpy(magtape, tbf);
                magtape[strlen(magtape) - 1] = '\0';
        if (tbf[0] != '\n') {
                (void) strcpy(magtape, tbf);
                magtape[strlen(magtape) - 1] = '\0';
@@ -310,8 +360,14 @@ gethdr:
                        panic("active file into volume 1\n");
                return;
        }
                        panic("active file into volume 1\n");
                return;
        }
+       /*
+        * Skip up to the beginning of the next record
+        */
+       if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER))
+               for (i = tmpbuf.c_count; i > 0; i--)
+                       readtape(buf);
        (void) gethead(&spcl);
        (void) gethead(&spcl);
-       findinode(&spcl, curfile.action == UNKNOWN ? 1 : 0);
+       findinode(&spcl);
        if (gettingfile) {
                gettingfile = 0;
                longjmp(restart, 1);
        if (gettingfile) {
                gettingfile = 0;
                longjmp(restart, 1);
@@ -342,19 +398,35 @@ setdumpnum()
 #endif
 }
 
 #endif
 }
 
+printdumpinfo()
+{
+       extern char *ctime();
+
+       fprintf(stdout, "Dump   date: %s", ctime(&spcl.c_date));
+       fprintf(stdout, "Dumped from: %s",
+           (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&spcl.c_ddate));
+       if (spcl.c_host[0] == '\0')
+               return;
+       fprintf(stderr, "Level %d dump of %s on %s:%s\n",
+               spcl.c_level, spcl.c_filesys, spcl.c_host, spcl.c_dev);
+       fprintf(stderr, "Label: %s\n", spcl.c_label);
+}
+
 extractfile(name)
        char *name;
 {
        int mode;
 extractfile(name)
        char *name;
 {
        int mode;
-       time_t timep[2];
+       struct timeval timep[2];
        struct entry *ep;
        extern int xtrlnkfile(), xtrlnkskip();
        extern int xtrfile(), xtrskip();
 
        curfile.name = name;
        curfile.action = USING;
        struct entry *ep;
        extern int xtrlnkfile(), xtrlnkskip();
        extern int xtrfile(), xtrskip();
 
        curfile.name = name;
        curfile.action = USING;
-       timep[0] = curfile.dip->di_atime;
-       timep[1] = curfile.dip->di_mtime;
+       timep[0].tv_sec = curfile.dip->di_atime;
+       timep[0].tv_usec = 0;
+       timep[1].tv_sec = curfile.dip->di_mtime;
+       timep[1].tv_usec = 0;
        mode = curfile.dip->di_mode;
        switch (mode & IFMT) {
 
        mode = curfile.dip->di_mode;
        switch (mode & IFMT) {
 
@@ -363,6 +435,11 @@ extractfile(name)
                skipfile();
                return (FAIL);
 
                skipfile();
                return (FAIL);
 
+       case IFSOCK:
+               vprintf(stdout, "skipped socket %s\n", name);
+               skipfile();
+               return (GOOD);
+
        case IFDIR:
                if (mflag) {
                        ep = lookupname(name);
        case IFDIR:
                if (mflag) {
                        ep = lookupname(name);
@@ -388,6 +465,10 @@ extractfile(name)
        case IFCHR:
        case IFBLK:
                vprintf(stdout, "extract special file %s\n", name);
        case IFCHR:
        case IFBLK:
                vprintf(stdout, "extract special file %s\n", name);
+               if (Nflag) {
+                       skipfile();
+                       return (GOOD);
+               }
                if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) {
                        fprintf(stderr, "%s: ", name);
                        (void) fflush(stderr);
                if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) {
                        fprintf(stderr, "%s: ", name);
                        (void) fflush(stderr);
@@ -398,11 +479,15 @@ extractfile(name)
                (void) chown(name, curfile.dip->di_uid, curfile.dip->di_gid);
                (void) chmod(name, mode);
                skipfile();
                (void) chown(name, curfile.dip->di_uid, curfile.dip->di_gid);
                (void) chmod(name, mode);
                skipfile();
-               utime(name, timep);
+               utimes(name, timep);
                return (GOOD);
 
        case IFREG:
                vprintf(stdout, "extract file %s\n", name);
                return (GOOD);
 
        case IFREG:
                vprintf(stdout, "extract file %s\n", name);
+               if (Nflag) {
+                       skipfile();
+                       return (GOOD);
+               }
                if ((ofile = creat(name, 0666)) < 0) {
                        fprintf(stderr, "%s: ", name);
                        (void) fflush(stderr);
                if ((ofile = creat(name, 0666)) < 0) {
                        fprintf(stderr, "%s: ", name);
                        (void) fflush(stderr);
@@ -414,7 +499,7 @@ extractfile(name)
                (void) fchmod(ofile, mode);
                getfile(xtrfile, xtrskip);
                (void) close(ofile);
                (void) fchmod(ofile, mode);
                getfile(xtrfile, xtrskip);
                (void) close(ofile);
-               utime(name, timep);
+               utimes(name, timep);
                return (GOOD);
        }
        /* NOTREACHED */
                return (GOOD);
        }
        /* NOTREACHED */
@@ -454,6 +539,7 @@ getfile(f1, f2)
        off_t size = spcl.c_dinode.di_size;
        static char clearedbuf[MAXBSIZE];
        char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
        off_t size = spcl.c_dinode.di_size;
        static char clearedbuf[MAXBSIZE];
        char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
+       char junk[TP_BSIZE];
 
        if (checktype(&spcl, TS_END) == GOOD)
                panic("ran off end of tape\n");
 
        if (checktype(&spcl, TS_END) == GOOD)
                panic("ran off end of tape\n");
@@ -482,8 +568,12 @@ loop:
                        (*f2)(clearedbuf, size > TP_BSIZE ?
                                (long) TP_BSIZE : size);
                }
                        (*f2)(clearedbuf, size > TP_BSIZE ?
                                (long) TP_BSIZE : size);
                }
-               if ((size -= TP_BSIZE) <= 0)
+               if ((size -= TP_BSIZE) <= 0) {
+                       for (i++; i < spcl.c_count; i++)
+                               if (spcl.c_addr[i])
+                                       readtape(junk);
                        break;
                        break;
+               }
        }
        if (readhdr(&spcl) == GOOD && size > 0) {
                if (checktype(&spcl, TS_ADDR) == GOOD)
        }
        if (readhdr(&spcl) == GOOD && size > 0) {
                if (checktype(&spcl, TS_ADDR) == GOOD)
@@ -493,7 +583,7 @@ loop:
        }
        if (curblk > 0)
                (*f1)(buf, (curblk * TP_BSIZE) + size);
        }
        if (curblk > 0)
                (*f1)(buf, (curblk * TP_BSIZE) + size);
-       findinode(&spcl, 1);
+       findinode(&spcl);
        gettingfile = 0;
 }
 
        gettingfile = 0;
 }
 
@@ -506,6 +596,8 @@ xtrfile(buf, size)
        long    size;
 {
 
        long    size;
 {
 
+       if (Nflag)
+               return;
        if (write(ofile, buf, (int) size) == -1) {
                fprintf(stderr, "write error extracting inode %d, name %s\n",
                        curfile.ino, curfile.name);
        if (write(ofile, buf, (int) size) == -1) {
                fprintf(stderr, "write error extracting inode %d, name %s\n",
                        curfile.ino, curfile.name);
@@ -591,14 +683,16 @@ readtape(b)
        long rd, newvol;
        int cnt;
 
        long rd, newvol;
        int cnt;
 
-       if (bct < ntrec) {
+top:
+       if (bct < numtrec) {
                bcopy(&tbf[(bct++*TP_BSIZE)], b, (long)TP_BSIZE);
                blksread++;
                return;
        }
        for (i = 0; i < ntrec; i++)
                ((struct s_spcl *)&tbf[i*TP_BSIZE])->c_magic = 0;
                bcopy(&tbf[(bct++*TP_BSIZE)], b, (long)TP_BSIZE);
                blksread++;
                return;
        }
        for (i = 0; i < ntrec; i++)
                ((struct s_spcl *)&tbf[i*TP_BSIZE])->c_magic = 0;
-       bct = 0;
+       if (numtrec == 0)
+               numtrec = ntrec;
        cnt = ntrec*TP_BSIZE;
        rd = 0;
 getmore:
        cnt = ntrec*TP_BSIZE;
        rd = 0;
 getmore:
@@ -607,6 +701,17 @@ getmore:
 #else
        i = read(mt, &tbf[rd], cnt);
 #endif
 #else
        i = read(mt, &tbf[rd], cnt);
 #endif
+       /*
+        * Check for mid-tape short read error.
+        * If found, return rest of buffer.
+        */
+       if (numtrec < ntrec && i != 0) {
+               numtrec = ntrec;
+               goto top;
+       }
+       /*
+        * Handle partial block read.
+        */
        if (i > 0 && i != ntrec*TP_BSIZE) {
                if (pipein) {
                        rd += i;
        if (i > 0 && i != ntrec*TP_BSIZE) {
                if (pipein) {
                        rd += i;
@@ -618,10 +723,12 @@ getmore:
                        if (i % TP_BSIZE != 0)
                                panic("partial block read: %d should be %d\n",
                                        i, ntrec * TP_BSIZE);
                        if (i % TP_BSIZE != 0)
                                panic("partial block read: %d should be %d\n",
                                        i, ntrec * TP_BSIZE);
-                       bcopy((char *)&endoftapemark, &tbf[i],
-                               (long)TP_BSIZE);
+                       numtrec = i / TP_BSIZE;
                }
        }
                }
        }
+       /*
+        * Handle read error.
+        */
        if (i < 0) {
                fprintf(stderr, "Tape read error while ");
                switch (curfile.action) {
        if (i < 0) {
                fprintf(stderr, "Tape read error while ");
                switch (curfile.action) {
@@ -629,7 +736,7 @@ getmore:
                        fprintf(stderr, "trying to set up tape\n");
                        break;
                case UNKNOWN:
                        fprintf(stderr, "trying to set up tape\n");
                        break;
                case UNKNOWN:
-                       fprintf(stderr, "trying to resyncronize\n");
+                       fprintf(stderr, "trying to resynchronize\n");
                        break;
                case USING:
                        fprintf(stderr, "restoring %s\n", curfile.name);
                        break;
                case USING:
                        fprintf(stderr, "restoring %s\n", curfile.name);
@@ -653,10 +760,14 @@ getmore:
                        done(1);
                }
        }
                        done(1);
                }
        }
+       /*
+        * Handle end of tape.
+        */
        if (i == 0) {
                if (!pipein) {
                        newvol = volno + 1;
                        volno = 0;
        if (i == 0) {
                if (!pipein) {
                        newvol = volno + 1;
                        volno = 0;
+                       numtrec = 0;
                        getvol(newvol);
                        readtape(b);
                        return;
                        getvol(newvol);
                        readtape(b);
                        return;
@@ -666,6 +777,7 @@ getmore:
                                rd, ntrec * TP_BSIZE);
                bcopy((char *)&endoftapemark, &tbf[rd], (long)TP_BSIZE);
        }
                                rd, ntrec * TP_BSIZE);
                bcopy((char *)&endoftapemark, &tbf[rd], (long)TP_BSIZE);
        }
+       bct = 0;
        bcopy(&tbf[(bct++*TP_BSIZE)], b, (long)TP_BSIZE);
        blksread++;
 }
        bcopy(&tbf[(bct++*TP_BSIZE)], b, (long)TP_BSIZE);
        blksread++;
 }
@@ -692,6 +804,7 @@ findtapeblksize()
                done(1);
        }
        ntrec = i / TP_BSIZE;
                done(1);
        }
        ntrec = i / TP_BSIZE;
+       numtrec = ntrec;
        vprintf(stdout, "Tape block size is %d\n", ntrec);
 }
 
        vprintf(stdout, "Tape block size is %d\n", ntrec);
 }
 
@@ -771,8 +884,18 @@ gethead(buf)
 
        if (!cvtflag) {
                readtape((char *)buf);
 
        if (!cvtflag) {
                readtape((char *)buf);
-               if (buf->c_magic != NFS_MAGIC || checksum((int *)buf) == FAIL)
-                       return(FAIL);
+               if (buf->c_magic != NFS_MAGIC) {
+                       if (swabl(buf->c_magic) != NFS_MAGIC)
+                               return (FAIL);
+                       if (!Bcvt) {
+                               vprintf(stdout, "Note: Doing Byte swapping\n");
+                               Bcvt = 1;
+                       }
+               }
+               if (checksum((int *)buf) == FAIL)
+                       return (FAIL);
+               if (Bcvt)
+                       swabst("8l4s31l", (char *)buf);
                goto good;
        }
        readtape((char *)(&u_ospcl.s_ospcl));
                goto good;
        }
        readtape((char *)(&u_ospcl.s_ospcl));
@@ -802,6 +925,19 @@ gethead(buf)
        buf->c_magic = NFS_MAGIC;
 
 good:
        buf->c_magic = NFS_MAGIC;
 
 good:
+       if (buf->c_dinode.di_size == 0 &&
+           (buf->c_dinode.di_mode & IFMT) == IFDIR && Qcvt == 0) {
+               if (buf->c_dinode.di_qsize.val[0] ||
+                   buf->c_dinode.di_qsize.val[1]) {
+                       printf("Note: Doing Quad swapping\n");
+                       Qcvt = 1;
+               }
+       }
+       if (Qcvt) {
+               i = buf->c_dinode.di_qsize.val[1];
+               buf->c_dinode.di_qsize.val[1] = buf->c_dinode.di_qsize.val[0];
+               buf->c_dinode.di_qsize.val[0] = i;
+       }
        switch (buf->c_type) {
 
        case TS_CLRI:
        switch (buf->c_type) {
 
        case TS_CLRI:
@@ -846,6 +982,7 @@ accthdr(header)
 
        if (header->c_type == TS_TAPE) {
                fprintf(stderr, "Volume header\n");
 
        if (header->c_type == TS_TAPE) {
                fprintf(stderr, "Volume header\n");
+               previno = 0x7fffffff;
                return;
        }
        if (previno == 0x7fffffff)
                return;
        }
        if (previno == 0x7fffffff)
@@ -887,11 +1024,12 @@ newcalc:
  * Find an inode header.
  * Complain if had to skip, and complain is set.
  */
  * Find an inode header.
  * Complain if had to skip, and complain is set.
  */
-findinode(header, complain)
+findinode(header)
        struct s_spcl *header;
        struct s_spcl *header;
-       int complain;
 {
        static long skipcnt = 0;
 {
        static long skipcnt = 0;
+       long i;
+       char buf[TP_BSIZE];
 
        curfile.name = "<name unknown>";
        curfile.action = UNKNOWN;
 
        curfile.name = "<name unknown>";
        curfile.action = UNKNOWN;
@@ -899,10 +1037,20 @@ findinode(header, complain)
        curfile.ino = 0;
        if (ishead(header) == FAIL) {
                skipcnt++;
        curfile.ino = 0;
        if (ishead(header) == FAIL) {
                skipcnt++;
-               while (gethead(header) == FAIL)
+               while (gethead(header) == FAIL || header->c_date != dumpdate)
                        skipcnt++;
        }
        for (;;) {
                        skipcnt++;
        }
        for (;;) {
+               if (checktype(header, TS_ADDR) == GOOD) {
+                       /*
+                        * Skip up to the beginning of the next record
+                        */
+                       for (i = 0; i < header->c_count; i++)
+                               if (header->c_addr[i])
+                                       readtape(buf);
+                       (void) gethead(header);
+                       continue;
+               }
                if (checktype(header, TS_INODE) == GOOD) {
                        curfile.dip = &header->c_dinode;
                        curfile.ino = header->c_inumber;
                if (checktype(header, TS_INODE) == GOOD) {
                        curfile.dip = &header->c_dinode;
                        curfile.ino = header->c_inumber;
@@ -923,7 +1071,7 @@ findinode(header, complain)
                while (gethead(header) == FAIL)
                        skipcnt++;
        }
                while (gethead(header) == FAIL)
                        skipcnt++;
        }
-       if (skipcnt > 0 && complain)
+       if (skipcnt > 0)
                fprintf(stderr, "resync restore, skipped %d blocks\n", skipcnt);
        skipcnt = 0;
 }
                fprintf(stderr, "resync restore, skipped %d blocks\n", skipcnt);
        skipcnt = 0;
 }
@@ -957,9 +1105,18 @@ checksum(b)
 
        j = sizeof(union u_spcl) / sizeof(int);
        i = 0;
 
        j = sizeof(union u_spcl) / sizeof(int);
        i = 0;
-       do
-               i += *b++;
-       while (--j);
+       if(!Bcvt) {
+               do
+                       i += *b++;
+               while (--j);
+       } else {
+               /* What happens if we want to read restore tapes
+                       for a 16bit int machine??? */
+               do 
+                       i += swabl(*b++);
+               while (--j);
+       }
+                       
        if (i != CHECKSUM) {
                fprintf(stderr, "Checksum error %o, inode %d file %s\n", i,
                        curfile.ino, curfile.name);
        if (i != CHECKSUM) {
                fprintf(stderr, "Checksum error %o, inode %d file %s\n", i,
                        curfile.ino, curfile.name);
@@ -977,3 +1134,76 @@ msg(cp, a1, a2, a3)
        fprintf(stderr, cp, a1, a2, a3);
 }
 #endif RRESTORE
        fprintf(stderr, cp, a1, a2, a3);
 }
 #endif RRESTORE
+
+u_char *
+swabshort(sp, n)
+       register u_char *sp;
+       register int n;
+{
+       char c;
+
+       while (--n >= 0) {
+               c = sp[0]; sp[0] = sp[1]; sp[1] = c;
+               sp += 2;
+       }
+       return (sp);
+}
+
+u_char *
+swablong(sp, n)
+       register u_char *sp;
+       register int n;
+{
+       char c;
+
+       while (--n >= 0) {
+               c = sp[0]; sp[0] = sp[3]; sp[3] = c;
+               c = sp[2]; sp[2] = sp[1]; sp[1] = c;
+               sp += 4;
+       }
+       return (sp);
+}
+
+swabst(cp, sp)
+       register u_char *cp, *sp;
+{
+       int n = 0;
+       u_char c;
+
+       while (*cp) {
+               switch (*cp) {
+               case '0': case '1': case '2': case '3': case '4':
+               case '5': case '6': case '7': case '8': case '9':
+                       n = (n * 10) + (*cp++ - '0');
+                       continue;
+               
+               case 's': case 'w': case 'h':
+                       if (n == 0)
+                               n = 1;
+                       sp = swabshort(sp, n);
+                       break;
+
+               case 'l':
+                       if (n == 0)
+                               n = 1;
+                       sp = swablong(sp, n);
+                       break;
+
+               default: /* Any other character, like 'b' counts as byte. */
+                       if (n == 0)
+                               n = 1;
+                       sp += n;
+                       break;
+               }
+               cp++;
+               n = 0;
+       }
+}
+
+u_long
+swabl(x)
+       u_long x;
+{
+       swabst("l", (char *)&x);
+       return (x);
+}