Annotation of coherent/d/etc/fsck/phase2.c, revision 1.1.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.