USG_PG3/usr/source/cmd1/dump.c
#
/*
* incremental dump
* dump fisbuodh filesystem
* f take output tape from arglist
* i from date in /etc/dtab
* s specify tape size in feet
* b specify tape size in blocks
* u update /etc/dtab to current date
* 0 dump from the epoch
* d dump specified number of days
* h dump specified number of hours
* a on incremental dump, dump files even >= MAXSIZE
* p old format 512 byte records
* n new format specify blocks per record
* q quick format 1600 bpi
*/
char *dargv[]
{
0,
"i",
"/dev/rp0",
0
};
#include "../head/ino.h"
#include "../head/filsys.h"
#define MAXSIZE 1000
struct filsys sblock;
struct
{
char name[16];
int date[2];
} dtab[10];
char *dfile "/etc/dtab";
char *ofile "/dev/rmt0"; /* defalt output */
char *qfile "/dev/rmt2"; /* 1600 bpi output */
char *pfile "/dev/mt0"; /* buffered output */
int *talist;
int fi;
int *bigbuf;
int bufsize;
int inum;
int buf[256];
int dbuf[256];
int ibuf[256];
int vbuf[256];
char *date[2];
char *ddate[2];
char *barg;
char *sarg;
char *narg;
int fo -1;
int pher;
int dflg;
int iflg;
int cflg;
int aflg;
int bflg;
int sflg;
int pflg;
int nflg;
int qflg;
int recsiz;
char *tsize;
char *taddr;
main(argc, argv)
char **argv;
{
char *key;
int s, i, nfil, nblk, f;
register *tap;
register struct inode *ip;
int ino;
long n;
time(date);
if(argc == 1) {
argv = dargv;
for(argc = 1; dargv[argc]; argc++);
}
argc--;
argv++;
key = *argv;
while(*key)
switch(*key++) {
default:
printf("bad character in key\n");
exit(0);
case 'a': /* dump all (even large) */
aflg++;
continue;
case '-':
continue;
case 'c': /* increment file name */
cflg++;
continue;
case 'f': /* file name from arg list */
argc--;
argv++;
qfile = *argv;
ofile = qfile;
continue;
case 'i': /* date from date file */
iflg++;
continue;
case 's': /* tape size */
sarg = argv[1];
sflg++;
argv++;
argc--;
continue;
case 'b': /* tape size */
barg = argv[1];
bflg++;
argv++;
argc--;
continue;
case 'u': /* rewrite date */
dflg++;
continue;
case '0': /* dump all */
ddate[0] = ddate[1] = 0;
continue;
case 'd': /* dump some number of days */
i = 21600;
goto sd;
case 'h': /* dump some number of hours */
i = 900;
goto sd;
case 'p': /* dump 512 byte records */
pflg++;
qfile = pfile;
ofile = qfile;
continue;
case 'n': /* dump recsiz*512 byte records */
narg = argv[1];
nflg++;
argv++;
argc--;
continue;
case 'q': /* 1600 bpi */
ofile = qfile;
qflg++;
continue;
sd:
ddate[0] = date[0];
ddate[1] = date[1];
s = number(argv[1])*4;
argv++;
argc--;
while(s) {
if(i > ddate[1])
ddate[0]--;
ddate[1] =- i;
s--;
}
continue;
}
if(argc <= 1) {
printf("no file system specified\n");
exit(0);
}
info();
bigbuf = sbrk(bufsize);
if(bigbuf == -1){
printf("No memory\n");
exit(0);
}
if(iflg) {
f = open(dfile, 0);
if(f >= 0) {
read(f, dtab, sizeof dtab);
close(f);
for(i=0; i<10; i++)
if(equal(dtab[i].name, argv[1])) {
ddate[0] = dtab[i].date[0];
ddate[1] = dtab[i].date[1];
}
}
}
printf("%s:\n", argv[1]);
fi = open(argv[1], 0);
if(fi < 0) {
printf("cannot open %s\n", argv[1]);
exit(0);
}
printf("incremental dump from\n");
pdate(ddate);
sync();
bread(1, &sblock);
talist = sbrk(size(0, sblock.s_isize*32)*512);
tap = talist;
if(tap == -1) {
printf("No memory\n");
exit(0);
}
nfil = 0;
nblk = size(0, sblock.s_isize*32);
n = nblk;
ino = 0;
for(i=0; i<sblock.s_isize; i++) {
bread(i+2, buf);
for(ip = &buf[0]; ip < &buf[256]; ip++) {
ino++;
if(ip->i_mode == 0 || ip->i_nlink == 0) {
*tap++ = -1;
continue;
}
if(ip->i_mtime[0] < ddate[0])
goto no;
if(ip->i_mtime[0] == ddate[0] &&
ip->i_mtime[1] < ddate[1])
goto no;
s = size(ip->i_size0&0377, ip->i_size1) + 1;
if (s>MAXSIZE && aflg==0 && iflg!=0) {
printf("%l big; not dumped.\n", ino);
goto no;
}
nfil++;
n =+ s;
*tap++ = s;
continue;
no:
*tap++ = 0;
}
}
printf("%l files\n%D blocks\n", nfil, n);
i = tsize;
n = n*100l;
i = (n/i)/recsiz;
s = i%100;
printf("%l.%l%l tapes\n", i/100, s/10, (s-(s/10)*10));
tap = buf;
clrbuf(tap);
*tap++ = sblock.s_isize;
*tap++ = sblock.s_fsize;
*tap++ = date[0];
*tap++ = date[1];
*tap++ = ddate[0];
*tap++ = ddate[1];
*tap++ = tsize;
*tap++ = recsiz;
swrite(buf);
i = size(0, sblock.s_isize*32);
tap = talist;
while(i--) {
bwrite(tap);
tap =+ 256;
}
tap = talist;
for(i=0; i<sblock.s_isize; i++) {
bread(i+2, buf);
s = 1;
for(ip = &buf[0]; ip < &buf[256]; ip++) {
inum = i*16 + s;
if(*tap && *tap != -1)
dump(ip, *tap-1);
tap++;
s++;
}
}
rawout();
printf("%l phase errors\n", pher);
if(!dflg)
exit(0);
for(i=0; i<10; i++)
dtab[i].name[0] = 0;
f = open(dfile, 2);
if(f < 0) {
f = creat(dfile, 0666);
if(f < 0) {
printf("cannot create %s\n", dfile);
exit(0);
}
} else
read(f, dtab, sizeof dtab);
for(i=0; i<10; i++)
if(dtab[i].name[0] == 0 || equal(dtab[i].name, argv[1]))
goto found;
printf("%s full\n", dfile);
exit(0);
found:
for(s=0; s<15; s++) {
dtab[i].name[s] = argv[1][s];
if(argv[1][s] == 0)
break;
}
dtab[i].date[0] = date[0];
dtab[i].date[1] = date[1];
seek(f, 0, 0);
write(f, dtab, sizeof dtab);
printf("date updated\n");
pdate(date);
}
pdate(d)
int *d;
{
if(d[0] == 0 && d[1] == 0)
printf("the epoch\n"); else
printf(ctime(d));
}
dump(ip, sz)
struct inode *ip;
{
register *p, *q, *r;
p = dbuf;
q = ip;
clrbuf(p);
while(q < &ip->i_mtime[2])
*p++ = *q++;
swrite(dbuf);
if(ip->i_mode & (IFBLK&IFCHR)) {
if(sz != 0)
printf("special\n");
return;
}
for(p = &ip->i_addr[0]; p < &ip->i_addr[8]; p++)
if(*p) {
if(ip->i_mode&ILARG) {
bread(*p, ibuf);
for(q = &ibuf[0]; q < &ibuf[256]; q++)
if(*q) {
/*this section dumps huge files*/
/*if(p == &ip->i_addr[7]) {
bread(*q, vbuf);
for(r = &vbuf[0]; r < &vbuf[256]; r++)
if(*r) {
if(--sz < 0)
goto pe;
bread(*r, dbuf);
bwrite(dbuf);
}
continue;
}*/
if(--sz < 0)
goto pe;
bread(*q, dbuf);
bwrite(dbuf);
}
} else {
if(--sz < 0)
goto pe;
bread(*p, dbuf);
bwrite(dbuf);
}
}
if(sz)
goto pe;
return;
pe:
clrbuf(dbuf);
while(--sz >= 0)
bwrite(dbuf);
pher++;
}
bread(bno, b)
{
seek(fi, bno, 3);
if(read(fi, b, 512) != 512) {
printf("read error %l\n", bno);
}
}
clrbuf(b)
int *b;
{
register i, *p;
p = b;
i = 256;
while(i--)
*p++ = 0;
}
swrite(b)
int *b;
{
register i, s, *p;
i = 253;
s = taddr + 1 + inum;
p = b;
while(i--)
s =+ *p++;
*p++ = inum;
*p++ = taddr + 1;
*p = 031415 - s;
bwrite(b);
}
bwrite(b)
{
register *p,*g;
int f,j;
static int i;
g = b;
p = bigbuf + i*(256);
for(j = 0;j < 256; j++) *p++ = *g++;
if(++i == recsiz) {
rawout();
i = 0;
}
}
rawout()
{
static int nrec;
int *ta ,*bi;
if(taddr == 0) {
if(fo != -1) {
printf("change tapes\n");
close(fo);
if(!cflg)
rdline();
}
otape();
}
ta = taddr;
bi = bigbuf;
while(write(fo, bi, bufsize) != bufsize) {
printf("write error\n");
printf("no. of records = %d\n",ta);
rdline();
}
taddr++;
if(taddr >= tsize)
taddr = 0;
for(ta = bigbuf; ta < bigbuf + (bufsize/2); ta++)
*ta = 0;
}
rdline()
{
char c;
while(read(0,&c,1) != 0){
if(c == '\n')
return;
}
exit(0);
}
number(s)
char *s;
{
register n, c;
n = 0;
while(c = *s++) {
if(c<'0' || c>'9')
continue;
n = n*10+c-'0';
}
return(n);
}
size(s0, s1)
{
register s;
extern ldivr;
s = ldiv(s0&0377, s1, 512);
if(ldivr)
s++;
return(s);
}
otape()
{
register char *p;
fo = creat(ofile, 0666);
if(fo < 0) {
printf("can not open %s\n", ofile);
exit(0);
}
if(!cflg)
return;
p = ofile;
while(*p++)
;
p[-2]++;
}
equal(a, b)
char *a, *b;
{
while(*a++ == *b)
if(*b++ == 0)
return(1);
return(0);
}
info()
{
int div, feet, i;
char *bsize;
long n;
bufsize = 5120;
feet = 2200;
i = 64;
if(pflg)
bufsize = 512;
else if(nflg)
bufsize = 512*number(narg);
if(sflg)
feet = number(sarg);
if(qflg && !pflg)
i = 32;
recsiz = bufsize/512;
div = ((i*recsiz)+60)/10;
if(tsize = (feet/div)*120);
else tsize = 1;
if(bflg){
n = number(barg);
n = n & 0177777l;
bsize = n/recsiz;
if(bsize > tsize){
printf("too many blocks for this tape\n");
exit(0);
}
tsize = bsize;
feet = (tsize/120)*div;
}
printf("tape size = %d records\n",tsize);
printf("each record is %d blocks long\n",recsiz);
printf("the tape must be longer than %d feet\n",feet);
}