#line 1 "/usr/include/stdio.h" extern struct _iobuf { int _cnt; unsigned char *_ptr; unsigned char *_base; short _flag; char _file; } _iob[ 120 ]; struct _iobuf *fopen(); struct _iobuf *fdopen(); struct _iobuf *freopen(); struct _iobuf *popen(); long ftell(); char *fgets(); #line 1 "/usr/include/tmpnam.h" #line 46 "/usr/include/stdio.h" #line 2 "fsck.c" #line 1 "/usr/include/ctype.h" extern char _ctype[]; #line 3 "fsck.c" #line 1 "/usr/include/sys/param.h" #line 4 "/usr/include/sys/param.h" #line 19 "/usr/include/sys/param.h" #line 36 "/usr/include/sys/param.h" #line 1 "/usr/include/signal.h" typedef int (*SIG_TYP)(); SIG_TYP signal(); #line 39 "/usr/include/sys/param.h" #line 44 "/usr/include/sys/param.h" #line 63 "/usr/include/sys/param.h" #line 75 "/usr/include/sys/param.h" #line 101 "/usr/include/sys/param.h" #line 107 "/usr/include/sys/param.h" #line 115 "/usr/include/sys/param.h" #line 121 "/usr/include/sys/param.h" #line 131 "/usr/include/sys/param.h" #line 1 "/usr/include/sys/types.h" #line 4 "/usr/include/sys/types.h" #line 9 "/usr/include/sys/types.h" #line 33 "/usr/include/sys/types.h" typedef unsigned char u_char; typedef unsigned short u_short; typedef unsigned int u_int; typedef unsigned long u_long; typedef long daddr_t; typedef char * caddr_t; typedef unsigned short ino_t; typedef long swblk_t; typedef long clicks_t; typedef long time_t; typedef long label_t[14]; typedef unsigned short dev_t; typedef long off_t; typedef struct { unsigned long lo; long hi; } llong_t; #line 62 "/usr/include/sys/types.h" typedef struct fd_set { unsigned int fds_bits[ (128+ sizeof(int) * 8 -1)/( sizeof(int) * 8 ) ]; } fd_set; #line 132 "/usr/include/sys/param.h" #line 136 "/usr/include/sys/param.h" llong_t ltoL(); llong_t Lladd(); llong_t Luadd(); llong_t LLadd(); unsigned Lshift(); #line 4 "fsck.c" #line 1 "/usr/include/sys/filsys.h" #line 4 "/usr/include/sys/filsys.h" struct filsys { unsigned short s_isize; daddr_t s_fsize; short s_ninode; ino_t s_inode[ 100 ]; char s_flock; char s_ilock; char s_fmod; char s_ronly; time_t s_time; daddr_t s_tfree; ino_t s_tinode; short s_dinfo[2]; char s_fsmnt[14]; ino_t s_lasti; ino_t s_nbehind; union { struct { short S_nfree; daddr_t S_free[ 178 ]; } R; struct { char S_valid; char S_flag; long S_bfree[ 961 ]; } B; struct { char S_valid; char S_flag; long S_bsize; struct buf * S_blk[ 961 -1]; } N; } U; }; #line 53 "/usr/include/sys/filsys.h" #line 5 "fsck.c" #line 1 "/usr/include/sys/dir.h" struct direct { ino_t d_ino; char d_name[ 14 ]; }; #line 6 "fsck.c" #line 1 "/usr/include/sys/fblk.h" struct fblk { int df_nfree; daddr_t df_free[ 178 ]; }; #line 7 "fsck.c" #line 1 "/usr/include/sys/ino.h" #line 5 "/usr/include/sys/ino.h" struct dinode { unsigned short di_mode; short di_nlink; short di_uid; short di_gid; off_t di_size; char di_addr[40]; time_t di_atime; time_t di_mtime; time_t di_ctime; }; #line 22 "/usr/include/sys/ino.h" #line 8 "fsck.c" #line 1 "/usr/include/sys/inode.h" #line 11 "/usr/include/sys/inode.h" struct inode { short i_flag; dev_t i_dev; char i_fstyp; unsigned short i_count; long i_number; unsigned short i_mode; short i_nlink; short i_uid; short i_gid; off_t i_size; struct inode *i_mroot; struct inode *i_mpoint; struct stdata *i_sptr; union { struct { daddr_t I_addr[ 13 ]; daddr_t I_lastr; struct buf *I_bufp; } i_f; struct { daddr_t I_rdev; } i_d; struct { long I_tag; struct inode *I_cip; int I_fsflags; time_t I_atime; time_t I_mtime; time_t I_ctime; dev_t I_rdev; } i_a; struct { struct proc *I_proc; int I_sigmask; } i_p; } i_un; struct inode *i_hlink; }; struct argnamei { short flag; short len; union { short mode; struct inode *il; caddr_t buf; } un; }; struct nx { struct inode *dp; char *cp; char *nbuf; short nlen; short nlink; }; #line 140 "/usr/include/sys/inode.h" #line 151 "/usr/include/sys/inode.h" #line 160 "/usr/include/sys/inode.h" #line 9 "fsck.c" #line 1 "/usr/include/sys/stat.h" struct stat { dev_t st_dev; ino_t st_ino; unsigned short st_mode; short st_nlink; short st_uid; short st_gid; dev_t st_rdev; off_t st_size; time_t st_atime; time_t st_mtime; time_t st_ctime; }; #line 10 "fsck.c" #line 1 "/usr/include/fstab.h" #line 7 "/usr/include/fstab.h" #line 11 "/usr/include/fstab.h" struct fstab{ char fs_spec[ 32 ]; char fs_file[ 32 ]; int fs_ftype; int fs_flags; int fs_passno; }; #line 28 "/usr/include/fstab.h" struct fstab *getfsent(); struct fstab *getfsspec(); struct fstab *getfsfile(); int setfsent(); int endfsent(); #line 41 "/usr/include/fstab.h" struct mtab { char file[ 32 ]; char spec[ 32 -1]; char type; }; #line 11 "fsck.c" #line 1 "/usr/include/pwd.h" struct passwd { char *pw_name; char *pw_passwd; int pw_uid; int pw_gid; int pw_quota; char *pw_comment; char *pw_gecos; char *pw_dir; char *pw_shell; }; extern struct passwd *getpwent(); extern struct passwd *getpwuid(); extern struct passwd *getpwnam(); extern struct passwd *pwdecode(); #line 12 "fsck.c" typedef struct dinode DINODE; typedef struct direct DIRECT; daddr_t startib; unsigned niblk; struct bufarea { struct bufarea *b_next; daddr_t b_bno; union { char b_buf[ ( (( 64 ) & 64) ? 4096: 1024) ]; short b_lnks[ ( ( (( 64 ) & 64) ? 4096: 1024) /sizeof(short)) ]; daddr_t b_indir[ ( ( (( 64 ) & 64) ? 4096: 1024) /sizeof(daddr_t)) ]; struct filsys b_fs; struct fblk b_fb; struct dinode b_dinode[ ( (( 64 ) & 64) ? 64: 16) ]; DIRECT b_dir[ ( ( (( 64 ) & 64) ? 4096: 1024) /sizeof(struct direct)) ]; } b_un; char b_dirty; }; typedef struct bufarea BUFAREA; BUFAREA inoblk; BUFAREA fileblk; BUFAREA sblk; BUFAREA *poolhead; struct filecntl { int rfdes; int wfdes; int mod; }; struct filecntl dfile; struct filecntl sfile; typedef unsigned MEMSIZE; MEMSIZE memsize; daddr_t duplist[ 100 ]; daddr_t *enddup; daddr_t *muldup; ino_t badlncnt[ 500 ]; ino_t *badlnp; char sflag; char csflag; char nflag; char yflag; char tflag; char preen; char rplyflag; char hotroot; char rawflg; char rmscr; char fixfree; char *membase; char *blkmap; char *freemap; char *statemap; char *pathp; char *thisname; char *srchname; char pathname[200]; char scrfile[80]; char *lfname = "lost+found"; char *checklist = "/etc/fstab" ; char big; short *lncntp; int cylsize; int stepsize; int badblk; int dupblk; int (*pfunc)(); int zcleared; ino_t inum; ino_t imax; ino_t parentdir; ino_t lastino; ino_t lfdir; ino_t orphan; off_t filsize; off_t maxblk; off_t bmapsz; daddr_t smapblk; daddr_t lncntblk; daddr_t fmapblk; daddr_t n_free; daddr_t n_blks; daddr_t n_files; daddr_t fmin; daddr_t fmax; int (*signal())(); long lseek(); long time(); DINODE *ginode(); BUFAREA *getblk(); BUFAREA *search(); int dirscan(); int findino(); int catch(); int mkentry(); int chgdd(); int pass1(); int pass1b(); int pass2(); int pass3(); int pass4(); int pass5(); char *devname; main(argc,argv) int argc; char *argv[]; { register struct _iobuf *fp; register n; register char *p; char filename[50]; char *sbrk(); setbuf( (&_iob[1]) , 0 ); sync(); while(--argc > 0 && **++argv == '-') { switch(*++*argv) { case 'p': preen++; break; case 't': case 'T': tflag++; if(**++argv == '-' || --argc <= 0) errexit("Bad -t option\n"); p = scrfile; while(*p++ = **argv) (*argv)++; break; case 's': stype(++*argv); sflag++; break; case 'S': stype(++*argv); csflag++; break; case 'n': case 'N': nflag++; yflag = 0; break; case 'y': case 'Y': yflag++; nflag = 0; break; default: errexit("%c option?\n",**argv); } } if(nflag && (sflag || csflag)) errexit("Incompatible options: -n and -%s\n",sflag?"s":"S"); if(sflag && csflag) sflag = 0; memsize = (MEMSIZE)sbrk(0); memsize = MAXDATA - memsize - sizeof(int); while(memsize >= 2*sizeof(BUFAREA) && (membase = sbrk(memsize)) == (char *)-1) memsize -= 1024; if(memsize < 2*sizeof(BUFAREA)) errexit("Can't get memory\n"); if (signal( 2 , (SIG_TYP)1 ) != (SIG_TYP)1 ) signal( 2 , catch); if(argc) { while(argc-- > 0){ hotroot = 0; check(*argv++); } } else { struct fstab *fsp; int pid, passno, anygtr, sumstatus = 0; passno = 1; do { anygtr = 0; if (setfsent() == 0) errexit("Can't open checklist file: %s\n", "/etc/fstab" ); while ( (fsp = getfsent()) != 0){ if (fsp->fs_ftype != 0) continue; if (preen == 0 || passno == 1 && fsp->fs_passno == passno) { if (blockcheck(fsp->fs_spec) == 0 && preen) exit(8); } else if (fsp->fs_passno > passno) anygtr = 1; else if (fsp->fs_passno == passno) { pid = fork(); if (pid < 0) { perror("fork"); exit(8); } if (pid == 0) if (blockcheck(fsp->fs_spec)== 0 ) exit(8); else exit(0); } } if (preen) { int status; while (wait(&status) != -1) sumstatus |= status; } passno++; } while (anygtr); if (sumstatus) exit(8); endfsent(); } exit(0); } char *rawname(), *strrchr(), *unrawname(); blockcheck(name) char *name; { struct stat stat_slash, stat_block, stat_char; char *raw; int looped = 0; hotroot = 0; if (stat("/", &stat_slash) < 0){ error("Can't stat root\n"); return( 0 ); } retry: if (stat(name, &stat_block) < 0){ error("Can't stat %s\n", name); return( 0 ); } big = 0 ; if (stat_block.st_mode & 0060000 ){ if( (( stat_block.st_rdev ) & 64) ) big = 64 ; raw = rawname(name); if (stat(raw, &stat_char) < 0){ error("Can't stat %s\n", raw); return( 0 ); } if (stat_char.st_mode & 0020000 ){ if (stat_slash.st_dev == stat_block.st_rdev) { hotroot++; raw = unrawname(name); } check(raw); return( 1 ); } else if(big == 64 ) { check(name); return( 1 ); } else { error("%s is not a character device\n", raw); return( 0 ); } } else if (stat_block.st_mode & 0020000 ){ if (looped) { error("Can't make sense out of name %s\n", name); return( 0 ); } name = unrawname(name); looped++; goto retry; } error("Can't make sense out of name %s\n", name); return( 0 ); } char * unrawname(cp) char *cp; { char *dp = strrchr(cp, '/'); struct stat stb; if (dp == 0) return(cp); if (stat(cp, &stb) < 0) return(cp); if ((stb.st_mode& 0170000 ) != 0020000 ) return(cp); if (*(dp+1) != 'r') return(cp); strcpy(dp+1, dp+2); return(cp); } char * rawname(cp) char *cp; { static char rawbuf[32]; char *dp = strrchr(cp, '/'); if (dp == 0) return (0); if(big == 64 ) return(cp); *dp = 0; strcpy(rawbuf, cp); *dp = '/'; strcat(rawbuf, "/r"); strcat(rawbuf, dp+1); return (rawbuf); } check(dev) char *dev; { devname = dev; check1(dev); devname = 0; } check1(dev) char *dev; { register DINODE *dp; register n; register ino_t *blp; ino_t savino; daddr_t blk; BUFAREA *bp1, *bp2; if(setup(dev) == 0 ) return; if (preen==0) { printf("** Checking %s\n", dev); printf("** Phase 1 - Check Blocks and Sizes\n"); } pfunc = pass1; for(inum = 1; inum <= imax; inum++) { if((dp = ginode()) == 0 ) continue; if( ((dp->di_mode & 0170000 ) != 0) ) { lastino = inum; if(ftypeok(dp) == 0 ) { pfatal("UNKNOWN FILE TYPE I=%u",inum); if(reply("CLEAR") == 1 ) { clear((char *)( dp ),sizeof(DINODE)) ; inoblk.b_dirty = 1 ; } continue; } n_files++; if( dolncnt( dp->di_nlink ,0) <= 0) { if(badlnp < &badlncnt[ 500 ]) *badlnp++ = inum; else { pfatal("LINK COUNT TABLE OVERFLOW"); if(reply("CONTINUE") == 0 ) errexit(""); } } dostate( ((dp->di_mode & 0170000 ) == 0040000 ) ? 02 : 01 ,0) ; badblk = dupblk = 0; filsize = 0; maxblk = 0; ckinode(dp, 0 ); if((n = dostate(0,1) ) == 02 || n == 01 ) sizechk(dp); } else if(dp->di_mode != 0) { pfatal("PARTIALLY ALLOCATED INODE I=%u",inum); if(reply("CLEAR") == 1 ) { clear((char *)( dp ),sizeof(DINODE)) ; inoblk.b_dirty = 1 ; } } } if(enddup != &duplist[0]) { if (preen) pfatal("INTERNAL ERROR: dups with -p"); printf("** Phase 1b - Rescan For More DUPS\n"); pfunc = pass1b; for(inum = 1; inum <= lastino; inum++) { if( dostate(0,1) != 0 && (dp = ginode()) != 0 ) if(ckinode(dp, 0 ) & 01 ) break; } } if(rawflg) { if(inoblk.b_dirty) bwrite(&dfile,membase,startib,(int)niblk* ( (( big ) & 64) ? 4096: 1024) ); inoblk.b_dirty = 0; if(poolhead) { clear(membase,niblk* ( (( 64 ) & 64) ? 4096: 1024) ); for(bp1 = poolhead;bp1->b_next;bp1 = bp1->b_next); bp2 = &((BUFAREA *)membase)[(niblk* ( (( 64 ) & 64) ? 4096: 1024) )/sizeof(BUFAREA)]; while(--bp2 >= (BUFAREA *)membase) { ( bp2 )->b_dirty = 0;( bp2 )->b_bno = (daddr_t)-1 ; bp2->b_next = bp1->b_next; bp1->b_next = bp2; } } rawflg = 0; } if (preen == 0) printf("** Phase 2 - Check Pathnames\n"); inum = ((ino_t)2) ; thisname = pathp = pathname; pfunc = pass2; switch( dostate(0,1) ) { case 0 : errexit("ROOT INODE UNALLOCATED. TERMINATING.\n"); case 01 : pfatal("ROOT INODE NOT DIRECTORY"); if(reply("FIX") == 0 || (dp = ginode()) == 0 ) errexit(""); dp->di_mode &= ~ 0170000 ; dp->di_mode |= 0040000 ; inoblk.b_dirty = 1 ; dostate( 02 ,0) ; case 02 : descend(); break; case 03 : pfatal("DUPS/BAD IN ROOT INODE"); printf("\n"); if(reply("CONTINUE") == 0 ) errexit(""); dostate( 02 ,0) ; descend(); } if (preen == 0) printf("** Phase 3 - Check Connectivity\n"); for(inum = 1; inum <= lastino; inum++) { if( dostate(0,1) == 02 ) { pfunc = findino; srchname = ".."; savino = inum; do { orphan = inum; if((dp = ginode()) == 0 ) break; filsize = dp->di_size; parentdir = 0; ckinode(dp, 1 ); if((inum = parentdir) == 0) break; } while( dostate(0,1) == 02 ); inum = orphan; if(linkup() == 1 ) { thisname = pathp = pathname; *pathp++ = '?'; pfunc = pass2; descend(); } inum = savino; } } if (preen == 0) printf("** Phase 4 - Check Reference Counts\n"); pfunc = pass4; zcleared = 0; for(inum = 1; inum <= lastino; inum++) { switch( dostate(0,1) ) { case 01 : if(n = dolncnt(0,1) ) adjust((short)n); else { for(blp = badlncnt;blp < badlnp; blp++) if(*blp == inum) { clri("UNREF",preen? 0 : 1 , 1 ); break; } } break; case 02 : clri("UNREF", 1 , 0 ); break; case 03 : clri("BAD/DUP", 1 , 0 ); } } if (zcleared) pwarn("%u LINKLESS FILES CLEARED\n", zcleared); if(imax - n_files != sblk.b_un.b_fs .s_tinode) { pwarn("FREE INODE COUNT %u SHOULD BE %u IN SUPERBLK", sblk.b_un.b_fs .s_tinode, imax - n_files); if (preen) printf(" (FIXED)\n"); if (preen || reply("FIX") == 1 ) { sblk.b_un.b_fs .s_tinode = imax - n_files; sblk.b_dirty = 1 ; } } flush(&dfile,&fileblk); if (preen == 0) printf("** Phase 5 - Check Free List "); if(sflag || (csflag && rplyflag == 0)) { if (preen == 0) printf("(Ignored)\n"); fixfree = 1; } else { if (preen == 0) printf("\n"); if(freemap) copy(blkmap,freemap,(MEMSIZE)bmapsz); else { for(blk = 0; blk < fmapblk; blk++) { bp1 = getblk((BUFAREA *) 0 ,blk); bp2 = getblk((BUFAREA *) 0 ,blk+fmapblk); copy(bp1->b_un.b_buf,bp2->b_un.b_buf, ( (( big ) & 64) ? 4096: 1024) ); ( bp2 )->b_dirty = 1 ; } } badblk = dupblk = 0; if(big == 0 ) { fileblk.b_un.b_fb .df_nfree = sblk.b_un.b_fs . U.R.S_nfree ; for(n = 0; n < 178 ; n++) fileblk.b_un.b_fb .df_free[n] = sblk.b_un.b_fs . U.R.S_free [n]; } freechk(); if(badblk) { pfatal("%d BAD BLKS IN FREE LIST",badblk); printf("\n"); } if(dupblk) pwarn("%d DUP BLKS IN FREE LIST\n",dupblk); if(fixfree == 0) { if((n_blks+n_free) != (fmax-fmin)) { pwarn("%ld BLK(S) MISSING\n", fmax-fmin-n_blks-n_free); fixfree = 1; } else if(big == 0 && n_free != sblk.b_un.b_fs .s_tfree) { pwarn("FREE BLK COUNT WRONG IN SUPERBLK"); if (preen) printf(" (FIXED)\n"); if(preen || reply("FIX") == 1 ) { sblk.b_un.b_fs .s_tfree = n_free; sblk.b_dirty = 1 ; } } } if(fixfree) { pwarn("BAD FREE LIST"); if (preen) printf(" (SALVAGED)\n"); else if(reply("SALVAGE") == 0 ) fixfree = 0; } } if(fixfree) { if (preen == 0) printf("** Phase 6 - Salvage Free List\n"); makefree(); n_free = sblk.b_un.b_fs .s_tfree; } pwarn("%ld files %ld blocks %ld free\n", n_files,n_blks,n_free); if(dfile.mod) { time(& sblk.b_un.b_fs .s_time); sblk.b_dirty = 1 ; } ckfini(); sync(); if(dfile.mod && hotroot) { printf("ROOT MODIFIED\n"); } if(dfile.mod && preen == 0) printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); } error(s1,s2,s3,s4) char *s1; { printf(s1,s2,s3,s4); } errexit(s1,s2,s3,s4) char *s1; { error(s1,s2,s3,s4); exit(8); } #line 718 "fsck.c" pfatal(s,a1,a2,a3) { if (preen) { printf("%s: ", devname); printf(s, a1, a2, a3); printf("\n"); preendie(); } printf(s, a1, a2, a3); } #line 734 "fsck.c" preendie() { printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", devname); exit(8); } #line 745 "fsck.c" pwarn(s,a1,a2,a3,a4,a5,a6) { if (preen) printf("%s: ", devname); printf(s, a1, a2, a3, a4, a5, a6); } ckinode(dp,flg) DINODE *dp; register flg; { register daddr_t *ap; register ret; int (*func)(), n; daddr_t iaddrs[ 13 ]; if( ( ((dp->di_mode & 0170000 ) == 0060000 ) || ((dp->di_mode & 0170000 ) == 0020000 ) ) ) return( 04 ); l3tol(iaddrs,dp->di_addr, 13 ); func = (flg == 0 ) ? pfunc : dirscan; for(ap = iaddrs; ap < &iaddrs[ 13 -3]; ap++) { if(*ap && (ret = (*func)(*ap)) & 01 ) return(ret); } for(n = 1; n < 4; n++) { if(*ap && (ret = iblock(*ap,n,flg)) & 01 ) return(ret); ap++; } return( 04 ); } iblock(blk,ilevel,flg) daddr_t blk; register ilevel; { register daddr_t *ap; register n; int (*func)(); BUFAREA ib; if(flg == 0 ) { func = pfunc; if(((n = (*func)(blk)) & 04 ) == 0) return(n); } else func = dirscan; if( ( blk < fmin || blk >= fmax) ) return( 02 ); ( &ib )->b_dirty = 0;( &ib )->b_bno = (daddr_t)-1 ; if(getblk(&ib,blk) == 0 ) return( 02 ); ilevel--; for(ap = ib.b_un.b_indir; ap < &ib.b_un.b_indir[ ( ( (( big ) & 64) ? 4096: 1024) /sizeof(daddr_t)) ]; ap++) { if(*ap) { if(ilevel > 0) { n = iblock(*ap,ilevel,flg); } else n = (*func)(*ap); if(n & 01 ) return(n); } } return( 04 ); } pass1(blk) daddr_t blk; { register daddr_t *dlp; if( ( blk < fmin || blk >= fmax) ) { blkerr("BAD",blk); if(++badblk >= 10 ) { printf("EXCESSIVE BAD BLKS I=%u",inum); if(reply("CONTINUE") == 0 ) errexit(""); return( 01 ); } return( 02 ); } if( domap( blk ,1) ) { blkerr("DUP",blk); if(++dupblk >= 10 ) { printf("EXCESSIVE DUP BLKS I=%u",inum); if(reply("CONTINUE") == 0 ) errexit(""); return( 01 ); } if(enddup >= &duplist[ 100 ]) { printf("DUP TABLE OVERFLOW."); if(reply("CONTINUE") == 0 ) errexit(""); return( 01 ); } for(dlp = duplist; dlp < muldup; dlp++) { if(*dlp == blk) { *enddup++ = blk; break; } } if(dlp >= muldup) { *enddup++ = *muldup; *muldup++ = blk; } } else { n_blks++; domap( blk ,0) ; } filsize++; return( 04 ); } pass1b(blk) daddr_t blk; { register daddr_t *dlp; if( ( blk < fmin || blk >= fmax) ) return( 02 ); for(dlp = duplist; dlp < muldup; dlp++) { if(*dlp == blk) { blkerr("DUP",blk); *dlp = *--muldup; *muldup = blk; return(muldup == duplist ? 01 : 04 ); } } return( 04 ); } pass2(dirp) register DIRECT *dirp; { register char *p; register n; DINODE *dp; if((inum = dirp->d_ino) == 0) return( 04 ); thisname = pathp; for(p = dirp->d_name; p < &dirp->d_name[ 14 ]; ) if((*pathp++ = *p++) == 0) { --pathp; break; } *pathp = 0; n = 0 ; if(inum > imax || inum <= 0) n = direrr("I OUT OF RANGE"); else { again: switch( dostate(0,1) ) { case 0 : n = direrr("UNALLOCATED"); break; case 03 : if((n = direrr("DUP/BAD")) == 1 ) break; if((dp = ginode()) == 0 ) break; dostate( ((dp->di_mode & 0170000 ) == 0040000 ) ? 02 : 01 ,0) ; goto again; case 01 : dolncnt(0,2) ; break; case 02 : dolncnt(0,2) ; descend(); } } pathp = thisname; if(n == 0 ) return( 04 ); dirp->d_ino = 0; return( 04 | 010 ); } pass4(blk) daddr_t blk; { register daddr_t *dlp; if( ( blk < fmin || blk >= fmax) ) return( 02 ); if( domap( blk ,1) ) { for(dlp = duplist; dlp < enddup; dlp++) if(*dlp == blk) { *dlp = *--enddup; return( 04 ); } domap( blk ,2) ; n_blks--; } return( 04 ); } pass5(blk) daddr_t blk; { if( ( blk < fmin || blk >= fmax) ) { fixfree = 1; if (preen) pfatal("BAD BLOCKS IN FREE LIST."); if(++badblk >= 10 ) { printf("EXCESSIVE BAD BLKS IN FREE LIST."); if(reply("CONTINUE") == 0 ) errexit(""); return( 01 ); } return( 02 ); } if( domap( blk ,1+4) ) { fixfree = 1; if(++dupblk >= 100 ) { printf("EXCESSIVE DUP BLKS IN FREE LIST."); if(reply("CONTINUE") == 0 ) errexit(""); return( 01 ); } } else { n_free++; domap( blk ,0+4) ; } return( 04 ); } blkerr(s,blk) daddr_t blk; char *s; { pfatal("%ld %s I=%u",blk,s,inum); printf("\n"); dostate( 03 ,0) ; } descend() { register DINODE *dp; register char *savname; off_t savsize; dostate( 01 ,0) ; if((dp = ginode()) == 0 ) return; savname = thisname; *pathp++ = '/'; savsize = filsize; filsize = dp->di_size; ckinode(dp, 1 ); thisname = savname; *--pathp = 0; filsize = savsize; } dirscan(blk) daddr_t blk; { register DIRECT *dirp; register char *p1, *p2; register n; DIRECT direntry; if( ( blk < fmin || blk >= fmax) ) { filsize -= ( (( big ) & 64) ? 4096: 1024) ; return( 02 ); } for(dirp = fileblk.b_un .b_dir; dirp < & fileblk.b_un .b_dir[ ( ( (( big ) & 64) ? 4096: 1024) /sizeof(struct direct)) ] && filsize > 0; dirp++, filsize -= sizeof(DIRECT)) { if(getblk(&fileblk,blk) == 0 ) { filsize -= (& fileblk.b_un .b_dir[ ( ( (( big ) & 64) ? 4096: 1024) /sizeof(struct direct)) ]-dirp)* sizeof(DIRECT); return( 02 ); } p1 = &dirp->d_name[ 14 ]; p2 = &direntry.d_name[ 14 ]; while(p1 > (char *)dirp) *--p2 = *--p1; if((n = (*pfunc)(&direntry)) & 010 ) { if(getblk(&fileblk,blk) != 0 ) { p1 = &dirp->d_name[ 14 ]; p2 = &direntry.d_name[ 14 ]; while(p1 > (char *)dirp) *--p1 = *--p2; fileblk.b_dirty = 1 ; } else n &= ~ 010 ; } if(n & 01 ) return(n); } return(filsize > 0 ? 04 : 01 ); } direrr(s) char *s; { register DINODE *dp; pwarn("%s ",s); pinode(); printf("\n"); if((dp = ginode()) != 0 && ftypeok(dp)) pfatal("%s=%s", ((dp->di_mode & 0170000 ) == 0040000 ) ?"DIR":"FILE",pathname); else pfatal("NAME=%s",pathname); return(reply("REMOVE")); } adjust(lcnt) register short lcnt; { register DINODE *dp; if((dp = ginode()) == 0 ) return; if(dp->di_nlink == lcnt) { if(linkup() == 0 ) clri("UNREF", 0 , 0 ); } else { pwarn("LINK COUNT %s", (lfdir==inum)?lfname:( ((dp->di_mode & 0170000 ) == 0040000 ) ?"DIR":"FILE")); pinode(); printf(" COUNT %d SHOULD BE %d", dp->di_nlink,dp->di_nlink-lcnt); if (preen) { if (lcnt < 0) { printf("\n"); preendie(); } printf(" (ADJUSTED)\n"); } if(preen || reply("ADJUST") == 1 ) { dp->di_nlink -= lcnt; inoblk.b_dirty = 1 ; } } } clri(s,flg,jclr) char *s; { register DINODE *dp; if((dp = ginode()) == 0 ) return; if(flg == 1 ) { pwarn("%s %s",s, ((dp->di_mode & 0170000 ) == 0040000 ) ?"DIR":"FILE"); pinode(); } if(preen || reply("CLEAR") == 1 ) { if (preen) if (jclr == 1 ) zcleared++; else printf(" (CLEARED)\n"); n_files--; pfunc = pass4; ckinode(dp, 0 ); clear((char *)( dp ),sizeof(DINODE)) ; inoblk.b_dirty = 1 ; } } setup(dev) char *dev; { register n; register BUFAREA *bp; register MEMSIZE msize; char *mbase; daddr_t bcnt, nscrblk; dev_t rootdev; off_t smapsz, lncntsz, totsz; struct stat statarea; if(stat("/",&statarea) < 0) errexit("Can't stat root\n"); rootdev = statarea.st_dev; if(stat(dev,&statarea) < 0) { error("Can't stat %s\n",dev); return( 0 ); } rawflg = 0; big = 0 ; if((statarea.st_mode & 0170000 ) == 0060000 ) { if( (( statarea.st_rdev ) & 64) ) big = 64 ; } else if((statarea.st_mode & 0170000 ) == 0020000 ) rawflg++; else { if (reply("file is not a block or character device; OK") == 0 ) return( 0 ); } if(rootdev == statarea.st_rdev) hotroot++; if((dfile.rfdes = open(dev,0)) < 0) { error("Can't open %s\n",dev); return( 0 ); } if (preen == 0) printf("\n%s",dev); if(nflag || (dfile.wfdes = open(dev,1)) < 0) { dfile.wfdes = -1; if (preen) pfatal("NO WRITE ACCESS"); printf(" (NO WRITE)"); } if (preen == 0) printf("\n"); fixfree = 0; dfile.mod = 0; n_files = n_blks = n_free = 0; muldup = enddup = &duplist[0]; badlnp = &badlncnt[0]; lfdir = 0; rplyflag = 0; ( &sblk )->b_dirty = 0;( &sblk )->b_bno = (daddr_t)-1 ; ( &fileblk )->b_dirty = 0;( &fileblk )->b_bno = (daddr_t)-1 ; ( &inoblk )->b_dirty = 0;( &inoblk )->b_bno = (daddr_t)-1 ; sfile.wfdes = sfile.rfdes = -1; rmscr = 0; if(getblk(&sblk, ((daddr_t)1) ) == 0 ) { ckfini(); return( 0 ); } imax = ((ino_t) sblk.b_un.b_fs .s_isize - ( ((daddr_t)1) +1)) * ( (( big ) & 64) ? 64: 16) ; fmin = (daddr_t) sblk.b_un.b_fs .s_isize; fmax = sblk.b_un.b_fs .s_fsize; if(fmin >= fmax || (imax/ ( (( big ) & 64) ? 64: 16) ) != ((ino_t) sblk.b_un.b_fs .s_isize-( ((daddr_t)1) +1))) { pfatal("Size check: fsize %ld isize %d", sblk.b_un.b_fs .s_fsize, sblk.b_un.b_fs .s_isize); printf("\n"); ckfini(); return( 0 ); } if (preen == 0) printf("File System: %.12s\n\n", sblk.b_un.b_fs .s_fsmnt); bmapsz = (((( ((( fmax )+(( 8 )-1))/( 8 )) )+(( sizeof(*lncntp) )-1))/( sizeof(*lncntp) ))*( sizeof(*lncntp) )) ; smapsz = (((( ((( (long)(imax+1) )+(( ( 8 / 2 ) )-1))/( ( 8 / 2 ) )) )+(( sizeof(*lncntp) )-1))/( sizeof(*lncntp) ))*( sizeof(*lncntp) )) ; lncntsz = (long)(imax+1) * sizeof(*lncntp); if(bmapsz > smapsz+lncntsz) smapsz = bmapsz-lncntsz; totsz = bmapsz+smapsz+lncntsz; msize = memsize; mbase = membase; if(rawflg) { if(msize < (MEMSIZE)( 11 * ( (( big ) & 64) ? 4096: 1024) ) + 2*sizeof(BUFAREA)) rawflg = 0; else { msize -= (MEMSIZE) 11 * ( (( big ) & 64) ? 4096: 1024) ; mbase += (MEMSIZE) 11 * ( (( big ) & 64) ? 4096: 1024) ; niblk = 11 ; startib = fmax; } } clear(mbase,msize); if((off_t)msize < totsz) { bmapsz = (((( bmapsz )+(( ( (( big ) & 64) ? 4096: 1024) )-1))/( ( (( big ) & 64) ? 4096: 1024) ))*( ( (( big ) & 64) ? 4096: 1024) )) ; smapsz = (((( smapsz )+(( ( (( big ) & 64) ? 4096: 1024) )-1))/( ( (( big ) & 64) ? 4096: 1024) ))*( ( (( big ) & 64) ? 4096: 1024) )) ; lncntsz = (((( lncntsz )+(( ( (( big ) & 64) ? 4096: 1024) )-1))/( ( (( big ) & 64) ? 4096: 1024) ))*( ( (( big ) & 64) ? 4096: 1024) )) ; nscrblk = (bmapsz+smapsz+lncntsz)>> ( (( big ) & 64) ? 12: 10) ; if(tflag == 0) { printf("\nNEED SCRATCH FILE (%ld BLKS)\n",nscrblk); do { printf("ENTER FILENAME: "); if((n = getline( (&_iob[0]) ,scrfile,sizeof(scrfile))) == (-1) ) errexit("\n"); } while(n == 0); } if(stat(scrfile,&statarea) < 0 || (statarea.st_mode & 0170000 ) == 0100000 ) rmscr++; if((sfile.wfdes = creat(scrfile,0666)) < 0 || (sfile.rfdes = open(scrfile,0)) < 0) { error("Can't create %s\n",scrfile); ckfini(); return( 0 ); } bp = &((BUFAREA *)mbase)[(msize/sizeof(BUFAREA))]; poolhead = 0 ; while(--bp >= (BUFAREA *)mbase) { ( bp )->b_dirty = 0;( bp )->b_bno = (daddr_t)-1 ; bp->b_next = poolhead; poolhead = bp; } bp = poolhead; for(bcnt = 0; bcnt < nscrblk; bcnt++) { bp->b_bno = bcnt; ( bp )->b_dirty = 1 ; flush(&sfile,bp); } blkmap = freemap = statemap = (char *) 0 ; lncntp = (short *) 0 ; smapblk = bmapsz / ( (( big ) & 64) ? 4096: 1024) ; lncntblk = smapblk + smapsz / ( (( big ) & 64) ? 4096: 1024) ; fmapblk = smapblk; } else { if(rawflg && (off_t)msize > totsz+ ( (( big ) & 64) ? 4096: 1024) ) { niblk += (unsigned)((off_t)msize-totsz)>> ( (( big ) & 64) ? 12: 10) ; if(niblk > 110 ) niblk = 110 ; msize = memsize - (niblk* ( (( big ) & 64) ? 4096: 1024) ); mbase = membase + (niblk* ( (( big ) & 64) ? 4096: 1024) ); } poolhead = 0 ; blkmap = mbase; statemap = &mbase[(MEMSIZE)bmapsz]; freemap = statemap; lncntp = (short *)&statemap[(MEMSIZE)smapsz]; } return( 1 ); } DINODE * ginode() { register DINODE *dp; register char *mbase; daddr_t iblk; if(inum > imax) return( 0 ); iblk = ((daddr_t)((((unsigned)( inum )+2* ( (( big ) & 64) ? 64: 16) -1)/ ( (( big ) & 64) ? 64: 16) ))) ; if(rawflg) { mbase = membase; if(iblk < startib || iblk >= startib+niblk) { if(inoblk.b_dirty) bwrite(&dfile,mbase,startib,(int)niblk* ( (( big ) & 64) ? 4096: 1024) ); inoblk.b_dirty = 0; if(bread(&dfile,mbase,iblk,(int)niblk* ( (( big ) & 64) ? 4096: 1024) ) == 0 ) { startib = fmax; return( 0 ); } startib = iblk; } dp = (DINODE *)&mbase[(unsigned)((iblk-startib)<< ( (( big ) & 64) ? 12: 10) )]; } else if(getblk(&inoblk,iblk) != 0 ) dp = inoblk.b_un.b_dinode; else return( 0 ); return(dp + ((int)((( inum )+2* ( (( big ) & 64) ? 64: 16) -1)% ( (( big ) & 64) ? 64: 16) )) ); } ftypeok(dp) DINODE *dp; { switch(dp->di_mode & 0170000 ) { case 0040000 : case 0100000 : case 0060000 : case 0020000 : case 0120000 : return( 1 ); default: return( 0 ); } } reply(s) char *s; { char line[80]; if (preen) pfatal("INTERNAL ERROR: GOT TO reply()"); rplyflag = 1; printf("\n%s? ",s); if(nflag || csflag || dfile.wfdes < 0) { printf(" no\n\n"); return( 0 ); } if(yflag) { printf(" yes\n\n"); return( 1 ); } if(getline( (&_iob[0]) ,line,sizeof(line)) == (-1) ) errexit("\n"); printf("\n"); if(line[0] == 'y' || line[0] == 'Y') return( 1 ); else return( 0 ); } getline(fp,loc,maxlen) struct _iobuf *fp; char *loc; { register n; register char *p, *lastloc; p = loc; lastloc = &p[maxlen-1]; while((n = (--( fp )->_cnt>=0? (int)*( fp )->_ptr++:_filbuf( fp )) ) != '\n') { if(n == (-1) ) return( (-1) ); if(! ((_ctype+1)[ n ]& 010 ) && p < lastloc) *p++ = n; } *p = 0; return(p - loc); } stype(p) register char *p; { if(*p == 0) return; cylsize = atoi(p); while(*p && *p != ':') p++; if(*p) p++; stepsize = atoi(p); if(stepsize <= 0 || stepsize > cylsize || cylsize <= 0 || cylsize > 1000 ) { error("Invalid -s argument, defaults assumed\n"); cylsize = stepsize = 0; } } dostate(s,flg) { register char *p; register unsigned byte, shift; BUFAREA *bp; byte = (inum)/ ( 8 / 2 ) ; shift = 2 * ((inum)% ( 8 / 2 ) ); if(statemap != 0 ) { bp = 0 ; p = &statemap[byte]; } else if((bp = getblk((BUFAREA *) 0 , (daddr_t)(smapblk+(byte/ ( (( big ) & 64) ? 4096: 1024) )))) == 0 ) errexit("Fatal I/O error\n"); else p = &bp->b_un.b_buf[byte% ( (( big ) & 64) ? 4096: 1024) ]; switch(flg) { case 0: *p &= ~( 03 <<(shift)); *p |= s<<(shift); if(bp != 0 ) ( bp )->b_dirty = 1 ; return(s); case 1: return((*p>>(shift)) & 03 ); } return( 0 ); } domap(blk,flg) daddr_t blk; { register char *p; register unsigned n; register BUFAREA *bp; off_t byte; byte = blk >> 3 ; n = 1<<((unsigned)(blk & 07 )); if(flg & 04) { p = freemap; blk = fmapblk; } else { p = blkmap; blk = 0; } if(p != 0 ) { bp = 0 ; p += (unsigned)byte; } else if((bp = getblk((BUFAREA *) 0 ,blk+(byte>> ( (( big ) & 64) ? 12: 10) ))) == 0 ) errexit("Fatal I/O error\n"); else p = &bp->b_un.b_buf[(unsigned)(byte& ( (( big ) & 64) ? 07777: 01777) )]; switch(flg&03) { case 0: *p |= n; break; case 1: n &= *p; bp = 0 ; break; case 2: *p &= ~n; } if(bp != 0 ) ( bp )->b_dirty = 1 ; return(n); } dolncnt(val,flg) short val; { register short *sp; register BUFAREA *bp; if(lncntp != 0 ) { bp = 0 ; sp = &lncntp[inum]; } else if((bp = getblk((BUFAREA *) 0 ,(daddr_t)(lncntblk+(inum/ ( ( (( big ) & 64) ? 4096: 1024) /sizeof(short)) )))) == 0 ) errexit("Fatal I/O error\n"); else sp = &bp->b_un.b_lnks[inum% ( ( (( big ) & 64) ? 4096: 1024) /sizeof(short)) ]; switch(flg) { case 0: *sp = val; break; case 1: bp = 0 ; break; case 2: (*sp)--; } if(bp != 0 ) ( bp )->b_dirty = 1 ; return(*sp); } BUFAREA * getblk(bp,blk) daddr_t blk; register BUFAREA *bp; { register struct filecntl *fcp; if(bp == 0 ) { bp = search(blk); fcp = &sfile; } else fcp = &dfile; if(bp->b_bno == blk) return(bp); flush(fcp,bp); if(bread(fcp,bp->b_un.b_buf,blk, ( (( big ) & 64) ? 4096: 1024) ) != 0 ) { bp->b_bno = blk; return(bp); } bp->b_bno = (daddr_t)-1; return( 0 ); } flush(fcp,bp) struct filecntl *fcp; register BUFAREA *bp; { if(bp->b_dirty) { bwrite(fcp,bp->b_un.b_buf,bp->b_bno, ( (( big ) & 64) ? 4096: 1024) ); } bp->b_dirty = 0; } rwerr(s,blk) char *s; daddr_t blk; { if (preen == 0) printf("\n"); pfatal("CAN NOT %s: BLK %ld",s,blk); if(reply("CONTINUE") == 0 ) errexit("Program terminated\n"); } sizechk(dp) register DINODE *dp; { #line 1559 "fsck.c" if( ((dp->di_mode & 0170000 ) == 0040000 ) && (dp->di_size % sizeof(DIRECT)) != 0) { pwarn("DIRECTORY MISALIGNED I=%u\n",inum); if (preen == 0) printf("\n"); } } ckfini() { flush(&dfile,&fileblk); flush(&dfile,&sblk); flush(&dfile,&inoblk); close(dfile.rfdes); close(dfile.wfdes); close(sfile.rfdes); close(sfile.wfdes); if(rmscr) { unlink(scrfile); } } pinode() { register DINODE *dp; register char *p; struct passwd *passwd; char *ctime(); printf(" I=%u ",inum); if((dp = ginode()) == 0 ) return; printf(" OWNER="); if((passwd = getpwuid((int)dp->di_uid)) != 0) { printf("%s ", passwd->pw_name); } else { printf("%d ",dp->di_uid); } printf("MODE=%o\n",dp->di_mode); if (preen) printf("%s: ", devname); printf("SIZE=%ld ",dp->di_size); p = ctime(&dp->di_mtime); printf("MTIME=%12.12s %4.4s ",p+4,p+20); } copy(fp,tp,size) register char *tp, *fp; MEMSIZE size; { while(size--) *tp++ = *fp++; } freechk() { register daddr_t *ap; register int i, j; if(big == 64 ) { for(i = sblk.b_un.b_fs .s_isize; i < sblk.b_un.b_fs .s_fsize; i++) { j = i - sblk.b_un.b_fs .s_isize; if(! domap( i ,1+4) ) { sblk.b_un.b_fs . U.B.S_bfree [j>>5] |= (1 << (j&31)); n_free++; } else sblk.b_un.b_fs . U.B.S_bfree [j>>5] &= ~(1 << (j&31)); } sblk.b_un.b_fs . U.B.S_valid = 1; sblk.b_un.b_fs .s_tfree = n_free; sblk.b_dirty = 1 ; return; } if( fileblk.b_un.b_fb .df_nfree == 0) return; do { if( fileblk.b_un.b_fb .df_nfree <= 0 || fileblk.b_un.b_fb .df_nfree > 178 ) { pwarn("BAD FREEBLK COUNT"); printf("\n"); fixfree = 1; return; } ap = & fileblk.b_un.b_fb .df_free[ fileblk.b_un.b_fb .df_nfree]; while(--ap > & fileblk.b_un.b_fb .df_free[0]) { if(pass5(*ap) == 01 ) return; } if(*ap == (daddr_t)0 || pass5(*ap) != 04 ) return; } while(getblk(&fileblk,*ap) != 0 ); } makefree() { register i, cyl, step; int j; char flg[ 1000 ]; short addr[ 1000 ]; daddr_t blk, baseblk; if(big == 64 ) return; sblk.b_un.b_fs . U.R.S_nfree = 0; sblk.b_un.b_fs .s_flock = 0; sblk.b_un.b_fs .s_fmod = 0; sblk.b_un.b_fs .s_tfree = 0; sblk.b_un.b_fs .s_ninode = 0; sblk.b_un.b_fs .s_ilock = 0; sblk.b_un.b_fs .s_ronly = 0; if(cylsize == 0 || stepsize == 0) { step = sblk.b_un.b_fs .s_dinfo[0]; cyl = sblk.b_un.b_fs .s_dinfo[1]; } else { step = stepsize; cyl = cylsize; } if(step > cyl || step <= 0 || cyl <= 0 || cyl > 1000 ) { error("Default free list spacing assumed\n"); step = 9 ; cyl = 400 ; } sblk.b_un.b_fs .s_dinfo[0] = step; sblk.b_un.b_fs .s_dinfo[1] = cyl; clear(flg,sizeof(flg)); i = 0; for(j = 0; j < cyl; j++) { while(flg[i]) i = (i + 1) % cyl; addr[j] = i + 1; flg[i]++; i = (i + step) % cyl; } baseblk = (daddr_t) (((( fmax )+(( cyl )-1))/( cyl ))*( cyl )) ; clear((char *)& fileblk.b_un.b_fb , ( (( big ) & 64) ? 4096: 1024) ); fileblk.b_un.b_fb .df_nfree++; for( ; baseblk > 0; baseblk -= cyl) for(i = 0; i < cyl; i++) { blk = baseblk - addr[i]; if(! ( blk < fmin || blk >= fmax) && ! domap( blk ,1) ) { sblk.b_un.b_fs .s_tfree++; if( fileblk.b_un.b_fb .df_nfree >= 178 ) { fileblk.b_dirty = 1 ; fileblk.b_bno = blk; flush(&dfile,&fileblk); clear((char *)& fileblk.b_un.b_fb , ( (( big ) & 64) ? 4096: 1024) ); } fileblk.b_un.b_fb .df_free[ fileblk.b_un.b_fb .df_nfree] = blk; fileblk.b_un.b_fb .df_nfree++; } } sblk.b_un.b_fs . U.R.S_nfree = fileblk.b_un.b_fb .df_nfree; for(i = 0; i < 178 ; i++) sblk.b_un.b_fs . U.R.S_free [i] = fileblk.b_un.b_fb .df_free[i]; sblk.b_dirty = 1 ; } clear(p,cnt) register char *p; MEMSIZE cnt; { while(cnt--) *p++ = 0; } BUFAREA * search(blk) daddr_t blk; { register BUFAREA *pbp, *bp; for(bp = (BUFAREA *) &poolhead; bp->b_next; ) { pbp = bp; bp = pbp->b_next; if(bp->b_bno == blk) break; } pbp->b_next = bp->b_next; bp->b_next = poolhead; poolhead = bp; return(bp); } findino(dirp) register DIRECT *dirp; { register char *p1, *p2; if(dirp->d_ino == 0) return( 04 ); for(p1 = dirp->d_name,p2 = srchname;*p2++ == *p1; p1++) { if(*p1 == 0 || p1 == &dirp->d_name[ 14 -1]) { if(dirp->d_ino > 0 && dirp->d_ino <= imax) parentdir = dirp->d_ino; return( 01 ); } } return( 04 ); } mkentry(dirp) register DIRECT *dirp; { register ino_t in; register char *p; if(dirp->d_ino) return( 04 ); dirp->d_ino = orphan; in = orphan; p = &dirp->d_name[8]; *--p = 0; while(p > dirp->d_name) { *--p = (in % 10) + '0'; in /= 10; } *p = '#'; return( 010 | 01 ); } chgdd(dirp) register DIRECT *dirp; { if(dirp->d_name[0] == '.' && dirp->d_name[1] == '.' && dirp->d_name[2] == 0) { dirp->d_ino = lfdir; return( 010 | 01 ); } return( 04 ); } linkup() { register DINODE *dp; register lostdir; register ino_t pdir; if((dp = ginode()) == 0 ) return( 0 ); lostdir = ((dp->di_mode & 0170000 ) == 0040000 ) ; pdir = parentdir; if (preen && dp->di_size == 0) return( 0 ); pwarn("UNREF %s ",lostdir ? "DIR" : "FILE"); pinode(); if (preen) printf(" (RECONNECTED)\n"); else if (reply("RECONNECT") == 0 ) return( 0 ); orphan = inum; if(lfdir == 0) { inum = ((ino_t)2) ; if((dp = ginode()) == 0 ) { inum = orphan; return( 0 ); } pfunc = findino; srchname = lfname; filsize = dp->di_size; parentdir = 0; ckinode(dp, 1 ); inum = orphan; if((lfdir = parentdir) == 0) { pfatal("SORRY. NO lost+found DIRECTORY"); printf("\n\n"); return( 0 ); } } inum = lfdir; if((dp = ginode()) == 0 || ! ((dp->di_mode & 0170000 ) == 0040000 ) || dostate(0,1) != 01 ) { inum = orphan; pfatal("SORRY. NO lost+found DIRECTORY"); printf("\n\n"); return( 0 ); } if(dp->di_size & ( (( big ) & 64) ? 07777: 01777) ) { dp->di_size = (((( dp->di_size )+(( ( (( big ) & 64) ? 4096: 1024) )-1))/( ( (( big ) & 64) ? 4096: 1024) ))*( ( (( big ) & 64) ? 4096: 1024) )) ; inoblk.b_dirty = 1 ; } filsize = dp->di_size; inum = orphan; pfunc = mkentry; if((ckinode(dp, 1 ) & 010 ) == 0) { pfatal("SORRY. NO SPACE IN lost+found DIRECTORY"); printf("\n\n"); return( 0 ); } dolncnt(0,2) ; if(lostdir) { pfunc = chgdd; dp = ginode(); filsize = dp->di_size; ckinode(dp, 1 ); inum = lfdir; if((dp = ginode()) != 0 ) { dp->di_nlink++; inoblk.b_dirty = 1 ; dolncnt( dolncnt(0,1) +1 ,0) ; } inum = orphan; pwarn("DIR I=%u CONNECTED. ",orphan); printf("PARENT WAS I=%u\n",pdir); if (preen == 0) printf("\n"); } return( 1 ); } bread(fcp,buf,blk,size) daddr_t blk; register struct filecntl *fcp; register size; char *buf; { if(lseek(fcp->rfdes,blk<< ( (( big ) & 64) ? 12: 10) ,0) < 0) rwerr("SEEK",blk); else if(read(fcp->rfdes,buf,size) == size) return( 1 ); rwerr("READ",blk); return( 0 ); } bwrite(fcp,buf,blk,size) daddr_t blk; register struct filecntl *fcp; register size; char *buf; { if(fcp->wfdes < 0) return( 0 ); if(lseek(fcp->wfdes,blk<< ( (( big ) & 64) ? 12: 10) ,0) < 0) rwerr("SEEK",blk); else if(write(fcp->wfdes,buf,size) == size) { fcp->mod = 1; return( 1 ); } rwerr("WRITE",blk); return( 0 ); } catch() { ckfini(); exit(12); }