- (void)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;
-{
- register struct direct *dp;
- register struct inotab *itp;
- int len;
-
- for (itp = inotab[INOHASH(inum)]; itp; itp = itp->t_next)
- if (itp->t_ino == inum)
- goto found;
- return(0);
-found:
- seekdir(dirp, itp->t_seekpt, itp->t_seekpt);
- len = strlen(cp);
- do {
- dp = readdir(dirp);
- if (dp->d_namlen == 1 && dp->d_name[0] == '/')
- return(0);
- } while (dp->d_namlen != len || strncmp(dp->d_name, cp, len));
- return(dp->d_ino);
-}
-
-/*
- * Do the file extraction, calling the supplied functions
- * with the blocks
- */
-getfile(f1, f2, size)
- int (*f2)(), (*f1)();
- off_t size;
-{
- register int i;
- char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
- union u_spcl addrblk;
-# define addrblock addrblk.s_spcl
-
- addrblock = spcl;
- for (;;) {
- for (i = 0; i < addrblock.c_count; i++) {
- if (addrblock.c_addr[i]) {
- readtape(&buf[curblk++][0]);
- if (curblk == fssize / TP_BSIZE) {
- (*f1)(buf, size > TP_BSIZE ?
- (long) (fssize) :
- (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) {
- gethead(&spcl);
- goto out;
- }
- }
- if (gethead(&addrblock) == 0) {
- fprintf(stderr, "Missing address (header) block for %s\n",
- entry->x_name);
- spcl.c_magic = 0;
- goto out;
- }
- 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.
- */
-xtrfile(buf, size)
- char *buf;
- long size;
-{
-
- if (write(ofile, buf, (int) size) == -1) {
- perror("extract write");
- done(1);
- }
-}
-
-xtrskip(buf, size)
- char *buf;
- long size;
-{
-
-#ifdef lint
- buf = buf;
-#endif
- if (lseek(ofile, size, 1) == -1) {
- perror("extract seek");
- done(1);
- }
-}
-
-xtrcvtdir(buf, size)
- struct odirect *buf;
- long size;
-{
- struct odirect *odp, *edp;
- struct direct cvtbuf;
-
- edp = &buf[size / sizeof(struct odirect)];
- for (odp = buf; odp < edp; odp++) {
- dcvt(odp, &cvtbuf);
- putent(&cvtbuf, xtrfile);
- }
-}
-
-xtrcvtskip(buf, size)
- char *buf;
- long size;
-{
-
- fprintf(stderr, "unallocated block in directory %s\n",
- entry->x_name);
- xtrskip(buf, size);
-}
-
-xtrlnkfile(buf, size)
- char *buf;
- long size;
-{
-
- pathlen += size;
- if (pathlen > MAXPATHLEN) {
- fprintf(stderr, "symbolic link name: %s; too long %d\n",
- buf, size);
- done(1);
- }
- strcat(lnkbuf, buf);
-}
-
-xtrlnkskip(buf, size)
- char *buf;
- long size;
-{
-
-#ifdef lint
- buf = buf, size = size;
-#endif
- fprintf(stderr, "unallocated block in symbolic link %s\n",
- entry->x_name);
- done(1);
-}
-
-null() {;}
-
-/*
- * Do the tape i/o, dealing with volume changes
- * etc..
- */
-readtape(b)
- char *b;
-{
- register long i;
- struct u_spcl tmpbuf;
- char c;
-
- if (bct >= NTREC) {
- for (i = 0; i < NTREC; i++)
- ((struct s_spcl *)&tbf[i*TP_BSIZE])->c_magic = 0;
- bct = 0;
-#ifdef RRESTOR
- if ((i = rmtread(tbf, NTREC*TP_BSIZE)) < 0) {
-#else
- if ((i = read(mt, tbf, NTREC*TP_BSIZE)) < 0) {
-#endif
- fprintf(stderr, "Tape read error while restoring %s\n",
- entry->x_name);
- if (!yflag) {
- fprintf(stderr, "continue? ");
- do {
- fprintf(stderr, "[yn] ");
- c = getchar();
- while (getchar() != '\n')
- /* void */;
- } while (c != 'y' && c != 'n');
- if (c == 'n')
- done(1);
- }
- eflag++;
- i = NTREC*TP_BSIZE;
- blkclr(tbf, i);
-#ifdef RRESTOR
- if (rmtseek(i, 1) < 0) {
-#else
- if (lseek(mt, i, 1) < 0) {
-#endif
- fprintf(stderr, "continuation failed\n");
- done(1);
- }
- }
- if (i == 0) {
- bct = NTREC + 1;
- volno++;
-loop:
- flsht();
-#ifdef RRESTOR
- rmtclose();
-#else
- close(mt);
-#endif
- fprintf(stderr, "Mount volume %d\n", volno);
- while (getchar() != '\n')
- ;
-#ifdef RRESTOR
- if ((mt = rmtopen(magtape, 0)) == -1) {
-#else
- if ((mt = open(magtape, 0)) == -1) {
-#endif
- 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;
- }
- }
- blkcpy(&tbf[(bct++*TP_BSIZE)], b, (long)TP_BSIZE);
-}
-
-flsht()
-{
-
- bct = NTREC+1;
-}
-
-blkcpy(from, to, size)
- char *from, *to;
- long size;
-{
-
-#ifdef lint
- from = from, to = to, size = size;
-#endif
- asm(" movc3 12(ap),*4(ap),*8(ap)");
-}
-
-blkclr(buf, size)
- char *buf;
- long size;
-{
-
-#ifdef lint
- buf = buf, size = size;
-#endif
- 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();
-#ifdef RRESTOR
- if (rmtioctl(tcom.mt_op, 1) == -1) {
- /* kludge for disk dumps */
- rmtseek((long)0, 0);
- }
-#else
- if (ioctl(mt,MTIOCTOP,&tcom) == -1) {
- /* kludge for disk dumps */
- lseek(mt, (long)0, 0);
- }
-#endif
- if (dumpnum > 1) {
-#ifdef RRESTOR
- rmtioctl(MTFSF, 1);
-#else
- tcom.mt_op = MTFSF;
- tcom.mt_count = 1;
- ioctl(mt,MTIOCTOP,&tcom);
-#endif
- }
-}
-
-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;
-{
- union u_ospcl {
- char dummy[TP_BSIZE];
- struct s_ospcl {
- int c_type;
- time_t c_date;
- time_t c_ddate;
- int c_volume;
- daddr_t c_tapea;
- ino_t c_inumber;
- int c_magic;
- int c_checksum;
- struct odinode {
- unsigned short odi_mode;
- short odi_nlink;
- short odi_uid;
- short odi_gid;
- off_t odi_size;
- daddr_t odi_rdev;
- char odi_addr[36];
- time_t odi_atime;
- time_t odi_mtime;
- time_t odi_ctime;
- } c_dinode;
- int c_count;
- char c_addr[TP_NINDIR];
- } s_ospcl;
- } u_ospcl;
-
- if (!cvtflag) {
- readtape((char *)buf);
- if (buf->c_magic != NFS_MAGIC || checksum((int *)buf) == 0)
- return(0);
- return(1);
- }
- readtape((char *)(&u_ospcl.s_ospcl));
- blkclr((char *)buf, TP_BSIZE);
- buf->c_type = u_ospcl.s_ospcl.c_type;
- buf->c_date = u_ospcl.s_ospcl.c_date;
- buf->c_ddate = u_ospcl.s_ospcl.c_ddate;
- buf->c_volume = u_ospcl.s_ospcl.c_volume;
- buf->c_tapea = u_ospcl.s_ospcl.c_tapea;
- buf->c_inumber = u_ospcl.s_ospcl.c_inumber;
- buf->c_checksum = u_ospcl.s_ospcl.c_checksum;
- buf->c_magic = u_ospcl.s_ospcl.c_magic;
- buf->c_dinode.di_mode = u_ospcl.s_ospcl.c_dinode.odi_mode;
- buf->c_dinode.di_nlink = u_ospcl.s_ospcl.c_dinode.odi_nlink;
- buf->c_dinode.di_uid = u_ospcl.s_ospcl.c_dinode.odi_uid;
- buf->c_dinode.di_gid = u_ospcl.s_ospcl.c_dinode.odi_gid;
- buf->c_dinode.di_size = u_ospcl.s_ospcl.c_dinode.odi_size;
- buf->c_dinode.di_rdev = u_ospcl.s_ospcl.c_dinode.odi_rdev;
- buf->c_dinode.di_atime = u_ospcl.s_ospcl.c_dinode.odi_atime;
- buf->c_dinode.di_mtime = u_ospcl.s_ospcl.c_dinode.odi_mtime;
- buf->c_dinode.di_ctime = u_ospcl.s_ospcl.c_dinode.odi_ctime;
- buf->c_count = u_ospcl.s_ospcl.c_count;
- blkcpy(u_ospcl.s_ospcl.c_addr, buf->c_addr, TP_NINDIR);
- if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
- checksum((int *)(&u_ospcl.s_ospcl)) == 0)
- return(0);
- buf->c_magic = NFS_MAGIC;
- return(1);
-}
-
-/*
- * return whether or not the buffer contains a header block
- */
-ishead(buf)
- struct s_spcl *buf;
-{
-
- if (buf->c_magic != NFS_MAGIC)
- 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(mapp)
- char **mapp;
-{
- register int i;
- char *m;
-
- i = spcl.c_count;
-
- if (*mapp == 0)
- *mapp = (char *)calloc(i, (TP_BSIZE/(NBBY/BITS)));
- m = *mapp;
- while (i--) {
- readtape((char *) m);
- m += (TP_BSIZE/(NBBY/BITS));
- }
- while (gethead(&spcl) == 0)
- ;
-}
-
-checksum(b)
- register 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, file %s\n", i,
- entry->x_name);
- 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 != '/')
- continue;
- *cp = '\0';
- if (access(name, 01) < 0 && mkdir(name, 0777) < 0)
- fprintf(stderr, "restor: "), perror(name);
- *cp = '/';
- }
-}
-
-setdir(dev)
- char *dev;
-{
- struct fstab *fsp;
-
- if (setfsent() == 0) {
- fprintf(stderr, "Can't open checklist file: %s\n", FSTAB);
- done(1);
- }
- while ((fsp = getfsent()) != 0) {
- if (strcmp(fsp->fs_spec, dev) == 0) {
- fprintf(stderr, "%s mounted on %s\n", dev, fsp->fs_file);
- if (chdir(fsp->fs_file) >= 0)
- return;
- fprintf(stderr, "%s cannot chdir to %s\n",
- fsp->fs_file);
- done(1);
- }
- }
- fprintf(stderr, "%s not mounted\n", dev);
- done(1);
-}
-
-/*
- * These variables are "local" to the following two functions.
- */
-char dirbuf[DIRBLKSIZ];
-long dirloc = 0;
-long prev = 0;
-
-/*
- * add a new directory entry to a file.
- */
-putent(dp, wrtfunc)
- struct direct *dp;
- int (*wrtfunc)();
-{
-
- if (dp->d_ino == 0)
- return;
- if (dirloc + dp->d_reclen > DIRBLKSIZ) {
- ((struct direct *)(dirbuf + prev))->d_reclen =
- DIRBLKSIZ - prev;
- (*wrtfunc)(dirbuf, DIRBLKSIZ);
- dirloc = 0;
- }
- blkcpy((char *)dp, dirbuf + dirloc, (long)dp->d_reclen);
- prev = dirloc;
- dirloc += dp->d_reclen;
-}
-
-/*
- * flush out a directory that is finished.
- */
-flushent(wrtfunc)
- int (*wrtfunc)();
-{
-
- ((struct direct *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev;
- (*wrtfunc)(dirbuf, dirloc);
- dirloc = 0;
-}
-
-dirwrite(buf, size)
- char *buf;
- int size;
-{
-
- fwrite(buf, 1, size, df);
- seekpt = ftell(df);
-}
-
-dcvt(odp, ndp)
- register struct odirect *odp;
- register struct direct *ndp;
-{
-
- blkclr((char *)ndp, (long)(sizeof *ndp));
- ndp->d_ino = odp->d_ino;
- strncpy(ndp->d_name, odp->d_name, ODIRSIZ);
- ndp->d_namlen = strlen(ndp->d_name);
- ndp->d_reclen = DIRSIZ(ndp);