Annotation of 43BSDReno/sbin/fsck/preen.c, revision 1.1.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.