Annotation of coherent/d/etc/fsck/util.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     general utility functions for phases of fsck
                      3:  */
                      4: 
                      5: #include "fsck.h"
                      6: 
                      7: struct stat stats;                     /* Used by statit() */
                      8: 
                      9: statit(name, probfun)
                     10: char *name;
                     11: int (*probfun)();
                     12: {
                     13:        
                     14:        if ( stat(name, &stats) == -1 ) {
                     15:                bclear(&stats, sizeof(struct stat));
                     16:                (*probfun)("Can not stat %s", name);
                     17:        }
                     18: }
                     19: 
                     20: 
                     21: query(x)
                     22: {
                     23:        while(1) {
                     24:                printf("%r [yes/no]: ", &x);
                     25:        
                     26:                switch (daction) {
                     27:                case YES:
                     28:                        printf("[default - YES]\n");
                     29:                        return(YES);
                     30:                        break;
                     31:                case NO:
                     32:                        printf("[default - NO]\n");
                     33:                        return(NO);
                     34:                        break;
                     35:                case ASK:
                     36:                        switch( nextchar() ) {
                     37:                        case 'Y':
                     38:                                return(YES);
                     39:                        case 'N':
                     40:                                return(NO);
                     41:                        }
                     42:                }
                     43:        }
                     44: }
                     45: 
                     46: action(msg)
                     47: char *msg;
                     48: {
                     49:        switch( query(msg) ) {
                     50:        case YES:
                     51:                return(TRUE);
                     52:        case NO:
                     53:                return(FALSE);
                     54:        }
                     55: }
                     56: 
                     57: char
                     58: nextchar()
                     59: {
                     60:        char buff[8];
                     61:        int i, n, ch;
                     62: 
                     63:        if ( ((n=read(0,buff,8)) <= 0) || (n == 8) )
                     64:                fatal("Invalid Response");
                     65: 
                     66:        for(i=0; i<n; i++)
                     67:                if ( ((ch=buff[i])!=' ') && (ch!='\t') )
                     68:                        break;
                     69: 
                     70:        if ( (ch>='a') && (ch<='z') )
                     71:                ch += 'A' - 'a';
                     72: 
                     73:        return(ch);
                     74: }
                     75: 
                     76: char   *nfile  = "FILE";
                     77: char   *ndir   = "DIR";
                     78: char   *nchr   = "Character Special";
                     79: char   *nblk   = "Block Special";
                     80: char   *npipe  = "PIPE";
                     81: char   *nunkwn = "Unknown I-node type";
                     82: 
                     83: char *
                     84: typename(ino)
                     85: ino_t ino;
                     86: {
                     87:        switch( flags(ino)&MODEMASK ) {
                     88:        case IREG:
                     89:                return(nfile);
                     90:        case IDIR:
                     91:                return(ndir);
                     92:        case ICHR:
                     93:                return(nchr);
                     94:        case IBLK:
                     95:                return(nblk);
                     96:        case IPIPE:
                     97:                return(npipe);
                     98:        default:
                     99:                return(nunkwn);
                    100:        }
                    101: }
                    102: 
                    103: abort()
                    104: {
                    105:        fatal("abort.");
                    106: }
                    107: 
                    108: fatal(x)
                    109: {
                    110:        printf("fsck: %r\n", &x);
                    111:        _exit(1);
                    112: }
                    113: 
                    114: nonfatal(x)
                    115: {
                    116:        printf("fsck: %r\n", &x);
                    117:        errflag = TRUE;
                    118: }
                    119: 
                    120: /*
                    121:  *     Inode Manipulation Routines
                    122:  *     ptrino: returns a pointer to the wanted inode using the given
                    123:  *             buffer to read in the block performing canonicalization.
                    124:  *     writeino: writes the block containing the given inode to the
                    125:  *             disk performing the necessary canonicalization
                    126:  *     candino: canonicalize an inode
                    127:  *
                    128:  */
                    129: 
                    130: struct dinode *
                    131: ptrino(ino, buf)
                    132: register ino_t ino;
                    133: register char *buf;
                    134: {
                    135:        register daddr_t bn;
                    136:        register struct dinode *dip;
                    137: 
                    138:        bn = iblockn(ino);
                    139:        if ( (testblock(bn)) && (bn!=INODEI) )          /* bad inode block */
                    140:                return(NULL);
                    141:        bread(bn, buf);
                    142:        dip = ((struct dinode *) buf) + iblocko(ino);
                    143:        candino(dip);
                    144:        return(dip);
                    145: }
                    146: 
                    147: writeino(ino, buf)
                    148: ino_t ino;
                    149: char *buf;
                    150: {
                    151:        struct dinode *dip;
                    152: 
                    153:        dip = ((struct dinode *) buf) + iblocko(ino);
                    154:        candino(dip);
                    155:        bwrite((daddr_t) iblockn(ino), buf);
                    156: }
                    157: 
                    158: candino(dip)
                    159: register struct dinode *dip;
                    160: {
                    161:        canshort(dip->di_mode);
                    162:        canshort(dip->di_nlink);
                    163:        canshort(dip->di_uid);
                    164:        canshort(dip->di_gid);
                    165:        cansize(dip->di_size);
                    166:        cantime(dip->di_atime);
                    167:        cantime(dip->di_mtime);
                    168:        cantime(dip->di_ctime);
                    169: }
                    170: 
                    171: /*
                    172:  *     Transfer a logical block number for an inode to a
                    173:  *     physical block number, chasing indirects as necessary.
                    174:  *     The inefficiency of this method is put up with since
                    175:  *     this is only used for directory inodes, and they tend
                    176:  *     not to use indirects.  Pass in 'addrs' which is a pointer
                    177:  *     to the 13 daddr_s in the inode, and the logical block
                    178:  *     number you would like.  (Stolen from dcheck.c)
                    179:  */
                    180: 
                    181: static daddr_t ranges[] = {
                    182:        ND,
                    183:        ND + (daddr_t)NI*NBN,
                    184:        ND + (daddr_t)NI*NBN + (daddr_t)NII*NBN*NBN,
                    185:        ND + (daddr_t)NI*NBN + (daddr_t)NII*NBN*NBN + (daddr_t)NIII*NBN*NBN*NBN
                    186: };
                    187: 
                    188: static char    index[] = {
                    189:        0,
                    190:        ND,
                    191:        ND+NI,
                    192:        ND+NI+NII
                    193: };
                    194: 
                    195: static daddr_t coeff[] = {
                    196:        1,      (daddr_t)NBN,   (daddr_t)NBN*NBN,       (daddr_t)NBN*NBN*NBN
                    197: };
                    198: 
                    199: daddr_t
                    200: imap(addrs, block)
                    201: daddr_t *addrs;
                    202: register daddr_t block;
                    203: {
                    204:        int i;
                    205:        register daddr_t bpos;
                    206:        register daddr_t *bp;
                    207:        register daddr_t bn;
                    208: 
                    209:        for (i=0; i<4; i++)
                    210:                if (block < ranges[i]) {
                    211:                        if (i != 0)
                    212:                                block -= ranges[i-1];
                    213:                        bpos = block/coeff[i];
                    214:                        block %= coeff[i];
                    215:                        bp = &addrs[(int)bpos + index[i]];
                    216:                        if ( (bn=*bp) != 0 ) {
                    217:                                /*
                    218:                                 * Map through indirects here
                    219:                                 */
                    220:                                while (i-- > 0) {
                    221:                                        bread(bn, databuf);
                    222:                                        bpos = block/coeff[i];
                    223:                                        block %= coeff[i];
                    224:                                        bp = (daddr_t *)databuf + bpos;
                    225:                                        if ( (bn=*bp) == 0 )
                    226:                                                break;
                    227:                                        bn = *bp;
                    228:                                        candaddr(bn);
                    229:                                }
                    230:                        }
                    231:                        return(bn);
                    232:                }
                    233:        return(0);
                    234: }
                    235: 
                    236: /*
                    237:  *     Read the specified block number into the given buffer
                    238:  */
                    239: 
                    240: char *rgblkerr = "Out of Range Block number: %U  (CONTINUE)";
                    241: char *skblkerr = "Can not Seek: Blk num: %U  (CONTINUE)";
                    242: char *rdblkerr = "Can not Read: Blk num: %U  (CONTINUE)";
                    243: char *wtblkerr = "Can not Write: Blk num: %U  (CONTINUE)";
                    244: 
                    245: bread(bn, buf)
                    246: register daddr_t bn;
                    247: register char *buf;
                    248: {
                    249: #ifdef DEBUG
                    250:        printf("Reading block number: %ld\n", bn);
                    251: #endif
                    252:        if (bn<0 || bn >= fsize ) 
                    253:                switch( query(rgblkerr, bn) ) {  
                    254:                case YES:
                    255:                        bclear(buf, BSIZE);
                    256:                        return;
                    257:                case NO:
                    258:                        abort();
                    259:                }
                    260: 
                    261:        if ( (bn<isize) && getcache(bn, buf) ) {
                    262: #if DEBUG
                    263:                bdump(buf);
                    264: #endif
                    265:                return;
                    266:        }
                    267:        
                    268:        if ( lseek(fsfd, (unsigned long)bn*BSIZE, 0) == (-1L) )
                    269:                switch( query(skblkerr, bn) ) {
                    270:                case YES:
                    271:                        bclear(buf, BSIZE);
                    272:                        return;
                    273:                case NO:
                    274:                        abort();
                    275:                }
                    276: 
                    277:        if ( read(fsfd, buf, BSIZE) != BSIZE ) 
                    278:                switch( query(rdblkerr, bn) ) {
                    279:                case YES:
                    280:                        bclear(buf, BSIZE);
                    281:                        return;
                    282:                case NO:
                    283:                        abort();
                    284:                }
                    285: #if DEBUG
                    286:        bdump(buf);
                    287: #endif
                    288: }
                    289: 
                    290: /*
                    291:  *     Write block number bn with data in buf
                    292:  */
                    293: 
                    294: bwrite(bn, buf)
                    295: daddr_t bn;
                    296: char *buf;
                    297: {
                    298: #ifdef DEBUG
                    299:        printf("Writing block number: %ld\n", bn);
                    300: #endif
                    301:        if (!writeflg)
                    302:                return;
                    303: 
                    304:        if (bn<0 || bn>=fsize) 
                    305:                switch( query(rgblkerr, bn) ) {
                    306:                case YES:
                    307:                        return;
                    308:                case NO:
                    309:                        abort();
                    310:                }
                    311:        
                    312:        if ( lseek(fsfd, (fsize_t)BSIZE*bn, 0) == (-1L) )
                    313:                switch( query(skblkerr, bn) ) {
                    314:                case YES:
                    315:                        return;
                    316:                case NO:
                    317:                        abort();
                    318:                }
                    319: 
                    320:        if ( write(fsfd, buf, BSIZE) != BSIZE ) 
                    321:                switch( query(wtblkerr, bn) ) {
                    322:                case YES:
                    323:                        return;
                    324:                case NO:
                    325:                        abort();
                    326:                }
                    327: 
                    328:        if ( bn <= isize )
                    329:                chgcache(bn, buf);
                    330:        changeflg = TRUE;
                    331: }
                    332: 
                    333: /*
                    334:  *     i-node block area caching routines
                    335:  */
                    336: 
                    337: static char    cache[NBLK * BSIZE];
                    338: static int     low = 0; high = -1;
                    339: 
                    340: getcache(bn, buf)
                    341: register daddr_t bn;
                    342: register char *buf;
                    343: {
                    344:        int totsize;
                    345: 
                    346:        if ( bn > isize )
                    347:                return(0);
                    348: 
                    349:        if ( (bn>=low) && (bn<=high) ) {
                    350:                blkmove(buf, &cache[BSIZE * (bn-low)]);
                    351:                return(1);
                    352:        }
                    353: 
                    354:        low = bn;
                    355:        if ( (high=bn+NBLK-1) > isize )
                    356:                high = isize;
                    357:        totsize = BSIZE * (high-low+1);
                    358: 
                    359:        if ( (lseek(fsfd, (unsigned long)bn*BSIZE, 0) == (-1L)) ||
                    360:             (read(fsfd, cache, totsize) != totsize) ) {
                    361:                low = 0; high = -1;
                    362:                return(0);
                    363:        }
                    364: 
                    365:        return( getcache(bn, buf) );
                    366: }
                    367: 
                    368: chgcache(bn, buf)
                    369: register daddr_t bn;
                    370: register char *buf;
                    371: {
                    372:        if ( (bn>=low) && (bn<=high) )
                    373:                blkmove(&cache[BSIZE * (bn-low)], buf);
                    374: }
                    375: 
                    376: blkmove(to, from)
                    377: register char *to, *from;
                    378: {
                    379:        register int num=BSIZE;
                    380: 
                    381:        while ( num-- )
                    382:                *to++= *from++;
                    383: }
                    384: 
                    385: /*
                    386:  *     Clear the given block of memory
                    387:  */
                    388: 
                    389: bclear(bp, nb)
                    390: register char *bp;
                    391: register unsigned nb;
                    392: {
                    393:        if (nb)
                    394:                do {
                    395:                        *bp++ = 0;
                    396:                } while (--nb);
                    397: }
                    398: 
                    399: 
                    400: /*
                    401:  *     Determine if the given block is bad
                    402:  */
                    403: 
                    404: bad(bn)
                    405: daddr_t bn;
                    406: {
                    407:        if ( (bn >= isize) && (bn < fsize) )
                    408:                return(GOOD);
                    409:        else
                    410:                return(BAD);
                    411: }
                    412: 
                    413: 
                    414: #if DEBUG
                    415: 
                    416: /*
                    417:  *     Debug dump a block of data.
                    418:  */
                    419: 
                    420: #define NUMPLIN        16
                    421: 
                    422: bdump(buf)
                    423: register unsigned char *buf;
                    424: {
                    425:        register int i;
                    426: 
                    427:        for (i=0; i<BSIZE; i++) {
                    428:                if ( (i % NUMPLIN) == 0 )
                    429:                        printf("\n0x%04x:  ", i);
                    430:                printf(" %02x", *buf++);
                    431:        }
                    432:        printf("\n\n");
                    433: }
                    434: 
                    435: #endif

unix.superglobalmegacorp.com

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