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

Defined functions

blockcheck defined in line 273; used 3 times
checkfilesys defined in line 166; used 3 times
main defined in line 30; never used
rawname defined in line 339; used 2 times
unrawname defined in line 320; used 3 times

Defined variables

copyright defined in line 8; never used
returntosingle defined in line 27; used 1 times
sccsid defined in line 12; never used
Last modified: 1996-02-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3395
Valid CSS Valid XHTML 1.0 Strict