|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: char copyright[] = ! 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif not lint ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)main.c 5.4 (Berkeley) 3/5/86"; ! 15: #endif not lint ! 16: ! 17: #include <sys/param.h> ! 18: #include <sys/inode.h> ! 19: #include <sys/fs.h> ! 20: #include <sys/stat.h> ! 21: #include <sys/wait.h> ! 22: #include <fstab.h> ! 23: #include <strings.h> ! 24: #include "fsck.h" ! 25: ! 26: char *rawname(), *unrawname(), *blockcheck(); ! 27: int catch(), catchquit(), voidquit(); ! 28: int returntosingle; ! 29: int (*signal())(); ! 30: ! 31: main(argc, argv) ! 32: int argc; ! 33: char *argv[]; ! 34: { ! 35: struct fstab *fsp; ! 36: int pid, passno, anygtr, sumstatus; ! 37: char *name; ! 38: ! 39: sync(); ! 40: while (--argc > 0 && **++argv == '-') { ! 41: switch (*++*argv) { ! 42: ! 43: case 'p': ! 44: preen++; ! 45: break; ! 46: ! 47: case 'b': ! 48: if (argv[0][1] != '\0') { ! 49: bflag = atoi(argv[0]+1); ! 50: } else { ! 51: bflag = atoi(*++argv); ! 52: argc--; ! 53: } ! 54: printf("Alternate super block location: %d\n", bflag); ! 55: break; ! 56: ! 57: case 'd': ! 58: debug++; ! 59: break; ! 60: ! 61: case 'n': /* default no answer flag */ ! 62: case 'N': ! 63: nflag++; ! 64: yflag = 0; ! 65: break; ! 66: ! 67: case 'y': /* default yes answer flag */ ! 68: case 'Y': ! 69: yflag++; ! 70: nflag = 0; ! 71: break; ! 72: ! 73: default: ! 74: errexit("%c option?\n", **argv); ! 75: } ! 76: } ! 77: if (signal(SIGINT, SIG_IGN) != SIG_IGN) ! 78: (void)signal(SIGINT, catch); ! 79: if (preen) ! 80: (void)signal(SIGQUIT, catchquit); ! 81: if (argc) { ! 82: while (argc-- > 0) { ! 83: hotroot = 0; ! 84: checkfilesys(*argv++); ! 85: } ! 86: exit(0); ! 87: } ! 88: sumstatus = 0; ! 89: passno = 1; ! 90: do { ! 91: anygtr = 0; ! 92: if (setfsent() == 0) ! 93: errexit("Can't open checklist file: %s\n", FSTAB); ! 94: while ((fsp = getfsent()) != 0) { ! 95: if (strcmp(fsp->fs_type, FSTAB_RW) && ! 96: strcmp(fsp->fs_type, FSTAB_RO) && ! 97: strcmp(fsp->fs_type, FSTAB_RQ)) ! 98: continue; ! 99: if (preen == 0 || ! 100: passno == 1 && fsp->fs_passno == passno) { ! 101: name = blockcheck(fsp->fs_spec); ! 102: if (name != NULL) ! 103: checkfilesys(name); ! 104: else if (preen) ! 105: exit(8); ! 106: } else if (fsp->fs_passno > passno) { ! 107: anygtr = 1; ! 108: } else if (fsp->fs_passno == passno) { ! 109: pid = fork(); ! 110: if (pid < 0) { ! 111: perror("fork"); ! 112: exit(8); ! 113: } ! 114: if (pid == 0) { ! 115: (void)signal(SIGQUIT, voidquit); ! 116: name = blockcheck(fsp->fs_spec); ! 117: if (name == NULL) ! 118: exit(8); ! 119: checkfilesys(name); ! 120: exit(0); ! 121: } ! 122: } ! 123: } ! 124: if (preen) { ! 125: union wait status; ! 126: while (wait(&status) != -1) ! 127: sumstatus |= status.w_retcode; ! 128: } ! 129: passno++; ! 130: } while (anygtr); ! 131: if (sumstatus) ! 132: exit(8); ! 133: (void)endfsent(); ! 134: if (returntosingle) ! 135: exit(2); ! 136: exit(0); ! 137: } ! 138: ! 139: checkfilesys(filesys) ! 140: char *filesys; ! 141: { ! 142: daddr_t n_ffree, n_bfree; ! 143: struct dups *dp; ! 144: struct zlncnt *zlnp; ! 145: ! 146: devname = filesys; ! 147: if (setup(filesys) == 0) { ! 148: if (preen) ! 149: pfatal("CAN'T CHECK FILE SYSTEM."); ! 150: return; ! 151: } ! 152: /* ! 153: * 1: scan inodes tallying blocks used ! 154: */ ! 155: if (preen == 0) { ! 156: printf("** Last Mounted on %s\n", sblock.fs_fsmnt); ! 157: if (hotroot) ! 158: printf("** Root file system\n"); ! 159: printf("** Phase 1 - Check Blocks and Sizes\n"); ! 160: } ! 161: pass1(); ! 162: ! 163: /* ! 164: * 1b: locate first references to duplicates, if any ! 165: */ ! 166: if (duplist) { ! 167: if (preen) ! 168: pfatal("INTERNAL ERROR: dups with -p"); ! 169: printf("** Phase 1b - Rescan For More DUPS\n"); ! 170: pass1b(); ! 171: } ! 172: ! 173: /* ! 174: * 2: traverse directories from root to mark all connected directories ! 175: */ ! 176: if (preen == 0) ! 177: printf("** Phase 2 - Check Pathnames\n"); ! 178: pass2(); ! 179: ! 180: /* ! 181: * 3: scan inodes looking for disconnected directories ! 182: */ ! 183: if (preen == 0) ! 184: printf("** Phase 3 - Check Connectivity\n"); ! 185: pass3(); ! 186: ! 187: /* ! 188: * 4: scan inodes looking for disconnected files; check reference counts ! 189: */ ! 190: if (preen == 0) ! 191: printf("** Phase 4 - Check Reference Counts\n"); ! 192: pass4(); ! 193: ! 194: /* ! 195: * 5: check and repair resource counts in cylinder groups ! 196: */ ! 197: if (preen == 0) ! 198: printf("** Phase 5 - Check Cyl groups\n"); ! 199: pass5(); ! 200: ! 201: /* ! 202: * print out summary statistics ! 203: */ ! 204: n_ffree = sblock.fs_cstotal.cs_nffree; ! 205: n_bfree = sblock.fs_cstotal.cs_nbfree; ! 206: pwarn("%d files, %d used, %d free ", ! 207: n_files, n_blks, n_ffree + sblock.fs_frag * n_bfree); ! 208: printf("(%d frags, %d blocks, %.1f%% fragmentation)\n", ! 209: n_ffree, n_bfree, (float)(n_ffree * 100) / sblock.fs_dsize); ! 210: if (debug && (n_files -= imax - ROOTINO - sblock.fs_cstotal.cs_nifree)) ! 211: printf("%d files missing\n", n_files); ! 212: if (debug) { ! 213: n_blks += sblock.fs_ncg * ! 214: (cgdmin(&sblock, 0) - cgsblock(&sblock, 0)); ! 215: n_blks += cgsblock(&sblock, 0) - cgbase(&sblock, 0); ! 216: n_blks += howmany(sblock.fs_cssize, sblock.fs_fsize); ! 217: if (n_blks -= fmax - (n_ffree + sblock.fs_frag * n_bfree)) ! 218: printf("%d blocks missing\n", n_blks); ! 219: if (duplist != NULL) { ! 220: printf("The following duplicate blocks remain:"); ! 221: for (dp = duplist; dp; dp = dp->next) ! 222: printf(" %d,", dp->dup); ! 223: printf("\n"); ! 224: } ! 225: if (zlnhead != NULL) { ! 226: printf("The following zero link count inodes remain:"); ! 227: for (zlnp = zlnhead; zlnp; zlnp = zlnp->next) ! 228: printf(" %d,", zlnp->zlncnt); ! 229: printf("\n"); ! 230: } ! 231: } ! 232: zlnhead = (struct zlncnt *)0; ! 233: duplist = (struct dups *)0; ! 234: if (dfile.mod) { ! 235: (void)time(&sblock.fs_time); ! 236: sbdirty(); ! 237: } ! 238: ckfini(); ! 239: free(blockmap); ! 240: free(statemap); ! 241: free((char *)lncntp); ! 242: if (!dfile.mod) ! 243: return; ! 244: if (!preen) { ! 245: printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); ! 246: if (hotroot) ! 247: printf("\n***** REBOOT UNIX *****\n"); ! 248: } ! 249: if (hotroot) { ! 250: sync(); ! 251: exit(4); ! 252: } ! 253: } ! 254: ! 255: char * ! 256: blockcheck(name) ! 257: char *name; ! 258: { ! 259: struct stat stslash, stblock, stchar; ! 260: char *raw; ! 261: int looped = 0; ! 262: ! 263: hotroot = 0; ! 264: if (stat("/", &stslash) < 0){ ! 265: printf("Can't stat root\n"); ! 266: return (0); ! 267: } ! 268: retry: ! 269: if (stat(name, &stblock) < 0){ ! 270: printf("Can't stat %s\n", name); ! 271: return (0); ! 272: } ! 273: if (stblock.st_mode & S_IFBLK) { ! 274: raw = rawname(name); ! 275: if (stat(raw, &stchar) < 0){ ! 276: printf("Can't stat %s\n", raw); ! 277: return (0); ! 278: } ! 279: if (stchar.st_mode & S_IFCHR) { ! 280: if (stslash.st_dev == stblock.st_rdev) { ! 281: hotroot++; ! 282: raw = unrawname(name); ! 283: } ! 284: return (raw); ! 285: } else { ! 286: printf("%s is not a character device\n", raw); ! 287: return (0); ! 288: } ! 289: } else if (stblock.st_mode & S_IFCHR) { ! 290: if (looped) { ! 291: printf("Can't make sense out of name %s\n", name); ! 292: return (0); ! 293: } ! 294: name = unrawname(name); ! 295: looped++; ! 296: goto retry; ! 297: } ! 298: printf("Can't make sense out of name %s\n", name); ! 299: return (0); ! 300: } ! 301: ! 302: char * ! 303: unrawname(cp) ! 304: char *cp; ! 305: { ! 306: char *dp = rindex(cp, '/'); ! 307: struct stat stb; ! 308: ! 309: if (dp == 0) ! 310: return (cp); ! 311: if (stat(cp, &stb) < 0) ! 312: return (cp); ! 313: if ((stb.st_mode&S_IFMT) != S_IFCHR) ! 314: return (cp); ! 315: if (*(dp+1) != 'r') ! 316: return (cp); ! 317: (void)strcpy(dp+1, dp+2); ! 318: return (cp); ! 319: } ! 320: ! 321: char * ! 322: rawname(cp) ! 323: char *cp; ! 324: { ! 325: static char rawbuf[32]; ! 326: char *dp = rindex(cp, '/'); ! 327: ! 328: if (dp == 0) ! 329: return (0); ! 330: *dp = 0; ! 331: (void)strcpy(rawbuf, cp); ! 332: *dp = '/'; ! 333: (void)strcat(rawbuf, "/r"); ! 334: (void)strcat(rawbuf, dp+1); ! 335: return (rawbuf); ! 336: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.