Annotation of 43BSDReno/sbin/fsck/preen.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1990 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted provided
        !             6:  * that: (1) source distributions retain this entire copyright notice and
        !             7:  * comment, and (2) distributions including binaries display the following
        !             8:  * acknowledgement:  ``This product includes software developed by the
        !             9:  * University of California, Berkeley and its contributors'' in the
        !            10:  * documentation or other materials provided with the distribution and in
        !            11:  * all advertising materials mentioning features or use of this software.
        !            12:  * Neither the name of the University nor the names of its contributors may
        !            13:  * be used to endorse or promote products derived from this software without
        !            14:  * specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: static char sccsid[] = "@(#)preen.c    5.5 (Berkeley) 7/20/90";
        !            22: #endif /* not lint */
        !            23: 
        !            24: #include <sys/param.h>
        !            25: #include <sys/stat.h>
        !            26: #include <sys/wait.h>
        !            27: #include <fstab.h>
        !            28: #include <string.h>
        !            29: #include <stdio.h>
        !            30: #include <stdlib.h>
        !            31: #include <ctype.h>
        !            32: 
        !            33: char   *rawname(), *unrawname(), *blockcheck();
        !            34: 
        !            35: struct part {
        !            36:        struct  part *next;             /* forward link of partitions on disk */
        !            37:        char    *name;                  /* device name */
        !            38:        char    *fsname;                /* mounted filesystem name */
        !            39:        long    auxdata;                /* auxillary data for application */
        !            40: } *badlist, **badnext = &badlist;
        !            41: 
        !            42: struct disk {
        !            43:        char    *name;                  /* disk base name */
        !            44:        struct  disk *next;             /* forward link for list of disks */
        !            45:        struct  part *part;             /* head of list of partitions on disk */
        !            46:        int     pid;                    /* If != 0, pid of proc working on */
        !            47: } *disks;
        !            48: 
        !            49: int    nrun, ndisks;
        !            50: char   hotroot;
        !            51: 
        !            52: checkfstab(preen, maxrun, docheck, chkit)
        !            53:        int preen, maxrun;
        !            54:        int (*docheck)(), (*chkit)();
        !            55: {
        !            56:        register struct fstab *fsp;
        !            57:        register struct disk *dk, *nextdisk;
        !            58:        register struct part *pt;
        !            59:        int ret, pid, retcode, passno, sumstatus, status;
        !            60:        long auxdata;
        !            61:        char *name;
        !            62: 
        !            63:        sumstatus = 0;
        !            64:        for (passno = 1; passno <= 2; passno++) {
        !            65:                if (setfsent() == 0) {
        !            66:                        fprintf(stderr, "Can't open checklist file: %s\n",
        !            67:                            _PATH_FSTAB);
        !            68:                        return (8);
        !            69:                }
        !            70:                while ((fsp = getfsent()) != 0) {
        !            71:                        if ((auxdata = (*docheck)(fsp)) == 0)
        !            72:                                continue;
        !            73:                        if (preen == 0 || passno == 1 && fsp->fs_passno == 1) {
        !            74:                                if (name = blockcheck(fsp->fs_spec)) {
        !            75:                                        if (sumstatus = (*chkit)(name,
        !            76:                                            fsp->fs_file, auxdata))
        !            77:                                                return (sumstatus);
        !            78:                                } else if (preen)
        !            79:                                        return (8);
        !            80:                        } else if (passno == 2 && fsp->fs_passno > 1) {
        !            81:                                if ((name = blockcheck(fsp->fs_spec)) == NULL) {
        !            82:                                        fprintf(stderr, "BAD DISK NAME %s\n",
        !            83:                                                fsp->fs_spec);
        !            84:                                        sumstatus |= 8;
        !            85:                                        continue;
        !            86:                                }
        !            87:                                addpart(name, fsp->fs_file, auxdata);
        !            88:                        }
        !            89:                }
        !            90:                if (preen == 0)
        !            91:                        return (0);
        !            92:        }
        !            93:        if (preen) {
        !            94:                if (maxrun == 0)
        !            95:                        maxrun = ndisks;
        !            96:                if (maxrun > ndisks)
        !            97:                        maxrun = ndisks;
        !            98:                nextdisk = disks;
        !            99:                for (passno = 0; passno < maxrun; ++passno) {
        !           100:                        while (ret = startdisk(nextdisk, chkit) && nrun > 0)
        !           101:                                sleep(10);
        !           102:                        if (ret)
        !           103:                                return (ret);
        !           104:                        nextdisk = nextdisk->next;
        !           105:                }
        !           106:                while ((pid = wait(&status)) != -1) {
        !           107:                        for (dk = disks; dk; dk = dk->next)
        !           108:                                if (dk->pid == pid)
        !           109:                                        break;
        !           110:                        if (dk == 0) {
        !           111:                                printf("Unknown pid %d\n", pid);
        !           112:                                continue;
        !           113:                        }
        !           114:                        if (WIFEXITED(status))
        !           115:                                retcode = WEXITSTATUS(status);
        !           116:                        else
        !           117:                                retcode = 0;
        !           118:                        if (WIFSIGNALED(status)) {
        !           119:                                printf("%s (%s): EXITED WITH SIGNAL %d\n",
        !           120:                                        dk->part->name, dk->part->fsname,
        !           121:                                        WTERMSIG(status));
        !           122:                                retcode = 8;
        !           123:                        }
        !           124:                        if (retcode != 0) {
        !           125:                                sumstatus |= retcode;
        !           126:                                *badnext = dk->part;
        !           127:                                badnext = &dk->part->next;
        !           128:                                dk->part = dk->part->next;
        !           129:                                *badnext = NULL;
        !           130:                        } else
        !           131:                                dk->part = dk->part->next;
        !           132:                        dk->pid = 0;
        !           133:                        nrun--;
        !           134:                        if (dk->part == NULL)
        !           135:                                ndisks--;
        !           136: 
        !           137:                        if (nextdisk == NULL) {
        !           138:                                if (dk->part) {
        !           139:                                        while (ret = startdisk(dk, chkit) &&
        !           140:                                            nrun > 0)
        !           141:                                                sleep(10);
        !           142:                                        if (ret)
        !           143:                                                return (ret);
        !           144:                                }
        !           145:                        } else if (nrun < maxrun && nrun < ndisks) {
        !           146:                                for ( ;; ) {
        !           147:                                        if ((nextdisk = nextdisk->next) == NULL)
        !           148:                                                nextdisk = disks;
        !           149:                                        if (nextdisk->part != NULL &&
        !           150:                                            nextdisk->pid == 0)
        !           151:                                                break;
        !           152:                                }
        !           153:                                while (ret = startdisk(nextdisk, chkit) &&
        !           154:                                    nrun > 0)
        !           155:                                        sleep(10);
        !           156:                                if (ret)
        !           157:                                        return (ret);
        !           158:                        }
        !           159:                }
        !           160:        }
        !           161:        if (sumstatus) {
        !           162:                if (badlist == 0)
        !           163:                        return (sumstatus);
        !           164:                fprintf(stderr, "THE FOLLOWING FILE SYSTEM%s HAD AN %s\n\t",
        !           165:                        badlist->next ? "S" : "", "UNEXPECTED INCONSISTENCY:");
        !           166:                for (pt = badlist; pt; pt = pt->next)
        !           167:                        fprintf(stderr, "%s (%s)%s", pt->name, pt->fsname,
        !           168:                            pt->next ? ", " : "\n");
        !           169:                return (sumstatus);
        !           170:        }
        !           171:        (void)endfsent();
        !           172:        return (0);
        !           173: }
        !           174: 
        !           175: struct disk *
        !           176: finddisk(name)
        !           177:        char *name;
        !           178: {
        !           179:        register struct disk *dk, **dkp;
        !           180:        register char *p;
        !           181:        size_t len;
        !           182: 
        !           183:        for (p = name + strlen(name) - 1; p >= name; --p)
        !           184:                if (isdigit(*p)) {
        !           185:                        len = p - name + 1;
        !           186:                        break;
        !           187:                }
        !           188:        if (p < name)
        !           189:                len = strlen(name);
        !           190: 
        !           191:        for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) {
        !           192:                if (strncmp(dk->name, name, len) == 0 &&
        !           193:                    dk->name[len] == 0)
        !           194:                        return (dk);
        !           195:        }
        !           196:        if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL) {
        !           197:                fprintf(stderr, "out of memory");
        !           198:                exit (8);
        !           199:        }
        !           200:        dk = *dkp;
        !           201:        if ((dk->name = malloc(len + 1)) == NULL) {
        !           202:                fprintf(stderr, "out of memory");
        !           203:                exit (8);
        !           204:        }
        !           205:        (void)strncpy(dk->name, name, len);
        !           206:        dk->name[len] = '\0';
        !           207:        dk->part = NULL;
        !           208:        dk->next = NULL;
        !           209:        dk->pid = 0;
        !           210:        ndisks++;
        !           211:        return (dk);
        !           212: }
        !           213: 
        !           214: addpart(name, fsname, auxdata)
        !           215:        char *name, *fsname;
        !           216:        long auxdata;
        !           217: {
        !           218:        struct disk *dk = finddisk(name);
        !           219:        register struct part *pt, **ppt = &dk->part;
        !           220: 
        !           221:        for (pt = dk->part; pt; ppt = &pt->next, pt = pt->next)
        !           222:                if (strcmp(pt->name, name) == 0) {
        !           223:                        printf("%s in fstab more than once!\n", name);
        !           224:                        return;
        !           225:                }
        !           226:        if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL) {
        !           227:                fprintf(stderr, "out of memory");
        !           228:                exit (8);
        !           229:        }
        !           230:        pt = *ppt;
        !           231:        if ((pt->name = malloc(strlen(name) + 1)) == NULL) {
        !           232:                fprintf(stderr, "out of memory");
        !           233:                exit (8);
        !           234:        }
        !           235:        (void)strcpy(pt->name, name);
        !           236:        if ((pt->fsname = malloc(strlen(fsname) + 1)) == NULL) {
        !           237:                fprintf(stderr, "out of memory");
        !           238:                exit (8);
        !           239:        }
        !           240:        (void)strcpy(pt->fsname, fsname);
        !           241:        pt->next = NULL;
        !           242:        pt->auxdata = auxdata;
        !           243: }
        !           244: 
        !           245: startdisk(dk, checkit)
        !           246:        register struct disk *dk;
        !           247:        int (*checkit)();
        !           248: {
        !           249:        register struct part *pt = dk->part;
        !           250: 
        !           251:        dk->pid = fork();
        !           252:        if (dk->pid < 0) {
        !           253:                perror("fork");
        !           254:                return (8);
        !           255:        }
        !           256:        if (dk->pid == 0)
        !           257:                exit((*checkit)(pt->name, pt->fsname, pt->auxdata));
        !           258:        nrun++;
        !           259:        return (0);
        !           260: }
        !           261: 
        !           262: char *
        !           263: blockcheck(name)
        !           264:        char *name;
        !           265: {
        !           266:        struct stat stslash, stblock, stchar;
        !           267:        char *raw;
        !           268:        int retried = 0;
        !           269: 
        !           270:        hotroot = 0;
        !           271:        if (stat("/", &stslash) < 0) {
        !           272:                perror("/");
        !           273:                printf("Can't stat root\n");
        !           274:                return (0);
        !           275:        }
        !           276: retry:
        !           277:        if (stat(name, &stblock) < 0) {
        !           278:                perror(name);
        !           279:                printf("Can't stat %s\n", name);
        !           280:                return (0);
        !           281:        }
        !           282:        if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
        !           283:                if (stslash.st_dev == stblock.st_rdev)
        !           284:                        hotroot++;
        !           285:                raw = rawname(name);
        !           286:                if (stat(raw, &stchar) < 0) {
        !           287:                        perror(raw);
        !           288:                        printf("Can't stat %s\n", raw);
        !           289:                        return (name);
        !           290:                }
        !           291:                if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
        !           292:                        return (raw);
        !           293:                } else {
        !           294:                        printf("%s is not a character device\n", raw);
        !           295:                        return (name);
        !           296:                }
        !           297:        } else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
        !           298:                name = unrawname(name);
        !           299:                retried++;
        !           300:                goto retry;
        !           301:        }
        !           302:        printf("Can't make sense out of name %s\n", name);
        !           303:        return (0);
        !           304: }
        !           305: 
        !           306: char *
        !           307: unrawname(name)
        !           308:        char *name;
        !           309: {
        !           310:        char *dp;
        !           311:        struct stat stb;
        !           312: 
        !           313:        if ((dp = rindex(name, '/')) == 0)
        !           314:                return (name);
        !           315:        if (stat(name, &stb) < 0)
        !           316:                return (name);
        !           317:        if ((stb.st_mode & S_IFMT) != S_IFCHR)
        !           318:                return (name);
        !           319:        if (*(dp + 1) != 'r')
        !           320:                return (name);
        !           321:        (void)strcpy(dp + 1, dp + 2);
        !           322:        return (name);
        !           323: }
        !           324: 
        !           325: char *
        !           326: rawname(name)
        !           327:        char *name;
        !           328: {
        !           329:        static char rawbuf[32];
        !           330:        char *dp;
        !           331: 
        !           332:        if ((dp = rindex(name, '/')) == 0)
        !           333:                return (0);
        !           334:        *dp = 0;
        !           335:        (void)strcpy(rawbuf, name);
        !           336:        *dp = '/';
        !           337:        (void)strcat(rawbuf, "/r");
        !           338:        (void)strcat(rawbuf, dp + 1);
        !           339:        return (rawbuf);
        !           340: }

unix.superglobalmegacorp.com

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