|
|
1.1 ! root 1: /* ! 2: * Perform initialization for phases of fsck ! 3: */ ! 4: #include "fsck.h" ! 5: #include <mnttab.h> ! 6: #include <mtab.h> ! 7: ! 8: int fsfd; /* file system file descriptor */ ! 9: int writeflg; /* write ok or read-only flag */ ! 10: daddr_t fsize = SUPERI+1; /* file system size in blocks */ ! 11: /* Allows for read of Super Block */ ! 12: int isize; /* First block not in inode list */ ! 13: daddr_t totfree; /* Running total free block count */ ! 14: unsigned ninodes; /* number of inodes */ ! 15: int numfiles; /* number of files in file system */ ! 16: ! 17: char superb[BSIZE]; /* Super Block */ ! 18: struct filsys *sbp = superb; ! 19: int sbpfix; /* flag for super block fixes */ ! 20: ! 21: int offsets[] = /* table of offsets for the levels */ ! 22: { ND, ND+NI, ND+NI+NII, /* of indirection of blocks in the */ ! 23: ND+NI+NII+NIII }; /* inode block list */ ! 24: ! 25: daddr_t dupblck[DUPTBLSIZE]; /* duplicate referenced blocks */ ! 26: int totdups; /* number of dup blocks so far */ ! 27: ! 28: #if !SMALLMODEL ! 29: unsigned short *linkPtr; ! 30: unsigned char *flagptr, *blockPtr, *dupPtr; ! 31: #endif ! 32: ! 33: init() ! 34: { ! 35: int mode; ! 36: struct stat status; ! 37: unsigned short stmode; ! 38: ! 39: mode = (mdaction == NO) ? 0 : 2; ! 40: ! 41: if ( (fsfd = open(fsname, mode)) == (-1) ) { ! 42: mode = 0; ! 43: if ( (fsfd = open(fsname, mode)) == (-1) ) { ! 44: nonfatal("Can't open: %s", fsname); ! 45: return; ! 46: } ! 47: } ! 48: ! 49: if (mode == 0) { ! 50: daction = NO; ! 51: writeflg = FALSE; ! 52: } else { ! 53: daction = mdaction; ! 54: writeflg = TRUE; ! 55: } ! 56: ! 57: printf("%s: %s\n", fsname, (mode == 0) ? "(NO WRITE)" : ""); ! 58: ! 59: if ( fstat(fsfd, &status) == (-1) ) { ! 60: nonfatal("Can't stat: %s", fsname); ! 61: return; ! 62: } ! 63: ! 64: stmode = status.st_mode & S_IFMT; ! 65: if ( (stmode != S_IFBLK) && (stmode != S_IFCHR) ) ! 66: switch(query("file is not a block or character device; OK?")){ ! 67: case YES: ! 68: break; ! 69: case NO: ! 70: errflag = TRUE; ! 71: return; ! 72: } ! 73: ! 74: domount(); ! 75: sbpfix = FALSE; ! 76: readsuper(); ! 77: checksuper(); ! 78: if ( !errflag ) ! 79: alloctables(); ! 80: } ! 81: ! 82: /* ! 83: * Read in the super block and canonicalize ! 84: */ ! 85: ! 86: readsuper() ! 87: { ! 88: register int i; ! 89: ! 90: bread((daddr_t)SUPERI, superb); ! 91: sbp = superb; ! 92: ! 93: canshort(sbp->s_isize); ! 94: candaddr(sbp->s_fsize); ! 95: canshort(sbp->s_nfree); ! 96: for(i=0; i<NICFREE; i++) ! 97: candaddr(sbp->s_free[i]); ! 98: canshort(sbp->s_ninode); ! 99: for(i=0; i<NICINOD; i++) ! 100: canino(sbp->s_inode[i]); ! 101: cantime(sbp->s_time); ! 102: candaddr(sbp->s_tfree); ! 103: canino(sbp->s_tinode); ! 104: canshort(sbp->s_m); ! 105: canshort(sbp->s_n); ! 106: canlong(sbp->s_unique); ! 107: ! 108: } ! 109: ! 110: /* ! 111: * Check super block for obvious inconsistencies ! 112: */ ! 113: ! 114: checksuper() ! 115: { ! 116: fsize = sbp->s_fsize; ! 117: isize = sbp->s_isize; ! 118: totfree = fsize - isize; ! 119: ! 120: if ( (isize<=INODEI) || (isize>=fsize) || (fsize<=INODEI) ) { ! 121: badsuper("Size check: fsize %U isize %u", fsize, isize); ! 122: errflag = TRUE; ! 123: } ! 124: ! 125: if ( sbp->s_nfree > NICFREE ) ! 126: badsuper("Too large free block count"); ! 127: ! 128: if ( sbp->s_ninode > NICINOD ) ! 129: badsuper("Too large free i-node count"); ! 130: } ! 131: ! 132: /* ! 133: * Super Block Error Functions ! 134: */ ! 135: badsuper(x) ! 136: { ! 137: printf("%r\n", &x); ! 138: printf("fsck: %s: Bad Super Block: %u\n", fsname, SUPERI); ! 139: } ! 140: ! 141: /* ! 142: * Allocate the necessary buffers for tables ! 143: */ ! 144: alloctables() ! 145: { ! 146: unsigned num, numl; ! 147: ! 148: numl = 0; ! 149: if (!fflag) { ! 150: ninodes = (unsigned) (isize - INODEI) * INOPB; ! 151: numl = (unsigned) ninodes; ! 152: } ! 153: ! 154: num = (unsigned) ((fsize+NBPC-1)/NBPC) * sizeof(char); ! 155: #if SMALLMODEL ! 156: initV(numl, numl, num, num); /* virtual allocation */ ! 157: #else ! 158: if (NULL != linkPtr) { ! 159: free(linkPtr); ! 160: free(flagPtr); ! 161: free(blockPtr); ! 162: free(dupPtr); ! 163: } ! 164: linkPtr = calloc(numl, sizeof(unsigned short)); ! 165: flagPtr = calloc(numl, sizeof(unsigned char)); ! 166: blockPtr = calloc(num, sizeof(unsigned char)); ! 167: dupPtr = calloc(num, sizeof(unsigned char)); ! 168: #endif ! 169: numfiles = /* number of files in the file system */ ! 170: totdups = 0; /* num dup blocks */ ! 171: } ! 172: ! 173: /* ! 174: * domount() checks the files /etc/mnttab and /etc/mtab to find ! 175: * out where the file system is mounted (if at all). It then ! 176: * reports where (and when if possible) it was last mounted. ! 177: */ ! 178: char *mnttab_name = "/etc/mnttab"; ! 179: char *mtab_name = "/etc/mtab"; ! 180: char *bttime_name = "/etc/boottime"; ! 181: ! 182: domount() ! 183: { ! 184: int fd; ! 185: struct mnttab mnttab; ! 186: struct mtab mtab; ! 187: register char *name; ! 188: struct stat sbuf; ! 189: time_t boottime; ! 190: int nothing(); ! 191: char devname[MNTNSIZ+6] = "/dev/"; ! 192: ! 193: mounted = FALSE; ! 194: name = fsname; /* strip off all initial */ ! 195: while (*name++ != '\0') ; /* directories in fsname */ ! 196: while ( (*--name != '/') && (name>fsname) ) ; ! 197: if (*name == '/') name++; ! 198: ! 199: if ( stat(bttime_name, &sbuf) == -1 ) ! 200: boottime = (time_t)0; ! 201: else ! 202: boottime = sbuf.st_mtime; ! 203: ! 204: if ( (fd=open(mnttab_name, 0)) != (-1) ) { ! 205: while ( read(fd, &mnttab, sizeof(mnttab))==sizeof(mnttab) ) ! 206: if ( mnttab.mt_dev[0] && mnttab.mt_filsys[0] ) { ! 207: strncpy(&devname[5], mnttab.mt_filsys, MNTNSIZ); ! 208: devname[MNTNSIZ+5] = '\0'; ! 209: statit(devname, nothing); ! 210: if (stats.st_rdev != fsysrdev) ! 211: continue; ! 212: statit(mnttab.mt_dev, nothing); ! 213: mounted = (stats.st_dev == fsysrdev); ! 214: prmnttab(&mnttab, boottime); ! 215: return; ! 216: } ! 217: } ! 218: if ( (fd=open(mtab_name, 0)) != (-1) ) { ! 219: while ( read(fd, &mtab, sizeof(mtab))==sizeof(mtab) ) ! 220: if ( mtab.mt_name[0] && mtab.mt_special[0] ) { ! 221: strncpy(&devname[5], mtab.mt_special, MNAMSIZ); ! 222: devname[MNAMSIZ+5] = '\0'; ! 223: statit(devname, nothing); ! 224: if (stats.st_rdev != fsysrdev) ! 225: continue; ! 226: statit(mtab.mt_name, nothing); ! 227: mounted = (stats.st_dev == fsysrdev); ! 228: prmtab(&mtab); ! 229: return; ! 230: } ! 231: } ! 232: ! 233: if (fsysrdev == rootdev) ! 234: mounted = TRUE; ! 235: else ! 236: mounted = FALSE; ! 237: ! 238: } ! 239: ! 240: prmnttab(ptr, boottime) ! 241: struct mnttab *ptr; ! 242: time_t boottime; ! 243: { ! 244: if (mounted) { ! 245: if (boottime < ptr->mt_time) ! 246: boottime = ptr->mt_time; ! 247: printf("%s mounted on %.*s as of %s", fsname, MNTNSIZ, ! 248: ptr->mt_dev, ctime(&boottime)); ! 249: } else ! 250: printf("%s unmounted. Last mounted on %.*s -- %s", ! 251: fsname, MNTNSIZ, ptr->mt_dev, ! 252: ctime(&ptr->mt_time)); ! 253: } ! 254: ! 255: ! 256: prmtab(ptr) ! 257: struct mtab *ptr; ! 258: { ! 259: if (mounted) ! 260: printf("%s mounted on %.*s\n", fsname, MNAMSIZ, ptr->mt_name); ! 261: else ! 262: printf("%s unmounted. Last mounted on %.*s\n", fsname, ! 263: MNAMSIZ, ptr->mt_name); ! 264: } ! 265: ! 266: nothing() ! 267: {}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.