# 2.11BSD#431 - /usr/src/sbin/quotacheck/preen.c

##### Functions

    addpart           X
    blockcheck        X
    checkfstab        X
    finddisk          X
    nomem             X
    rawname           X
    startdisk         X
    unrawname         X

##### Variables

    badlist           X
    badnext           X
    disks             X
    hotroot           X
    ndisks            X
    nrun              X

##### struct's

    disk              X
    part              X

       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

- in line 100

blockcheck defined in line 262; used 5 times

- in line 47, 88, 95
- in /usr/src/sbin/quotacheck/quotacheck.c line 98, 158

checkfstab defined in line 66; used 1 times

- in /usr/src/sbin/quotacheck/quotacheck.c line 151

finddisk defined in line 185; used 1 times

- in line 224

nomem defined in line 342; used 7 times

- in line 207-210(2), 233-239(3)
- in /usr/src/sbin/quotacheck/quotacheck.c line 190, 502

rawname defined in line 325; used 2 times

- in line 47, 285

startdisk defined in line 245; used 3 times

- in line 113, 152, 166

unrawname defined in line 306; used 3 times

- in line 47, 298
- in /usr/src/sbin/quotacheck/quotacheck.c line 286

#### Defined variables

badlist defined in line 54; used 4 times

- in line 54, 175-178(3)

badnext defined in line 54; used 3 times

- in line 139-142(3)

disks defined in line 61; used 5 times

- in line 111, 120, 161, 201(2)

hotroot defined in line 64; used 2 times

- in line 270, 284

ndisks defined in line 63; used 6 times

- in line 108-110(3), 148, 158, 216

nrun defined in line 63; used 7 times

- in line 113, 146, 153-158(3), 167, 258

sccsid defined in line 35; never used

#### Defined struct's

disk defined in line 56; used 16 times

- in line 58(2), 71(2), 185-189(4), 206(4), 224(2), 246(2)

part defined in line 49; used 14 times

- in line 50(2), 59(2), 72(2), 225(2), 232(4), 249(2)

Last modified: 1996-01-25 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1830 |