- getleaves(dir.d_ino, locname);
- fseek(df, bpt, 0);
- fread(&dir, 1, sizeof(struct direct), df);
- bpt = ftell(df);
- }
- return;
- }
- /*
- * locname is name of a simple file
- */
- allocxtr(ino, pname, XINUSE);
-}
-
-/*
- * Search the directory tree rooted at inode ROOTINO
- * for the path pointed at by n
- */
-psearch(n)
- char *n;
-{
- register char *cp, *cp1;
- char c;
-
- ino = ROOTINO;
- if (*(cp = n) == '/')
- cp++;
-next:
- cp1 = cp + 1;
- while (*cp1 != '/' && *cp1)
- cp1++;
- c = *cp1;
- *cp1 = 0;
- ino = search(ino, cp);
- if (ino == 0) {
- *cp1 = c;
- return(0);
- }
- *cp1 = c;
- if (c == '/') {
- cp = cp1+1;
- goto next;
- }
- return(ino);
-}
-
-/*
- * search the directory inode ino
- * looking for entry cp
- */
-ino_t
-search(inum, cp)
- ino_t inum;
- char *cp;
-{
- struct direct dir;
- register struct inotab *itp;
-
- for (itp = inotab[INOHASH(inum)]; itp; itp = itp->t_next)
- if (itp->t_ino == inum)
- goto found;
- return(0);
-found:
- fseek(df, itp->t_seekpt, 0);
- do {
- fread(&dir, 1, sizeof(struct direct), df);
- if (!strncmp(dir.d_name, "/", DIRSIZ))
- return(0);
- } while (strncmp(dir.d_name, cp, DIRSIZ));
- return(dir.d_ino);
-}
-#endif
-
-/*
- * Do the file extraction, calling the supplied functions
- * with the blocks
- */
-getfile(f1, f2, size)
- int (*f2)(), (*f1)();
- long size;
-{
- register int i;
- char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
- union u_spcl addrblk;
- register struct fs *fs;
-# define addrblock addrblk.s_spcl
-
- addrblock = spcl;
- fs = getfs(dev);
- for (;;) {
- for (i = 0; i < addrblock.c_count; i++) {
- if (addrblock.c_addr[i]) {
- readtape(&buf[curblk++][0]);
- if (curblk == BLKING(fs) * fs->fs_frag) {
- (*f1)(buf, size > TP_BSIZE ?
- (long) (BLKING(fs) * fs->fs_frag * TP_BSIZE) :
- (curblk - 1) * TP_BSIZE + size);
- curblk = 0;
- }
- } else {
- if (curblk > 0) {
- (*f1)(buf, size > TP_BSIZE ?
- (long) (curblk * TP_BSIZE) :
- (curblk - 1) * TP_BSIZE + size);
- curblk = 0;
- }
- (*f2)(clearedbuf, size > TP_BSIZE ?
- (long) TP_BSIZE : size);
- }
- if ((size -= TP_BSIZE) <= 0) {
-eloop:
- while (gethead(&spcl) == 0)
- ;
- if (checktype(&spcl, TS_ADDR) == 1)
- goto eloop;
- goto out;
- }
- }
- if (gethead(&addrblock) == 0) {
- fprintf(stderr, "Missing address (header) block, ino%u\n", ino);
- goto eloop;
- }
- if (checktype(&addrblock, TS_ADDR) == 0) {
- spcl = addrblock;
- goto out;
- }
- }
-out:
- if (curblk > 0) {
- (*f1)(buf, (curblk * TP_BSIZE) + size);
- curblk = 0;
- }
-}
-
-/*
- * The next routines are called during file extraction to
- * put the data into the right form and place.
- */
-#ifndef STANDALONE
-xtrfile(buf, size)
- char *buf;
- long size;
-{
- if (xwrite(ofile, buf, (int) size) == -1) {
- perror("extract write");
- done(1);
- }
-}
-
-xtrskip(buf, size)
- char *buf;
- long size;
-{
- if (xseek(ofile, size, 1) == -1) {
- perror("extract seek");
- done(1);
- }
-}
-
-xtrcvtdir(buf, size)
- struct odirect *buf;
- long size;
-{
- struct direct
- cvtbuf[MAXBSIZE / sizeof(struct odirect)];
- struct odirect *odp, *edp;
- struct direct *dp;
-
- edp = &buf[size / sizeof(struct odirect)];
- for (odp = buf, dp = cvtbuf; odp < edp; odp++, dp++)
- dcvt(odp, dp);
- size = size * sizeof(struct direct) / sizeof(struct odirect);
- if (xwrite(ofile, cvtbuf, (int) size) == -1) {
- perror("extract write");
- done(1);
- }
-}
-
-xtrcvtskip(buf, size)
- char *buf;
- long size;
-{
- fprintf(stderr, "unallocated block in directory\n");
- if (xseek(ofile, size, 1) == -1) {
- perror("extract seek");
- done(1);
- }
-}
-#endif
-
-rstrfile(buf, size)
- char *buf;
- long size;
-{
- u.u_base = buf;
- u.u_count = size;
- writei(cur_ip);
- if (u.u_error) {
- perror("restor write");
- done(1);
- }
-}
-
-rstrskip(buf, size)
- char *buf;
- long size;
-{
- u.u_offset += size;
-}
-
-rstrcvtdir(buf, size)
- struct odirect *buf;
- long size;
-{
- struct direct
- cvtbuf[MAXBSIZE / sizeof(struct odirect)];
- struct odirect *odp, *edp;
- struct direct *dp;
-
- edp = &buf[size / sizeof(struct odirect)];
- for (odp = buf, dp = cvtbuf; odp < edp; odp++, dp++)
- dcvt(odp, dp);
- u.u_base = (char *)cvtbuf;
- u.u_count = size * sizeof(struct direct) / sizeof(struct odirect);
- writei(cur_ip);
- if (u.u_error) {
- perror("restor write");
- done(1);
- }
-}
-
-rstrcvtskip(buf, size)
- char *buf;
- long size;
-{
- fprintf(stderr, "unallocated block in directory\n");
- u.u_offset += size;
-}
-
-null() {;}
-
-/*
- * Do the tape i/o, dealing with volume changes
- * etc..
- */
-readtape(b)
- char *b;
-{
- register int i;
- struct s_spcl tmpbuf;
-
- if (bct >= NTREC) {
- for (i = 0; i < NTREC; i++)
- ((struct s_spcl *)&tbf[i*TP_BSIZE])->c_magic = 0;
- bct = 0;
- if ((i = read(mt, tbf, NTREC*TP_BSIZE)) < 0) {
- perror("Tape read error");
- eflag++;
- done(1);
- }
- if (i == 0) {
- bct = NTREC + 1;
- volno++;
-loop:
- flsht();
- close(mt);
- fprintf(stderr, "Mount volume %d\n", volno);
- while (getchar() != '\n')
- ;
- if ((mt = open(magtape, 0)) == -1) {
- fprintf(stderr, "Cannot open tape!\n");
- goto loop;
- }
- if (readhdr(&tmpbuf) == 0) {
- fprintf(stderr, "Not a dump tape.Try again\n");
- goto loop;
- }
- if (checkvol(&tmpbuf, volno) == 0) {
- fprintf(stderr, "Wrong tape. Try again\n");
- goto loop;
- }
- readtape(b);
- return;
- }
- }
- copy(&tbf[(bct++*TP_BSIZE)], b, TP_BSIZE);
-}
-
-flsht()
-{
- bct = NTREC+1;
-}
-
-copy(f, t, s)
- register char *f, *t;
-{
- register int i;
-
- i = s;
- do
- *t++ = *f++;
- while (--i);
-}
-
-blkclr(buf, size)
- char *buf;
- int size;
-{
- asm("movc5 $0,(r0),$0,8(ap),*4(ap)");
-}
-
-resetmt()
-{
- struct mtop tcom;
-
- if(dumpnum > 1)
- tcom.mt_op = MTBSF;
- else
- tcom.mt_op = MTREW;
- tcom.mt_count = 1;
- flsht();
- if (ioctl(mt,MTIOCTOP,&tcom) == -1) {
- /* kludge for disk dumps */
- lseek(mt, (long)0, 0);
- }
- if (dumpnum > 1) {
- tcom.mt_op = MTFSF;
- tcom.mt_count = 1;
- ioctl(mt,MTIOCTOP,&tcom);
- }
-}
-
-checkvol(b, t)
- struct s_spcl *b;
- int t;
-{
- if (b->c_volume == t)
- return(1);
- return(0);
-}
-
-readhdr(b)
- struct s_spcl *b;
-{
- if (gethead(b) == 0)
- return(0);
- if (checktype(b, TS_TAPE) == 0)
- return(0);
- return(1);
-}
-
-/*
- * read the tape into buf, then return whether or
- * or not it is a header block.
- */
-gethead(buf)
- struct s_spcl *buf;
-{
- readtape((char *)buf);
- if (buf->c_magic != MAGIC || checksum((int *)buf) == 0)
- return(0);
- return(1);
-}
-
-/*
- * return whether or not the buffer contains a header block
- */
-ishead(buf)
- struct s_spcl *buf;
-{
- if (buf->c_magic != MAGIC || checksum((int *)buf) == 0)
- return(0);
- return(1);
-}
-
-checktype(b, t)
- struct s_spcl *b;
- int t;
-{
- return(b->c_type == t);
-}
-
-/*
- * read a bit mask from the tape into m.
- */
-readbits(m)
- char *m;
-{
- register int i;
-
- i = spcl.c_count;
-
- while (i--) {
- readtape((char *) m);
- m += (TP_BSIZE/(NBBY/BITS));
- }
- while (gethead(&spcl) == 0)
- ;
-}
-
-checksum(b)
- int *b;
-{
- register int i, j;
-
- j = sizeof(union u_spcl) / sizeof(int);
- i = 0;
- do
- i += *b++;
- while (--j);
- if (i != CHECKSUM) {
- fprintf(stderr, "Checksum error %o, ino %u\n", i, ino);
- return(0);
- }
- return(1);
-}
-
-/*
- * Check for access into each directory in the pathname of an extracted
- * file and create such a directory if needed in preparation for moving
- * the file to its proper home.
- */
-checkdir(name)
- register char *name;
-{
- register char *cp;
- int i;
-
- for (cp = name; *cp; cp++) {
- if (*cp == '/') {
- *cp = '\0';
- if (xaccess(name, 01) < 0) {
- register int pid, rp;
-
- xumount();
- if ((pid = fork()) == 0) {
- execl("/bin/xmkdir", "xmkdir", name, 0);
- execl("/usr/bin/xmkdir", "xmkdir", name, 0);
- execl("./xmkdir", "xmkdir", name, 0);
- fprintf(stderr, "xrestor: cannot find xmkdir!\n");
- done(0);
- }
- while ((rp = wait(&i)) >= 0 && rp != pid)
- ;
- xmount(envp);
- }
- *cp = '/';