Annotation of coherent/b/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 %lu 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:                        linkincr(inum);
                    300:                        numfiles++;
                    301:                        return(UNALLOC);        /* Don't traverse this baby */
                    302:                }
                    303:        }
                    304: 
                    305:        linkincr(inum);
                    306:        numfiles++;
                    307:        return( flags(inum)&MODEMASK );
                    308: }
                    309: 
                    310: zeroent(elemnt)
                    311: struct direct *elemnt;
                    312: {
                    313:        elemnt->d_ino = 0;
                    314:        fixflag = TRUE;
                    315: }
                    316: 
                    317: pname(name)
                    318: char *name;
                    319: {
                    320:        int i=0;
                    321: 
                    322:        while (i<depth) 
                    323:                prdirsize(path[i++]->d_name);
                    324:        prdirsize(name);
                    325:        putchar('\n');
                    326: }
                    327: 
                    328: prdirsize(name)
                    329: char *name;
                    330: {
                    331:        if (name[DIRSIZ-1] == '\0')
                    332:                printf("/%s", name);
                    333:        else
                    334:                printf("/%*s", DIRSIZ, name);
                    335: }
                    336: 
                    337: fsize_t
                    338: pinfo(inum)
                    339: ino_t inum;
                    340: {
                    341:        register struct dinode *dip;
                    342:        register struct passwd *pwd;
                    343: 
                    344:        if ( (dip=ptrino(inum, buf2)) == NULL ) {
                    345:                printf("i-number = %u is in a bad inode block.\n", inum);
                    346:                return(0);
                    347:        }
                    348: 
                    349:        printf("i-number = %u, ", inum);
                    350:        if ( (pwd=getpwuid(dip->di_uid)) != NULL )
                    351:                printf("Owner=%s, ", pwd->pw_name);
                    352:        else
                    353:                printf("Owner=%u, ", dip->di_uid);
                    354:        printf(" Mode=0%o\n", dip->di_mode);
                    355:        printf("Size=%lu, Mtime=%s", dip->di_size, ctime(&dip->di_mtime));
                    356:        return(dip->di_size);
                    357: }
                    358: 
                    359: char *remove = "(Remove)";
                    360: 
                    361: irange(inum, name)
                    362: ino_t inum;
                    363: char *name;
                    364: {
                    365:        printf("I-number is out of range  I=%u\n", inum);
                    366:        pname(name);
                    367:        return(action(remove));
                    368: }
                    369: 
                    370: unalloc(inum, name)
                    371: ino_t inum;
                    372: char *name;
                    373: {      
                    374:        fsize_t size;
                    375: 
                    376:        printf("Unallocated\n");
                    377:        size = pinfo(inum);
                    378:        pname(name);
                    379:        if ( (daction != NO) && (size == 0) && (mounted == FALSE) ) {
                    380:                printf("%s [Forced - Yes]\n", remove);
                    381:                return(YES);
                    382:        }
                    383:        return(action(remove));
                    384: }
                    385: 
                    386: baddup(inum, name)
                    387: ino_t inum;
                    388: char *name;
                    389: {
                    390:        register int mode = flags(inum)&MODEMASK;
                    391: 
                    392:        printf("Bad or Dup blocks in %s\n", typename(inum));
                    393:        pinfo(inum);
                    394:        pname(name);
                    395:        return(action(remove));
                    396: }
                    397: 
                    398: checkpath(ino)
                    399: register ino_t ino;
                    400: {
                    401:        static daddr_t  addrs[NADDR];
                    402:        static struct dinode *dip;
                    403:        static list *temp;
                    404:        register list *ptr;
                    405: 
                    406:        if ( (flags(ino)&VISITED)==VISITED ) {
                    407:                circle(ino);
                    408:                return;
                    409:        } else
                    410:                orflags(ino, VISITED);
                    411: 
                    412:        dip = ptrino(ino, databuf);
                    413:        l3tol(addrs, dip->di_addr, NADDR);
                    414:        
                    415:        if ( (dip->di_mode&IFMT) != IFDIR )
                    416:                fatal("Tried to checkpath i-node %u which is not dir.\n", ino);
                    417: 
                    418:        ptr = procfiles(addrs, dip->di_size);
                    419: 
                    420:        while (ptr->d_entry.d_ino) {
                    421:                if (depth >= MAXDEPTH)
                    422:                        toolong();
                    423:                path[depth++] = &ptr->d_entry;
                    424:                checkpath(ptr->d_entry.d_ino);
                    425:                depth--;
                    426:                temp = ptr;
                    427:                ptr = ptr->next;
                    428:                free(temp);
                    429:        }
                    430:        free(ptr);
                    431: }
                    432: 
                    433: circle(ino)
                    434: ino_t ino;
                    435: {
                    436:        printf("I-node %u is a multiply referenced directory i-node.\n", ino);
                    437: }
                    438: 
                    439: toolong()
                    440: {
                    441:        printf("Name too long.\n");
                    442:        pname("\0");
                    443:        abort();
                    444: }
                    445: 
                    446:        

unix.superglobalmegacorp.com

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