Annotation of coherent/d/etc/fsck/phase2.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     phase 2 of fsck - Check Pathnames
        !             3:  */
        !             4: 
        !             5: #include "fsck.h"
        !             6: #include <pwd.h>
        !             7: 
        !             8: #define MAXDEPTH 50
        !             9: struct direct *path[MAXDEPTH];
        !            10: int    depth;
        !            11: int    fixflag;                        /* flags when must rewrite databuf  */
        !            12: daddr_t blocknum;                      /* Current block num read in        */
        !            13: 
        !            14: typedef struct list {
        !            15:        struct direct d_entry;
        !            16:        struct list *next;
        !            17: } list;
        !            18: 
        !            19: char   buf2[BSIZE];                    /* buffer for blocks            */
        !            20: daddr_t        cdbn;                           /* current logical block number */
        !            21: 
        !            22: /*     Format errors, args to blkerr() */
        !            23: 
        !            24: #define        NULLNAME        5
        !            25: #define        NULLPAD         6
        !            26: #define SLASHES                7
        !            27: #define DOT            8
        !            28: #define DOTDOT         9
        !            29: 
        !            30: phase2()
        !            31: {
        !            32:        if (!qflag)
        !            33:                printf("Phase 2 : Check Pathnames\n");
        !            34:        checkroot();
        !            35:        depth = 0;
        !            36:        checkpath(ROOTIN);
        !            37: }
        !            38: 
        !            39: 
        !            40: checkroot()
        !            41: {
        !            42:        if ( (flags(ROOTIN)&MODEMASK) == UNALLOC )
        !            43:                fatal("Root i-node is unallocated.  Terminating");
        !            44: 
        !            45:        if ( (flags(ROOTIN)&MODEMASK) != IDIR ) {
        !            46:                switch ( query("Root i-node is not a directory (FIX)") ){
        !            47:                case YES:
        !            48:                        fixroot();
        !            49:                        break;
        !            50:                case NO:
        !            51:                        abort();
        !            52:                }
        !            53:        }
        !            54:        
        !            55:        if ( badblks(ROOTIN) ){
        !            56:                switch ( query("Dup/Bad blocks in root i-node (Continue)") ) {
        !            57:                case YES:
        !            58:                        break;
        !            59:                case NO:
        !            60:                        abort();
        !            61:                }
        !            62:        }
        !            63:        linkincr(ROOTIN);               /* (?) Feature (?) of mkfs is  */
        !            64:                                        /* that root inode of a file   */
        !            65:                                        /* system has a link count one */
        !            66:                                        /* too large.                  */
        !            67: }
        !            68: 
        !            69: fixroot()
        !            70: {
        !            71:        register struct dinode *dip;
        !            72: 
        !            73:        if (!writeflg) 
        !            74:                fatal("File System Read-Only (NO WRITE)\n");
        !            75: 
        !            76:        setflags(ROOTIN, (flags(ROOTIN) & ~MODEMASK) | IDIR);
        !            77: 
        !            78:        /* Save change to disk */
        !            79:        
        !            80:        dip = ptrino(ROOTIN, databuf);
        !            81:        dip->di_mode &= (~IFMT);
        !            82:        dip->di_mode |= IFDIR;
        !            83:        writeino(ROOTIN, databuf);
        !            84: }
        !            85: 
        !            86: #define        myinum  ( (depth>0) ? path[depth-1]->d_ino : ROOTIN )
        !            87: #define popinum        ( (depth>1) ? path[depth-2]->d_ino : ROOTIN )
        !            88: 
        !            89: char *memory = "Can't malloc memory, phase 2";
        !            90: 
        !            91: list *
        !            92: procfiles(addrs, length)
        !            93: daddr_t *addrs;
        !            94: fsize_t length;
        !            95: {
        !            96:        register struct direct *elemnt;
        !            97:        register list *first, *ptr;
        !            98: 
        !            99:        if ((first=ptr=(list *)malloc(sizeof(list)))==NULL)
        !           100:                fatal(memory);
        !           101:        first->d_entry.d_ino = 0;
        !           102:        first->next = NULL;
        !           103:        if ( length < DSIZE )
        !           104:                return( first );
        !           105:        cdbn = 0;
        !           106:        nextblock(addrs);
        !           107:        fixflag = FALSE;
        !           108:        elemnt = (struct direct *) databuf;
        !           109:        cdots(elemnt++, ".", myinum, DOT);
        !           110:        ++numfiles;
        !           111:        if ( (length-=DSIZE) < DSIZE )
        !           112:                return( first );
        !           113:        cdots(elemnt++, "..", popinum, DOTDOT);
        !           114:        ++numfiles;
        !           115:        length -= DSIZE;
        !           116: 
        !           117:        while ( length >= DSIZE ) {
        !           118:                while ( (elemnt<&databuf[BSIZE]) && (length>=DSIZE) ) {
        !           119:                        if (chck(elemnt)==IDIR) {
        !           120:                                copy(elemnt, &ptr->d_entry, 
        !           121:                                                sizeof(struct direct));
        !           122:                                if ((ptr->next=(list *)malloc(sizeof(list))) ==
        !           123:                                        NULL)
        !           124:                                        fatal(memory);
        !           125:                                ptr = ptr->next;
        !           126:                                ptr->d_entry.d_ino = 0;
        !           127:                                ptr->next = NULL;
        !           128:                        }
        !           129:                        elemnt++;
        !           130:                        length -= DSIZE;
        !           131:                }
        !           132:                if (fixflag && (fixblock(addrs) == NUL) )
        !           133:                        fixblkerr();
        !           134:                nextblock(addrs);
        !           135:                fixflag = FALSE;
        !           136:                elemnt = (struct direct *) databuf;
        !           137:        }
        !           138:        return(first);   
        !           139: }
        !           140: 
        !           141: candblock(dptr)
        !           142: register struct direct *dptr;
        !           143: {
        !           144:        register int num, i;
        !           145: 
        !           146:        num = BSIZE/sizeof(struct direct);
        !           147:        for (i=0; i<num; i++)
        !           148:                canino(dptr[i].d_ino);
        !           149: }
        !           150: 
        !           151: nextblock(addrs)
        !           152: register daddr_t *addrs;
        !           153: {
        !           154:        register daddr_t bn;
        !           155: 
        !           156:        if ( (bn=imap(addrs, cdbn++)) == 0 ) {
        !           157:                bclear(databuf, BSIZE);
        !           158:                return;
        !           159:        }
        !           160:        bread(bn, databuf);
        !           161:        candblock(databuf);
        !           162:        blocknum = bn;
        !           163: }
        !           164: 
        !           165: fixblock(addrs)
        !           166: daddr_t *addrs;
        !           167: {
        !           168:        daddr_t bn;
        !           169: 
        !           170:        if ( (bn=imap(addrs, cdbn-1)) == 0 ) 
        !           171:                return(NUL);
        !           172:        candblock(databuf);
        !           173:        bwrite(bn, databuf);
        !           174:        return(TRUE);
        !           175: }
        !           176: 
        !           177: fixblkerr()
        !           178: {
        !           179:        fatal("Fixblock error.");
        !           180: }
        !           181: 
        !           182: copy(from, to, size)
        !           183: register char *from, *to;
        !           184: register int size;
        !           185: {
        !           186:        while (size--)
        !           187:                *to++=*from++;
        !           188: }
        !           189: 
        !           190: cdots(elemnt, dots, ino, type)
        !           191: register struct direct *elemnt;
        !           192: char *dots;
        !           193: ino_t ino;     /* what the inode number should be */
        !           194: int type;
        !           195: {
        !           196:        register char *name = elemnt->d_name;
        !           197:        register ino_t inum;
        !           198: 
        !           199:        inum = elemnt->d_ino;
        !           200:        if ( (strcmp(name, dots) != 0) || (inum != ino) ||
        !           201:                (format(name) != GOOD) ) {
        !           202:                blkerr(type);
        !           203:                return;
        !           204:        }
        !           205:        linkincr(inum);
        !           206: }
        !           207: 
        !           208: format(name)
        !           209: register char *name;
        !           210: {
        !           211:        register char *ptr=name;
        !           212:        register char *end=&name[DIRSIZ];
        !           213: 
        !           214:        while ( (ptr<end) && (*ptr++ != '\0') ) ;
        !           215: 
        !           216:        if ( (ptr-1) == name )
        !           217:                return(NULLNAME);
        !           218:        
        !           219:        if (ptr<end) {
        !           220:                while ( (ptr<end) && (*ptr++ == '\0') ) ;
        !           221:                if (ptr!=end)
        !           222:                        return(NULLPAD);
        !           223:        }
        !           224: 
        !           225:        ptr = name;
        !           226:        while (ptr < end) 
        !           227:                if (*ptr++ == '/')
        !           228:                        return(SLASHES);
        !           229: 
        !           230:        return(GOOD);
        !           231: }
        !           232: 
        !           233:        
        !           234: blkerr(type)
        !           235: int type;
        !           236: {      
        !           237:        char *errname;
        !           238: 
        !           239:        switch(type) {
        !           240:        case NULLNAME:
        !           241:                errname = "Null name";
        !           242:                break;
        !           243:        case NULLPAD:
        !           244:                errname = "Non null padded";
        !           245:                break;
        !           246:        case SLASHES:
        !           247:                errname = "Embedded slashes in";
        !           248:                break;
        !           249:        case DOT:
        !           250:                errname = "Inconsistent .";
        !           251:                break;
        !           252:        case DOTDOT:
        !           253:                errname = "Inconsistent ..";
        !           254:                break;
        !           255:        default:
        !           256:                errname = "Bad";
        !           257:                break;
        !           258:        }
        !           259: 
        !           260:        printf("%s entry in block %U in directory\n", errname, blocknum);
        !           261:        pinfo(myinum);
        !           262:        pname(path[--depth]->d_name);
        !           263:        depth++;
        !           264: }
        !           265: 
        !           266: chck(elemnt)
        !           267: register struct direct *elemnt;
        !           268: {
        !           269:        register ino_t inum;
        !           270:        register char *name;
        !           271:        int type;
        !           272: 
        !           273:        inum = elemnt->d_ino;
        !           274:        if ( inum == 0 )
        !           275:                return(UNALLOC);
        !           276: 
        !           277:        name = elemnt->d_name;
        !           278:        if ( (type=format(name)) != GOOD )
        !           279:                blkerr(type);
        !           280: 
        !           281:        if (inum>ninodes) {
        !           282:                if ( irange(inum, name) ) 
        !           283:                        zeroent(elemnt);
        !           284:                return(UNALLOC);
        !           285:        }
        !           286: 
        !           287:        if ( (flags(inum)&ALLOCMASK)==UNALLOC ) {
        !           288:                if ( unalloc(inum, name) )
        !           289:                        zeroent(elemnt);
        !           290:                return(UNALLOC);
        !           291:        }
        !           292: 
        !           293:        if ( badblks(inum) ) {
        !           294:                if ( baddup(inum, name) ) {
        !           295:                        zeroent(elemnt);
        !           296:                        return(UNALLOC);
        !           297:                }
        !           298:                if ( (flags(inum)&MODEMASK)==IDIR )
        !           299:                        return(UNALLOC);
        !           300:        }
        !           301: 
        !           302:        linkincr(inum);
        !           303:        numfiles++;
        !           304:        return( flags(inum)&MODEMASK );
        !           305: }
        !           306: 
        !           307: zeroent(elemnt)
        !           308: struct direct *elemnt;
        !           309: {
        !           310:        elemnt->d_ino = 0;
        !           311:        fixflag = TRUE;
        !           312: }
        !           313: 
        !           314: pname(name)
        !           315: char *name;
        !           316: {
        !           317:        int i=0;
        !           318: 
        !           319:        while (i<depth) 
        !           320:                prdirsize(path[i++]->d_name);
        !           321:        prdirsize(name);
        !           322:        putchar('\n');
        !           323: }
        !           324: 
        !           325: prdirsize(name)
        !           326: char *name;
        !           327: {
        !           328:        if (name[DIRSIZ-1] == '\0')
        !           329:                printf("/%s", name);
        !           330:        else
        !           331:                printf("/%*s", DIRSIZ, name);
        !           332: }
        !           333: 
        !           334: fsize_t
        !           335: pinfo(inum)
        !           336: ino_t inum;
        !           337: {
        !           338:        register struct dinode *dip;
        !           339:        register struct passwd *pwd;
        !           340: 
        !           341:        if ( (dip=ptrino(inum, buf2)) == NULL ) {
        !           342:                printf("i-number = %u is in a bad inode block.\n", inum);
        !           343:                return(0);
        !           344:        }
        !           345: 
        !           346:        printf("i-number = %u, ", inum);
        !           347:        if ( (pwd=getpwuid(dip->di_uid)) != NULL )
        !           348:                printf("Owner=%s, ", pwd->pw_name);
        !           349:        else
        !           350:                printf("Owner=%u, ", dip->di_uid);
        !           351:        printf(" Mode=0%o\n", dip->di_mode);
        !           352:        printf("Size=%U, Mtime=%s", dip->di_size, ctime(&dip->di_mtime));
        !           353:        return(dip->di_size);
        !           354: }
        !           355: 
        !           356: char *remove = "(Remove)";
        !           357: 
        !           358: irange(inum, name)
        !           359: ino_t inum;
        !           360: char *name;
        !           361: {
        !           362:        printf("I-number is out of range  I=%u\n", inum);
        !           363:        pname(name);
        !           364:        return(action(remove));
        !           365: }
        !           366: 
        !           367: unalloc(inum, name)
        !           368: ino_t inum;
        !           369: char *name;
        !           370: {      
        !           371:        fsize_t size;
        !           372: 
        !           373:        printf("Unallocated\n");
        !           374:        size = pinfo(inum);
        !           375:        pname(name);
        !           376:        if ( (daction != NO) && (size == 0) && (mounted == FALSE) ) {
        !           377:                printf("%s [Forced - Yes]\n", remove);
        !           378:                return(YES);
        !           379:        }
        !           380:        return(action(remove));
        !           381: }
        !           382: 
        !           383: baddup(inum, name)
        !           384: ino_t inum;
        !           385: char *name;
        !           386: {
        !           387:        register int mode = flags(inum)&MODEMASK;
        !           388: 
        !           389:        printf("Bad or Dup blocks in %s\n",(mode==IDIR) ? "Directory" : "File");
        !           390:        pinfo(inum);
        !           391:        pname(name);
        !           392:        return(action(remove));
        !           393: }
        !           394: 
        !           395: checkpath(ino)
        !           396: register ino_t ino;
        !           397: {
        !           398:        static daddr_t  addrs[NADDR];
        !           399:        static struct dinode *dip;
        !           400:        static list *temp;
        !           401:        register list *ptr;
        !           402: 
        !           403:        if ( (flags(ino)&VISITED)==VISITED ) {
        !           404:                circle(ino);
        !           405:                return;
        !           406:        } else
        !           407:                orflags(ino, VISITED);
        !           408: 
        !           409:        dip = ptrino(ino, databuf);
        !           410:        l3tol(addrs, dip->di_addr, NADDR);
        !           411:        
        !           412:        if ( (dip->di_mode&IFMT) != IFDIR )
        !           413:                fatal("Tried to checkpath i-node %u which is not dir.\n", ino);
        !           414: 
        !           415:        ptr = procfiles(addrs, dip->di_size);
        !           416: 
        !           417:        while (ptr->d_entry.d_ino) {
        !           418:                if (depth >= MAXDEPTH)
        !           419:                        toolong();
        !           420:                path[depth++] = &ptr->d_entry;
        !           421:                checkpath(ptr->d_entry.d_ino);
        !           422:                depth--;
        !           423:                temp = ptr;
        !           424:                ptr = ptr->next;
        !           425:                free(temp);
        !           426:        }
        !           427:        free(ptr);
        !           428: }
        !           429: 
        !           430: circle(ino)
        !           431: ino_t ino;
        !           432: {
        !           433:        printf("I-node %u is a multiply referenced directory i-node.\n", ino);
        !           434: }
        !           435: 
        !           436: toolong()
        !           437: {
        !           438:        printf("Name too long.\n");
        !           439:        pname("\0");
        !           440:        abort();
        !           441: }
        !           442: 
        !           443:        

unix.superglobalmegacorp.com

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