|
|
researchv10 Dan Cross
#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);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.