USG_PG3/usr/source/cmd4/restor.c
#
/*
* restore from incremental dumps
*/
char *dargv[]
{
0,
"t",
0
};
char *ifile "/dev/rmt0";
char *ifile1 "/dev/rmt2";
char *ofile;
#include "../head/ino.h"
#include "../head/filsys.h"
struct filsys sblock;
int isize;
int *talist;
int bufsiz;
int fi;
int *bigbuf;
int buf[256];
int dbuf[256];
int cbuf[256];
char *date[2];
char *ddate[2];
int fo;
int pher;
char *tsize;
int recsiz;
int iflg;
int wflg;
int cflg;
char file[10];
int ilist[100];
main(argc, argv)
char **argv;
{
char *key;
register *tap, *p;
register struct inode *ip;
int i, com, sz, *q, l;
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 't':
case 'r':
case 'x':
com = key[-1];
continue;
case 'i':
iflg++;
continue;
case '-':
continue;
case 'c':
cflg++;
continue;
case 'f':
argv++;
argc--;
ifile = *argv;
continue;
case 'w':
wflg++;
continue;
case 'q':
ifile = ifile1;
continue;
}
otape(1);
i = read(fi,buf,512);
if(i != 512){
printf("Read error in super-block ! Is tape drive key set ?\n");
}
i = 0;
tap = buf;
for(l = 0;l < 256;l++)
i =+ *tap++;
if(i != 031415){
printf("Checksum error in the super-block !\n");
if(!iflg)
exit(0);
}
close(fi);
otape(0);
tap = buf;
isize = *tap++;
*tap++; /* fsize */
date[0] = *tap++;
date[1] = *tap++;
ddate[0] = *tap++;
ddate[1] = *tap++;
tsize = *tap++;
recsiz = *tap++;
if(recsiz == 0)
recsiz = 1;
printf("The record size of this tape = %d blocks\n",recsiz);
bufsiz = recsiz*512;
bigbuf = sbrk(bufsiz);
if(bigbuf == -1){
printf("No memory !\n");
exit(0);
}
rawin(1,0,1);
sread(buf, 0);
i = size(0, isize*32);
talist = sbrk(i*512);
if(talist == -1){
printf("NO memory !\n");
exit(0);
}
tap = talist;
while(i--) {
tread(tap, 0);
tap =+ 256;
}
switch(com) {
case 't':
l = 0;
com = 0;
pdate(ddate);
pdate(date);
tap = talist;
for(i=0; i<isize*16; i++) {
sz = *tap++;
if(sz == 0 || sz == -1) {
if(com == 0)
continue;
if(i == com) {
printf("%l", i);
l =+ 5;
} else {
printf("%l-%l", com, i);
l =+ 10;
}
if(l > 60) {
printf("\n");
l = 0;
} else
printf(",");
com = 0;
} else
if(com == 0)
com = i+1;
}
if(com)
printf("%l-\n", com);
printf("\n");
exit(0);
case 'r':
if(argc <= 1) {
printf("no filesystem name\n");
exit(0);
}
ofile = argv[1];
fo = open(ofile, 2);
if(fo < 0) {
printf("can not open %s\n", ofile);
exit(0);
}
printf("last chance before scribbling on %s\n", ofile);
rdline();
dread(1, &sblock);
tap = talist;
for(i=0; i<sblock.s_isize; i++) {
if(i >= isize)
break;
dread(i+2, buf);
for(ip = &buf[0]; ip < &buf[256]; ip++) {
sz = *tap++;
if(sz == 0)
continue;
dealoc(ip);
if(sz == -1) {
for(p = ip; p < &ip->i_mtime[2]; )
*p++ = 0;
continue;
}
sread(dbuf, 0);
q = dbuf;
for(p = ip; p < &ip->i_mtime[2]; )
*p++ = *q++;
restor(ip, sz-1);
}
dwrite(i+2, buf);
}
dwrite(1, &sblock);
com = 0;
for(; i < isize; i++)
for(l = 0; l < 16; l++) {
sz = *tap++;
if(sz != 0 && sz != -1)
com++;
}
if(com)
printf("%l files not restored - small ilist\n", com);
exit(0);
case 'x':
i = 0;
tap = ilist;
while(argc > 1) {
i++;
sz = number(argv[1]);
argv++;
argc--;
if(sz <= 0 || sz >=isize*16) {
printf("%l not in range\n", sz);
continue;
}
if(talist[sz-1] == 0) {
printf("%l not dumped\n", sz);
continue;
}
if(talist[sz-1] == -1) {
printf("%l does not exist\n", sz);
continue;
}
*tap++ = sz;
}
if(i != 0 && ilist[0] == 0)
exit(0);
tap = talist;
for(i=1; i<=isize*16; i++) {
if(ilist[0] != 0) {
for(sz=0; ilist[sz]; sz++)
if(ilist[sz] == i)
goto yes;
sz = *tap++;
no:
if(sz == -1)
sz = 0;
while(sz--)
tread(dbuf, 1);
continue;
}
yes:
sz = *tap++;
if(sz == 0 || sz == -1)
continue;
fo = dwait(i);
if(fo < 0)
goto no;
sz--;
sread(buf, 0);
ip = buf;
while(sz--) {
tread(dbuf, 0);
com = 512;
if(ip->i_size0 == 0 && ip->i_size1 < 512)
com = ip->i_size1;
write(fo, dbuf, com);
if(com > ip->i_size1)
ip->i_size0--;
ip->i_size1 =- com;
}
close(fo);
chmod(file, ip->i_mode);
chown(file, ip->i_uid);
}
exit(0);
}
}
dealoc(p)
struct inode *p;
{
register struct inode *ip;
register i, j;
int k;
int xbuf[256], ybuf[256];
ip = p;
if(ip->i_mode & (IFCHR&IFBLK))
return;
for(i=7; i>=0; i--)
if(ip->i_addr[i]) {
if(ip->i_mode&ILARG) {
dread(ip->i_addr[i], xbuf);
for(j=255; j>=0; j--)
if(xbuf[j]) {
/* this section for huge files */
/*if(i == 7) {
dread(xbuf[j], ybuf);
for(k=255; k>=0; k--)
if(ybuf[k])
free(ybuf[k]);
}*/
free(xbuf[j]);
}
}
free(ip->i_addr[i]);
}
}
restor(p, sz)
struct inode *p;
{
register struct inode *ip;
register i, j;
int xbuf[256];
ip = p;
if(ip->i_mode & (IFCHR&IFBLK))
return;
for(i=0; i<8; i++)
ip->i_addr[i] = 0;
if(sz <= 8) {
for(i=0; i<sz; i++)
ip->i_addr[i] = rcop();
ip->i_mode =& ~ILARG;
return;
}
for(i=0; i<256; i++)
xbuf[i] = 0;
for(j=0; sz >= 256; j++) {
/*if(j <= 7) huge*/
ip->i_addr[j] = alloc();
/*if(j >= 7) huge*/
/*xbuf[j-7] = alloc(); huge*/
for(i=0; i<256; i++)
dbuf[i] = rcop();
/*if(j < 7) huge*/
dwrite(ip->i_addr[j], dbuf);
/*else dwrite(xbuf[j-7], dbuf); huge*/
sz =- 256;
}
if(sz) {
/*if(j <= 7) huge*/
ip->i_addr[j] = alloc();
/*if(j >= 7) huge*/
/*xbuf[j-7] = alloc(); huge*/
for(i=0; i<sz; i++)
dbuf[i] = rcop();
for(; i<256; i++)
dbuf[i] = 0;
/*if(j < 7) huge*/
dwrite(ip->i_addr[j], dbuf);
/*else dwrite(xbuf[j-7], dbuf); huge*/
}
/*if(j >= 7) huge*/
/*dwrite(ip->i_addr[7], xbuf); huge*/
ip->i_mode =| ILARG;
}
rcop()
{
register b;
b = alloc();
tread(cbuf, 0);
dwrite(b, cbuf);
return(b);
}
pdate(d)
int *d;
{
if(d[0] == 0 && d[1] == 0)
printf("the epoch\n"); else
printf(ctime(d));
}
dread(bno, b)
{
seek(fo, bno, 3);
if(read(fo, b, 512) != 512) {
printf("disk read error %l\n", bno);
exit(0);
}
}
dwrite(bno, b)
{
seek(fo, bno, 3);
if(write(fo, b, 512) != 512) {
printf("disk write error %l\n", bno);
exit(0);
}
}
sread(b, flag)
int *b;
{
register i, s, *p;
tread(b, flag);
if(flag)
return;
i = 256;
s = 0;
p = b;
while(i--)
s =+ *p++;
if(s != 031415) {
printf("checksum error\n");
if(!iflg)
exit(0);
}
}
tread(b, flag)
int *b;
{
register c;
static char *pta, *ctflg, *ntape;
static int tapeno;
int *p, pt;
if(pta++ >= recsiz) {
pta = 1;
ctflg++;
ntape++;
if(ntape == tsize){
ctflg = 1;
ntape = 1;
tapeno++;
}
}
if(flag)
return;
if(ctflg) {
rawin(ctflg,tapeno,ntape);
ctflg = 0;
tapeno = 0;
}
pt = pta;
p = bigbuf + (pt - 1)*256;
for(pt = 0;pt < 256;pt++)
*b++ = *p++;
}
rawin(ctflg,tapeno,ntape)
char *ctflg;
{
register *b, i;
int c;
if(tapeno){
printf("change tapes\n");
if(tapeno > 1)
printf("skip %d tapes\n",tapeno-1);
close(fi);
if (!cflg)
rdline();
otape(0);
}
for(i = ctflg-1;i > 0;i--){
if(read(fi, bigbuf, bufsiz) != bufsiz)
printf("read error at record %l\n",ntape);
}
if(read(fi, bigbuf, bufsiz) != bufsiz) {
printf("read error at record %l\n",ntape);
if(!iflg)
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(flg)
{
register char *p;
while(( fi = open(ifile, 0)) < 0){
printf("can not open %s\n", ifile);
rdline();
}
if(!cflg || flg)
return;
p = ifile;
while(*p++)
;
p[-2]++;
}
rdline()
{
char c;
while(read(0,&c,1) != '\0'){
if(c == '\n')
return;
}
exit(0);
}
dwait(ino)
{
register i, yflg;
dconv(ino, file);
if(wflg){
printf("%s ",file);
while((i = getchar()) != '\n'){
if(i == 'y') yflg++;
if(i == 'x') exit(0);
}
if(yflg)
return(creat(file, 0666));
else return(-1);
}
return(creat(file, 0666));
}
dconv(n, p)
char *p;
{
register i;
if(i = ldiv(0, n, 10))
p = dconv(i, p);
*p++ = lrem(0, n, 10) + '0';
*p = '\0';
return(p);
}
alloc()
{
register b, i;
i = --sblock.s_nfree;
if(i<0 || i>=100) {
printf("bad freeblock\n");
exit(0);
}
b = sblock.s_free[i];
if(b == 0) {
printf("out of freelist\n");
exit(0);
}
if(sblock.s_nfree <= 0) {
dread(b, cbuf);
sblock.s_nfree = cbuf[0];
for(i=0; i<100; i++)
sblock.s_free[i] = cbuf[i+1];
}
return(b);
}
free(in)
{
register i;
if(sblock.s_nfree >= 100) {
cbuf[0] = sblock.s_nfree;
for(i=0; i<100; i++)
cbuf[i+1] = sblock.s_free[i];
sblock.s_nfree = 0;
dwrite(in, cbuf);
}
sblock.s_free[sblock.s_nfree++] = in;
}