8K only dump/restor
authorKirk McKusick <mckusic@ucbvax.Berkeley.EDU>
Sun, 1 Nov 1981 10:30:56 +0000 (02:30 -0800)
committerKirk McKusick <mckusic@ucbvax.Berkeley.EDU>
Sun, 1 Nov 1981 10:30:56 +0000 (02:30 -0800)
SCCS-vsn: sbin/restore/main.c 1.3
SCCS-vsn: sbin/restore/main.c 1.3
SCCS-vsn: sbin/dump/dump.h 1.2
SCCS-vsn: sbin/dump/itime.c 1.2
SCCS-vsn: sbin/dump/traverse.c 1.2

usr/src/sbin/dump/dump.h
usr/src/sbin/dump/itime.c
usr/src/sbin/dump/traverse.c
usr/src/sbin/restore/main.c

index 1790362..2f57115 100644 (file)
@@ -1,21 +1,20 @@
 /*
 /*
- * "@(#)dump.h 1.1 (Berkeley) %G%"
+ * "@(#)dump.h 1.2 (Berkeley) %G%"
  */
 #define        NI      16
 #define        DIRPB   (BSIZE/sizeof(struct direct))
 
 #include <stdio.h>
 #include <ctype.h>
  */
 #define        NI      16
 #define        DIRPB   (BSIZE/sizeof(struct direct))
 
 #include <stdio.h>
 #include <ctype.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/filsys.h>
-#include <sys/ino.h>
-#include <sys/inode.h>
-#include <sys/fblk.h>
-#include <sys/dir.h>
+#include "../../h/param.h"
+#include "../../h/stat.h"
+#include "../../h/fs.h"
+#include "../../h/inode.h"
+#include "../../h/dir.h"
 #include <utmp.h>
 #include <time.h>
 #include <signal.h>
 #include <utmp.h>
 #include <time.h>
 #include <signal.h>
+int (*signal())();
 #include <dumprestor.h>
 #include <fstab.h>
 
 #include <dumprestor.h>
 #include <fstab.h>
 
@@ -69,6 +68,7 @@ int   dsrch();
 int    nullf();
 char   *getsuffix();
 char   *rawname();
 int    nullf();
 char   *getsuffix();
 char   *rawname();
+struct dinode *getino();
 
 int    interrupt();            /* in case operator bangs on console */
 
 
 int    interrupt();            /* in case operator bangs on console */
 
index ce559c8..28e889e 100644 (file)
@@ -1,4 +1,4 @@
-static char *sccsid = "@(#)itime.c     1.1 (Berkeley) %G%";
+static char *sccsid = "@(#)itime.c     1.2 (Berkeley) %G%";
 #include "dump.h"
 
 char *prdate(d)
 #include "dump.h"
 
 char *prdate(d)
@@ -209,6 +209,11 @@ int makeidate(ip, buf)
        return(0);
 }
 
        return(0);
 }
 
+/*
+ * This is an estimation of the size of the file.
+ * It assumes that there are no unallocated blocks; hence
+ * the estimate may be high
+ */
 est(ip)
        struct dinode *ip;
 {
 est(ip)
        struct dinode *ip;
 {
@@ -217,14 +222,11 @@ est(ip)
        esize++;
        s = (ip->di_size + BSIZE-1) / BSIZE;
        esize += s;
        esize++;
        s = (ip->di_size + BSIZE-1) / BSIZE;
        esize += s;
-       if(s > NADDR-3) {
-               /*
-                *      This code is only appproximate.
-                *      it totally estimates low on doubly and triply indirect
-                *      files.
-                */
-               s -= NADDR-3;
-               s = (s + (BSIZE/sizeof(daddr_t))-1) / (BSIZE/sizeof(daddr_t));
+       if (s > NDADDR) {
+               s -= NDADDR;
+               if (s > BSIZE / sizeof(daddr_t))
+                       esize++;
+               s = (s + (BSIZE/sizeof(daddr_t)) - 1) / (BSIZE/sizeof(daddr_t));
                esize += s;
        }
 }
                esize += s;
        }
 }
index e057d8e..9468713 100644 (file)
@@ -1,62 +1,52 @@
-static char *sccsid = "@(#)traverse.c  1.1 (Berkeley) %G%";
+static char *sccsid = "@(#)traverse.c  1.2 (Berkeley) %G%";
 #include "dump.h"
 
 #include "dump.h"
 
-struct filsys  sblock;
-struct dinode  itab[INOPB * NI];
+struct fs      sblock;
 
 pass(fn, map)
 
 pass(fn, map)
-int (*fn)();
-short *map;
+       int (*fn)();
+       short *map;
 {
 {
-       register i, j;
+       struct dinode *dp;
        int bits;
        int bits;
-       ino_t mino;
-       daddr_t d;
+       ino_t maxino;
 
        sync();
 
        sync();
-       bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
-       mino = (sblock.s_isize-2) * INOPB;
-       ino = 0;
-       for(i=2;; i+=NI) {
-               if(ino >= mino)
-                       break;
-               d = (unsigned)i;
-               for(j=0; j<INOPB*NI; j++) {
-                       if(ino >= mino)
-                               break;
-                       if((ino % MLEN) == 0) {
-                               bits = ~0;
-                               if(map != NULL)
-                                       bits = *map++;
-                       }
-                       ino++;
-                       if(bits & 1) {
-                               if(d != 0) {
-                                       bread(d, (char *)itab, sizeof(itab));
-                                       d = 0;
-                               }
-                               (*fn)(&itab[j]);
-                       }
-                       bits >>= 1;
+       bread(SBLOCK, &sblock, sizeof sblock);
+       if (sblock.fs_magic != FS_MAGIC) {
+               msg("bad sblock magic number\n");
+               dumpabort();
+       }
+       maxino = sblock.fs_ipg * sblock.fs_ncg;
+       for (ino = 0; ino < maxino; ) {
+               if((ino % MLEN) == 0) {
+                       bits = ~0;
+                       if(map != NULL)
+                               bits = *map++;
+               }
+               ino++;
+               if(bits & 1) {
+                       dp = getino(ino);
+                       (*fn)(dp);
                }
                }
+               bits >>= 1;
        }
 }
 
        }
 }
 
-icat(ip, fn1, fn2)
-struct dinode  *ip;
-int (*fn1)(), (*fn2)();
+icat(dp, fn1, fn2)
+       register struct dinode  *dp;
+       int (*fn1)(), (*fn2)();
 {
 {
-       register i;
-       daddr_t d[NADDR];
+       register int i;
 
 
-       l3tol(&d[0], &ip->di_addr[0], NADDR);
-       (*fn2)(d, NADDR-3);
-       for(i=0; i<NADDR; i++) {
-               if(d[i] != 0) {
-                       if(i < NADDR-3)
-                               (*fn1)(d[i]); else
-                               indir(d[i], fn1, fn2, i-(NADDR-3));
-               }
+       (*fn2)(dp->di_db, NDADDR);
+       for (i = 0; i < NDADDR; i++) {
+               if (dp->di_db[i] != 0)
+                       (*fn1)(dp->di_db[i]);
+       }
+       for (i = 0; i < NIADDR; i++) {
+               if (dp->di_ib[i] != 0)
+                       indir(dp->di_ib[i], fn1, fn2, i);
        }
 }
 
        }
 }
 
@@ -235,6 +225,22 @@ nullf()
 {
 }
 
 {
 }
 
+struct dinode *
+getino(ino)
+       daddr_t ino;
+{
+       static daddr_t minino, maxino;
+       static struct dinode itab[INOPB];
+
+       if (ino >= minino && ino < maxino) {
+               return (&itab[ino - minino]);
+       }
+       bread(itod(ino, &sblock), itab, BSIZE);
+       minino = ino - (ino % INOPB);
+       maxino = minino + INOPB;
+       return (&itab[ino - minino]);
+}
+
 int    breaderrors = 0;                
 #define        BREADEMAX 32
 
 int    breaderrors = 0;                
 #define        BREADEMAX 32
 
@@ -246,7 +252,7 @@ bread(da, ba, c)
        register n;
        register        regc;
 
        register n;
        register        regc;
 
-       if (lseek(fi, (long)(da*BSIZE), 0) < 0){
+       if (lseek(fi, (long)(da*FSIZE), 0) < 0){
                msg("bread: lseek fails\n");
        }
        regc = c;       /* put c someplace safe; it gets clobbered */
                msg("bread: lseek fails\n");
        }
        regc = c;       /* put c someplace safe; it gets clobbered */
index 27df312..06f9038 100644 (file)
@@ -1,6 +1,6 @@
 /* Copyright (c) 1981 Regents of the University of California */
 
 /* Copyright (c) 1981 Regents of the University of California */
 
-char version[] = "@(#)main.c 1.2 %G%";
+char version[] = "@(#)main.c 1.3 %G%";
 
 /*     Modified to include h option (recursively extract all files within
  *     a subtree) and m option (recreate the heirarchical structure of
 
 /*     Modified to include h option (recursively extract all files within
  *     a subtree) and m option (recreate the heirarchical structure of
@@ -23,13 +23,13 @@ char version[] = "@(#)main.c 1.2 %G%";
 #include <stdio.h>
 #include <signal.h>
 #endif
 #include <stdio.h>
 #include <signal.h>
 #endif
-#include <sys/param.h>
-#include <sys/inode.h>
-#include <sys/ino.h>
-#include <sys/fblk.h>
-#include <sys/filsys.h>
-#include <sys/dir.h>
-#include <dumprestor.h>
+#include "../h/param.h"
+#include "../h/inode.h"
+#include "../h/fs.h"
+#include "../h/buf.h"
+#include "../h/dir.h"
+#include "../h/user.h"
+#include "../h/dumprestor.h"
 
 #define        MWORD(m,i) (m[(unsigned)(i-1)/MLEN])
 #define        MBIT(i) (1<<((unsigned)(i-1)%MLEN))
 
 #define        MWORD(m,i) (m[(unsigned)(i-1)/MLEN])
 #define        MBIT(i) (1<<((unsigned)(i-1)%MLEN))
@@ -37,14 +37,16 @@ char version[] = "@(#)main.c 1.2 %G%";
 #define        BIC(i,w)        (MWORD(w,i) &= ~MBIT(i))
 #define        BIT(i,w)        (MWORD(w,i) & MBIT(i))
 
 #define        BIC(i,w)        (MWORD(w,i) &= ~MBIT(i))
 #define        BIT(i,w)        (MWORD(w,i) & MBIT(i))
 
-struct filsys  sblock;
 struct  direct dir;
 
 int    fi;
 struct  direct dir;
 
 int    fi;
-ino_t  ino, maxi, curino;
+ino_t  ino, maxi;
 
 
-int    mt, hflag, mflag, i;
+int    mt, i;
+int    eflag, hflag, mflag;
 
 
+char   mounted = 0;
+dev_t  dev = 0;
 char   tapename[] = "/dev/rmt8";
 char   *magtape = tapename;
 
 char   tapename[] = "/dev/rmt8";
 char   *magtape = tapename;
 
@@ -78,49 +80,40 @@ char        drblock[BSIZE];
 int    bpt, nread, xsize,
        init = 1;
 
 int    bpt, nread, xsize,
        init = 1;
 
-
 #include <sys/mtio.h>
 struct mtop tcom;
 
 #include <sys/mtio.h>
 struct mtop tcom;
 
-
 int dumpnum = 1;
 int    volno = 1;
 
 int dumpnum = 1;
 int    volno = 1;
 
-
-int    eflag;
-
-struct dinode tino, dino;
-daddr_t        taddr[NADDR];
-
-daddr_t        curbno;
+struct inode *cur_ip;
 
 short  dumpmap[MSIZ];
 short  clrimap[MSIZ];
 
 short  dumpmap[MSIZ];
 short  clrimap[MSIZ];
-
+char   clearedbuf[BSIZE];
 
 int bct = NTREC+1;
 char tbf[NTREC*BSIZE];
 
 
 int bct = NTREC+1;
 char tbf[NTREC*BSIZE];
 
-struct cache {
-       daddr_t c_bno;
-       int     c_time;
-       char    c_block[BSIZE];
-} cache[NCACHE];
-int    curcache;
+char **envp;
 
 
-main(argc, argv)
-char *argv[];
+main(argc, argv, arge)
+       int argc;
+       char *argv[];
+       char **arge;
 {
        register char *cp;
        char command;
 {
        register char *cp;
        char command;
+       int (*signal())();
        int done();
 
 #ifndef STANDALONE
        int done();
 
 #ifndef STANDALONE
-       mktemp(dirfile);
+       envp = arge;
+       mktmp(dirfile);
        if (argc < 2) {
 usage:
        if (argc < 2) {
 usage:
-               printf("Usage: restor x[s|m|h] file file..., restor r filesys, or restor t\n");
-               exit(1);
+               fprintf(stderr, "Usage: restor x[s|m|h] file file..., restor r filesys, or restor t\n");
+               done(1);
        }
        argv++;
        argc -= 2;
        }
        argv++;
        argc -= 2;
@@ -136,8 +129,8 @@ usage:
                case 's':
                        dumpnum = atoi(*argv++);
                        if(dumpnum <= 0) {
                case 's':
                        dumpnum = atoi(*argv++);
                        if(dumpnum <= 0) {
-                               printf("Dump number must be a positive integer\n");
-                               exit(1);
+                               fprintf(stderr, "Dump number must be a positive integer\n");
+                               done(1);
                        }
                        argc--;
                        break;
                        }
                        argc--;
                        break;
@@ -154,7 +147,7 @@ usage:
                        command = *cp;
                        break;
                default:
                        command = *cp;
                        break;
                default:
-                       printf("Bad key character %c\n", *cp);
+                       fprintf(stderr, "Bad key character %c\n", *cp);
                        goto usage;
                }
        }
                        goto usage;
                }
        }
@@ -166,16 +159,18 @@ usage:
 
                df = creat(dirfile, 0666);
                if (df < 0) {
 
                df = creat(dirfile, 0666);
                if (df < 0) {
-                       printf("restor: %s - cannot create directory temporary\n", dirfile);
-                       exit(1);
+                       fprintf(stderr, "restor: %s - cannot create directory temporary\n", dirfile);
+                       done(1);
                }
                close(df);
                }
                close(df);
+               xmount(envp);
+               mounted++;
                df = open(dirfile, 2);
        }
        doit(command, argc, argv);
        if (command == 'x')
                unlink(dirfile);
                df = open(dirfile, 2);
        }
        doit(command, argc, argv);
        if (command == 'x')
                unlink(dirfile);
-       exit(0);
+       done(0);
 #else
        magtape = "tape";
        doit('r', 1, 0);
 #else
        magtape = "tape";
        doit('r', 1, 0);
@@ -183,9 +178,9 @@ usage:
 }
 
 doit(command, argc, argv)
 }
 
 doit(command, argc, argv)
-char   command;
-int    argc;
-char   *argv[]; 
+       char    command;
+       int     argc;
+       char    *argv[]; 
 {
        extern char *ctime();
        char *ststore();
 {
        extern char *ctime();
        char *ststore();
@@ -195,13 +190,15 @@ char      *argv[];
        int     xtrfile(), skip(), null();
 #endif
        int     rstrfile(), rstrskip();
        int     xtrfile(), skip(), null();
 #endif
        int     rstrfile(), rstrskip();
-       struct dinode *ip, *ip1;
+       register struct dinode *dp;
+       register struct inode *ip;
+       struct fs *fs;
 
 #ifndef STANDALONE
        getxtrlist();
        if ((mt = open(magtape, 0)) < 0) {
 
 #ifndef STANDALONE
        getxtrlist();
        if ((mt = open(magtape, 0)) < 0) {
-               printf("%s: cannot open tape\n", magtape);
-               exit(1);
+               fprintf(stderr, "%s: cannot open tape\n", magtape);
+               done(1);
        }
        if(dumpnum != 1) {
                tcom.mt_op = MTFSF;
        }
        if(dumpnum != 1) {
                tcom.mt_op = MTFSF;
@@ -211,29 +208,30 @@ char      *argv[];
        }
 #else
        do {
        }
 #else
        do {
-               printf("Tape? ");
+               fprintf(stderr, "Tape? ");
                gets(mbuf);
                mt = open(mbuf, 0);
        } while (mt == -1);
        magtape = mbuf;
                gets(mbuf);
                mt = open(mbuf, 0);
        } while (mt == -1);
        magtape = mbuf;
+       clearbuf(clearedbuf);
 #endif
        switch(command) {
 #ifndef STANDALONE
        case 't':
                if (readhdr(&spcl) == 0) {
 #endif
        switch(command) {
 #ifndef STANDALONE
        case 't':
                if (readhdr(&spcl) == 0) {
-                       printf("Tape is not a dump tape\n");
-                       exit(1);
+                       fprintf(stderr, "Tape is not a dump tape\n");
+                       done(1);
                }
                }
-               printf("Dump   date: %s", ctime(&spcl.c_date));
-               printf("Dumped from: %s", ctime(&spcl.c_ddate));
+               fprintf(stderr, "Dump   date: %s", ctime(&spcl.c_date));
+               fprintf(stderr, "Dumped from: %s", ctime(&spcl.c_ddate));
                return;
        case 'x':
                if (readhdr(&spcl) == 0) {
                return;
        case 'x':
                if (readhdr(&spcl) == 0) {
-                       printf("Tape is not a dump tape\n");
-                       exit(1);
+                       fprintf(stderr, "Tape is not a dump tape\n");
+                       done(1);
                }
                if (checkvol(&spcl, 1) == 0) {
                }
                if (checkvol(&spcl, 1) == 0) {
-                       printf("Tape is not volume 1 of the dump\n");
+                       fprintf(stderr, "Tape is not volume 1 of the dump\n");
                }
                pass1();  /* This sets the various maps on the way by */
                i = 0;
                }
                pass1();  /* This sets the various maps on the way by */
                i = 0;
@@ -243,14 +241,14 @@ char      *argv[];
                        else {
                                if( (d = psearch(*argv)) == 0 ||
                                                        BIT(d,dumpmap) == 0 ) {
                        else {
                                if( (d = psearch(*argv)) == 0 ||
                                                        BIT(d,dumpmap) == 0 ) {
-                                       printf( "%s: not on tape\n", *argv++ );
+                                       fprintf(stderr,  "%s: not on tape\n", *argv++ );
                                        continue;
                                }
                                xtrlist[i].x_ino = d;
                                xtrlist[i].x_flags |= XINUSE;
                                if( mflag )
                                        xtrlist[i].x_name = ststore( *argv );
                                        continue;
                                }
                                xtrlist[i].x_ino = d;
                                xtrlist[i].x_flags |= XINUSE;
                                if( mflag )
                                        xtrlist[i].x_name = ststore( *argv );
-                               printf( "%s: inode %u\n", *argv, d );
+                               fprintf(stderr,  "%s: inode %u\n", *argv, d );
                                argv++;
                                if( ++i >= xsize ) getxtrlist();
                        }
                                argv++;
                                if( ++i >= xsize ) getxtrlist();
                        }
@@ -270,30 +268,31 @@ newvol:
                        tcom.mt_count = 1;
                        ioctl(mt,MTIOCTOP,&tcom);
                }
                        tcom.mt_count = 1;
                        ioctl(mt,MTIOCTOP,&tcom);
                }
+               lseek(mt, 0, 0);
 
 
 getvol:
 
 
 getvol:
-               printf("Mount desired tape volume: Specify volume #: ");
+               fprintf(stderr, "Mount desired tape volume: Specify volume #: ");
                if (gets(tbf) == NULL)
                        return;
                volno = atoi(tbf);
                if (volno <= 0) {
                if (gets(tbf) == NULL)
                        return;
                volno = atoi(tbf);
                if (volno <= 0) {
-                       printf("Volume numbers are positive numerics\n");
+                       fprintf(stderr, "Volume numbers are positive numerics\n");
                        goto getvol;
                }
                if (readhdr(&spcl) == 0) {
                        goto getvol;
                }
                if (readhdr(&spcl) == 0) {
-                       printf("tape is not dump tape\n");
+                       fprintf(stderr, "tape is not dump tape\n");
                        goto newvol;
                }
                if (checkvol(&spcl, volno) == 0) {
                        goto newvol;
                }
                if (checkvol(&spcl, volno) == 0) {
-                       printf("Wrong volume (%d)\n", spcl.c_volume);
+                       fprintf(stderr, "Wrong volume (%d)\n", spcl.c_volume);
                        goto newvol;
                }
 rbits:
                while (gethead(&spcl) == 0)
                        ;
                if (checktype(&spcl, TS_INODE) == 1) {
                        goto newvol;
                }
 rbits:
                while (gethead(&spcl) == 0)
                        ;
                if (checktype(&spcl, TS_INODE) == 1) {
-                       printf("Can't find inode mask!\n");
+                       fprintf(stderr, "Can't find inode mask!\n");
                        goto newvol;
                }
                if (checktype(&spcl, TS_BITS) == 0)
                        goto newvol;
                }
                if (checktype(&spcl, TS_BITS) == 0)
@@ -312,7 +311,7 @@ again:
                                while(gethead(&spcl) == 0)
                                        ;
                        if (checktype(&spcl, TS_END) == 1) {
                                while(gethead(&spcl) == 0)
                                        ;
                        if (checktype(&spcl, TS_END) == 1) {
-                               printf("end of tape\n");
+                               fprintf(stderr, "end of tape\n");
 checkdone:
                                for (k = 0; xtrlist[k].x_flags; k++)
                                        if ((xtrlist[k].x_flags&XTRACTD) == 0) {
 checkdone:
                                for (k = 0; xtrlist[k].x_flags; k++)
                                        if ((xtrlist[k].x_flags&XTRACTD) == 0) {
@@ -332,28 +331,28 @@ checkdone:
                                if (d == xtrlist[k].x_ino) {
                                        if( mflag ) {
                                                sprintf(name, "%s", xtrlist[k].x_name);
                                if (d == xtrlist[k].x_ino) {
                                        if( mflag ) {
                                                sprintf(name, "%s", xtrlist[k].x_name);
-                                               printf("extract file %s\n",name);
+                                               fprintf(stderr, "extract file %s\n",name);
                                                checkdir( name );
                                        }
                                        else {
                                                checkdir( name );
                                        }
                                        else {
-                                               printf("extract file %u\n", xtrlist[k].x_ino );
+                                               fprintf(stderr, "extract file %u\n", xtrlist[k].x_ino );
                                                sprintf(name, "%u", xtrlist[k].x_ino);
                                        }
                                                sprintf(name, "%u", xtrlist[k].x_ino);
                                        }
-                                       if ((ofile = creat(name, 0666)) < 0) {
-                                               printf("%s: cannot create file\n", name);
+                                       if ((ofile = xcreat(name, 0666)) < 0) {
+                                               fprintf(stderr, "%s: cannot create file\n", name);
                                                i--;
                                                continue;
                                        }
                                                i--;
                                                continue;
                                        }
-                                       chown(name, spcl.c_dinode.di_uid, spcl.c_dinode.di_gid);
-                                       getfile(ino, xtrfile, skip, spcl.c_dinode.di_size);
+                                       xchown(name, spcl.c_dinode.di_uid, spcl.c_dinode.di_gid);
+                                       getfile(xtrfile, skip, spcl.c_dinode.di_size);
                                        i--;
                                        xtrlist[k].x_flags |= XTRACTD;
                                        i--;
                                        xtrlist[k].x_flags |= XTRACTD;
-                                       close(ofile);
-                                       goto done;
+                                       xclose(ofile);
+                                       goto finished;
                                }
                        }
                                }
                        }
-                       getfile(d, null, null, spcl.c_dinode.di_size);
-done:
+                       getfile(null, null, spcl.c_dinode.di_size);
+finished:
                        ;
                }
                goto checkdone;
                        ;
                }
                goto checkdone;
@@ -361,25 +360,34 @@ done:
        case 'r':
        case 'R':
 #ifndef STANDALONE
        case 'r':
        case 'R':
 #ifndef STANDALONE
-               if ((fi = open(*argv, 2)) < 0) {
-                       printf("%s: cannot open\n", *argv);
-                       exit(1);
+               {
+                       char mount[80];
+                       char *ptr[2];
+
+                       strcpy(mount, "MOUNT=");
+                       strcat(mount, *argv);
+                       ptr[0] = mount;
+                       ptr[1] = 0;
+                       xmount(ptr);
+                       iput(u.u_cdir); /* release root inode */
+                       iput(u.u_rdir); /* release root inode */
+                       mounted++;
                }
 #else
                do {
                        char charbuf[50];
 
                }
 #else
                do {
                        char charbuf[50];
 
-                       printf("Disk? ");
+                       fprintf(stderr, "Disk? ");
                        gets(charbuf);
                        fi = open(charbuf, 2);
                } while (fi == -1);
 #endif
 #ifndef STANDALONE
                if (command == 'R') {
                        gets(charbuf);
                        fi = open(charbuf, 2);
                } while (fi == -1);
 #endif
 #ifndef STANDALONE
                if (command == 'R') {
-                       printf("Enter starting volume number: ");
+                       fprintf(stderr, "Enter starting volume number: ");
                        if (gets(tbf) == EOF) {
                                volno = 1;
                        if (gets(tbf) == EOF) {
                                volno = 1;
-                               printf("\n");
+                               fprintf(stderr, "\n");
                        }
                        else
                                volno = atoi(tbf);
                        }
                        else
                                volno = atoi(tbf);
@@ -387,50 +395,52 @@ done:
                else
 #endif
                        volno = 1;
                else
 #endif
                        volno = 1;
-               printf("Last chance before scribbling on %s. ",
+               fprintf(stderr, "Last chance before scribbling on %s. ",
 #ifdef STANDALONE
                                                                "disk");
 #else
                                                                *argv);
 #endif
                while (getchar() != '\n');
 #ifdef STANDALONE
                                                                "disk");
 #else
                                                                *argv);
 #endif
                while (getchar() != '\n');
-               dread((daddr_t)1, (char *)&sblock, sizeof(sblock));
-               maxi = (sblock.s_isize-2)*INOPB;
+               fs = getfs(dev);
+               maxi = fs->fs_ipg * fs->fs_ncg;
                if (readhdr(&spcl) == 0) {
                if (readhdr(&spcl) == 0) {
-                       printf("Missing volume record\n");
-                       exit(1);
+                       fprintf(stderr, "Missing volume record\n");
+                       done(1);
                }
                if (checkvol(&spcl, volno) == 0) {
                }
                if (checkvol(&spcl, volno) == 0) {
-                       printf("Tape is not volume %d\n", volno);
-                       exit(1);
+                       fprintf(stderr, "Tape is not volume %d\n", volno);
+                       done(1);
                }
                gethead(&spcl);
                for (;;) {
 ragain:
                        if (ishead(&spcl) == 0) {
                }
                gethead(&spcl);
                for (;;) {
 ragain:
                        if (ishead(&spcl) == 0) {
-                               printf("Missing header block\n");
+                               fprintf(stderr, "Missing header block\n");
                                while (gethead(&spcl) == 0)
                                        ;
                                eflag++;
                        }
                        if (checktype(&spcl, TS_END) == 1) {
                                while (gethead(&spcl) == 0)
                                        ;
                                eflag++;
                        }
                        if (checktype(&spcl, TS_END) == 1) {
-                               printf("End of tape\n");
+                               fprintf(stderr, "End of tape\n");
                                close(mt);
                                close(mt);
-                               dwrite( (daddr_t) 1, (char *) &sblock);
                                return;
                        }
                        if (checktype(&spcl, TS_CLRI) == 1) {
                                readbits(clrimap);
                                for (ino = 1; ino <= maxi; ino++)
                                        if (BIT(ino, clrimap) == 0) {
                                return;
                        }
                        if (checktype(&spcl, TS_CLRI) == 1) {
                                readbits(clrimap);
                                for (ino = 1; ino <= maxi; ino++)
                                        if (BIT(ino, clrimap) == 0) {
-                                               getdino(ino, &tino);
-                                               if (tino.di_mode == 0)
+                                               if (!iexist(dev, ino))
                                                        continue;
                                                        continue;
-                                               itrunc(&tino);
-                                               clri(&tino);
-                                               putdino(ino, &tino);
+                                               ip = iget(dev, ino);
+                                               if (ip == NULL) {
+                                                       fprintf(stderr, "can't find inode %u\n", ino);
+                                                       done(1);
+                                               }
+                                               ip->i_nlink = 0;
+                                               ip->i_flag |= ICHG;
+                                               iput(ip);
                                        }
                                        }
-                               dwrite( (daddr_t) 1, (char *) &sblock);
                                goto ragain;
                        }
                        if (checktype(&spcl, TS_BITS) == 1) {
                                goto ragain;
                        }
                        if (checktype(&spcl, TS_BITS) == 1) {
@@ -438,41 +448,51 @@ ragain:
                                goto ragain;
                        }
                        if (checktype(&spcl, TS_INODE) == 0) {
                                goto ragain;
                        }
                        if (checktype(&spcl, TS_INODE) == 0) {
-                               printf("Unknown header type\n");
+                               fprintf(stderr, "Unknown header type\n");
                                eflag++;
                                gethead(&spcl);
                                goto ragain;
                        }
                        ino = spcl.c_inumber;
                        if (eflag)
                                eflag++;
                                gethead(&spcl);
                                goto ragain;
                        }
                        ino = spcl.c_inumber;
                        if (eflag)
-                               printf("Resynced at inode %u\n", ino);
+                               fprintf(stderr, "Resynced at inode %u\n", ino);
                        eflag = 0;
                        if (ino > maxi) {
                        eflag = 0;
                        if (ino > maxi) {
-                               printf("%u: ilist too small\n", ino);
+                               fprintf(stderr, "%u: ilist too small\n", ino);
                                gethead(&spcl);
                                goto ragain;
                        }
                                gethead(&spcl);
                                goto ragain;
                        }
-                       dino = spcl.c_dinode;
-                       getdino(ino, &tino);
-                       curbno = 0;
-                       itrunc(&tino);
-                       clri(&tino);
-                       for (i = 0; i < NADDR; i++)
-                               taddr[i] = 0;
-                       l3tol(taddr, dino.di_addr, 1);
-                       getfile(d, rstrfile, rstrskip, dino.di_size);
-                       ip = &tino;
-                       ltol3(ip->di_addr, taddr, NADDR);
-                       ip1 = &dino;
-                       ip->di_mode = ip1->di_mode;
-                       ip->di_nlink = ip1->di_nlink;
-                       ip->di_uid = ip1->di_uid;
-                       ip->di_gid = ip1->di_gid;
-                       ip->di_size = ip1->di_size;
-                       ip->di_atime = ip1->di_atime;
-                       ip->di_mtime = ip1->di_mtime;
-                       ip->di_ctime = ip1->di_ctime;
-                       putdino(ino, &tino);
+                       if (iexist(dev, ino)) {
+                               ip = iget(dev, ino);
+                               if (ip == NULL) {
+                                       fprintf(stderr, "can't find inode %u\n",
+                                               ino);
+                                       done(1);
+                               }
+                               ip->i_nlink = 0;
+                               ip->i_flag |= ICHG;
+                               iput(ip);
+                       }
+                       dp = &spcl.c_dinode;
+                       ip = ialloc(dev, ino, dp->di_mode);
+                       if (ip == NULL || ip->i_number != ino) {
+                               fprintf(stderr, "can't create inode %u\n", ino);
+                               done(1);
+                       }
+                       ip->i_mode = dp->di_mode;
+                       ip->i_nlink = dp->di_nlink;
+                       ip->i_uid = dp->di_uid;
+                       ip->i_gid = dp->di_gid;
+                       ip->i_size = dp->di_size;
+                       ip->i_atime = dp->di_atime;
+                       ip->i_mtime = dp->di_mtime;
+                       ip->i_ctime = dp->di_ctime;
+                       cur_ip = ip;
+                       u.u_offset = 0;
+                       u.u_segflg = 1;
+                       getfile(rstrfile, rstrskip, dp->di_size);
+                       ip->i_flag |= ICHG;
+                       iput(ip);
                }
        }
 }
                }
        }
 }
@@ -489,7 +509,7 @@ pass1()
        int     putdir(), null();
 
        while (gethead(&spcl) == 0) {
        int     putdir(), null();
 
        while (gethead(&spcl) == 0) {
-               printf("Can't find directory header!\n");
+               fprintf(stderr, "Can't find directory header!\n");
        }
        for (;;) {
                if (checktype(&spcl, TS_BITS) == 1) {
        }
        for (;;) {
                if (checktype(&spcl, TS_BITS) == 1) {
@@ -515,7 +535,7 @@ finish:
                }
                inotab[ipos].t_ino = spcl.c_inumber;
                inotab[ipos++].t_seekpt = seekpt;
                }
                inotab[ipos].t_ino = spcl.c_inumber;
                inotab[ipos++].t_seekpt = seekpt;
-               getfile(spcl.c_inumber, putdir, null, spcl.c_dinode.di_size);
+               getfile(putdir, null, spcl.c_dinode.di_size);
                putent("\000\000/");
        }
 }
                putent("\000\000/");
        }
 }
@@ -525,38 +545,23 @@ finish:
  * Do the file extraction, calling the supplied functions
  * with the blocks
  */
  * Do the file extraction, calling the supplied functions
  * with the blocks
  */
-getfile(n, f1, f2, size)
-ino_t  n;
-int    (*f2)(), (*f1)();
-long   size;
+getfile(f1, f2, size)
+       int     (*f2)(), (*f1)();
+       long    size;
 {
        register i;
        struct spcl addrblock;
        char buf[BSIZE];
 
        addrblock = spcl;
 {
        register i;
        struct spcl addrblock;
        char buf[BSIZE];
 
        addrblock = spcl;
-       curino = n;
-       goto start;
        for (;;) {
        for (;;) {
-               if (gethead(&addrblock) == 0) {
-                       printf("Missing address (header) block\n");
-                       goto eloop;
-               }
-               if (checktype(&addrblock, TS_ADDR) == 0) {
-                       spcl = addrblock;
-                       curino = 0;
-                       curino = 0;
-                       return;
-               }
-start:
                for (i = 0; i < addrblock.c_count; i++) {
                        if (addrblock.c_addr[i]) {
                                readtape(buf);
                                (*f1)(buf, size > BSIZE ? (long) BSIZE : size);
                        }
                        else {
                for (i = 0; i < addrblock.c_count; i++) {
                        if (addrblock.c_addr[i]) {
                                readtape(buf);
                                (*f1)(buf, size > BSIZE ? (long) BSIZE : size);
                        }
                        else {
-                               clearbuf(buf);
-                               (*f2)(buf, size > BSIZE ? (long) BSIZE : size);
+                               (*f2)(clearedbuf, size > BSIZE ? (long) BSIZE : size);
                        }
                        if ((size -= BSIZE) <= 0) {
 eloop:
                        }
                        if ((size -= BSIZE) <= 0) {
 eloop:
@@ -564,10 +569,17 @@ eloop:
                                        ;
                                if (checktype(&spcl, TS_ADDR) == 1)
                                        goto eloop;
                                        ;
                                if (checktype(&spcl, TS_ADDR) == 1)
                                        goto eloop;
-                               curino = 0;
                                return;
                        }
                }
                                return;
                        }
                }
+               if (gethead(&addrblock) == 0) {
+                       fprintf(stderr, "Missing address (header) block\n");
+                       goto eloop;
+               }
+               if (checktype(&addrblock, TS_ADDR) == 0) {
+                       spcl = addrblock;
+                       return;
+               }
        }
 }
 
        }
 }
 
@@ -576,7 +588,7 @@ eloop:
  * etc..
  */
 readtape(b)
  * etc..
  */
 readtape(b)
-char *b;
+       char *b;
 {
        register i;
        struct spcl tmpbuf;
 {
        register i;
        struct spcl tmpbuf;
@@ -586,9 +598,9 @@ char *b;
                        ((struct spcl *)&tbf[i*BSIZE])->c_magic = 0;
                bct = 0;
                if ((i = read(mt, tbf, NTREC*BSIZE)) < 0) {
                        ((struct spcl *)&tbf[i*BSIZE])->c_magic = 0;
                bct = 0;
                if ((i = read(mt, tbf, NTREC*BSIZE)) < 0) {
-                       printf("Tape read error: inode %u\n", curino);
+                       perror("Tape read error");
                        eflag++;
                        eflag++;
-                       exit(1);
+                       done(1);
                }
                if (i == 0) {
                        bct = NTREC + 1;
                }
                if (i == 0) {
                        bct = NTREC + 1;
@@ -596,19 +608,19 @@ char *b;
 loop:
                        flsht();
                        close(mt);
 loop:
                        flsht();
                        close(mt);
-                       printf("Mount volume %d\n", volno);
+                       fprintf(stderr, "Mount volume %d\n", volno);
                        while (getchar() != '\n')
                                ;
                        if ((mt = open(magtape, 0)) == -1) {
                        while (getchar() != '\n')
                                ;
                        if ((mt = open(magtape, 0)) == -1) {
-                               printf("Cannot open tape!\n");
+                               fprintf(stderr, "Cannot open tape!\n");
                                goto loop;
                        }
                        if (readhdr(&tmpbuf) == 0) {
                                goto loop;
                        }
                        if (readhdr(&tmpbuf) == 0) {
-                               printf("Not a dump tape.Try again\n");
+                               fprintf(stderr, "Not a dump tape.Try again\n");
                                goto loop;
                        }
                        if (checkvol(&tmpbuf, volno) == 0) {
                                goto loop;
                        }
                        if (checkvol(&tmpbuf, volno) == 0) {
-                               printf("Wrong tape. Try again\n");
+                               fprintf(stderr, "Wrong tape. Try again\n");
                                goto loop;
                        }
                        readtape(b);
                                goto loop;
                        }
                        readtape(b);
@@ -624,7 +636,7 @@ flsht()
 }
 
 copy(f, t, s)
 }
 
 copy(f, t, s)
-register char *f, *t;
+       register char *f, *t;
 {
        register i;
 
 {
        register i;
 
@@ -635,7 +647,7 @@ register char *f, *t;
 }
 
 clearbuf(cp)
 }
 
 clearbuf(cp)
-register char *cp;
+       register char *cp;
 {
        register i;
 
 {
        register i;
 
@@ -651,7 +663,7 @@ register char *cp;
  */
 #ifndef STANDALONE
 putent(cp)
  */
 #ifndef STANDALONE
 putent(cp)
-char   *cp;
+       char    *cp;
 {
        register i;
 
 {
        register i;
 
@@ -666,7 +678,7 @@ char        *cp;
 }
 
 getent(bf)
 }
 
 getent(bf)
-register char *bf;
+       register char *bf;
 {
        register i;
 
 {
        register i;
 
@@ -682,7 +694,7 @@ register char *bf;
  * read/write te directory file
  */
 writec(c)
  * read/write te directory file
  */
 writec(c)
-char c;
+       char c;
 {
        drblock[bpt++] = c;
        seekpt++;
 {
        drblock[bpt++] = c;
        seekpt++;
@@ -702,7 +714,7 @@ readc()
 }
 
 mseek(pt)
 }
 
 mseek(pt)
-daddr_t pt;
+       daddr_t pt;
 {
        bpt = BSIZE;
        lseek(df, pt, 0);
 {
        bpt = BSIZE;
        lseek(df, pt, 0);
@@ -719,8 +731,8 @@ flsh()
  */
 ino_t
 search(inum, cp)
  */
 ino_t
 search(inum, cp)
-ino_t  inum;
-char   *cp;
+       ino_t   inum;
+       char    *cp;
 {
        register i;
 
 {
        register i;
 
@@ -740,16 +752,16 @@ found:
 }
 
 /*
 }
 
 /*
- * Search the directory tree rooted at inode 2
+ * Search the directory tree rooted at inode ROOTINO
  * for the path pointed at by n
  */
 psearch(n)
  * for the path pointed at by n
  */
 psearch(n)
-char   *n;
+       char    *n;
 {
        register char *cp, *cp1;
        char c;
 
 {
        register char *cp, *cp1;
        char c;
 
-       ino = 2;
+       ino = ROOTINO;
        if (*(cp = n) == '/')
                cp++;
 next:
        if (*(cp = n) == '/')
                cp++;
 next:
@@ -772,7 +784,7 @@ next:
 }
 
 direq(s1, s2)
 }
 
 direq(s1, s2)
-register char *s1, *s2;
+       register char *s1, *s2;
 {
        register i;
 
 {
        register i;
 
@@ -786,283 +798,12 @@ register char *s1, *s2;
 }
 #endif
 
 }
 #endif
 
-/*
- * read/write a disk block, be sure to update the buffer
- * cache if needed.
- */
-dwrite(bno, b)
-daddr_t        bno;
-char   *b;
-{
-       register i;
-
-       for (i = 0; i < NCACHE; i++) {
-               if (cache[i].c_bno == bno) {
-                       copy(b, cache[i].c_block, BSIZE);
-                       cache[i].c_time = 0;
-                       break;
-               }
-               else
-                       cache[i].c_time++;
-       }
-       lseek(fi, bno*BSIZE, 0);
-       if(write(fi, b, BSIZE) != BSIZE) {
-#ifdef STANDALONE
-               printf("disk write error %D\n", bno);
-#else
-               fprintf(stderr, "disk write error %ld\n", bno);
-#endif
-               exit(1);
-       }
-}
-
-dread(bno, buf, cnt)
-daddr_t bno;
-char *buf;
-{
-       register i, j;
-
-       j = 0;
-       for (i = 0; i < NCACHE; i++) {
-               if (++curcache >= NCACHE)
-                       curcache = 0;
-               if (cache[curcache].c_bno == bno) {
-                       copy(cache[curcache].c_block, buf, cnt);
-                       cache[curcache].c_time = 0;
-                       return;
-               }
-               else {
-                       cache[curcache].c_time++;
-                       if (cache[j].c_time < cache[curcache].c_time)
-                               j = curcache;
-               }
-       }
-
-       lseek(fi, bno*BSIZE, 0);
-       if (read(fi, cache[j].c_block, BSIZE) != BSIZE) {
-#ifdef STANDALONE
-               printf("read error %D\n", bno);
-#else
-               printf("read error %ld\n", bno);
-#endif
-               exit(1);
-       }
-       copy(cache[j].c_block, buf, cnt);
-       cache[j].c_time = 0;
-       cache[j].c_bno = bno;
-}
-
-/*
- * the inode manpulation routines. Like the system.
- *
- * clri zeros the inode
- */
-clri(ip)
-struct dinode *ip;
-{
-       int i, *p;
-       if (ip->di_mode&IFMT)
-               sblock.s_tinode++;
-       i = sizeof(struct dinode)/sizeof(int);
-       p = (int *)ip;
-       do
-               *p++ = 0;
-       while(--i);
-}
-
-/*
- * itrunc/tloop/bfree free all of the blocks pointed at by the inode
- */
-itrunc(ip)
-register struct dinode *ip;
-{
-       register i;
-       daddr_t bn, iaddr[NADDR];
-
-       if (ip->di_mode == 0)
-               return;
-       i = ip->di_mode & IFMT;
-       if (i != IFDIR && i != IFREG)
-               return;
-       l3tol(iaddr, ip->di_addr, NADDR);
-       for(i=NADDR-1;i>=0;i--) {
-               bn = iaddr[i];
-               if(bn == 0) continue;
-               switch(i) {
-
-               default:
-                       bfree(bn);
-                       break;
-
-               case NADDR-3:
-                       tloop(bn, 0, 0);
-                       break;
-
-               case NADDR-2:
-                       tloop(bn, 1, 0);
-                       break;
-
-               case NADDR-1:
-                       tloop(bn, 1, 1);
-               }
-       }
-       ip->di_size = 0;
-}
-
-tloop(bn, f1, f2)
-daddr_t        bn;
-int    f1, f2;
-{
-       register i;
-       daddr_t nb;
-       union {
-               char    data[BSIZE];
-               daddr_t indir[NINDIR];
-       } ibuf;
-
-       dread(bn, ibuf.data, BSIZE);
-       for(i=NINDIR-1;i>=0;i--) {
-               nb = ibuf.indir[i];
-               if(nb) {
-                       if(f1)
-                               tloop(nb, f2, 0);
-                       else
-                               bfree(nb);
-               }
-       }
-       bfree(bn);
-}
-
-bfree(bn)
-daddr_t        bn;
-{
-       register i;
-       union {
-               char    data[BSIZE];
-               struct  fblk frees;
-       } fbun;
-#define        fbuf fbun.frees
-
-       if(sblock.s_nfree >= NICFREE) {
-               fbuf.df_nfree = sblock.s_nfree;
-               for(i=0;i<NICFREE;i++)
-                       fbuf.df_free[i] = sblock.s_free[i];
-               sblock.s_nfree = 0;
-               dwrite(bn, fbun.data);
-       }
-       sblock.s_free[sblock.s_nfree++] = bn;
-       sblock.s_tfree++;
-}
-
-/*
- * allocate a block off the free list.
- */
-daddr_t
-balloc()
-{
-       daddr_t bno;
-       register i;
-       static char zeroes[BSIZE];
-       union {
-               char    data[BSIZE];
-               struct  fblk frees;
-       } fbun;
-#undef         fbuf
-#define                fbuf fbun.frees
-
-       if(sblock.s_nfree == 0 || (bno=sblock.s_free[--sblock.s_nfree]) == 0) {
-#ifdef STANDALONE
-               printf("Out of space\n");
-#else
-               fprintf(stderr, "Out of space.\n");
-#endif
-               exit(1);
-       }
-       if(sblock.s_nfree == 0) {
-               dread(bno, (char * )&fbuf, BSIZE);
-               sblock.s_nfree = fbuf.df_nfree;
-               for(i=0;i<NICFREE;i++)
-                       sblock.s_free[i] = fbuf.df_free[i];
-       }
-       dwrite(bno, zeroes);
-       sblock.s_tfree--;
-       return(bno);
-}
-
-/*
- * map a block number into a block address, ensuring
- * all of the correct indirect blocks are around. Allocate
- * the block requested.
- */
-daddr_t
-bmap(iaddr, bn)
-daddr_t        iaddr[NADDR];
-daddr_t        bn;
-{
-       register i;
-       int j, sh;
-       daddr_t nb, nnb;
-       daddr_t indir[NINDIR];
-
-       /*
-        * blocks 0..NADDR-4 are direct blocks
-        */
-       if(bn < NADDR-3) {
-               iaddr[bn] = nb = balloc();
-               return(nb);
-       }
-
-       /*
-        * addresses NADDR-3, NADDR-2, and NADDR-1
-        * have single, double, triple indirect blocks.
-        * the first step is to determine
-        * how many levels of indirection.
-        */
-       sh = 0;
-       nb = 1;
-       bn -= NADDR-3;
-       for(j=3; j>0; j--) {
-               sh += NSHIFT;
-               nb <<= NSHIFT;
-               if(bn < nb)
-                       break;
-               bn -= nb;
-       }
-       if(j == 0) {
-               return((daddr_t)0);
-       }
-
-       /*
-        * fetch the address from the inode
-        */
-       if((nb = iaddr[NADDR-j]) == 0) {
-               iaddr[NADDR-j] = nb = balloc();
-       }
-
-       /*
-        * fetch through the indirect blocks
-        */
-       for(; j<=3; j++) {
-               dread(nb, (char *)indir, BSIZE);
-               sh -= NSHIFT;
-               i = (bn>>sh) & NMASK;
-               nnb = indir[i];
-               if(nnb == 0) {
-                       nnb = balloc();
-                       indir[i] = nnb;
-                       dwrite(nb, (char *)indir);
-               }
-               nb = nnb;
-       }
-       return(nb);
-}
-
 /*
  * read the tape into buf, then return whether or
  * or not it is a header block.
  */
 gethead(buf)
 /*
  * read the tape into buf, then return whether or
  * or not it is a header block.
  */
 gethead(buf)
-struct spcl *buf;
+       struct spcl *buf;
 {
        readtape((char *)buf);
        if (buf->c_magic != MAGIC || checksum((int *) buf) == 0)
 {
        readtape((char *)buf);
        if (buf->c_magic != MAGIC || checksum((int *) buf) == 0)
@@ -1074,7 +815,7 @@ struct spcl *buf;
  * return whether or not the buffer contains a header block
  */
 ishead(buf)
  * return whether or not the buffer contains a header block
  */
 ishead(buf)
-struct spcl *buf;
+       struct spcl *buf;
 {
        if (buf->c_magic != MAGIC || checksum((int *) buf) == 0)
                return(0);
 {
        if (buf->c_magic != MAGIC || checksum((int *) buf) == 0)
                return(0);
@@ -1082,15 +823,15 @@ struct spcl *buf;
 }
 
 checktype(b, t)
 }
 
 checktype(b, t)
-struct spcl *b;
-int    t;
+       struct  spcl *b;
+       int     t;
 {
        return(b->c_type == t);
 }
 
 
 checksum(b)
 {
        return(b->c_type == t);
 }
 
 
 checksum(b)
-int *b;
+       int *b;
 {
        register i, j;
 
 {
        register i, j;
 
@@ -1100,15 +841,15 @@ int *b;
                i += *b++;
        while (--j);
        if (i != CHECKSUM) {
                i += *b++;
        while (--j);
        if (i != CHECKSUM) {
-               printf("Checksum error %o\n", i);
+               fprintf(stderr, "Checksum error %o\n", i);
                return(0);
        }
        return(1);
 }
 
 checkvol(b, t)
                return(0);
        }
        return(1);
 }
 
 checkvol(b, t)
-struct spcl *b;
-int t;
+       struct spcl *b;
+       int t;
 {
        if (b->c_volume == t)
                return(1);
 {
        if (b->c_volume == t)
                return(1);
@@ -1116,7 +857,7 @@ int t;
 }
 
 readhdr(b)
 }
 
 readhdr(b)
-struct spcl *b;
+       struct  spcl *b;
 {
        if (gethead(b) == 0)
                return(0);
 {
        if (gethead(b) == 0)
                return(0);
@@ -1130,48 +871,79 @@ struct   spcl *b;
  * put the data into the right form and place.
  */
 #ifndef STANDALONE
  * put the data into the right form and place.
  */
 #ifndef STANDALONE
-xtrfile(b, size)
-char   *b;
-long   size;
+xtrfile(buf, size)
+       char    *buf;
+       long    size;
 {
 {
-       write(ofile, b, (int) size);
+       xwrite(ofile, buf, (int) size);
 }
 
 null() {;}
 
 }
 
 null() {;}
 
-skip()
+skip(buf, size)
+       char *buf;
+       long size;
 {
 {
-       lseek(ofile, (long) BSIZE, 1);
+       xseek(ofile, size, 1);
 }
 #endif
 
 
 }
 #endif
 
 
-rstrfile(b, s)
-char *b;
-long s;
+rstrfile(buf, size)
+       char *buf;
+       long size;
 {
 {
-       daddr_t d;
+       u.u_base = buf;
+       u.u_count = size;
+       writei(cur_ip);
+}
 
 
-       d = bmap(taddr, curbno);
-       dwrite(d, b);
-       curbno += 1;
+rstrskip(buf, size)
+       char *buf;
+       long size;
+{
+       u.u_offset += size;
 }
 
 }
 
-rstrskip(b, s)
-char *b;
-long s;
+/*
+ * tell whether an inode is allocated
+ * this is drawn from ialloccg in sys/alloc.c
+ */
+iexist(dev, ino)
+       dev_t dev;
+       ino_t ino;
 {
 {
-       curbno += 1;
+       register struct fs *fs;
+       register struct cg *cgp;
+       register struct buf *bp;
+       int cg;
+
+       fs = getfs(dev);
+       if ((unsigned)ino >= fs->fs_ipg*fs->fs_ncg)
+               return (0);
+       cg = itog(ino, fs);
+       bp = bread(dev, cgtod(cg, fs), BSIZE);
+       if (bp->b_flags & B_ERROR)
+               return(0);
+       cgp = bp->b_un.b_cg;
+       ino %= fs->fs_ipg;
+       if (isclr(cgp->cg_iused, ino)) {
+               brelse(bp);
+               return(0);
+       }
+       brelse(bp);
+       return (1);
 }
 
 #ifndef STANDALONE
 }
 
 #ifndef STANDALONE
-putdir(b)
-char *b;
+putdir(buf, size)
+       char *buf;
+       int size;
 {
        register struct direct *dp;
        register i;
 
 {
        register struct direct *dp;
        register i;
 
-       for (dp = (struct direct *) b, i = 0; i < BSIZE; dp++, i += sizeof(*dp)) {
+       for (dp = (struct direct *) buf, i = 0; i < size; dp++, i += sizeof(*dp)) {
                if (dp->d_ino == 0)
                        continue;
                putent((char *) dp);
                if (dp->d_ino == 0)
                        continue;
                putent((char *) dp);
@@ -1179,42 +951,11 @@ char *b;
 }
 #endif
 
 }
 #endif
 
-/*
- * read/write an inode from the disk
- */
-getdino(inum, b)
-ino_t  inum;
-struct dinode *b;
-{
-       daddr_t bno;
-       char buf[BSIZE];
-
-       bno = (ino - 1)/INOPB;
-       bno += 2;
-       dread(bno, buf, BSIZE);
-       copy(&buf[((inum-1)%INOPB)*sizeof(struct dinode)], (char *) b, sizeof(struct dinode));
-}
-
-putdino(inum, b)
-ino_t  inum;
-struct dinode *b;
-{
-       daddr_t bno;
-       char buf[BSIZE];
-       if (b->di_mode&IFMT)
-               sblock.s_tinode--;
-
-       bno = ((ino - 1)/INOPB) + 2;
-       dread(bno, buf, BSIZE);
-       copy((char *) b, &buf[((inum-1)%INOPB)*sizeof(struct dinode)], sizeof(struct dinode));
-       dwrite(bno, buf);
-}
-
 /*
  * read a bit mask from the tape into m.
  */
 readbits(m)
 /*
  * read a bit mask from the tape into m.
  */
 readbits(m)
-short  *m;
+       short   *m;
 {
        register i;
 
 {
        register i;
 
@@ -1228,17 +969,20 @@ short    *m;
                ;
 }
 
                ;
 }
 
-done()
+done(exitcode)
+       int exitcode;
 {
 #ifndef STANDALONE
        unlink(dirfile);
 #endif
 {
 #ifndef STANDALONE
        unlink(dirfile);
 #endif
-       exit(0);
+       if (mounted)
+               xumount();
+       exit(exitcode);
 }
 
 stcopy( sourcep, destp, max )
 }
 
 stcopy( sourcep, destp, max )
-char *sourcep, *destp;
-int max;
+       char *sourcep, *destp;
+       int max;
 {
        int i;
        for( i=1; i<=max && (*destp++ = *sourcep++); i++ )
 {
        int i;
        for( i=1; i<=max && (*destp++ = *sourcep++); i++ )
@@ -1248,8 +992,8 @@ int max;
 }
 
 append( sourcep, destp, max )
 }
 
 append( sourcep, destp, max )
-char *sourcep, *destp;
-int max;
+       char *sourcep, *destp;
+       int max;
 {
        int i;
        for( i=0; *destp; i++ )
 {
        int i;
        for( i=0; *destp; i++ )
@@ -1265,7 +1009,7 @@ int max;
  */
 
 trunc( cp )
  */
 
 trunc( cp )
-char *cp;
+       char *cp;
 {
        char *lstslsh;
        lstslsh = 0;
 {
        char *lstslsh;
        lstslsh = 0;
@@ -1301,25 +1045,28 @@ getxtrlist() {
  *     the file to its proper home.
  */
 checkdir(name)
  *     the file to its proper home.
  */
 checkdir(name)
-register char *name;
+       register char *name;
 {
        register char *cp;
        int i;
        for (cp = name; *cp; cp++) {
                if (*cp == '/') {
                        *cp = '\0';
 {
        register char *cp;
        int i;
        for (cp = name; *cp; cp++) {
                if (*cp == '/') {
                        *cp = '\0';
-                       if (access(name, 01) < 0) {
+                       if (xaccess(name, 01) < 0) {
                                register int pid, rp;
 
                                register int pid, rp;
 
+                               xumount();
                                if ((pid = fork()) == 0) {
                                if ((pid = fork()) == 0) {
-                                       execl("/bin/mkdir", "mkdir", name, 0);
-                                       execl("/usr/bin/mkdir", "mkdir", name, 0);
-                                       fprintf(stderr, "tar: cannot find mkdir!\n");
+                                       execl("/bin/xmkdir", "xmkdir", name, 0);
+                                       execl("/usr/bin/xmkdir", "xmkdir", name, 0);
+                                       execl("./xmkdir", "xmkdir", name, 0);
+                                       fprintf(stderr, "xrestor: cannot find xmkdir!\n");
                                        done(0);
                                }
                                while ((rp = wait(&i)) >= 0 && rp != pid)
                                        ;
                                        done(0);
                                }
                                while ((rp = wait(&i)) >= 0 && rp != pid)
                                        ;
-                               chown(name, spcl.c_dinode.di_uid, spcl.c_dinode.di_gid);
+                               xmount(envp);
+                               xchown(name, spcl.c_dinode.di_uid, spcl.c_dinode.di_gid);
                        }
                        *cp = '/';
                }
                        }
                        *cp = '/';
                }
@@ -1332,7 +1079,7 @@ register char *name;
  */
 char *
 ststore( stringp )
  */
 char *
 ststore( stringp )
-char *stringp;
+       char *stringp;
 {
        static char *spacep;
        static int spaceleft;
 {
        static char *spacep;
        static int spaceleft;
@@ -1355,7 +1102,7 @@ char *stringp;
  *     pname and put them in xtrlist[]
  */
 getleaves( pname )
  *     pname and put them in xtrlist[]
  */
 getleaves( pname )
-char *pname;
+       char *pname;
 {
        int     n,              /* loop counter */
                bptsave,        /* placeholder for pointer into drblock */
 {
        int     n,              /* loop counter */
                bptsave,        /* placeholder for pointer into drblock */
@@ -1368,7 +1115,7 @@ char *pname;
 
        stcopy( pname, locname, NSIZE );
        if( (d = psearch(locname)) == 0 || BIT( d, dumpmap) == 0 ) {
 
        stcopy( pname, locname, NSIZE );
        if( (d = psearch(locname)) == 0 || BIT( d, dumpmap) == 0 ) {
-               printf("%s: not on the tape\n", locname );
+               fprintf(stderr, "%s: not on the tape\n", locname );
                return;
        }
 
                return;
        }
 
@@ -1396,7 +1143,7 @@ char *pname;
                                }
 
                                if( append(dir.d_name,locname,NSIZE) == 0 ) {
                                }
 
                                if( append(dir.d_name,locname,NSIZE) == 0 ) {
-                                       printf("name exceedes %d char\n",NSIZE);
+                                       fprintf(stderr, "name exceedes %d char\n",NSIZE);
                                        continue;
                                }
 
                                        continue;
                                }
 
@@ -1412,7 +1159,7 @@ char *pname;
                                bpt = bptsave;
 
                                if( trunc(locname) == 0 ) {
                                bpt = bptsave;
 
                                if( trunc(locname) == 0 ) {
-                                       printf( "Trouble with name trunc\n" );
+                                       fprintf(stderr,  "Trouble with name trunc\n" );
                                        abort();
                                }
                                        /* get next entry from drblock; reset
                                        abort();
                                }
                                        /* get next entry from drblock; reset
@@ -1432,7 +1179,7 @@ char *pname;
        xtrlist[i].x_flags |= XINUSE;
        xtrlist[i].x_name = (char *)ststore( locname );
        if( ++i >= xsize ) getxtrlist();
        xtrlist[i].x_flags |= XINUSE;
        xtrlist[i].x_name = (char *)ststore( locname );
        if( ++i >= xsize ) getxtrlist();
-       printf( "%s: inode %u\n", locname, d );
+       fprintf(stderr,  "%s: inode %u\n", locname, d );
 
 }
 
 
 }