|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.