V5/usr/source/s1/dump.c
#
/*
* incremental dump
* dump isuodh filesystem
* i from date in /etc/ddate
* s specify tape size in feet (feet = blocks/9)
* u update /etc/ddate to current date
* 0 dump from the epoch
* d dump specified number of days
* h dump specified number of hours
*/
char *dargv[]
{
0,
"i",
"/dev/rp0",
0
};
char *dfile "/etc/ddate";
char *ofile "/dev/mt0";
struct inode
{
int i_mode;
char i_nlink;
char i_uid;
char i_gid;
char i_size0;
char *i_size1;
int i_addr[8];
int i_atime[2];
int i_mtime[2];
};
/* modes */
#define IALLOC 0100000
#define IFMT 060000
#define IFDIR 040000
#define IFCHR 020000
#define IFBLK 060000
#define ILARG 010000
struct
{
char *s_isize;
char *s_fsize;
int s_nfree;
int s_free[100];
int s_ninode;
int s_inode[100];
char s_flock;
char s_ilock;
char s_fmod;
int time[2];
int pad[50];
} sblock;
int *talist;
int fi;
int buf[256];
int dbuf[256];
int ibuf[256];
char *date[2];
char *ddate[2];
int fo;
int pher;
int dflg;
char *tsize 19000;
main(argc, argv)
char **argv;
{
char *key;
int s, i, nfil, nblk;
register *tap;
register struct inode *ip;
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();
case 'i':
i = open(dfile, 0);
if(i >= 0) {
read(i, ddate, 4);
close(i);
}
continue;
case 's': /* tape size */
tsize = number(argv[1]) * 9;
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;
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();
}
printf("%s:\n", argv[1]);
fi = open(argv[1], 0);
if(fi < 0) {
printf("cannot open %s\n", argv[1]);
exit();
}
printf("incremental dump from\n");
pdate(ddate);
sync();
bread(1, &sblock);
talist = sbrk(size(0, sblock.s_isize*32)*512);
tap = talist;
nfil = 0;
nblk = 0;
for(i=0; i<sblock.s_isize; i++) {
bread(i+2, buf);
for(ip = &buf[0]; ip < &buf[256]; ip++) {
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, ip->i_size1);
nfil++;
nblk =+ s;
*tap = s+1;
no:
tap++;
}
}
printf("%l files\n%l blocks\n", nfil, nblk);
otape();
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;
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);
for(ip = &buf[0]; ip < &buf[256]; ip++) {
if(*tap)
dump(ip, *tap-1);
tap++;
}
}
printf("%l phase errors\n", pher);
if(dflg) {
i = open(dfile, 1);
if(i >= 0) {
write(i, date, 4);
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;
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 == 0)
continue;
if(ip->i_mode&ILARG) {
bread(*p, ibuf);
for(q = &ibuf[0]; q < &ibuf[256]; q++) {
if(*q == 0)
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 = 255;
s = 0;
p = b;
while(i--)
s =+ *p++;
*p = 031415 - s;
bwrite(b);
}
bwrite(b)
{
static char *ta;
if(ta++ > tsize) {
printf("change tapes\n");
close(fo);
rdline();
ta = 0;
otape();
}
wloop:
if(write(fo, b, 512) != 512) {
printf("write error\n");
rdline();
goto wloop;
}
}
rdline()
{
register ta;
while((ta = getchar()) != '\n')
if(ta == 0)
exit();
}
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()
{
fo = open(ofile, 1);
if(fo < 0) {
printf("can not open %s\n", ofile);
exit();
}
}