BSD 3 development
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Sun, 23 Dec 1979 22:43:42 +0000 (14:43 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Sun, 23 Dec 1979 22:43:42 +0000 (14:43 -0800)
Work on file usr/src/cmd/clri.c
Work on file usr/src/cmd/cp.c
Work on file usr/src/cmd/dump.c
Work on file usr/include/dumprestor.h

Synthesized-from: 3bsd

usr/include/dumprestor.h [new file with mode: 0644]
usr/src/cmd/clri.c [new file with mode: 0644]
usr/src/cmd/cp.c [new file with mode: 0644]
usr/src/cmd/dump.c [new file with mode: 0644]

diff --git a/usr/include/dumprestor.h b/usr/include/dumprestor.h
new file mode 100644 (file)
index 0000000..2481168
--- /dev/null
@@ -0,0 +1,33 @@
+#define NTREC          10
+#define MLEN           16
+#define MSIZ           4096
+
+#define TS_TAPE        1
+#define TS_INODE       2
+#define TS_BITS        3
+#define TS_ADDR        4
+#define TS_END         5
+#define TS_CLRI        6
+#define MAGIC          (int)60011
+#define CHECKSUM       (int)84446
+struct spcl
+{
+       int     c_type;
+       time_t  c_date;
+       time_t  c_ddate;
+       int     c_volume;
+       daddr_t c_tapea;
+       ino_t   c_inumber;
+       int     c_magic;
+       int     c_checksum;
+       struct  dinode  c_dinode;
+       int     c_count;
+       char    c_addr[BSIZE];
+} spcl;
+
+struct idates
+{
+       char    id_name[16];
+       char    id_incno;
+       time_t  id_ddate;
+};
diff --git a/usr/src/cmd/clri.c b/usr/src/cmd/clri.c
new file mode 100644 (file)
index 0000000..8c2fa62
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * clri filsys inumber ...
+ */
+
+#include <sys/param.h>
+#include <sys/ino.h>
+
+#define ISIZE  (sizeof(struct dinode))
+#define        NI      (BSIZE/ISIZE)
+struct ino
+{
+       char    junk[ISIZE];
+};
+struct ino     buf[NI];
+int    status;
+
+main(argc, argv)
+char *argv[];
+{
+       register i, f;
+       unsigned n;
+       int j, k;
+       long off;
+
+       if(argc < 3) {
+               printf("usage: clri filsys inumber ...\n");
+               exit(4);
+       }
+       f = open(argv[1], 2);
+       if(f < 0) {
+               printf("cannot open %s\n", argv[1]);
+               exit(4);
+       }
+       for(i=2; i<argc; i++) {
+               if(!isnumber(argv[i])) {
+                       printf("%s: is not a number\n", argv[i]);
+                       status = 1;
+                       continue;
+               }
+               n = atoi(argv[i]);
+               if(n == 0) {
+                       printf("%s: is zero\n", argv[i]);
+                       status = 1;
+                       continue;
+               }
+               off = itod(n) * BSIZE;
+               lseek(f, off, 0);
+               if(read(f, (char *)buf, BSIZE) != BSIZE) {
+                       printf("%s: read error\n", argv[i]);
+                       status = 1;
+               }
+       }
+       if(status)
+               exit(status);
+       for(i=2; i<argc; i++) {
+               n = atoi(argv[i]);
+               printf("clearing %u\n", n);
+               off = itod(n) * BSIZE;
+               lseek(f, off, 0);
+               read(f, (char *)buf, BSIZE);
+               j = itoo(n);
+               for(k=0; k<ISIZE; k++)
+                       buf[j].junk[k] = 0;
+               lseek(f, off, 0);
+               write(f, (char *)buf, BSIZE);
+       }
+       exit(status);
+}
+
+isnumber(s)
+char *s;
+{
+       register c;
+
+       while(c = *s++)
+               if(c < '0' || c > '9')
+                       return(0);
+       return(1);
+}
diff --git a/usr/src/cmd/cp.c b/usr/src/cmd/cp.c
new file mode 100644 (file)
index 0000000..7303883
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * cp oldfile newfile
+ */
+
+#define        BSIZE   1024
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+struct stat    stbuf1, stbuf2;
+char   iobuf[BSIZE];
+
+main(argc, argv)
+char *argv[];
+{
+       register i, r;
+
+       if (argc < 3) 
+               goto usage;
+       if (argc > 3) {
+               if (stat(argv[argc-1], &stbuf2) < 0)
+                       goto usage;
+               if ((stbuf2.st_mode&S_IFMT) != S_IFDIR) 
+                       goto usage;
+       }
+       r = 0;
+       for(i=1; i<argc-1;i++)
+               r |= copy(argv[i], argv[argc-1]);
+       exit(r);
+usage:
+       fprintf(stderr, "Usage: cp: f1 f2; or cp f1 ... fn d2\n");
+       exit(1);
+}
+
+copy(from, to)
+char *from, *to;
+{
+       int fold, fnew, n;
+       register char *p1, *p2, *bp;
+       int mode;
+       if ((fold = open(from, 0)) < 0) {
+               fprintf(stderr, "cp: cannot open %s\n", from);
+               return(1);
+       }
+       fstat(fold, &stbuf1);
+       mode = stbuf1.st_mode;
+       /* is target a directory? */
+       if (stat(to, &stbuf2) >=0 &&
+          (stbuf2.st_mode&S_IFMT) == S_IFDIR) {
+               p1 = from;
+               p2 = to;
+               bp = iobuf;
+               while(*bp++ = *p2++)
+                       ;
+               bp[-1] = '/';
+               p2 = bp;
+               while(*bp = *p1++)
+                       if (*bp++ == '/')
+                               bp = p2;
+               to = iobuf;
+       }
+       if (stat(to, &stbuf2) >= 0) {
+               if (stbuf1.st_dev == stbuf2.st_dev &&
+                  stbuf1.st_ino == stbuf2.st_ino) {
+                       fprintf(stderr, "cp: cannot copy file to itself.\n");
+                       return(1);
+               }
+       }
+       if ((fnew = creat(to, mode)) < 0) {
+               fprintf(stderr, "cp: cannot create %s\n", to);
+               close(fold);
+               return(1);
+       }
+       while(n = read(fold,  iobuf,  BSIZE)) {
+               if (n < 0) {
+                       perror("cp: read");
+                       close(fold);
+                       close(fnew);
+                       return(1);
+               } else
+                       if (write(fnew, iobuf, n) != n) {
+                               perror("cp: write");
+                               close(fold);
+                               close(fnew);
+                               return(1);
+                       }
+       }
+       close(fold);
+       close(fnew);
+       return(0);
+}
diff --git a/usr/src/cmd/dump.c b/usr/src/cmd/dump.c
new file mode 100644 (file)
index 0000000..77273d3
--- /dev/null
@@ -0,0 +1,639 @@
+#define        NI      16
+#define        DIRPB   (BSIZE/sizeof(struct direct))
+
+#include <stdio.h>
+#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>
+
+#define        MWORD(m,i) (m[(unsigned)(i-1)/MLEN])
+#define        MBIT(i) (1<<((unsigned)(i-1)%MLEN))
+#define        BIS(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 dinode  itab[INOPB*NI];
+short  clrmap[MSIZ];
+short  dirmap[MSIZ];
+short  nodmap[MSIZ];
+
+char   *disk;
+char   *tape;
+char   *increm;
+char   incno;
+int    uflag;
+int    fi;
+int    to;
+ino_t  ino;
+int    nsubdir;
+int    ntape;
+int    nadded;
+int    dadded;
+int    density = 160;
+
+char   *ctime();
+char   *prdate();
+long   atol();
+int    fi;
+long   tsize;
+long   esize;
+long   asize;
+int    mark();
+int    add();
+int    dump();
+int    tapsrec();
+int    dmpspc();
+int    dsrch();
+int    nullf();
+
+#define        HOUR    (60L*60L)
+#define        DAY     (24L*HOUR)
+#define        YEAR    (365L*DAY)
+
+main(argc, argv)
+char *argv[];
+{
+       char *arg;
+       register i;
+
+       time(&spcl.c_date);
+
+       tsize = 2300L*12L*10L;
+       tape = "/dev/rmt1";
+       disk = "/dev/rrp1g";
+       increm = "/etc/ddate";
+       incno = '9';
+       uflag = 0;
+       arg = "u";
+       if(argc > 1) {
+               argv++;
+               argc--;
+               arg = *argv;
+       }
+       while(*arg)
+       switch (*arg++) {
+
+       case 'f':
+               if(argc > 1) {
+                       argv++;
+                       argc--;
+                       tape = *argv;
+               }
+               break;
+
+       case 'd':
+               if (argc > 1) {
+                       argv++;
+                       argc--;
+                       density = atoi(*argv);
+               }
+               break;
+
+       case 's':
+               if(argc > 1) {
+                       argv++;
+                       argc--;
+                       tsize = atol(*argv);
+                       tsize *= 12L*10L;
+               }
+               break;
+
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+               incno = arg[-1];
+               break;
+
+       case 'u':
+               uflag++;
+               break;
+
+       default:
+               printf("bad key '%c%'\n", arg[-1]);
+               exit(1);
+       }
+       if(argc > 1) {
+               argv++;
+               argc--;
+               disk = *argv;
+       }
+
+       getitime();
+       printf("     date = %s\n", prdate(spcl.c_date));
+       printf("dump date = %s\n", prdate(spcl.c_ddate));
+       printf("dumping %s to %s\n", disk, tape);
+       fi = open(disk, 0);
+       if(fi < 0) {
+               printf("dump: cannot open %s\n", disk);
+               exit(1);
+       }
+       otape();
+       printf("I\n");
+       esize = 0;
+       CLR(clrmap);
+       CLR(dirmap);
+       CLR(nodmap);
+
+       pass(mark, (short *)NULL);
+       do {
+               printf("II\n");
+               nadded = 0;
+               pass(add, dirmap);
+       } while(nadded);
+
+       bmapest(clrmap);
+       bmapest(nodmap);
+       printf("estimated %ld tape blocks on %d tape(s)\n",
+               esize, 0);
+
+       printf("III\n");
+       bitmap(clrmap, TS_CLRI);
+       pass(dump, dirmap);
+       printf("IV\n");
+       pass(dump, nodmap);
+       putitime();
+       printf("DONE\n");
+       spcl.c_type = TS_END;
+       for(i=0; i<NTREC; i++)
+               spclrec();
+       printf("%ld tape blocks on %d tape(s)\n",
+               spcl.c_tapea, spcl.c_volume);
+}
+
+pass(fn, map)
+int (*fn)();
+short *map;
+{
+       register i, j;
+       int bits;
+       ino_t mino;
+       daddr_t d;
+
+       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;
+               }
+       }
+}
+
+icat(ip, fn1, fn2)
+struct dinode  *ip;
+int (*fn1)(), (*fn2)();
+{
+       register i;
+       daddr_t d[NADDR];
+
+       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));
+               }
+       }
+}
+
+indir(d, fn1, fn2, n)
+daddr_t d;
+int (*fn1)(), (*fn2)();
+{
+       register i;
+       daddr_t idblk[NINDIR];
+
+       bread(d, (char *)idblk, sizeof(idblk));
+       if(n <= 0) {
+               spcl.c_type = TS_ADDR;
+               (*fn2)(idblk, NINDIR);
+               for(i=0; i<NINDIR; i++) {
+                       d = idblk[i];
+                       if(d != 0)
+                               (*fn1)(d);
+               }
+       } else {
+               n--;
+               for(i=0; i<NINDIR; i++) {
+                       d = idblk[i];
+                       if(d != 0)
+                               indir(d, fn1, fn2, n);
+               }
+       }
+}
+
+mark(ip)
+struct dinode *ip;
+{
+       register f;
+
+       f = ip->di_mode & IFMT;
+       if(f == 0)
+               return;
+       BIS(ino, clrmap);
+       if(f == IFDIR)
+               BIS(ino, dirmap);
+       if(ip->di_mtime >= spcl.c_ddate ||
+          ip->di_ctime >= spcl.c_ddate) {
+               BIS(ino, nodmap);
+               if (f != IFREG)
+                       return;
+               est(ip);
+       }
+}
+
+add(ip)
+struct dinode *ip;
+{
+
+       if(BIT(ino, nodmap))
+               return;
+       nsubdir = 0;
+       dadded = 0;
+       icat(ip, dsrch, nullf);
+       if(dadded) {
+               BIS(ino, nodmap);
+               est(ip);
+               nadded++;
+       }
+       if(nsubdir == 0)
+               if(!BIT(ino, nodmap))
+                       BIC(ino, dirmap);
+}
+
+dump(ip)
+struct dinode *ip;
+{
+       register i;
+
+       if(ntape) {
+               ntape = 0;
+               bitmap(nodmap, TS_BITS);
+       }
+       BIC(ino, nodmap);
+       spcl.c_dinode = *ip;
+       spcl.c_type = TS_INODE;
+       spcl.c_count = 0;
+       i = ip->di_mode & IFMT;
+       if(i != IFDIR && i != IFREG) {
+               spclrec();
+               return;
+       }
+       icat(ip, tapsrec, dmpspc);
+}
+
+dmpspc(dp, n)
+daddr_t *dp;
+{
+       register i, t;
+
+       spcl.c_count = n;
+       for(i=0; i<n; i++) {
+               t = 0;
+               if(dp[i] != 0)
+                       t++;
+               spcl.c_addr[i] = t;
+       }
+       spclrec();
+}
+
+bitmap(map, typ)
+short *map;
+{
+       register i, n;
+       char *cp;
+
+       n = -1;
+       for(i=0; i<MSIZ; i++)
+               if(map[i])
+                       n = i;
+       if(n < 0)
+               return;
+       spcl.c_type = typ;
+       spcl.c_count = (n*sizeof(map[0]) + BSIZE)/BSIZE;
+       spclrec();
+       cp = (char *)map;
+       for(i=0; i<spcl.c_count; i++) {
+               taprec(cp);
+               cp += BSIZE;
+       }
+}
+
+spclrec()
+{
+       register i, *ip, s;
+
+       spcl.c_inumber = ino;
+       spcl.c_magic = MAGIC;
+       spcl.c_checksum = 0;
+       ip = (int *)&spcl;
+       s = 0;
+       for(i=0; i<BSIZE/sizeof(*ip); i++)
+               s += *ip++;
+       spcl.c_checksum = CHECKSUM - s;
+       taprec((char *)&spcl);
+}
+
+dsrch(d)
+daddr_t d;
+{
+       register char *cp;
+       register i;
+       register ino_t in;
+       struct direct dblk[DIRPB];
+
+       if(dadded)
+               return;
+       bread(d, (char *)dblk, sizeof(dblk));
+       for(i=0; i<DIRPB; i++) {
+               in = dblk[i].d_ino;
+               if(in == 0)
+                       continue;
+               cp = dblk[i].d_name;
+               if(cp[0] == '.') {
+                       if(cp[1] == '\0')
+                               continue;
+                       if(cp[1] == '.' && cp[2] == '\0')
+                               continue;
+               }
+               if(BIT(in, nodmap)) {
+                       dadded++;
+                       return;
+               }
+               if(BIT(in, dirmap))
+                       nsubdir++;
+       }
+}
+
+nullf()
+{
+}
+
+bread(da, ba, c)
+daddr_t da;
+char *ba;
+{
+       register n;
+
+       lseek(fi, da*BSIZE, 0);
+       n = read(fi, ba, c);
+       if(n != c)
+               printf("asked %d; got %d\n", c, n);
+}
+
+CLR(map)
+register short *map;
+{
+       register n;
+
+       n = MSIZ;
+       do
+               *map++ = 0;
+       while(--n);
+}
+
+
+char   tblock[NTREC][BSIZE];
+daddr_t        tdaddr[NTREC];
+int    trecno;
+
+taprec(dp)
+char *dp;
+{
+       register i;
+
+       for(i=0; i<BSIZE; i++)
+               tblock[trecno][i] = *dp++;
+       tdaddr[trecno] = 0;
+       trecno++;
+       spcl.c_tapea++;
+       if(trecno >= NTREC)
+               flusht();
+}
+
+tapsrec(d)
+daddr_t d;
+{
+
+       if(d == 0)
+               return;
+       tdaddr[trecno] = d;
+       trecno++;
+       spcl.c_tapea++;
+       if(trecno >= NTREC)
+               flusht();
+}
+
+flusht()
+{
+       char place[100];
+       register i, si;
+       daddr_t d;
+
+       while(trecno < NTREC)
+               tdaddr[trecno++] = 1;
+
+loop:
+       d = 0;
+       for(i=0; i<NTREC; i++)
+               if(tdaddr[i] != 0)
+               if(d == 0 || tdaddr[i] < d) {
+                       si = i;
+                       d = tdaddr[i];
+               }
+       if(d != 0) {
+               bread(d, tblock[si], BSIZE);
+               tdaddr[si] = 0;
+               goto loop;
+       }
+       trecno = 0;
+       write(to, tblock[0], sizeof(tblock));
+       asize += sizeof(tblock)/density;
+       asize += 7;
+       if(asize > tsize) {
+               close(to);
+               printf("change tapes\n");
+               read(0, place, sizeof(place));
+               otape();
+       }
+}
+
+otape()
+{
+       to = creat(tape, 0666);
+       if(to < 0) {
+               printf("dump: cannot create %s\n", tape);
+               exit(1);
+       }
+       asize = 0;
+       ntape++;
+       spcl.c_volume++;
+       spcl.c_type = TS_TAPE;
+       spclrec();
+}
+
+char *
+prdate(d)
+time_t d;
+{
+       char *p;
+
+       if(d == 0)
+               return("the epoch");
+       p = ctime(&d);
+       p[24] = 0;
+       return(p);
+}
+
+getitime()
+{
+       register i, df;
+       struct idates idbuf;
+       char *fname;
+
+       fname = disk;
+l1:
+       for(i=0; fname[i]; i++)
+               if(fname[i] == '/') {
+                       fname += i+1;
+                       goto l1;
+               }
+
+       spcl.c_ddate = 0;
+       df = open(increm, 0);
+       if(df < 0) {
+               printf("cannot open %s\n", increm);
+               exit(1);
+       }
+
+l2:
+       i = read(df, (char *)&idbuf, sizeof(idbuf));
+       if(i != sizeof(idbuf)) {
+               close(df);
+               return;
+       }
+       for(i=0;; i++) {
+               if(fname[i] != idbuf.id_name[i])
+                       goto l2;
+               if(fname[i] == '\0')
+                       break;
+       }
+       if(idbuf.id_incno >= incno)
+               goto l2;
+       if(idbuf.id_ddate <= spcl.c_ddate)
+               goto l2;
+       spcl.c_ddate = idbuf.id_ddate;
+       goto l2;
+}
+
+putitime()
+{
+       register i, n, df;
+       struct idates idbuf;
+       char *fname;
+
+       if(uflag == 0)
+               return;
+       fname = disk;
+l1:
+       for(i=0; fname[i]; i++)
+               if(fname[i] == '/') {
+                       fname += i+1;
+                       goto l1;
+               }
+
+       spcl.c_ddate = 0;
+       df = open(increm, 2);
+       if(df < 0) {
+               printf("cannot open %s\n", increm);
+               exit(1);
+       }
+       n = 0;
+l2:
+       i = read(df, (char *)&idbuf, sizeof(idbuf));
+       if(i != sizeof(idbuf))
+               goto l3;
+       n++;
+       for(i=0;; i++) {
+               if(fname[i] != idbuf.id_name[i])
+                       goto l2;
+               if(fname[i] == '\0')
+                       break;
+       }
+       if(idbuf.id_incno != incno)
+               goto l2;
+l3:
+       lseek(df, (long)n*sizeof(idbuf), 0);
+       for(i=0;; i++) {
+               idbuf.id_name[i] = fname[i];
+               if(fname[i] == '\0')
+                       break;
+       }
+       idbuf.id_incno = incno;
+       idbuf.id_ddate = spcl.c_date;
+       write(df, (char *)&idbuf, sizeof(idbuf));
+       close(df);
+       printf("level %c dump on %s\n", incno, prdate(spcl.c_date));
+}
+
+est(ip)
+struct dinode *ip;
+{
+       long s;
+
+       esize++;
+       s = (ip->di_size + BSIZE-1) / BSIZE;
+       esize += s;
+       if(s > NADDR-3) {
+               s -= NADDR-3;
+               s = (s + (BSIZE/sizeof(daddr_t))-1) / (BSIZE/sizeof(daddr_t));
+               esize += s;
+       }
+}
+
+bmapest(map)
+short *map;
+{
+       register i, n;
+
+       n = -1;
+       for(i=0; i<MSIZ; i++)
+               if(map[i])
+                       n = i;
+       if(n < 0)
+               return;
+       esize++;
+       esize += (n + (BSIZE/sizeof(short))-1) / (BSIZE/sizeof(short));
+}