# 2.11BSD#431 - /usr/src/sbin/fsck/utilities.c

##### Functions

    allocblk          X
    bread             X
    bwrite            X
    catch             X
    catchquit         X
    ckfini            X
    dofix             X
    dolncnt           X
    domap             X
    dostate           X
    errexit           X
    flush             X
    fr_blk            X
    ftypeok           X
    getblk            X
    getline           X
    getpathname       X
    pfatal            X
    pwarn             X
    reply             X
    rwerr             X
    search            X
    stype             X
    voidquit          X

       1: /*
       2:  * Copyright (c) 1980 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #if !defined(lint) && defined(DOSCCS)
       8: static char sccsid[] = "@(#)utilities.c	5.2 (Berkeley) 9/10/85";
       9: #endif not lint
      10:
      11: #include <stdio.h>
      12: #include <ctype.h>
      13: #include <sys/param.h>
      14: #include <sys/inode.h>
      15: #include <sys/fs.h>
      16: #include <sys/dir.h>
      17: #include "fsck.h"
      18:
      19: long    lseek();
      20:
      21: ftypeok(dp)
      22:     DINODE *dp;
      23: {
      24:     switch (dp->di_mode & IFMT) {
      25:
      26:     case IFDIR:
      27:     case IFREG:
      28:     case IFBLK:
      29:     case IFCHR:
      30:     case IFLNK:
      31:     case IFSOCK:
      32:         return (1);
      33:
      34:     default:
      35:         if (debug)
      36:             printf("bad file type 0%o\n", dp->di_mode);
      37:         return (0);
      38:     }
      39: }
      40:
      41: reply(s)
      42:     char *s;
      43: {
      44:     char line[80];
      45:
      46:     if (preen)
      47:         pfatal("INTERNAL ERROR: GOT TO reply()");
      48:     printf("\n%s? ", s);
      49:     if (nflag || dfile.wfdes < 0) {
      50:         printf(" no\n\n");
      51:         return (0);
      52:     }
      53:     if (yflag) {
      54:         printf(" yes\n\n");
      55:         return (1);
      56:     }
      57:     if (getline(stdin, line, sizeof(line)) == EOF)
      58:         errexit("\n");
      59:     printf("\n");
      60:     if (line[0] == 'y' || line[0] == 'Y')
      61:         return (1);
      62:     else
      63:         return (0);
      64: }
      65:
      66: getline(fp, loc, maxlen)
      67:     FILE *fp;
      68:     char *loc;
      69: {
      70:     register n;
      71:     register char *p, *lastloc;
      72:
      73:     p = loc;
      74:     lastloc = &p[maxlen-1];
      75:     while ((n = getc(fp)) != '\n') {
      76:         if (n == EOF)
      77:             return (EOF);
      78:         if (!isspace(n) && p < lastloc)
      79:             *p++ = n;
      80:     }
      81:     *p = 0;
      82:     return (p - loc);
      83: }
      84:
      85: BUFAREA *
      86: getblk(bp, blk)
      87:     register BUFAREA *bp;
      88:     daddr_t blk;
      89: {
      90:     register struct filecntl *fcp;
      91:     extern BUFAREA *search();
      92:
      93:     if(bp == NULL) {
      94:         bp = search(blk);
      95:         fcp = &sfile;
      96:     }
      97:     else
      98:         fcp = &dfile;
      99:     if(bp->b_bno == blk)
     100:         return(bp);
     101:     flush(fcp,bp);
     102:     bp->b_errs = bread(fcp,bp->b_un.b_buf,blk,DEV_BSIZE);
     103:     bp->b_bno = blk;
     104:     bp->b_size = DEV_BSIZE;
     105:     return(bp);
     106: }
     107:
     108: flush(fcp, bp)
     109:     struct filecntl *fcp;
     110:     register BUFAREA *bp;
     111: {
     112:
     113:     if (!bp->b_dirty)
     114:         return;
     115:     if (bp->b_errs != 0)
     116:         pfatal("WRITING ZERO'ED BLOCK %ld TO DISK\n", bp->b_bno);
     117:     bp->b_dirty = 0;
     118:     bp->b_errs = 0;
     119:     if (bp == &inoblk)
     120:         bwrite(fcp, inobuf, startib, NINOBLK * DEV_BSIZE);
     121:     else
     122:         bwrite(fcp, bp->b_un.b_buf, bp->b_bno, DEV_BSIZE);
     123: }
     124:
     125: rwerr(s, blk)
     126:     char *s;
     127:     daddr_t blk;
     128: {
     129:
     130:     if (preen == 0)
     131:         printf("\n");
     132:     pfatal("CANNOT %s: BLK %ld", s, blk);
     133:     if (reply("CONTINUE") == 0)
     134:         errexit("Program terminated\n");
     135: }
     136:
     137: ckfini()
     138: {
     139:
     140:     flush(&dfile, &fileblk);
     141:     flush(&dfile, &sblk);
     142:     if (sblk.b_bno != SBLOCK) {
     143:         sblk.b_bno = SBLOCK;
     144:         sbdirty();
     145:         flush(&dfile, &sblk);
     146:     }
     147:     flush(&dfile, &inoblk);
     148:     if (dfile.rfdes)
     149:         (void)close(dfile.rfdes);
     150:     if (dfile.wfdes)
     151:         (void)close(dfile.wfdes);
     152:     if (sfile.rfdes)
     153:         (void)close(sfile.rfdes);
     154:     if (sfile.wfdes)
     155:         (void)close(sfile.wfdes);
     156: }
     157:
     158: bread(fcp, buf, blk, size)
     159:     register struct filecntl *fcp;
     160:     char *buf;
     161:     daddr_t blk;
     162:     int size;
     163: {
     164:     char *cp;
     165:     register int i, errs;
     166:
     167:     if (lseek(fcp->rfdes, blk << DEV_BSHIFT, 0) < 0)
     168:         rwerr("SEEK", blk);
     169:     else if (read(fcp->rfdes, buf, size) == size)
     170:         return (0);
     171:     rwerr("READ", blk);
     172:     if (lseek(fcp->rfdes, blk << DEV_BSHIFT, 0) < 0)
     173:         rwerr("SEEK", blk);
     174:     errs = 0;
     175:     pfatal("THE FOLLOWING SECTORS COULD NOT BE READ:");
     176:     for (cp = buf, i = 0; i < size; i += DEV_BSIZE, cp += DEV_BSIZE) {
     177:         if (read(fcp->rfdes, cp, DEV_BSIZE) < 0) {
     178:             printf(" %ld,", blk + i / DEV_BSIZE);
     179:             bzero(cp, DEV_BSIZE);
     180:             errs++;
     181:         }
     182:     }
     183:     printf("\n");
     184:     return (errs);
     185: }
     186:
     187: bwrite(fcp, buf, blk, size)
     188:     register struct filecntl *fcp;
     189:     char *buf;
     190:     daddr_t blk;
     191:     int size;
     192: {
     193:     int i;
     194:     char *cp;
     195:
     196:     if (fcp->wfdes < 0)
     197:         return;
     198:     if (lseek(fcp->wfdes, blk << DEV_BSHIFT, 0) < 0)
     199:         rwerr("SEEK", blk);
     200:     else if (write(fcp->wfdes, buf, size) == size) {
     201:         fcp->mod = 1;
     202:         return;
     203:     }
     204:     rwerr("WRITE", blk);
     205:     if (lseek(fcp->wfdes, blk << DEV_BSHIFT, 0) < 0)
     206:         rwerr("SEEK", blk);
     207:     pfatal("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:");
     208:     for (cp = buf, i = 0; i < size; i += DEV_BSIZE, cp += DEV_BSIZE)
     209:         if (write(fcp->wfdes, cp, DEV_BSIZE) < 0)
     210:             printf(" %ld,", blk + i / DEV_BSIZE);
     211:     printf("\n");
     212:     return;
     213: }
     214:
     215: /*
     216:  * allocate a data block
     217:  */
     218: daddr_t
     219: allocblk()
     220: {
     221:     daddr_t i;
     222:
     223:     for (i = 0; i < fmax; i++) {
     224:         if (getbmap(i))
     225:             continue;
     226:         setbmap(i);
     227:         n_blks++;
     228:         return (i);
     229:     }
     230:     return (0);
     231: }
     232:
     233: /*
     234:  * Free a previously allocated block
     235:  */
     236: fr_blk(blkno)
     237:     daddr_t blkno;
     238: {
     239:     struct inodesc idesc;
     240:
     241:     idesc.id_blkno = blkno;
     242:     pass4check(&idesc);
     243: }
     244:
     245: /*
     246:  * Find a pathname
     247:  */
     248: getpathname(namebuf, curdir, ino)
     249:     char *namebuf;
     250:     ino_t curdir, ino;
     251: {
     252:     int len, st;
     253:     register char *cp;
     254:     struct inodesc idesc;
     255:     extern int findname();
     256:
     257:     st = getstate(ino);
     258:     if (st != DSTATE && st != DFOUND) {
     259:         strcpy(namebuf, "?");
     260:         return;
     261:     }
     262:     bzero(&idesc, sizeof(struct inodesc));
     263:     idesc.id_type = DATA;
     264:     cp = &namebuf[MAXPATHLEN - 1];
     265:     *cp-- = '\0';
     266:     if (curdir != ino) {
     267:         idesc.id_parent = curdir;
     268:         goto namelookup;
     269:     }
     270:     while (ino != ROOTINO) {
     271:         idesc.id_number = ino;
     272:         idesc.id_func = findino;
     273:         idesc.id_name = "..";
     274:         if ((ckinode(ginode(ino), &idesc) & STOP) == 0)
     275:             break;
     276:     namelookup:
     277:         idesc.id_number = idesc.id_parent;
     278:         idesc.id_parent = ino;
     279:         idesc.id_func = findname;
     280:         idesc.id_name = namebuf;
     281:         if ((ckinode(ginode(idesc.id_number), &idesc) & STOP) == 0)
     282:             break;
     283:         len = strlen(namebuf);
     284:         cp -= len;
     285:         if (cp < &namebuf[MAXNAMLEN])
     286:             break;
     287:         bcopy(namebuf, cp, len);
     288:         *--cp = '/';
     289:         ino = idesc.id_number;
     290:     }
     291:     if (ino != ROOTINO) {
     292:         strcpy(namebuf, "?");
     293:         return;
     294:     }
     295:     bcopy(cp, namebuf, &namebuf[MAXPATHLEN] - cp);
     296: }
     297:
     298: catch()
     299: {
     300:
     301:     ckfini();
     302:     exit(12);
     303: }
     304:
     305: /*
     306:  * When preening, allow a single quit to signal
     307:  * a special exit after filesystem checks complete
     308:  * so that reboot sequence may be interrupted.
     309:  */
     310: catchquit()
     311: {
     312:     extern returntosingle;
     313:
     314:     printf("returning to single-user after filesystem check\n");
     315:     returntosingle = 1;
     316:     (void)signal(SIGQUIT, SIG_DFL);
     317: }
     318:
     319: /*
     320:  * Ignore a single quit signal; wait and flush just in case.
     321:  * Used by child processes in preen.
     322:  */
     323: voidquit()
     324: {
     325:
     326:     sleep(1);
     327:     (void)signal(SIGQUIT, SIG_IGN);
     328:     (void)signal(SIGQUIT, SIG_DFL);
     329: }
     330:
     331: /*
     332:  * determine whether an inode should be fixed.
     333:  */
     334: dofix(idesc, msg)
     335:     register struct inodesc *idesc;
     336:     char *msg;
     337: {
     338:
     339:     switch (idesc->id_fix) {
     340:
     341:     case DONTKNOW:
     342:         if (idesc->id_type == DATA)
     343:             direrr(idesc->id_number, msg);
     344:         else
     345:             pwarn(msg);
     346:         if (preen) {
     347:             printf(" (SALVAGED)\n");
     348:             idesc->id_fix = FIX;
     349:             return (ALTERED);
     350:         }
     351:         if (reply("SALVAGE") == 0) {
     352:             idesc->id_fix = NOFIX;
     353:             return (0);
     354:         }
     355:         idesc->id_fix = FIX;
     356:         return (ALTERED);
     357:
     358:     case FIX:
     359:         return (ALTERED);
     360:
     361:     case NOFIX:
     362:         return (0);
     363:
     364:     default:
     365:         errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix);
     366:     }
     367:     /* NOTREACHED */
     368: }
     369:
     370: /* VARARGS1 */
     371: errexit(s1, s2, s3, s4)
     372:     char *s1;
     373: {
     374:     printf(s1, s2, s3, s4);
     375:     exit(8);
     376: }
     377:
     378: /*
     379:  * An inconsistency occured which shouldn't during normal operations.
     380:  * Die if preening, otherwise just printf.
     381:  */
     382: /* VARARGS1 */
     383: pfatal(s, a1, a2, a3, a4)
     384:     char *s;
     385: {
     386:
     387:     if (preen) {
     388:         printf("%s: ", devname);
     389:         printf(s, a1, a2, a3, a4);
     390:         printf("\n");
     391:         printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n",
     392:             devname);
     393:         exit(8);
     394:     }
     395:     printf(s, a1, a2, a3, a4);
     396: }
     397:
     398: /*
     399:  * Pwarn is like printf when not preening,
     400:  * or a warning (preceded by filename) when preening.
     401:  */
     402: /* VARARGS1 */
     403: pwarn(s, a1, a2, a3, a4, a5, a6)
     404:     char *s;
     405: {
     406:
     407:     if (preen)
     408:         printf("%s: ", devname);
     409:     printf(s, a1, a2, a3, a4, a5, a6);
     410: }
     411:
     412: stype(p)
     413: register char *p;
     414: {
     415:     if(*p == 0)
     416:         return;
     417:     if (*(p+1) == 0) {
     418:         if (*p == '3') {
     419:             cylsize = 200;
     420:             stepsize = 5;
     421:             return;
     422:         }
     423:         if (*p == '4') {
     424:             cylsize = 418;
     425:             stepsize = 9;
     426:             return;
     427:         }
     428:     }
     429:     cylsize = atoi(p);
     430:     while(*p && *p != ':')
     431:         p++;
     432:     if(*p)
     433:         p++;
     434:     stepsize = atoi(p);
     435:     if(stepsize <= 0 || stepsize > cylsize ||
     436:     cylsize <= 0 || cylsize > MAXCYL) {
     437:         printf("Invalid -s argument, defaults assumed\n");
     438:         cylsize = stepsize = 0;
     439:     }
     440: }
     441:
     442: dostate(ino, s,flg)
     443:     ino_t ino;
     444:     int s, flg;
     445: {
     446:     register char *p;
     447:     register unsigned byte, shift;
     448:     BUFAREA *bp;
     449:
     450:     byte = ino / STATEPB;
     451:     shift = LSTATE * (ino % STATEPB);
     452:     if(statemap != NULL) {
     453:         bp = NULL;
     454:         p = &statemap[byte];
     455:     }
     456:     else {
     457:         bp = getblk(NULL,(daddr_t)(smapblk+(byte/DEV_BSIZE)));
     458:         if (bp->b_errs)
     459:             errexit("Fatal I/O error\n");
     460:         else
     461:             p = &bp->b_un.b_buf[byte%DEV_BSIZE];
     462:     }
     463:     switch(flg) {
     464:         case 0:
     465:             *p &= ~(SMASK<<(shift));
     466:             *p |= s << shift;
     467:             if(bp != NULL)
     468:                 dirty(bp);
     469:             return(s);
     470:         case 1:
     471:             return((*p >> shift) & SMASK);
     472:     }
     473:     return(USTATE);
     474: }
     475:
     476: domap(blk,flg)
     477: daddr_t blk;
     478: int flg;
     479: {
     480:     register char *p;
     481:     register unsigned n;
     482:     register BUFAREA *bp;
     483:     off_t byte;
     484:
     485:     byte = blk >> BITSHIFT;
     486:     n = 1<<((unsigned)(blk & BITMASK));
     487:     if(flg & 04) {
     488:         p = freemap;
     489:         blk = fmapblk;
     490:     }
     491:     else {
     492:         p = blockmap;
     493:         blk = bmapblk;
     494:     }
     495:     if(p != NULL) {
     496:         bp = NULL;
     497:         p += (unsigned)byte;
     498:     }
     499:     else {
     500:         bp = getblk((BUFAREA *)NULL,blk+(byte>>DEV_BSHIFT));
     501:         if (bp->b_errs)
     502:             errexit("Fatal I/O error\n");
     503:         else
     504:             p = &bp->b_un.b_buf[(unsigned)(byte&DEV_BMASK)];
     505:     }
     506:     switch(flg&03) {
     507:         case 0:
     508:             *p |= n;
     509:             break;
     510:         case 1:
     511:             n &= *p;
     512:             bp = NULL;
     513:             break;
     514:         case 2:
     515:             *p &= ~n;
     516:     }
     517:     if(bp != NULL)
     518:         dirty(bp);
     519:     return(n);
     520: }
     521:
     522: dolncnt(ino, flg, val)
     523: ino_t ino;
     524: short val, flg;
     525: {
     526:     register short *sp;
     527:     register BUFAREA *bp;
     528:
     529:     if(lncntp != NULL) {
     530:         bp = NULL;
     531:         sp = &lncntp[ino];
     532:     }
     533:     else {
     534:         bp = getblk((BUFAREA *)NULL,(daddr_t)(lncntblk+(ino/SPERB)));
     535:         if (bp->b_errs)
     536:             errexit("Fatal I/O error\n");
     537:         else
     538:             sp = &bp->b_un.b_lnks[ino%SPERB];
     539:     }
     540:     switch(flg) {
     541:         case 0:
     542:             *sp = val;
     543:             break;
     544:         case 1:
     545:             bp = NULL;
     546:             break;
     547:         case 2:
     548:             (*sp)--;
     549:             break;
     550:         case 3:
     551:             (*sp)++;
     552:             break;
     553:         default:
     554:             abort();
     555:     }
     556:     if(bp != NULL)
     557:         dirty(bp);
     558:     return(*sp);
     559: }
     560:
     561: BUFAREA *
     562: search(blk)
     563: daddr_t blk;
     564: {
     565:     register BUFAREA *pbp, *bp;
     566:
     567:     for(bp = (BUFAREA *) &poolhead; bp->b_next; ) {
     568:         pbp = bp;
     569:         bp = pbp->b_next;
     570:         if(bp->b_bno == blk)
     571:             break;
     572:     }
     573:     pbp->b_next = bp->b_next;
     574:     bp->b_next = poolhead;
     575:     poolhead = bp;
     576:     return(bp);
     577: }

#### Defined functions

allocblk defined in line 218; used 3 times

- in /usr/src/sbin/fsck/dir.c line 444
- in /usr/src/sbin/fsck/fsck.h line 221
- in /usr/src/sbin/fsck/inode.c line 271

bread defined in line 158; used 3 times

- in line 102
- in /usr/src/sbin/fsck/inode.c line 129
- in /usr/src/sbin/fsck/setup.c line 73

bwrite defined in line 187; used 3 times

- in line 120-122(2)
- in /usr/src/sbin/fsck/inode.c line 126

catch defined in line 298; used 2 times

- in /usr/src/sbin/fsck/main.c line 26, 102

catchquit defined in line 310; used 2 times

- in /usr/src/sbin/fsck/main.c line 26, 104

ckfini defined in line 137; used 4 times

- in line 301
- in /usr/src/sbin/fsck/main.c line 259
- in /usr/src/sbin/fsck/setup.c line 87, 127

dofix defined in line 334; used 6 times

- in /usr/src/sbin/fsck/dir.c line 136, 155
- in /usr/src/sbin/fsck/inode.c line 93
- in /usr/src/sbin/fsck/pass5.c line 55-63(3)

dolncnt defined in line 522; used 4 times

- in /usr/src/sbin/fsck/fsck.h line 196-199(4)

domap defined in line 476; used 6 times

- in /usr/src/sbin/fsck/fsck.h line 201-207(6)

dostate defined in line 442; used 2 times

- in /usr/src/sbin/fsck/fsck.h line 209-210(2)

errexit defined in line 371; used 34 times

- in line 58, 134, 365, 459, 502, 536
- in /usr/src/sbin/fsck/dir.c line 42, 81
- in /usr/src/sbin/fsck/inode.c line 122, 234
- in /usr/src/sbin/fsck/main.c line 55, 80, 90, 99, 117
- in /usr/src/sbin/fsck/pass1.c line 114, 148, 164, 170
- in /usr/src/sbin/fsck/pass2.c line 35-37(2), 46-51(2), 62-67(2), 80, 200, 251-256(2)
- in /usr/src/sbin/fsck/pass4.c line 62
- in /usr/src/sbin/fsck/pass5.c line 198, 208
- in /usr/src/sbin/fsck/setup.c line 34, 118

flush defined in line 108; used 10 times

- in line 101, 140-147(4)
- in /usr/src/sbin/fsck/inode.c line 98
- in /usr/src/sbin/fsck/main.c line 220
- in /usr/src/sbin/fsck/pass1b.c line 40
- in /usr/src/sbin/fsck/pass5.c line 175
- in /usr/src/sbin/fsck/setup.c line 146

fr_blk defined in line 236; used 1 times

- in /usr/src/sbin/fsck/dir.c line 478

ftypeok defined in line 21; used 2 times

- in /usr/src/sbin/fsck/dir.c line 207
- in /usr/src/sbin/fsck/pass1.c line 106

getblk defined in line 85; used 14 times

- in line 457, 500, 534
- in /usr/src/sbin/fsck/dir.c line 95, 120, 449-453(2), 462, 497
- in /usr/src/sbin/fsck/fsck.h line 219
- in /usr/src/sbin/fsck/inode.c line 77
- in /usr/src/sbin/fsck/pass5.c line 35-36(2), 121

getline defined in line 66; used 2 times

- in line 57
- in /usr/src/sbin/fsck/setup.c line 116

getpathname defined in line 248; used 1 times

- in /usr/src/sbin/fsck/pass2.c line 228

pfatal defined in line 383; used 36 times

- in line 47, 116, 132, 175, 207
- in /usr/src/sbin/fsck/dir.c line 203-210(3), 232, 332, 338-343(2), 352, 364, 372
- in /usr/src/sbin/fsck/inode.c line 217
- in /usr/src/sbin/fsck/main.c line 175, 194
- in /usr/src/sbin/fsck/pass1.c line 45, 112, 124, 168
- in /usr/src/sbin/fsck/pass2.c line 33, 42, 58, 114-117(2), 165-168(2)
- in /usr/src/sbin/fsck/pass5.c line 47, 109, 194
- in /usr/src/sbin/fsck/setup.c line 60, 84, 113, 134

pwarn defined in line 403; used 16 times

- in line 345
- in /usr/src/sbin/fsck/dir.c line 58, 199, 224, 293, 315, 393, 466
- in /usr/src/sbin/fsck/inode.c line 146
- in /usr/src/sbin/fsck/main.c line 232
- in /usr/src/sbin/fsck/pass1.c line 78, 144, 159
- in /usr/src/sbin/fsck/pass2.c line 229
- in /usr/src/sbin/fsck/pass5.c line 49, 89

reply defined in line 41; used 39 times

- in line 133, 351
- in /usr/src/sbin/fsck/dir.c line 47, 54, 63, 236, 300, 316, 339, 469
- in /usr/src/sbin/fsck/inode.c line 149
- in /usr/src/sbin/fsck/pass1.c line 47, 61, 81, 113, 126, 147, 163, 169
- in /usr/src/sbin/fsck/pass2.c line 34, 43, 50, 59, 66, 103, 121, 132, 158, 172, 184, 191, 208, 214, 220, 234
- in /usr/src/sbin/fsck/pass5.c line 92, 197, 207
- in /usr/src/sbin/fsck/setup.c line 46

rwerr defined in line 125; used 6 times

- in line 168-173(3), 199-206(3)

search defined in line 561; used 2 times

- in line 91-94(2)

stype defined in line 412; used 1 times

- in /usr/src/sbin/fsck/main.c line 48

voidquit defined in line 323; used 2 times

- in /usr/src/sbin/fsck/main.c line 26, 141

#### Defined variables

sccsid defined in line 8; never used

Last modified: 1990-09-16 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1536 |