1: /*
   2:  * Copyright (c) 1990, 1993
   3:  *	The Regents of the University of California.  All rights reserved.
   4:  *
   5:  * Redistribution and use in source and binary forms, with or without
   6:  * modification, are permitted provided that the following conditions
   7:  * are met:
   8:  * 1. Redistributions of source code must retain the above copyright
   9:  *    notice, this list of conditions and the following disclaimer.
  10:  * 2. Redistributions in binary form must reproduce the above copyright
  11:  *    notice, this list of conditions and the following disclaimer in the
  12:  *    documentation and/or other materials provided with the distribution.
  13:  * 3. All advertising materials mentioning features or use of this software
  14:  *    must display the following acknowledgement:
  15:  *	This product includes software developed by the University of
  16:  *	California, Berkeley and its contributors.
  17:  * 4. Neither the name of the University nor the names of its contributors
  18:  *    may be used to endorse or promote products derived from this software
  19:  *    without specific prior written permission.
  20:  *
  21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31:  * SUCH DAMAGE.
  32:  */
  33: 
  34: #if !defined(lint) && defined(DOSCCS)
  35: static char sccsid[] = "@(#)preen.c	8.1.1 (2.11BSD) 1996/1/23";
  36: #endif /* not lint */
  37: 
  38: #include <sys/param.h>
  39: #include <sys/stat.h>
  40: #include <sys/wait.h>
  41: #include <fstab.h>
  42: #include <string.h>
  43: #include <stdio.h>
  44: #include <stdlib.h>
  45: #include <ctype.h>
  46: 
  47: char    *rawname(), *unrawname(), *blockcheck();
  48: 
  49: struct part {
  50:     struct  part *next;     /* forward link of partitions on disk */
  51:     char    *name;          /* device name */
  52:     char    *fsname;        /* mounted filesystem name */
  53:     int auxdata;        /* auxillary data for application */
  54: } *badlist, **badnext = &badlist;
  55: 
  56: struct disk {
  57:     char    *name;          /* disk base name */
  58:     struct  disk *next;     /* forward link for list of disks */
  59:     struct  part *part;     /* head of list of partitions on disk */
  60:     int pid;            /* If != 0, pid of proc working on */
  61: } *disks;
  62: 
  63: int nrun, ndisks;
  64: char    hotroot;
  65: 
  66: checkfstab(preen, maxrun, docheck, chkit)
  67:     int preen, maxrun;
  68:     int (*docheck)(), (*chkit)();
  69: {
  70:     register struct fstab *fsp;
  71:     register struct disk *dk, *nextdisk;
  72:     struct part *pt;
  73:     int ret, pid, retcode, passno, sumstatus;
  74:     union   wait status;
  75:     int auxdata;
  76:     char *name;
  77: 
  78:     sumstatus = 0;
  79:     for (passno = 1; passno <= 2; passno++) {
  80:         if (setfsent() == 0) {
  81:             warn("Can't open %s\n", _PATH_FSTAB);
  82:             return (8);
  83:         }
  84:         while ((fsp = getfsent()) != 0) {
  85:             if ((auxdata = (*docheck)(fsp)) == 0)
  86:                 continue;
  87:             if (preen == 0 || passno == 1 && fsp->fs_passno == 1) {
  88:                 if (name = blockcheck(fsp->fs_spec)) {
  89:                     if (sumstatus = (*chkit)(name,
  90:                         fsp->fs_file, auxdata, 0))
  91:                         return (sumstatus);
  92:                 } else if (preen)
  93:                     return (8);
  94:             } else if (passno == 2 && fsp->fs_passno > 1) {
  95:                 if ((name = blockcheck(fsp->fs_spec)) == NULL) {
  96:                     warn("BAD DISK NAME %s\n",fsp->fs_spec);
  97:                     sumstatus |= 8;
  98:                     continue;
  99:                 }
 100:                 addpart(name, fsp->fs_file, auxdata);
 101:             }
 102:         }
 103:         if (preen == 0)
 104:             return (0);
 105:     }
 106:     if (preen) {
 107:         if (maxrun == 0)
 108:             maxrun = ndisks;
 109:         if (maxrun > ndisks)
 110:             maxrun = ndisks;
 111:         nextdisk = disks;
 112:         for (passno = 0; passno < maxrun; ++passno) {
 113:             while (ret = startdisk(nextdisk, chkit) && nrun > 0)
 114:                 sleep(10);
 115:             if (ret)
 116:                 return (ret);
 117:             nextdisk = nextdisk->next;
 118:         }
 119:         while ((pid = wait(&status)) != -1) {
 120:             for (dk = disks; dk; dk = dk->next)
 121:                 if (dk->pid == pid)
 122:                     break;
 123:             if (dk == 0) {
 124:                 warn("Unknown pid %d\n", pid);
 125:                 continue;
 126:             }
 127:             if (WIFEXITED(status))
 128:                 retcode = WEXITSTATUS(status);
 129:             else
 130:                 retcode = 0;
 131:             if (WIFSIGNALED(status)) {
 132:                 warn("%s (%s): EXITED WITH SIGNAL %d\n",
 133:                     dk->part->name, dk->part->fsname,
 134:                     status.w_termsig);
 135:                 retcode = 8;
 136:             }
 137:             if (retcode != 0) {
 138:                 sumstatus |= retcode;
 139:                 *badnext = dk->part;
 140:                 badnext = &dk->part->next;
 141:                 dk->part = dk->part->next;
 142:                 *badnext = NULL;
 143:             } else
 144:                 dk->part = dk->part->next;
 145:             dk->pid = 0;
 146:             nrun--;
 147:             if (dk->part == NULL)
 148:                 ndisks--;
 149: 
 150:             if (nextdisk == NULL) {
 151:                 if (dk->part) {
 152:                     while (ret = startdisk(dk, chkit) &&
 153:                         nrun > 0)
 154:                         sleep(10);
 155:                     if (ret)
 156:                         return (ret);
 157:                 }
 158:             } else if (nrun < maxrun && nrun < ndisks) {
 159:                 for ( ;; ) {
 160:                     if ((nextdisk = nextdisk->next) == NULL)
 161:                         nextdisk = disks;
 162:                     if (nextdisk->part != NULL &&
 163:                         nextdisk->pid == 0)
 164:                         break;
 165:                 }
 166:                 while (ret = startdisk(nextdisk, chkit) &&
 167:                     nrun > 0)
 168:                     sleep(10);
 169:                 if (ret)
 170:                     return (ret);
 171:             }
 172:         }
 173:     }
 174:     (void)endfsent();
 175:     if (badlist) {
 176:         warn("FOLLOWING FILE SYSTEM%s HAD AN %s\n\t",
 177:             badlist->next ? "S" : "", "UNEXPECTED INCONSISTENCY:");
 178:         for (pt = badlist; pt; pt = pt->next)
 179:             warn("%s (%s)%s", pt->name, pt->fsname,
 180:                 pt->next ? ", " : "\n");
 181:     }
 182:     return(sumstatus);
 183: }
 184: 
 185: struct disk *
 186: finddisk(name)
 187:     char *name;
 188: {
 189:     register struct disk *dk, **dkp;
 190:     register char *p;
 191:     size_t len;
 192: 
 193:     for (p = name + strlen(name) - 1; p >= name; --p)
 194:         if (isdigit(*p)) {
 195:             len = p - name + 1;
 196:             break;
 197:         }
 198:     if (p < name)
 199:         len = strlen(name);
 200: 
 201:     for (dk = disks, dkp = &disks; dk; dkp = &dk->next, dk = dk->next) {
 202:         if (strncmp(dk->name, name, len) == 0 &&
 203:             dk->name[len] == 0)
 204:             return (dk);
 205:     }
 206:     if ((*dkp = (struct disk *)malloc(sizeof(struct disk))) == NULL)
 207:         nomem();
 208:     dk = *dkp;
 209:     if ((dk->name = (char *)malloc(len + 1)) == NULL)
 210:         nomem();
 211:     (void)strncpy(dk->name, name, len);
 212:     dk->name[len] = '\0';
 213:     dk->part = NULL;
 214:     dk->next = NULL;
 215:     dk->pid = 0;
 216:     ndisks++;
 217:     return (dk);
 218: }
 219: 
 220: addpart(name, fsname, auxdata)
 221:     char *name, *fsname;
 222:     int auxdata;
 223: {
 224:     struct disk *dk = finddisk(name);
 225:     register struct part *pt, **ppt = &dk->part;
 226: 
 227:     for (pt = dk->part; pt; ppt = &pt->next, pt = pt->next)
 228:         if (strcmp(pt->name, name) == 0) {
 229:             warn("%s in fstab more than once!\n", name);
 230:             return;
 231:         }
 232:     if ((*ppt = (struct part *)malloc(sizeof(struct part))) == NULL)
 233:         nomem();
 234:     pt = *ppt;
 235:     if ((pt->name = (char *)malloc(strlen(name) + 1)) == NULL)
 236:         nomem();
 237:     (void)strcpy(pt->name, name);
 238:     if ((pt->fsname = (char *)malloc(strlen(fsname) + 1)) == NULL)
 239:         nomem();
 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, 1));
 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:         warn("Can't stat root\n");
 274:         return (0);
 275:     }
 276: retry:
 277:     if (stat(name, &stblock) < 0) {
 278:         perror(name);
 279:         warn("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:             warn("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:             warn("%s 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:     warn("Can't make sense 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: }
 341: 
 342: nomem()
 343:     {
 344:     err(8, "out of memory");
 345:     /* NOTREACHED */
 346:     }

Defined functions

addpart defined in line 220; used 1 times
blockcheck defined in line 262; used 5 times
checkfstab defined in line 66; used 1 times
finddisk defined in line 185; used 1 times
nomem defined in line 342; used 7 times
rawname defined in line 325; used 2 times
startdisk defined in line 245; used 3 times
unrawname defined in line 306; used 3 times

Defined variables

badlist defined in line 54; used 4 times
badnext defined in line 54; used 3 times
disks defined in line 61; used 5 times
hotroot defined in line 64; used 2 times
ndisks defined in line 63; used 6 times
nrun defined in line 63; used 7 times
sccsid defined in line 35; never used

Defined struct's

disk defined in line 56; used 16 times
part defined in line 49; used 14 times
Last modified: 1996-01-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3915
Valid CSS Valid XHTML 1.0 Strict