Annotation of 43BSD/etc/fsck/main.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.