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: }

Defined functions

blockcheck defined in line 255; used 3 times
checkfilesys defined in line 139; used 3 times
main defined in line 31; never used
rawname defined in line 321; used 2 times
unrawname defined in line 302; used 3 times

Defined variables

copyright defined in line 8; never used
returntosingle defined in line 28; used 1 times
sccsid defined in line 14; never used
Last modified: 1986-03-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1556
Valid CSS Valid XHTML 1.0 Strict