SCCS-vsn: sbin/restore/main.c 3.5
SCCS-vsn: sbin/restore/tape.c 3.6
SCCS-vsn: sbin/restore/restore.c 3.5
/* Copyright (c) 1983 Regents of the University of California */
#ifndef lint
/* Copyright (c) 1983 Regents of the University of California */
#ifndef lint
-static char sccsid[] = "@(#)main.c 3.4 (Berkeley) 83/02/28";
+static char sccsid[] = "@(#)main.c 3.5 (Berkeley) 83/03/05";
yflag++;
break;
case 'f':
yflag++;
break;
case 'f':
+ if (argc < 1) {
+ fprintf(stderr, "missing device specifier\n");
+ done(1);
+ }
inputdev = *argv++;
argc--;
break;
inputdev = *argv++;
argc--;
break;
/*
* dumpnum (skip to) for multifile dump tapes
*/
/*
* dumpnum (skip to) for multifile dump tapes
*/
+ if (argc < 1) {
+ fprintf(stderr, "missing dump number\n");
+ done(1);
+ }
dumpnum = atoi(*argv++);
if (dumpnum <= 0) {
fprintf(stderr, "Dump number must be a positive integer\n");
dumpnum = atoi(*argv++);
if (dumpnum <= 0) {
fprintf(stderr, "Dump number must be a positive integer\n");
- if (command != '\0') {
- fprintf(stderr,
- "t and %c are mutually exclusive\n",
- command);
- goto usage;
- }
- command = 't';
- break;
- if (command != '\0') {
- fprintf(stderr,
- "R and %c are mutually exclusive\n",
- command);
- goto usage;
- }
- command = 'R';
- break;
- if (command != '\0') {
- fprintf(stderr,
- "r and %c are mutually exclusive\n",
- command);
- goto usage;
- }
- command = 'r';
- break;
case 'x':
if (command != '\0') {
fprintf(stderr,
case 'x':
if (command != '\0') {
fprintf(stderr,
- "x and %c are mutually exclusive\n",
- command);
+ "%c and %c are mutually exclusive\n",
+ *cp, command);
break;
default:
fprintf(stderr, "Bad key character %c\n", *cp);
break;
default:
fprintf(stderr, "Bad key character %c\n", *cp);
fprintf(stderr, "%s: not on tape\n", name);
continue;
}
fprintf(stderr, "%s: not on tape\n", name);
continue;
}
- treescan(name, ino, listfile);
+ if (hflag)
+ treescan(name, ino, listfile);
+ else
+ listfile(name, ino, inodetype(ino));
/* Copyright (c) 1983 Regents of the University of California */
#ifndef lint
/* Copyright (c) 1983 Regents of the University of California */
#ifndef lint
-static char sccsid[] = "@(#)restore.c 3.4 (Berkeley) 83/02/28";
+static char sccsid[] = "@(#)restore.c 3.5 (Berkeley) 83/03/05";
#endif
#include "restore.h"
#endif
#include "restore.h"
- * For each directory entry, determine which catagory it falls
+ * For each directory entry, determine which category it falls
* into as follows:
* KEEP - entries that are to be left alone.
* NEW - new entries to be added.
* into as follows:
* KEEP - entries that are to be left alone.
* NEW - new entries to be added.
/*
* This routine is called once for each element in the
/*
* This routine is called once for each element in the
- * directory heirarchy, with a full path name.
+ * directory hierarchy, with a full path name.
* The "type" value is incorrectly specified as LEAF for
* directories that are not on the dump tape.
*/
* The "type" value is incorrectly specified as LEAF for
* directories that are not on the dump tape.
*/
vprintf(stdout, "Extract requested files\n");
curfile.action = SKIP;
getvol((long)1);
vprintf(stdout, "Extract requested files\n");
curfile.action = SKIP;
getvol((long)1);
+ skipmaps();
+ skipdirs();
first = lowerbnd(ROOTINO);
last = upperbnd(maxino - 1);
for (;;) {
first = lowerbnd(ROOTINO);
last = upperbnd(maxino - 1);
for (;;) {
- skipmaps();
- skipdirs();
first = lowerbnd(first);
last = upperbnd(last);
first = lowerbnd(first);
last = upperbnd(last);
+ /*
+ * Check to see if any files remain to be extracted
+ */
if (first > last)
return;
if (first > last)
return;
+ /*
+ * Reject any volumes with inodes greater
+ * than the last one needed
+ */
while (curfile.ino > last) {
curfile.action = SKIP;
getvol((long)0);
while (curfile.ino > last) {
curfile.action = SKIP;
getvol((long)0);
- if (volno == 1) {
- skipmaps();
- skipdirs();
- }
+ skipmaps();
+ skipdirs();
+ /*
+ * Decide on the next inode needed.
+ * Skip across the inodes until it is found
+ * or an out of order volume change is encountered
+ */
next = lowerbnd(curfile.ino);
do {
curvol = volno;
while (next > curfile.ino && volno == curvol)
skipfile();
next = lowerbnd(curfile.ino);
do {
curvol = volno;
while (next > curfile.ino && volno == curvol)
skipfile();
+ skipmaps();
+ skipdirs();
} while (volno == curvol + 1);
} while (volno == curvol + 1);
+ /*
+ * If volume change out of order occurred the
+ * current state must be re calculated
+ */
if (volno != curvol)
continue;
if (volno != curvol)
continue;
+ /*
+ * If the current inode is greater than the one we were
+ * looking for then we missed the one we were looking for.
+ * Since we only attempt to extract files listed in the
+ * dump map, the file must have been lost due to a tape
+ * read error. Thus we report all requested files between
+ * the one we were looking for, and the one we found as
+ * missing, and delete their request flags.
+ */
while (next < curfile.ino) {
ep = lookupino(next);
if (ep == NIL)
panic("corrupted symbol table\n");
fprintf(stderr, "%s: not found on tape\n", myname(ep));
ep->e_flags &= ~NEW;
while (next < curfile.ino) {
ep = lookupino(next);
if (ep == NIL)
panic("corrupted symbol table\n");
fprintf(stderr, "%s: not found on tape\n", myname(ep));
ep->e_flags &= ~NEW;
- next = lowerbnd(next + 1);
+ /*
+ * The current inode is the one that we are looking for,
+ * so extract it per its requested name.
+ */
if (next == curfile.ino && next <= last) {
ep = lookupino(next);
if (ep == NIL)
if (next == curfile.ino && next <= last) {
ep = lookupino(next);
if (ep == NIL)
/* Copyright (c) 1983 Regents of the University of California */
#ifndef lint
/* Copyright (c) 1983 Regents of the University of California */
#ifndef lint
-static char sccsid[] = "@(#)tape.c 3.5 (Berkeley) 83/02/28";
+static char sccsid[] = "@(#)tape.c 3.6 (Berkeley) 83/03/05";
#endif
#include "restore.h"
#endif
#include "restore.h"
magtape = index(host, ':');
if (magtape == 0) {
nohost:
magtape = index(host, ':');
if (magtape == 0) {
nohost:
- msg("need keyletter ``f'' and device ``host:tape''");
+ msg("need keyletter ``f'' and device ``host:tape''\n");
done(1);
}
*magtape++ = '\0';
done(1);
}
*magtape++ = '\0';
- if (readhdr(&spcl) == FAIL) {
+ if (gethead(&spcl) == FAIL) {
bct--; /* push back this block */
cvtflag++;
bct--; /* push back this block */
cvtflag++;
- if (readhdr(&spcl) == FAIL) {
+ if (gethead(&spcl) == FAIL) {
fprintf(stderr, "Tape is not a dump tape\n");
done(1);
}
fprintf(stderr, "Tape is not a dump tape\n");
done(1);
}
else
newvol = 0;
while (newvol <= 0) {
else
newvol = 0;
while (newvol <= 0) {
- fprintf(stderr, "Specify volume #: ");
+ fprintf(stderr, "Specify next volume #: ");
if (gets(tbf) == NULL)
continue;
newvol = atoi(tbf);
if (gets(tbf) == NULL)
continue;
newvol = atoi(tbf);
if (newvol == volno)
return;
closemt();
if (newvol == volno)
return;
closemt();
- fprintf(stderr, "Mount tape volume %d then type return: ", newvol);
+ fprintf(stderr, "Mount tape volume %d then type return ", newvol);
while (getchar() != '\n')
;
#ifdef RRESTOR
while (getchar() != '\n')
;
#ifdef RRESTOR
if (curfile.action == USING) {
if (volno == 1)
panic("active file into volume 1\n");
if (curfile.action == USING) {
if (volno == 1)
panic("active file into volume 1\n");
- if (readhdr(&spcl) == FAIL)
- panic("no header after volume mark!\n");
findinode(&spcl, curfile.action == UNKNOWN ? 1 : 0);
if (gettingfile) {
gettingfile = 0;
findinode(&spcl, curfile.action == UNKNOWN ? 1 : 0);
if (gettingfile) {
gettingfile = 0;
if ((size -= TP_BSIZE) <= 0)
break;
}
if ((size -= TP_BSIZE) <= 0)
break;
}
- if (gethead(&spcl) == GOOD && size > 0) {
+ if (readhdr(&spcl) == GOOD && size > 0) {
if (checktype(&spcl, TS_ADDR) == GOOD)
goto loop;
fprintf(stderr, "Missing address (header) block for %s\n",
if (checktype(&spcl, TS_ADDR) == GOOD)
goto loop;
fprintf(stderr, "Missing address (header) block for %s\n",
- if (gethead(b) == FAIL)
+ if (gethead(b) == FAIL) {
+ dprintf(stderr, "readhdr fails at %d blocks\n", blksread);
gethead(buf)
struct s_spcl *buf;
{
gethead(buf)
struct s_spcl *buf;
{
union u_ospcl {
char dummy[TP_BSIZE];
struct s_ospcl {
union u_ospcl {
char dummy[TP_BSIZE];
struct s_ospcl {
if (!cvtflag) {
readtape((char *)buf);
if (!cvtflag) {
readtape((char *)buf);
- if (buf->c_magic != NFS_MAGIC || checksum((int *)buf) == FAIL) {
- dprintf(stderr, "gethead fails at %d blocks\n",
- blksread);
+ if (buf->c_magic != NFS_MAGIC || checksum((int *)buf) == FAIL)
- }
- if (dflag)
- accthdr(buf);
- return(GOOD);
}
readtape((char *)(&u_ospcl.s_ospcl));
bzero((char *)buf, (long)TP_BSIZE);
}
readtape((char *)(&u_ospcl.s_ospcl));
bzero((char *)buf, (long)TP_BSIZE);
buf->c_count = u_ospcl.s_ospcl.c_count;
bcopy(u_ospcl.s_ospcl.c_addr, buf->c_addr, (long)256);
if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
buf->c_count = u_ospcl.s_ospcl.c_count;
bcopy(u_ospcl.s_ospcl.c_addr, buf->c_addr, (long)256);
if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
- checksum((int *)(&u_ospcl.s_ospcl)) == FAIL) {
- dprintf(stderr, "gethead fails at %d blocks\n", blksread);
+ checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
buf->c_magic = NFS_MAGIC;
buf->c_magic = NFS_MAGIC;
+
+good:
+ switch (buf->c_type) {
+
+ case TS_CLRI:
+ case TS_BITS:
+ /*
+ * Have to patch up missing information in bit map headers
+ */
+ buf->c_inumber = 0;
+ buf->c_dinode.di_size = buf->c_count * TP_BSIZE;
+ for (i = 0; i < buf->c_count; i++)
+ buf->c_addr[i]++;
+ break;
+
+ case TS_TAPE:
+ case TS_END:
+ buf->c_inumber = 0;
+ break;
+
+ case TS_INODE:
+ case TS_ADDR:
+ break;
+
+ default:
+ panic("gethead: unknown inode type %d\n", buf->c_type);
+ break;
+ }
if (dflag)
accthdr(buf);
return(GOOD);
if (dflag)
accthdr(buf);
return(GOOD);
accthdr(header)
struct s_spcl *header;
{
accthdr(header)
struct s_spcl *header;
{
- static ino_t previno = 0;
+ static ino_t previno = 0xffffffff;
static int prevtype;
static long predict;
long blks, i;
static int prevtype;
static long predict;
long blks, i;
+ if (header->c_type == TS_TAPE) {
+ fprintf(stderr, "Volume header\n");
+ return;
+ }
+ if (previno == 0xffffffff)
goto newcalc;
switch (prevtype) {
goto newcalc;
switch (prevtype) {
- case TS_TAPE:
- fprintf(stderr, "Volume");
- break;
- fprintf(stderr, "Dump mask");
+ fprintf(stderr, "Dump mask header");
- fprintf(stderr, "Remove mask");
+ fprintf(stderr, "Remove mask header");
- fprintf(stderr, "File");
+ fprintf(stderr, "File header, ino %d", previno);
- fprintf(stderr, "File continuation");
+ fprintf(stderr, "File continuation header, ino %d", previno);
- fprintf(stderr, "End of tape");
+ fprintf(stderr, "End of tape header");
- fprintf(stderr, " header, ino %d", previno);
if (predict != blksread - 1)
fprintf(stderr, "; predicted %d blocks, got %d blocks",
predict, blksread - 1);
fprintf(stderr, "\n");
newcalc:
blks = 0;
if (predict != blksread - 1)
fprintf(stderr, "; predicted %d blocks, got %d blocks",
predict, blksread - 1);
fprintf(stderr, "\n");
newcalc:
blks = 0;
- if (header->c_type != TS_TAPE && header->c_type != TS_END)
+ if (header->c_type != TS_END)
for (i = 0; i < header->c_count; i++)
if (header->c_addr[i] != 0)
blks++;
for (i = 0; i < header->c_count; i++)
if (header->c_addr[i] != 0)
blks++;
int complain;
{
static long skipcnt = 0;
int complain;
{
static long skipcnt = 0;
curfile.name = "<name unknown>";
curfile.action = UNKNOWN;
curfile.name = "<name unknown>";
curfile.action = UNKNOWN;
}
if (checktype(header, TS_CLRI) == GOOD) {
curfile.name = "<file removal list>";
}
if (checktype(header, TS_CLRI) == GOOD) {
curfile.name = "<file removal list>";
- header->c_dinode.di_size = header->c_count * TP_BSIZE;
- for (i = 0; i < header->c_count; i++)
- header->c_addr[i]++;
break;
}
if (checktype(header, TS_BITS) == GOOD) {
curfile.name = "<file dump list>";
break;
}
if (checktype(header, TS_BITS) == GOOD) {
curfile.name = "<file dump list>";
- header->c_dinode.di_size = header->c_count * TP_BSIZE;
- for (i = 0; i < header->c_count; i++)
- header->c_addr[i]++;
break;
}
while (gethead(header) == FAIL)
break;
}
while (gethead(header) == FAIL)