Annotation of 43BSD/etc/fsck/utilities.c, revision 1.1

1.1     ! root        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: #ifndef lint
        !             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, size)
        !            87:        register BUFAREA *bp;
        !            88:        daddr_t blk;
        !            89:        long size;
        !            90: {
        !            91:        register struct filecntl *fcp;
        !            92:        daddr_t dblk;
        !            93: 
        !            94:        fcp = &dfile;
        !            95:        dblk = fsbtodb(&sblock, blk);
        !            96:        if (bp->b_bno == dblk)
        !            97:                return (bp);
        !            98:        flush(fcp, bp);
        !            99:        bp->b_errs = bread(fcp, bp->b_un.b_buf, dblk, size);
        !           100:        bp->b_bno = dblk;
        !           101:        bp->b_size = size;
        !           102:        return (bp);
        !           103: }
        !           104: 
        !           105: flush(fcp, bp)
        !           106:        struct filecntl *fcp;
        !           107:        register BUFAREA *bp;
        !           108: {
        !           109:        register int i, j;
        !           110: 
        !           111:        if (!bp->b_dirty)
        !           112:                return;
        !           113:        if (bp->b_errs != 0)
        !           114:                pfatal("WRITING ZERO'ED BLOCK %d TO DISK\n", bp->b_bno);
        !           115:        bp->b_dirty = 0;
        !           116:        bp->b_errs = 0;
        !           117:        bwrite(fcp, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size);
        !           118:        if (bp != &sblk)
        !           119:                return;
        !           120:        for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
        !           121:                bwrite(&dfile, (char *)sblock.fs_csp[j],
        !           122:                    fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
        !           123:                    sblock.fs_cssize - i < sblock.fs_bsize ?
        !           124:                    sblock.fs_cssize - i : sblock.fs_bsize);
        !           125:        }
        !           126: }
        !           127: 
        !           128: rwerr(s, blk)
        !           129:        char *s;
        !           130:        daddr_t blk;
        !           131: {
        !           132: 
        !           133:        if (preen == 0)
        !           134:                printf("\n");
        !           135:        pfatal("CANNOT %s: BLK %ld", s, blk);
        !           136:        if (reply("CONTINUE") == 0)
        !           137:                errexit("Program terminated\n");
        !           138: }
        !           139: 
        !           140: ckfini()
        !           141: {
        !           142: 
        !           143:        flush(&dfile, &fileblk);
        !           144:        flush(&dfile, &sblk);
        !           145:        if (sblk.b_bno != SBLOCK) {
        !           146:                sblk.b_bno = SBLOCK;
        !           147:                sbdirty();
        !           148:                flush(&dfile, &sblk);
        !           149:        }
        !           150:        flush(&dfile, &inoblk);
        !           151:        flush(&dfile, &cgblk);
        !           152:        (void)close(dfile.rfdes);
        !           153:        (void)close(dfile.wfdes);
        !           154: }
        !           155: 
        !           156: bread(fcp, buf, blk, size)
        !           157:        register struct filecntl *fcp;
        !           158:        char *buf;
        !           159:        daddr_t blk;
        !           160:        long size;
        !           161: {
        !           162:        char *cp;
        !           163:        int i, errs;
        !           164: 
        !           165:        if (lseek(fcp->rfdes, (long)dbtob(blk), 0) < 0)
        !           166:                rwerr("SEEK", blk);
        !           167:        else if (read(fcp->rfdes, buf, (int)size) == size)
        !           168:                return (0);
        !           169:        rwerr("READ", blk);
        !           170:        if (lseek(fcp->rfdes, (long)dbtob(blk), 0) < 0)
        !           171:                rwerr("SEEK", blk);
        !           172:        errs = 0;
        !           173:        pfatal("THE FOLLOWING SECTORS COULD NOT BE READ:");
        !           174:        for (cp = buf, i = 0; i < size; i += DEV_BSIZE, cp += DEV_BSIZE) {
        !           175:                if (read(fcp->rfdes, cp, DEV_BSIZE) < 0) {
        !           176:                        printf(" %d,", blk + i / DEV_BSIZE);
        !           177:                        bzero(cp, DEV_BSIZE);
        !           178:                        errs++;
        !           179:                }
        !           180:        }
        !           181:        printf("\n");
        !           182:        return (errs);
        !           183: }
        !           184: 
        !           185: bwrite(fcp, buf, blk, size)
        !           186:        register struct filecntl *fcp;
        !           187:        char *buf;
        !           188:        daddr_t blk;
        !           189:        long size;
        !           190: {
        !           191:        int i;
        !           192:        char *cp;
        !           193: 
        !           194:        if (fcp->wfdes < 0)
        !           195:                return;
        !           196:        if (lseek(fcp->wfdes, (long)dbtob(blk), 0) < 0)
        !           197:                rwerr("SEEK", blk);
        !           198:        else if (write(fcp->wfdes, buf, (int)size) == size) {
        !           199:                fcp->mod = 1;
        !           200:                return;
        !           201:        }
        !           202:        rwerr("WRITE", blk);
        !           203:        if (lseek(fcp->wfdes, (long)dbtob(blk), 0) < 0)
        !           204:                rwerr("SEEK", blk);
        !           205:        pfatal("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:");
        !           206:        for (cp = buf, i = 0; i < size; i += DEV_BSIZE, cp += DEV_BSIZE)
        !           207:                if (write(fcp->wfdes, cp, DEV_BSIZE) < 0)
        !           208:                        printf(" %d,", blk + i / DEV_BSIZE);
        !           209:        printf("\n");
        !           210:        return;
        !           211: }
        !           212: 
        !           213: /*
        !           214:  * allocate a data block with the specified number of fragments
        !           215:  */
        !           216: allocblk(frags)
        !           217:        int frags;
        !           218: {
        !           219:        register int i, j, k;
        !           220: 
        !           221:        if (frags <= 0 || frags > sblock.fs_frag)
        !           222:                return (0);
        !           223:        for (i = 0; i < fmax - sblock.fs_frag; i += sblock.fs_frag) {
        !           224:                for (j = 0; j <= sblock.fs_frag - frags; j++) {
        !           225:                        if (getbmap(i + j))
        !           226:                                continue;
        !           227:                        for (k = 1; k < frags; k++)
        !           228:                                if (getbmap(i + j + k))
        !           229:                                        break;
        !           230:                        if (k < frags) {
        !           231:                                j += k;
        !           232:                                continue;
        !           233:                        }
        !           234:                        for (k = 0; k < frags; k++)
        !           235:                                setbmap(i + j + k);
        !           236:                        n_blks += frags;
        !           237:                        return (i + j);
        !           238:                }
        !           239:        }
        !           240:        return (0);
        !           241: }
        !           242: 
        !           243: /*
        !           244:  * Free a previously allocated block
        !           245:  */
        !           246: freeblk(blkno, frags)
        !           247:        daddr_t blkno;
        !           248:        int frags;
        !           249: {
        !           250:        struct inodesc idesc;
        !           251: 
        !           252:        idesc.id_blkno = blkno;
        !           253:        idesc.id_numfrags = frags;
        !           254:        pass4check(&idesc);
        !           255: }
        !           256: 
        !           257: /*
        !           258:  * Find a pathname
        !           259:  */
        !           260: getpathname(namebuf, curdir, ino)
        !           261:        char *namebuf;
        !           262:        ino_t curdir, ino;
        !           263: {
        !           264:        int len;
        !           265:        register char *cp;
        !           266:        struct inodesc idesc;
        !           267:        extern int findname();
        !           268: 
        !           269:        if (statemap[ino] != DSTATE && statemap[ino] != DFOUND) {
        !           270:                strcpy(namebuf, "?");
        !           271:                return;
        !           272:        }
        !           273:        bzero(&idesc, sizeof(struct inodesc));
        !           274:        idesc.id_type = DATA;
        !           275:        cp = &namebuf[BUFSIZ - 1];
        !           276:        *cp-- = '\0';
        !           277:        if (curdir != ino) {
        !           278:                idesc.id_parent = curdir;
        !           279:                goto namelookup;
        !           280:        }
        !           281:        while (ino != ROOTINO) {
        !           282:                idesc.id_number = ino;
        !           283:                idesc.id_func = findino;
        !           284:                idesc.id_name = "..";
        !           285:                if ((ckinode(ginode(ino), &idesc) & STOP) == 0)
        !           286:                        break;
        !           287:        namelookup:
        !           288:                idesc.id_number = idesc.id_parent;
        !           289:                idesc.id_parent = ino;
        !           290:                idesc.id_func = findname;
        !           291:                idesc.id_name = namebuf;
        !           292:                if ((ckinode(ginode(idesc.id_number), &idesc) & STOP) == 0)
        !           293:                        break;
        !           294:                len = strlen(namebuf);
        !           295:                cp -= len;
        !           296:                if (cp < &namebuf[MAXNAMLEN])
        !           297:                        break;
        !           298:                bcopy(namebuf, cp, len);
        !           299:                *--cp = '/';
        !           300:                ino = idesc.id_number;
        !           301:        }
        !           302:        if (ino != ROOTINO) {
        !           303:                strcpy(namebuf, "?");
        !           304:                return;
        !           305:        }
        !           306:        bcopy(cp, namebuf, &namebuf[BUFSIZ] - cp);
        !           307: }
        !           308: 
        !           309: catch()
        !           310: {
        !           311: 
        !           312:        ckfini();
        !           313:        exit(12);
        !           314: }
        !           315: 
        !           316: /*
        !           317:  * When preening, allow a single quit to signal
        !           318:  * a special exit after filesystem checks complete
        !           319:  * so that reboot sequence may be interrupted.
        !           320:  */
        !           321: catchquit()
        !           322: {
        !           323:        extern returntosingle;
        !           324: 
        !           325:        printf("returning to single-user after filesystem check\n");
        !           326:        returntosingle = 1;
        !           327:        (void)signal(SIGQUIT, SIG_DFL);
        !           328: }
        !           329: 
        !           330: /*
        !           331:  * Ignore a single quit signal; wait and flush just in case.
        !           332:  * Used by child processes in preen.
        !           333:  */
        !           334: voidquit()
        !           335: {
        !           336: 
        !           337:        sleep(1);
        !           338:        (void)signal(SIGQUIT, SIG_IGN);
        !           339:        (void)signal(SIGQUIT, SIG_DFL);
        !           340: }
        !           341: 
        !           342: /*
        !           343:  * determine whether an inode should be fixed.
        !           344:  */
        !           345: dofix(idesc, msg)
        !           346:        register struct inodesc *idesc;
        !           347:        char *msg;
        !           348: {
        !           349: 
        !           350:        switch (idesc->id_fix) {
        !           351: 
        !           352:        case DONTKNOW:
        !           353:                if (idesc->id_type == DATA)
        !           354:                        direrr(idesc->id_number, msg);
        !           355:                else
        !           356:                        pwarn(msg);
        !           357:                if (preen) {
        !           358:                        printf(" (SALVAGED)\n");
        !           359:                        idesc->id_fix = FIX;
        !           360:                        return (ALTERED);
        !           361:                }
        !           362:                if (reply("SALVAGE") == 0) {
        !           363:                        idesc->id_fix = NOFIX;
        !           364:                        return (0);
        !           365:                }
        !           366:                idesc->id_fix = FIX;
        !           367:                return (ALTERED);
        !           368: 
        !           369:        case FIX:
        !           370:                return (ALTERED);
        !           371: 
        !           372:        case NOFIX:
        !           373:                return (0);
        !           374: 
        !           375:        default:
        !           376:                errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix);
        !           377:        }
        !           378:        /* NOTREACHED */
        !           379: }
        !           380: 
        !           381: /* VARARGS1 */
        !           382: errexit(s1, s2, s3, s4)
        !           383:        char *s1;
        !           384: {
        !           385:        printf(s1, s2, s3, s4);
        !           386:        exit(8);
        !           387: }
        !           388: 
        !           389: /*
        !           390:  * An inconsistency occured which shouldn't during normal operations.
        !           391:  * Die if preening, otherwise just printf.
        !           392:  */
        !           393: /* VARARGS1 */
        !           394: pfatal(s, a1, a2, a3)
        !           395:        char *s;
        !           396: {
        !           397: 
        !           398:        if (preen) {
        !           399:                printf("%s: ", devname);
        !           400:                printf(s, a1, a2, a3);
        !           401:                printf("\n");
        !           402:                printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n",
        !           403:                        devname);
        !           404:                exit(8);
        !           405:        }
        !           406:        printf(s, a1, a2, a3);
        !           407: }
        !           408: 
        !           409: /*
        !           410:  * Pwarn is like printf when not preening,
        !           411:  * or a warning (preceded by filename) when preening.
        !           412:  */
        !           413: /* VARARGS1 */
        !           414: pwarn(s, a1, a2, a3, a4, a5, a6)
        !           415:        char *s;
        !           416: {
        !           417: 
        !           418:        if (preen)
        !           419:                printf("%s: ", devname);
        !           420:        printf(s, a1, a2, a3, a4, a5, a6);
        !           421: }
        !           422: 
        !           423: #ifndef lint
        !           424: /*
        !           425:  * Stub for routines from kernel.
        !           426:  */
        !           427: panic(s)
        !           428:        char *s;
        !           429: {
        !           430: 
        !           431:        pfatal("INTERNAL INCONSISTENCY:");
        !           432:        errexit(s);
        !           433: }
        !           434: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.