📄 restor.c
字号:
for (i = 0; i < sizeof(ino_t); i++) writec(*cp++); for (i = 0; i < DIRSIZ; i++) { writec(*cp); if (*cp++ == 0) return; } return;}getent(bf)register char *bf;{ register i; for (i = 0; i < sizeof(ino_t); i++) *bf++ = readc(); for (i = 0; i < DIRSIZ; i++) if ((*bf++ = readc()) == 0) return; return;}/* * read/write te directory file */writec(c)char c;{ drblock[bpt++] = c; seekpt++; if (bpt >= BSIZE) { bpt = 0; write(df, drblock, BSIZE); }}readc(){ if (bpt >= BSIZE) { read(df, drblock, BSIZE); bpt = 0; } return(drblock[bpt++]);}mseek(pt)daddr_t pt;{ bpt = BSIZE; lseek(df, pt, 0);}flsh(){ write(df, drblock, bpt+1);}/* * search the directory inode ino * looking for entry cp */ino_tsearch(inum, cp)ino_t inum;char *cp;{ register i; struct direct dir; for (i = 0; i < MAXINO; i++) if (inotab[i].t_ino == inum) { goto found; } return(0);found: mseek(inotab[i].t_seekpt); do { getent((char *)&dir); if (direq(dir.d_name, "/")) return(0); } while (direq(dir.d_name, cp) == 0); return(dir.d_ino);}/* * Search the directory tree rooted at inode 2 * for the path pointed at by n */psearch(n)char *n;{ register char *cp, *cp1; char c; ino = 2; 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);}direq(s1, s2)register char *s1, *s2;{ register i; for (i = 0; i < DIRSIZ; i++) if (*s1++ == *s2) { if (*s2++ == 0) return(1); } else return(0); return(1);}#endif/* * read/write a disk block, be sure to update the buffer * cache if needed. */dwrite(bno, b)daddr_t bno;char *b;{ register i; for (i = 0; i < NCACHE; i++) { if (cache[i].c_bno == bno) { copy(b, cache[i].c_block, BSIZE); cache[i].c_time = 0; break; } else cache[i].c_time++; } lseek(fi, bno*BSIZE, 0); if(write(fi, b, BSIZE) != BSIZE) {#ifdef STANDALONE printf("disk write error %D\n", bno);#else fprintf(stderr, "disk write error %ld\n", bno);#endif exit(1); }}dread(bno, buf, cnt)daddr_t bno;char *buf;{ register i, j; j = 0; for (i = 0; i < NCACHE; i++) { if (++curcache >= NCACHE) curcache = 0; if (cache[curcache].c_bno == bno) { copy(cache[curcache].c_block, buf, cnt); cache[curcache].c_time = 0; return; } else { cache[curcache].c_time++; if (cache[j].c_time < cache[curcache].c_time) j = curcache; } } lseek(fi, bno*BSIZE, 0); if (read(fi, cache[j].c_block, BSIZE) != BSIZE) {#ifdef STANDALONE printf("read error %D\n", bno);#else printf("read error %ld\n", bno);#endif exit(1); } copy(cache[j].c_block, buf, cnt); cache[j].c_time = 0; cache[j].c_bno = bno;}/* * the inode manpulation routines. Like the system. * * clri zeros the inode */clri(ip)struct dinode *ip;{ int i, *p; i = sizeof(struct dinode)/sizeof(int); p = (int *)ip; do *p++ = 0; while(--i);}/* * itrunc/tloop/bfree free all of the blocks pointed at by the inode */itrunc(ip)register struct dinode *ip;{ register i; daddr_t bn, iaddr[NADDR]; if (ip->di_mode == 0) return; i = ip->di_mode & IFMT; if (i != IFDIR && i != IFREG) return; l3tol(iaddr, ip->di_addr, NADDR); for(i=NADDR-1;i>=0;i--) { bn = iaddr[i]; if(bn == 0) continue; switch(i) { default: bfree(bn); break; case NADDR-3: tloop(bn, 0, 0); break; case NADDR-2: tloop(bn, 1, 0); break; case NADDR-1: tloop(bn, 1, 1); } } ip->di_size = 0;}tloop(bn, f1, f2)daddr_t bn;int f1, f2;{ register i; daddr_t nb; union { char data[BSIZE]; daddr_t indir[NINDIR]; } ibuf; dread(bn, ibuf.data, BSIZE); for(i=NINDIR-1;i>=0;i--) { nb = ibuf.indir[i]; if(nb) { if(f1) tloop(nb, f2, 0); else bfree(nb); } } bfree(bn);}bfree(bn)daddr_t bn;{ register i; union { char data[BSIZE]; struct fblk frees; } fbuf; if(sblock.s_nfree >= NICFREE) { fbuf.df_nfree = sblock.s_nfree; for(i=0;i<NICFREE;i++) fbuf.df_free[i] = sblock.s_free[i]; sblock.s_nfree = 0; dwrite(bn, fbuf.data); } sblock.s_free[sblock.s_nfree++] = bn;}/* * allocate a block off the free list. */daddr_tballoc(){ daddr_t bno; register i; static char zeroes[BSIZE]; union { char data[BSIZE]; struct fblk frees; } fbuf; if(sblock.s_nfree == 0 || (bno=sblock.s_free[--sblock.s_nfree]) == 0) {#ifdef STANDALONE printf("Out of space\n");#else fprintf(stderr, "Out of space.\n");#endif exit(1); } if(sblock.s_nfree == 0) { dread(bno, fbuf.data, BSIZE); sblock.s_nfree = fbuf.df_nfree; for(i=0;i<NICFREE;i++) sblock.s_free[i] = fbuf.df_free[i]; } dwrite(bno, zeroes); return(bno);}/* * map a block number into a block address, ensuring * all of the correct indirect blocks are around. Allocate * the block requested. */daddr_tbmap(iaddr, bn)daddr_t iaddr[NADDR];daddr_t bn;{ register i; int j, sh; daddr_t nb, nnb; daddr_t indir[NINDIR]; /* * blocks 0..NADDR-4 are direct blocks */ if(bn < NADDR-3) { iaddr[bn] = nb = balloc(); return(nb); } /* * addresses NADDR-3, NADDR-2, and NADDR-1 * have single, double, triple indirect blocks. * the first step is to determine * how many levels of indirection. */ sh = 0; nb = 1; bn -= NADDR-3; for(j=3; j>0; j--) { sh += NSHIFT; nb <<= NSHIFT; if(bn < nb) break; bn -= nb; } if(j == 0) { return((daddr_t)0); } /* * fetch the address from the inode */ if((nb = iaddr[NADDR-j]) == 0) { iaddr[NADDR-j] = nb = balloc(); } /* * fetch through the indirect blocks */ for(; j<=3; j++) { dread(nb, (char *)indir, BSIZE); sh -= NSHIFT; i = (bn>>sh) & NMASK; nnb = indir[i]; if(nnb == 0) { nnb = balloc(); indir[i] = nnb; dwrite(nb, (char *)indir); } nb = nnb; } return(nb);}/* * read the tape into buf, then return whether or * or not it is a header block. */gethead(buf)struct 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 spcl *buf;{ if (buf->c_magic != MAGIC || checksum((int *) buf) == 0) return(0); return(1);}checktype(b, t)struct spcl *b;int t;{ return(b->c_type == t);}checksum(b)int *b;{ register i, j; j = BSIZE/sizeof(int); i = 0; do i += *b++; while (--j); if (i != CHECKSUM) { printf("Checksum error %o\n", i); return(0); } return(1);}checkvol(b, t)struct spcl *b;int t;{ if (b->c_volume == t) return(1); return(0);}readhdr(b)struct spcl *b;{ if (gethead(b) == 0) return(0); if (checktype(b, TS_TAPE) == 0) return(0); return(1);}/* * The next routines are called during file extraction to * put the data into the right form and place. */#ifndef STANDALONExtrfile(b, size)char *b;long size;{ write(ofile, b, (int) size);}null() {;}skip(){ lseek(ofile, (long) BSIZE, 1);}#endifrstrfile(b, s)char *b;long s;{ daddr_t d; d = bmap(taddr, curbno); dwrite(d, b); curbno += 1;}rstrskip(b, s)char *b;long s;{ curbno += 1;}#ifndef STANDALONEputdir(b)char *b;{ register struct direct *dp; register i; for (dp = (struct direct *) b, i = 0; i < BSIZE; dp++, i += sizeof(*dp)) { if (dp->d_ino == 0) continue; putent((char *) dp); }}#endif/* * read/write an inode from the disk */getdino(inum, b)ino_t inum;struct dinode *b;{ daddr_t bno; char buf[BSIZE]; bno = (ino - 1)/INOPB; bno += 2; dread(bno, buf, BSIZE); copy(&buf[((inum-1)%INOPB)*sizeof(struct dinode)], (char *) b, sizeof(struct dinode));}putdino(inum, b)ino_t inum;struct dinode *b;{ daddr_t bno; char buf[BSIZE]; bno = ((ino - 1)/INOPB) + 2; dread(bno, buf, BSIZE); copy((char *) b, &buf[((inum-1)%INOPB)*sizeof(struct dinode)], sizeof(struct dinode)); dwrite(bno, buf);}/* * read a bit mask from the tape into m. */readbits(m)short *m;{ register i; i = spcl.c_count; while (i--) { readtape((char *) m); m += (BSIZE/(MLEN/BITS)); } while (gethead(&spcl) == 0) ;}done(){#ifndef STANDALONE unlink(dirfile);#endif exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -