# 2.11BSD#431 - /usr/src/sbin/fsck/main.c

##### Functions

    blockcheck        X
    checkfilesys      X
    main              X
    rawname           X
    unrawname         X

##### Variables

    copyright         X
    returntosingle    X

       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

- in line 25, 127, 142

checkfilesys defined in line 166; used 3 times

- in line 108, 129, 145

main defined in line 30; never used
rawname defined in line 339; used 2 times

- in line 25, 292

unrawname defined in line 320; used 3 times

- in line 25, 300, 312

#### Defined variables

copyright defined in line 8; never used
returntosingle defined in line 27; used 1 times

- in line 161

sccsid defined in line 12; never used

Last modified: 1996-02-04 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1054 |