Annotation of coherent/d/etc/fsck.tar, revision 1.1.1.1

1.1       root        1: fsck/Makefile   644      3      3        1224  5045007365   6404 #
                      2: #      for Inetco      : CFLAGS = -O -DHPCOHERENT
                      3: #      for PDP-11      : CFLAGS = -O
                      4: #      others          : CFLAGS =
                      5: #
                      6: 
                      7: DESTDIR=/interim/etc/
                      8: CFLAGS = -O
                      9: #
                     10: #      for PDP-11 and IBM PC:  LFLAGS = -i
                     11: #      for Z8000            :  LFLAGS =
                     12: #
                     13: LFLAGS = -i
                     14: OBJ=main.o init.o phase1.o phase1b.o phase2.o phase3.o phase4.o phase5.o\
                     15:        phase6.o cleanup.o util.o printf.o link.o virtual.o is_fs.o
                     16: 
                     17: fsck:  $(OBJ)
                     18:        $(CC) $(CFLAGS) $(LFLAGS) -o $(DESTDIR)fsck $(OBJ)
                     19: 
                     20: #
                     21: #      for IBM PC Coherent executable, use:  -DNBLK=1
                     22: #      for others, use                    :  -DNBLK=8
                     23: #
                     24: #      If you are running out of malloc space, try lowering the
                     25: #      value of NBLK (no smaller than 1).
                     26: #
                     27: 
                     28: util.o: util.c
                     29:        $(CC) -c $(CFLAGS) $< -DNBLK=8
                     30: 
                     31: $(OBJ):        fsck.h
                     32: M PC:  LFLAGS = -i
                     33: #      for Z8000            :  LFLAGS =
                     34: #
                     35: LFLAGS = -i
                     36: OBJ=main.o init.o phase1.o phase1b.o phase2.o phase3.o phase4.o phase5.o\
                     37:        phase6.o cleanup.o util.o printf.o link.o virtual.o is_fs.o
                     38: 
                     39: fsck:  $(OBJ)
                     40:        $(CC) $(CFLAGS) $(LFLAGS) -o $(DESTDIR)fsck $(OBJ)
                     41: 
                     42: #
                     43: #      for IBM PC Coherent executable, use:  -DNBLK=1
                     44: #      for others, use                    :  -DNBLK=8
                     45: #
                     46: #      If you are rfsck/RCS/   755      3      3           0  5050254740   5304 fsck/RCS/Makefile,v   444      3      3        2644  5045006646   7303 head     1.3;
                     47: branch   ;
                     48: access   ;
                     49: symbols  ;
                     50: locks    bin:1.3;
                     51: comment  @@;
                     52: 
                     53: 
                     54: 1.3
                     55: date     91.07.29.07.44.07;  author bin;  state Exp;
                     56: branches ;
                     57: next     1.2;
                     58: 
                     59: 1.2
                     60: date     91.03.15.18.33.07;  author bin;  state Exp;
                     61: branches ;
                     62: next     1.1;
                     63: 
                     64: 1.1
                     65: date     91.02.08.13.26.09;  author bin;  state Exp;
                     66: branches ;
                     67: next     ;
                     68: 
                     69: 
                     70: desc
                     71: @initial version provided byinitial version provided by epstein
                     72: @
                     73: 
                     74: 
                     75: 1.3
                     76: log
                     77: @Updated by epstein for version 321.
                     78: @
                     79: text
                     80: @#
                     81: #      for Inetco      : CFLAGS = -O -DHPCOHERENT
                     82: #      for PDP-11      : CFLAGS = -O
                     83: #      others          : CFLAGS =
                     84: #
                     85: CFLAGS = -O
                     86: #
                     87: #      for PDP-11 and IBM PC:  LFLAGS = -i
                     88: #      for Z8000            :  LFLAGS =
                     89: #
                     90: LFLAGS = -i
                     91: OBJ=main.o init.o phase1.o phase1b.o phase2.o phase3.o phase4.o phase5.o\
                     92:        phase6.o cleanup.o util.o printf.o link.o virtual.o is_fs.o
                     93: 
                     94: fsck:  $(OBJ)
                     95:        $(CC) $(CFLAGS) $(LFLAGS) -o fsck $(OBJ)
                     96: 
                     97: #
                     98: #      for IBM PC Coherent executable, use:  -DNBLK=1
                     99: #      for others, use                    :  -DNBLK=8
                    100: #
                    101: #      If you are running out of malloc space, try lowering the
                    102: #      value of NBLK (no smaller than 1).
                    103: #
                    104: 
                    105: util.o: util.c
                    106:        $(CC) -c $(CFLAGS) util.c -DNBLK=8
                    107: 
                    108: $(OBJ):        fsck.h
                    109: @
                    110: 
                    111: 
                    112: 1.2
                    113: log
                    114: @bob h added destdir, ownership, permissions...
                    115: @
                    116: text
                    117: @a6 1
                    118: DESTDIR = /interim/etc/
                    119: d16 2
                    120: a17 4
                    121:        $(CC) $(CFLAGS) $(LFLAGS) -o $(DESTDIR)fsck $(OBJ)
                    122:        su root chown bin $(DESTDIR)$@@
                    123:        su root chgrp bin $(DESTDIR)$@@
                    124:        su root chmod 511 $(DESTDIR)$@@
                    125: @
                    126: 
                    127: 
                    128: 1.1
                    129: log
                    130: @Initial revision
                    131: @
                    132: text
                    133: @d7 1
                    134: d17 4
                    135: a20 2
                    136:        $(CC) $(CFLAGS) $(LFLAGS) -o fsck $(OBJ)
                    137: 
                    138: @
                    139: unning out of malloc space, try lowering the
                    140: #      value of NBLK (no smaller than 1).
                    141: #
                    142: 
                    143: util.o:fsck/RCS/READ_ME,v   444      3      3        1565  4754523421   6664 head     1.1;
                    144: access   ;
                    145: symbols  ;
                    146: locks    ;
                    147: comment  @@;
                    148: 
                    149: 
                    150: 1.1
                    151: date     91.02.08.13.26.37;  author bin;  state Exp;
                    152: branches ;
                    153: next   ;
                    154: 
                    155: 
                    156: desc
                    157: @updated version provided by epstein
                    158: @
                    159: 
                    160: 
                    161: 
                    162: 1.1
                    163: log
                    164: @Initial revision
                    165: @
                    166: text
                    167: @Ideas for improving the performance of fsck:
                    168: 
                    169: (1)  Utilize a different mechanism for storing the (struct direct)
                    170:      entries throughout phase2.c, to remove implicit memory intensive
                    171:      redundancy.
                    172: 
                    173: (2)  Encode the number of links per i-node count differently, in order
                    174:      to save space taking advantage of the typical usage under Coherent.
                    175: 
                    176: (3)  Arrange space for the tables in a total needed way to avoid later
                    177:      fragmentation problems affecting the memory requests for successive
                    178:      file systems.
                    179: 
                    180: (4)  Devise a more clever buffering scheme for the blocks containing
                    181:      i-nodes to understand the differences between phase1, phase2, and
                    182:      phase4.
                    183: @
                    184: ove implicit memory intensive
                    185:      redundancy.
                    186: 
                    187: (2)  Encode the number of links per i-node count differently, in order
                    188:      to save space tfsck/RCS/cleanup.c,v   444      3      3        2652  4753557355   7452 head     1.1;
                    189: access   ;
                    190: symbols  ;
                    191: locks    ;
                    192: comment  @ * @;
                    193: 
                    194: 
                    195: 1.1
                    196: date     91.02.05.16.35.30;  author bin;  state Exp;
                    197: branches ;
                    198: next   ;
                    199: 
                    200: 
                    201: desc
                    202: @provided by Mark Epstein
                    203: @
                    204: 
                    205: 
                    206: 
                    207: 1.1
                    208: log
                    209: @Initial revision
                    210: @
                    211: text
                    212: @/*
                    213:  *     Cleanup functions for phases of fsck
                    214:  */
                    215: 
                    216: #include "fsck.h"
                    217: 
                    218: cleanup()
                    219: {
                    220:        int retval = 0;
                    221: 
                    222:        if (sbpfix == TRUE) 
                    223:                writesuper();
                    224:        prtstats();
                    225:        if (changeflg == TRUE)
                    226:                retval = advise();
                    227:        close(fsfd);
                    228:        cleanV();
                    229:        return(retval);
                    230: }
                    231: 
                    232: writesuper()
                    233: {
                    234:        register int i;
                    235: 
                    236:        canshort(sbp->s_isize);
                    237:        candaddr(sbp->s_fsize);
                    238:        canshort(sbp->s_nfree);
                    239:        for(i=0; i<NICFREE; i++)
                    240:                candaddr(sbp->s_free[i]);
                    241:        canshort(sbp->s_ninode);
                    242:        for(i=0; i<NICINOD; i++)
                    243:                canino(sbp->s_inode[i]);
                    244:        cantime(sbp->s_time);
                    245:        candaddr(sbp->s_tfree);
                    246:        canino(sbp->s_tinode);
                    247:        canshort(sbp->s_m);
                    248:        canshort(sbp->s_n);
                    249:        canlong(sbp->s_unique);
                    250: 
                    251:        bwrite((daddr_t)SUPERI, sbp);
                    252: }
                    253: 
                    254: prtstats()
                    255: {
                    256:        if (!fflag)
                    257:                printf("%u files ", numfiles);
                    258:        printf("%U blocks ", fsize - isize - totfree);
                    259:        printf("%U free\n", totfree);
                    260:        if ( lostsize ) {
                    261:                lostsize = (lostsize + BSIZE - 1)/BSIZE;
                    262:                printf("Expect roughly %U missing block%s next\n", lostsize,
                    263:                                (lostsize!=1) ? "s" : "" );
                    264:                printf("time fsck is run as a result of inodes ");
                    265:                printf("being cleared.\n");
                    266:        }
                    267: }
                    268: 
                    269: advise()
                    270: {
                    271:        int retval = 0;
                    272: 
                    273:        printf(" ***** File System %s was modified *****\n", fsname);
                    274:        if ( mounted ) {
                    275:                printf(" ***** BOOT Coherent (NO SYNC!) *****\n");
                    276:                retval = 1;
                    277:        }
                    278:        return(retval);
                    279: }
                    280: @
                    281: ocks ", fsize - isize - totfree);
                    282:        printf("%U free\n", totfree);
                    283:        if ( lostsize ) {
                    284:                fsck/RCS/fsck.h,v   444      3      3       14557  4771205357   6775 head     1.2;
                    285: access   ;
                    286: symbols  ;
                    287: locks    bin:1.2;
                    288: comment  @ * @;
                    289: 
                    290: 
                    291: 1.2
                    292: date     91.03.18.18.45.54;  author bin;  state Exp;
                    293: branches ;
                    294: next   1.1;
                    295: 
                    296: 1.1
                    297: date     91.02.08.13.26.49;  author bin;  state Exp;
                    298: branches ;
                    299: next   ;
                    300: 
                    301: 
                    302: desc
                    303: @updated version provided by epstein
                    304: @
                    305: 
                    306: 
                    307: 1.2
                    308: log
                    309: @update provided by epstein
                    310: @
                    311: text
                    312: @/*
                    313:  *     Header file for fsck  --  File System Check Program
                    314:  *
                    315:  */
                    316: 
                    317: #include <canon.h>
                    318: #include <sys/dir.h>
                    319: #include <sys/fblk.h>
                    320: #include <sys/filsys.h>
                    321: #include <sys/ino.h>
                    322: #include <sys/stat.h>
                    323: #include <sys/types.h>
                    324: #include <time.h>
                    325: 
                    326: #if HPCOHERENT
                    327: typedef long fsize_t;
                    328: #endif
                    329: 
                    330: /*
                    331:  *     Conditional Compilation Flags
                    332:  */
                    333: 
                    334: #define NOT_ALL_ZERO_INODE     /* Dependent on whether or not an inode */
                    335: #ifdef         ALL_ZERO_INODE          /* is totally zeroed when unallocated   */
                    336: #undef ALL_ZERO_INODE          /* or simply a zero mode and zero link  */
                    337: #endif
                    338: 
                    339: 
                    340: /*
                    341:  *     Definitions and Externs
                    342:  */
                    343: 
                    344: #define NUL    0               /* true zero ! */
                    345: #define NULL   ((char *)0)
                    346: 
                    347: #define        YES     3               /* default actions */
                    348: #define        NO      2
                    349: #define ASK    1
                    350: 
                    351: #define        NFILSYS 10              /* max number of file systems */
                    352: #define        MAXCH   20              /* max length of filesys name */
                    353: 
                    354: #define        MAXBADOK        10      /* Max number of bad blocks before excessive */
                    355: extern int numbad;             /* num bad blocks found so far this inode*/
                    356: 
                    357: #define MAXDUPOK       10      /* Max number of dup blocks */
                    358:                                /* in a single inode before excessive */
                    359: #define        DUPTBLSIZE      20      /* Max number of dup referenced blocks */
                    360: extern daddr_t dupblck[];      /* table of duplicate referenced blocks */
                    361: extern         int totdups;            /* number of dup blocks found so far */
                    362: 
                    363: #define MAXBADFREE     10      /* max bad in free list before abort */
                    364: #define MAXDUPFREE     10      /* max dup in free list before abort */
                    365: 
                    366: #define GOOD   1               /* returned by bad() in util.c */
                    367: #define        BAD     0
                    368: 
                    369: #define        TRUE    1               /* errflag possibilities */
                    370: #define        FALSE   0
                    371: extern         int     errflag;        /* errflag indicates not to do phases */
                    372: 
                    373: #define OK     1               /* used to indicate excessive bad/dup */
                    374: #define STOP   0               /* blocks in an inode in phase1.c     */
                    375: #define BAD_DUP        2
                    376: 
                    377: #define FIRSTIN        2               /* First real inode number */
                    378: 
                    379: #define        ND      10              /* Number of Direct Blocks */
                    380: #undef NI
                    381: #define        NI      1
                    382: #define        NII     1
                    383: #define        NIII    1
                    384: #undef NADDR
                    385: #define        NADDR   (ND+NI+NII+NIII)
                    386: extern int     offsets[];      /* table of offsets for level of indirection */
                    387:                                /* for the blocks in an inode */
                    388: 
                    389: extern char    nextchar();     /* used in util.c */
                    390: extern int     fsfd;           /* file system file descriptor */
                    391: extern         int     mdaction;       /* default action for this invocation */
                    392: extern         int     daction;        /* default action for current file system */
                    393: extern  int    writeflg;       /* system write ok or read-only */
                    394: extern  int    qflag;          /* quiet fsck flag */
                    395: extern int     fflag;          /* fast fsck flag */
                    396: extern int     sflag;          /* force free list salvation    */
                    397: extern daddr_t fsize;          /* file system size in blocks */
                    398: extern int     isize;          /* first block not in inode list */
                    399:                                /* isize is NOT unsigned so that comparisons */
                    400:                                /* with longs will not cast the long to */
                    401:                                /* unsigned thus producing confusing results */
                    402: 
                    403: extern  daddr_t        totfree;        /* running count of total free blocks */
                    404: extern         unsigned        ninodes;/* Number of inodes in the files system */
                    405: extern         char    *fsname;        /* file system name */
                    406: extern  fsize_t  pinfo();      /* returns size of file, in phase2.c */
                    407: extern ino_t   lostfound();    /* returns inumber of lost+found dir */
                    408: extern struct dinode *ptrino(); /* returns a ptr to inode, give number */
                    409: extern         char databuf[];         /* buffer to read in block, used throughout */
                    410: extern char buf2[];            /* alternate data buffer */
                    411: extern         daddr_t cdbn;           /* current block number, used by nextblock() */
                    412: #define DSIZE  (sizeof(struct direct))
                    413: extern         char *lostname;         /* name of lost+found directory */
                    414: extern  char *nameit();                /* nameing function for lost dirs and files */
                    415: extern         int     depth;          /* used during tree traversal in phase2.c */
                    416: extern  struct direct *path[];         /* used during tree traversal in phase2.c */
                    417: extern char    *typename();    /* return string to type of inode */
                    418: extern         struct filsys *sbp;     /* Super Block */
                    419: extern         int     sbpfix;         /* flag for super block fixes */
                    420: extern  struct stat stats;     /* used by statit() in util.c */
                    421: extern dev_t   rootdev;        /* root device number */
                    422: extern dev_t   fsysrdev;       /* file system real device number */
                    423: extern int     mounted;        /* flag indicating mountedness of filesystem */
                    424: extern         int     changeflg;      /* file system modified flag */
                    425: extern         int     fixerup;        /* flag to rebuild free list */
                    426: extern char    *fixit;         /* Prompt message phase[45].c */
                    427: extern         int     numfiles;       /* num files in system */
                    428: extern daddr_t imap();         /* function for disk block mapping in util.c */
                    429: extern fsize_t lostsize;       /* Size of files cleared in phase4.c */
                    430: extern char    *tmpfile;       /* TMP File name for virtual.c */
                    431: 
                    432: #define SUCCESS        1               /* used in connect() in phase3.c */
                    433: #define FAILURE        0
                    434: 
                    435: #define        MODEMASK        0x07
                    436: #define ALLOCMASK      0x06
                    437: #define UNALLOC                0x00
                    438: #define UNKNOWN                0x01
                    439: #define        IDIR            0x02
                    440: #define        IREG            0x03
                    441: #define ICHR           0x04
                    442: #define IBLK           0x05
                    443: #define IPIPE          0x06
                    444: #define IBAD_IDUP      0x08
                    445: #define VISITED                0x10
                    446: #define UNREFDIR       0x20
                    447: #define CHILDDIR       0x40
                    448: #define IFREELIST      0x80
                    449: 
                    450: /*
                    451:  *     Macros for tables
                    452:  */
                    453: 
                    454: #define        LOGNBPC 3               /* Log2 Number of Bits per Character    */
                    455: 
                    456: /* Actions for virtual block system */
                    457: enum vact { testBlock, markBlock, unmarkBlock, grabBlock,
                    458:            testDup, markDup, unmarkDup, setDup,
                    459:            Flags, setFlags, orFlags,
                    460:            linkCtr, incLinkctr, setLinkctr };
                    461:              
                    462: #define testblock(bn)  findblock((unsigned long)(bn), testBlock)
                    463: #define markblock(bn)  findblock((unsigned long)(bn), markBlock)
                    464: #define unmarkblock(bn) findblock((unsigned long)(bn), unmarkBlock)
                    465: 
                    466: #define testdup(bn) findblock((unsigned long)(bn), testDup)
                    467: #define markdup(bn) findblock((unsigned long)(bn), markDup)
                    468: #define unmarkdup(bn) findblock((unsigned long)(bn), unmarkDup)
                    469: 
                    470: #define flags(ino) findblock((unsigned long)(ino), Flags)
                    471: #define setflags(ino, data) findblock((unsigned long)(ino), setFlags, data)
                    472: #define orflags(ino, data)  findblock((unsigned long)(ino), orFlags, data)
                    473: 
                    474: #define linkctr(ino) findblock((unsigned long)(ino), linkCtr)
                    475: #define inclinkctr(ino) findblock((unsigned long)(ino), incLinkctr)
                    476: #define setlinkctr(ino, data) findblock((unsigned long)(ino), setLinkctr, data)
                    477: 
                    478: #define badblks(ino)   ( flags(ino)&IBAD_IDUP )
                    479: 
                    480: /*
                    481:  *     Miscellany
                    482:  */
                    483: 
                    484: #define        NBPC    8                       /* number of bits per character */
                    485: #define        MAXINTN 255                     /* used for interleave table    */
                    486:                                        /* in phase6.c                  */
                    487: /*
                    488:  *     Stdio Stuff
                    489:  */
                    490: 
                    491: #define putchar(c) { char b = c; write(1, &b, 1); }
                    492: extern char *malloc();
                    493: extern char *calloc();
                    494: 
                    495: @
                    496: 
                    497: 
                    498: 1.1
                    499: log
                    500: @Initial revision
                    501: @
                    502: text
                    503: @d85 1
                    504: @
                    505: ne inclinkctr(ino) findblock((unsigned long)(ino), incLinkctr)
                    506: #define setlinkctr(ino, data) findblock((unsigned long)(ino), setLinkctr, data)
                    507: 
                    508: #fsck/RCS/init.c,v   444      3      3       14501  5045006666   6767 head     1.2;
                    509: branch   ;
                    510: access   ;
                    511: symbols  ;
                    512: locks    bin:1.2;
                    513: comment  @ * @;
                    514: 
                    515: 
                    516: 1.2
                    517: date     91.07.29.07.44.33;  author bin;  state Exp;
                    518: branches ;
                    519: next     1.1;
                    520: 
                    521: 1.1
                    522: date     91.02.05.16.36.03;  author bin;  state Exp;
                    523: branches ;
                    524: next     ;
                    525: 
                    526: 
                    527: desc
                    528: @prov by epstein
                    529: @
                    530: 
                    531: 
                    532: 1.2
                    533: log
                    534: @Updated by epstein for version 321.
                    535: @
                    536: text
                    537: @/*
                    538:  *     Perform initialization for phases of fsck
                    539:  */
                    540: #include "fsck.h"
                    541: #include <mnttab.h>
                    542: #include <mtab.h>
                    543: 
                    544: int    fsfd;                           /* file system file descriptor */
                    545: int    writeflg;                       /* write ok or read-only flag */
                    546: daddr_t        fsize = SUPERI+1;               /* file system size in blocks  */
                    547:                                        /* Allows for read of Super Block */
                    548: int    isize;                          /* First block not in inode list */
                    549: daddr_t        totfree;                        /* Running total free block count */
                    550: unsigned       ninodes;                /* number of inodes */
                    551: int    numfiles;                       /* number of files in file system */
                    552: 
                    553: char   superb[BSIZE];                  /* Super Block */
                    554: struct filsys *sbp = superb;
                    555: int    sbpfix;                         /* flag for super block fixes */
                    556: 
                    557: int    offsets[] =                     /* table of offsets for the levels */
                    558:                { ND, ND+NI, ND+NI+NII, /* of indirection of blocks in the */
                    559:                  ND+NI+NII+NIII };     /* inode block list */
                    560: 
                    561: daddr_t        dupblck[DUPTBLSIZE];            /* duplicate referenced blocks */
                    562: int    totdups;                        /* number of dup blocks so far */
                    563: 
                    564: init()
                    565: {
                    566:        int mode;
                    567:        struct stat status;
                    568:        unsigned short stmode;
                    569: 
                    570:        mode = (mdaction == NO) ? 0 : 2;
                    571: 
                    572:        if ( (fsfd = open(fsname, mode)) == (-1) ) {
                    573:                mode = 0;
                    574:                if ( (fsfd = open(fsname, mode)) == (-1) ) {
                    575:                        nonfatal("Can't open: %s", fsname);
                    576:                        return;
                    577:                }
                    578:        }
                    579: 
                    580:        if (mode == 0) {
                    581:                daction  = NO;
                    582:                writeflg = FALSE;
                    583:        } else {
                    584:                daction  = mdaction;
                    585:                writeflg = TRUE;
                    586:        }
                    587:        
                    588:        printf("%s: %s\n", fsname, (mode == 0) ? "(NO WRITE)" : "");
                    589: 
                    590:        if ( fstat(fsfd, &status) == (-1) ) {
                    591:                nonfatal("Can't stat: %s", fsname);
                    592:                return;
                    593:        }
                    594: 
                    595:        stmode = status.st_mode & S_IFMT;
                    596:        if ( (stmode != S_IFBLK) && (stmode != S_IFCHR) ) 
                    597:                switch(query("file is not a block or character device; OK?")){
                    598:                case YES:
                    599:                        break;
                    600:                case NO:
                    601:                        errflag = TRUE;
                    602:                        return;
                    603:                }
                    604: 
                    605:        domount();
                    606:        sbpfix = FALSE;
                    607:        readsuper();
                    608:        checksuper();
                    609:        if ( !errflag )
                    610:                alloctables();
                    611: }
                    612: 
                    613: /*
                    614:  *     Read in the super block and canonicalize
                    615:  */
                    616: 
                    617: readsuper()
                    618: {
                    619:        register int i;
                    620: 
                    621:        bread((daddr_t)SUPERI, superb);
                    622:        sbp = superb;
                    623: 
                    624:        canshort(sbp->s_isize);
                    625:        candaddr(sbp->s_fsize);
                    626:        canshort(sbp->s_nfree);
                    627:        for(i=0; i<NICFREE; i++)
                    628:                candaddr(sbp->s_free[i]);
                    629:        canshort(sbp->s_ninode);
                    630:        for(i=0; i<NICINOD; i++)
                    631:                canino(sbp->s_inode[i]);
                    632:        cantime(sbp->s_time);
                    633:        candaddr(sbp->s_tfree);
                    634:        canino(sbp->s_tinode);
                    635:        canshort(sbp->s_m);
                    636:        canshort(sbp->s_n);
                    637:        canlong(sbp->s_unique);
                    638: 
                    639: }
                    640: 
                    641: /*
                    642:  *     Check super block for obvious inconsistencies
                    643:  */
                    644: 
                    645: checksuper()
                    646: {
                    647:        fsize = sbp->s_fsize;
                    648:        isize = sbp->s_isize;
                    649:        totfree = fsize - isize;
                    650:        
                    651:        if ( (isize<=INODEI) || (isize>=fsize) || (fsize<=INODEI) ) {
                    652:                badsuper("Size check: fsize %U isize %u", fsize, isize);
                    653:                errflag = TRUE;
                    654:        }
                    655: 
                    656:        if ( sbp->s_nfree > NICFREE )
                    657:                badsuper("Too large free block count");
                    658: 
                    659:        if ( sbp->s_ninode > NICINOD )
                    660:                badsuper("Too large free i-node count");
                    661: }
                    662: 
                    663: /*
                    664:  *     Super Block Error Functions
                    665:  */
                    666: 
                    667: badsuper(x)
                    668: {
                    669:        printf("%r\n", &x);
                    670:        printf("fsck: %s: Bad Super Block: %u\n", fsname, SUPERI);
                    671: }
                    672: 
                    673: /*
                    674:  *     Allocate the necessary buffers for tables
                    675:  */
                    676: 
                    677: alloctables()
                    678: {
                    679:        unsigned num, numl;
                    680: 
                    681:        numl = 0;
                    682:        if (!fflag) {
                    683:                ninodes = (unsigned) (isize - INODEI) * INOPB;
                    684:                numl = (unsigned) ninodes;
                    685:        }
                    686:        
                    687:        num = (unsigned) ((fsize+NBPC-1)/NBPC) * sizeof(char);
                    688:        initV(numl, numl, num, num); /* virtual allocation */
                    689: 
                    690:        numfiles =              /* number of files in the file system */
                    691:        totdups = 0;            /* num dup blocks */
                    692: }
                    693: 
                    694: /*
                    695:  *     domount() checks the files /etc/mnttab and /etc/mtab to find
                    696:  *     out where the file system is mounted (if at all).  It then 
                    697:  *     reports where (and when if possible) it was last mounted.
                    698:  */
                    699: char *mnttab_name = "/etc/mnttab";
                    700: char *mtab_name          = "/etc/mtab";
                    701: char *bttime_name = "/etc/boottime";
                    702: 
                    703: domount()
                    704: {
                    705:        int fd;
                    706:        struct mnttab mnttab;
                    707:        struct mtab mtab;
                    708:        register char *name;
                    709:        struct stat sbuf;
                    710:        time_t boottime;
                    711:        int nothing();
                    712:        char devname[MNTNSIZ+6] = "/dev/";
                    713: 
                    714:        mounted = FALSE;
                    715:        name = fsname;                          /* strip off all initial */
                    716:        while (*name++ != '\0') ;               /* directories in fsname */
                    717:        while ( (*--name != '/') && (name>fsname) ) ;
                    718:        if (*name == '/') name++;
                    719: 
                    720:        if ( stat(bttime_name, &sbuf) == -1 )
                    721:                boottime = (time_t)0;
                    722:        else
                    723:                boottime = sbuf.st_mtime;
                    724:                                
                    725:        if ( (fd=open(mnttab_name, 0)) != (-1) ) {
                    726:                while ( read(fd, &mnttab, sizeof(mnttab))==sizeof(mnttab) ) 
                    727:                        if ( mnttab.mt_dev[0] && mnttab.mt_filsys[0] ) {
                    728:                                strncpy(&devname[5], mnttab.mt_filsys, MNTNSIZ);
                    729:                                devname[MNTNSIZ+5] = '\0';
                    730:                                statit(devname, nothing);
                    731:                                if (stats.st_rdev != fsysrdev)
                    732:                                        continue;
                    733:                                statit(mnttab.mt_dev, nothing);
                    734:                                mounted = (stats.st_dev == fsysrdev);
                    735:                                prmnttab(&mnttab, boottime);
                    736:                                return;
                    737:                        }
                    738:        }
                    739:        if ( (fd=open(mtab_name, 0)) != (-1) ) {
                    740:                while ( read(fd, &mtab, sizeof(mtab))==sizeof(mtab) ) 
                    741:                        if ( mtab.mt_name[0] && mtab.mt_special[0] ) {
                    742:                                strncpy(&devname[5], mtab.mt_special, MNAMSIZ);
                    743:                                devname[MNAMSIZ+5] = '\0';
                    744:                                statit(devname, nothing);
                    745:                                if (stats.st_rdev != fsysrdev)
                    746:                                        continue;
                    747:                                statit(mtab.mt_name, nothing);
                    748:                                mounted = (stats.st_dev == fsysrdev);
                    749:                                prmtab(&mtab);
                    750:                                return;
                    751:                        }
                    752:        }
                    753: 
                    754:        if (fsysrdev == rootdev)
                    755:                mounted = TRUE;
                    756:        else
                    757:                mounted = FALSE;
                    758: 
                    759: }
                    760: 
                    761: prmnttab(ptr, boottime)
                    762: struct mnttab *ptr;
                    763: time_t boottime;
                    764: {
                    765:        if (mounted) {
                    766:                if (boottime < ptr->mt_time)
                    767:                        boottime = ptr->mt_time;
                    768:                printf("%s mounted on %.*s as of %s", fsname, MNTNSIZ, 
                    769:                                        ptr->mt_dev, ctime(&boottime));
                    770:        } else
                    771:                printf("%s unmounted.  Last mounted on %.*s -- %s",
                    772:                                                fsname, MNTNSIZ, ptr->mt_dev,
                    773:                                                        ctime(&ptr->mt_time));
                    774: }
                    775: 
                    776: 
                    777: prmtab(ptr)
                    778: struct mtab *ptr;
                    779: {
                    780:        if (mounted)
                    781:                printf("%s mounted on %.*s\n", fsname, MNAMSIZ, ptr->mt_name);
                    782:        else
                    783:                printf("%s unmounted.  Last mounted on %.*s\n", fsname,
                    784:                                                        MNAMSIZ, ptr->mt_name);
                    785: }
                    786: 
                    787: nothing()
                    788: {}
                    789: @
                    790: 
                    791: 
                    792: 1.1
                    793: log
                    794: @Initial revision
                    795: @
                    796: text
                    797: @d176 1
                    798: d178 1
                    799: d191 11
                    800: a201 10
                    801:                        if (mnttab.mt_dev[0] != '\0') 
                    802:                                if ( strcmp(name, mnttab.mt_filsys) == 0 ) {
                    803:                                        statit(mnttab.mt_dev, nothing);
                    804:                                        if (stats.st_dev == fsysrdev)
                    805:                                                mounted = TRUE;
                    806:                                        else
                    807:                                                mounted = FALSE;
                    808:                                        prmnttab(&mnttab, boottime);
                    809:                                        return;
                    810:                                }
                    811: d205 11
                    812: a215 10
                    813:                        if (mtab.mt_name[0] != '\0')
                    814:                                if ( strcmp(name, mtab.mt_special) == 0 ) {
                    815:                                        statit(mtab.mt_name, nothing);
                    816:                                        if (stats.st_dev == fsysrdev)
                    817:                                                mounted = TRUE;
                    818:                                        else
                    819:                                                mounted = FALSE;
                    820:                                        prmtab(&mtab);
                    821:                                        return;
                    822:                                }
                    823: @
                    824: mt_dev[0] != '\0') 
                    825:                                if ( strcmp(name, mnttab.mt_filsys) == 0 ) {
                    826:                                        statit(mnttab.mt_dev, nothing);
                    827:                                        if (stats.st_dev == fsysrdev)
                    828:                                                mounted = TRUE;
                    829:                                        else
                    830:                                                mounted = FAfsck/RCS/is_fs.c,v   444      3      3        4004  4753557413   7112 head     1.1;
                    831: access   ;
                    832: symbols  ;
                    833: locks    ;
                    834: comment  @ * @;
                    835: 
                    836: 
                    837: 1.1
                    838: date     91.02.05.16.36.22;  author bin;  state Exp;
                    839: branches ;
                    840: next   ;
                    841: 
                    842: 
                    843: desc
                    844: @prov by epstein
                    845: @
                    846: 
                    847: 
                    848: 
                    849: 1.1
                    850: log
                    851: @Initial revision
                    852: @
                    853: text
                    854: @#include <sys/stat.h>
                    855: #include <canon.h>
                    856: #include <sys/filsys.h>
                    857: 
                    858: /*
                    859:  * Check if a special file is a well-formed filesystem.
                    860:  * This routine is derived from code in "mount.c".
                    861:  * Return values:
                    862:  *     -1      Not a device, cannot open, read or seek failed
                    863:  *     0       No filesystem
                    864:  *     1       Legal filesystem
                    865:  */
                    866: int
                    867: is_fs(special) char *special;
                    868: {
                    869:        static struct filsys f;
                    870:        struct stat sbuf;
                    871:        register int fd;
                    872:        register struct filsys *fp;
                    873:        register daddr_t *dp;
                    874:        register ino_t *ip, maxinode;
                    875: 
                    876:        if (stat(special, &sbuf) < 0)
                    877:                return -1;                      /* cannot stat device */
                    878:        else if ((sbuf.st_mode&S_IFMT) != S_IFBLK
                    879:              && (sbuf.st_mode&S_IFMT) != S_IFCHR)
                    880:                return -1;                      /* not a special file */
                    881:        else if ((fd = open(special, 2)) < 0)
                    882:                return -1;                      /* cannot open */
                    883:        else if (lseek(fd, (long)SUPERI*BSIZE, 0) == -1L
                    884:              || read(fd, &f, sizeof(f)) != sizeof(f)) {
                    885:                close(fd);
                    886:                return -1;                      /* seek or read failed */
                    887:        } else
                    888:                close(fd);                      /* so far so good */
                    889: 
                    890:        /* Canonical stuff. */
                    891:        fp = &f;
                    892:        canshort(fp->s_isize);
                    893:        candaddr(fp->s_fsize);
                    894:        canshort(fp->s_nfree);
                    895:        for (dp = &fp->s_free[0]; dp < &fp->s_free[NICFREE]; dp += 1)
                    896:                candaddr(*dp);
                    897:        canshort(fp->s_ninode);
                    898:        for (ip = &fp->s_inode[0]; ip < &fp->s_inode[NICINOD]; ip += 1)
                    899:                canino(*ip);
                    900:        candaddr(fp->s_tfree);
                    901:        canino(fp->s_tinode);
                    902: 
                    903:        /* Test for rationality. */
                    904:        maxinode = (fp->s_isize - INODEI) * INOPB + 1;
                    905:        if (fp->s_isize >= fp->s_fsize)
                    906:                return 0;
                    907:        if ((fp->s_tfree < fp->s_nfree)
                    908:        ||  (fp->s_tfree >= fp->s_fsize - fp->s_isize + 1))
                    909:                return 0;
                    910:        if ((fp->s_tinode < fp->s_ninode) || (fp->s_tinode >= maxinode-1 ))
                    911:                return 0;
                    912:        for (dp = &fp->s_free[0]; dp < &fp->s_free[fp->s_nfree]; dp += 1)
                    913:                if ((*dp < fp->s_isize) || (*dp >= fp->s_fsize))
                    914:                        return 0;
                    915:        for (ip = &fp->s_inode[0]; ip < &fp->s_inode[fp->s_ninode]; ip += 1)
                    916:                if ((*ip < 1) || (*ip > maxinode))
                    917:                        return 0;
                    918:        return 1;
                    919: }
                    920: @
                    921:  INODEI) * INOPB + 1;
                    922:        if (fp->s_isize >= fp->s_fsize)
                    923:                return 0;
                    924:        if ((fp->s_tfree < fp->s_nfree)
                    925:        ||  (fp->s_tfree >= fp->s_fsize - fp->s_isize + 1))
                    926:                return 0;
                    927:        if ((fp->s_tinode < fp->s_ninode) || (fp->s_tinode >= maxinode-1 ))
                    928:                return 0;
                    929:        for (dp = &fp->s_free[0]; dp < &fp->s_free[fp->s_nfree]; dp += 1)
                    930:                if ((*dp < fp->s_isize) || (*dp >= fp->s_fsize))
                    931:                        return 0;
                    932:        for (ip = &fp->s_inode[0]; ip < &fp->s_inode[fp->s_ninode]; ip += 1)
                    933:                if ((*ip < 1) || (*ip > maxinode))
                    934:                        return 0;
                    935:        return 1;
                    936: fsck/RCS/link.c,v   444      3      3        3277  4753557430   6756 head     1.1;
                    937: access   ;
                    938: symbols  ;
                    939: locks    ;
                    940: comment  @ * @;
                    941: 
                    942: 
                    943: 1.1
                    944: date     91.02.05.16.36.34;  author bin;  state Exp;
                    945: branches ;
                    946: next   ;
                    947: 
                    948: 
                    949: desc
                    950: @prov by epstein
                    951: @
                    952: 
                    953: 
                    954: 
                    955: 1.1
                    956: log
                    957: @Initial revision
                    958: @
                    959: text
                    960: @/*
                    961:  *     Routines to handle the counting of links for each i-node
                    962:  */
                    963: 
                    964: #include "fsck.h"
                    965: 
                    966: linkincr(inum)
                    967: ino_t inum;
                    968: {
                    969:        if (inclinkctr(inum) == 0 )
                    970:                fatal("Too many links in i-node, %d", inum);
                    971: }
                    972: 
                    973: /*
                    974:  *     The following is the beginning of thinking of how to change
                    975:  *     the number of bits used in the link count tables from 8-per
                    976:  *     i-node to 2-per i-node, with additional tables for those
                    977:  *     i-nodes with more than 2 links.  The changes would be to the
                    978:  *     definition of i_lnks, the macro linkctr(), the function linkincr(),
                    979:  *     and in init.c, the allocation of table space.
                    980:  */
                    981: 
                    982: #ifdef NEWLINKSTUFFF
                    983: 
                    984: char   *linkmap;       /* table of inodes with one link */
                    985: 
                    986: #define testlink(in)   ( linkmap[((unsigned)bn)>>(LOGNBPC-1)] & \
                    987:                          3 << (((unsigned)bn)&(NBPC>>1)) )
                    988: #define marklink(in)   ( linkmap[((unsigned)bn)>>(LOGNBPC-1)] |= \
                    989:                          1 << (((unsigned)bn)&(NBPC-2)) )
                    990: #define unmarklink(in) ( linkmap[((unsigned)bn)>>(LOGNBPC-1)] ^= \
                    991:                          1 << (((unsigned)bn)&(NBPC-2)) )
                    992: 
                    993: linkcntr(inum)
                    994: ino_t inum;
                    995: {
                    996:        index = ((unsigned) inum) >> (LOGNBPC-1) ;
                    997:        distance = ((unsigned) inum) & ((NBPC>>1) - 1) ;
                    998:        mask = 3 << distance;
                    999:        answer = ( linkmap[index] & mask ) >> distance;
                   1000: 
                   1001:        if ( answer < 3 )
                   1002:                return(answer);
                   1003: 
                   1004:        hash = inum & 0xFF;
                   1005:        bucket = &linktable[hash];
                   1006:        bktinum = bucket->inumb;
                   1007: 
                   1008:        if ( bktinum == inum ) {
                   1009:                answer = bucket->numlink;
                   1010:                if ( answer == 0xFF )
                   1011:                        return( bigcntr(inum) );
                   1012:                else
                   1013:                        return( answer + 3 );
                   1014:        }
                   1015: 
                   1016:        if ( bktinum > inum )
                   1017:                fatal("internal linktable corruption.");
                   1018: 
                   1019:        
                   1020: }
                   1021: 
                   1022: linkincr(inum)
                   1023: ino_t inum;
                   1024: {
                   1025: }
                   1026: 
                   1027: #endif
                   1028: @
                   1029: m) >> (LOGNBPC-1) ;
                   1030:        distance = ((unsigned) inum) & ((NBPC>>1) - 1) ;
                   1031:        mask = 3 << distance;
                   1032:        answer = ( linkmap[index] & mask ) >> distance;
                   1033: 
                   1034:        if ( answer < 3 )
                   1035:                return(answer);
                   1036: 
                   1037:        hash = inum & 0xFF;
                   1038:        bucket = &linktable[hash];
                   1039:        bktinum = bucket->inumb;
                   1040: 
                   1041:        if ( bktinum == inum ) {
                   1042:                answer = bucket->numlink;
                   1043:                if ( ansfsck/RCS/main.c,v   444      3      3       15241  5045006700   6737 head     1.3;
                   1044: branch   ;
                   1045: access   ;
                   1046: symbols  ;
                   1047: locks    bin:1.3;
                   1048: comment  @ * @;
                   1049: 
                   1050: 
                   1051: 1.3
                   1052: date     91.07.29.07.44.44;  author bin;  state Exp;
                   1053: branches ;
                   1054: next     1.2;
                   1055: 
                   1056: 1.2
                   1057: date     91.03.18.18.43.33;  author bin;  state Exp;
                   1058: branches ;
                   1059: next     1.1;
                   1060: 
                   1061: 1.1
                   1062: date     91.02.05.16.36.45;  author bin;  state Exp;
                   1063: branches ;
                   1064: next     ;
                   1065: 
                   1066: 
                   1067: desc
                   1068: @prov by epstein
                   1069: @
                   1070: 
                   1071: 
                   1072: 1.3
                   1073: log
                   1074: @Updated by epstein for version 321.
                   1075: @
                   1076: text
                   1077: @/*                                    
                   1078:  * fsck  --  File System Check Program
                   1079:  * an interactive file system check and repair program.
                   1080:  *
                   1081:  * Usage:
                   1082:  *     /etc/fsck [-y] [-n] [-q] [-f] [-{sS}] [-t TMPFILE] [filesystem ...]
                   1083:  *     audit and interactively repair inconsistent conditions for
                   1084:  *     file systems.  Options -y and -n indicate an assumed response
                   1085:  *     to all questions asked by fsck.  Default is to prompt operator
                   1086:  *     for yes/no response.  Option -q is to quiet fsck from printing
                   1087:  *     certain messages, i.e. no size check messages, unreferenced
                   1088:  *     pipes will be silently removed, and counts in the superblock
                   1089:  *     will be automatically fixed and free list salvaged, if necessary.
                   1090:  *     Option -f is for a 'fast' check of the file system, i.e. only
                   1091:  *     check blocks, sizes, superblock counts, and the free list.
                   1092:  *     (-f) does not check pathnames, connectivity, or reference
                   1093:  *     counts.  Option -s forces the reconstruction (or salvaging) of
                   1094:  *     both the free inode list and the free block list, even if there
                   1095:  *     are no file system problems.  This will reorder the free block
                   1096:  *     list in the best order to limit additional fragmentation (respecting
                   1097:  *     interleaving as well).  Note: Option -s will be ignored on mounted
                   1098:  *     file systems.  The option -S acts in the same manner as -s except
                   1099:  *     that it will not be ignored on mounted file systems.  Beware: -S
                   1100:  *     on mounted file systems should only be used if you intend to reboot
                   1101:  *     NO SYNC immediately afterwards.  Option -t sets the temporary file
                   1102:  *     to use for disk caching of necessary tables on filesystems which are
                   1103:  *     too big to do in core. The temporary file defaults to "/dev/rram1",
                   1104:  *     which must be there.
                   1105:  */
                   1106: 
                   1107: #include "fsck.h"
                   1108: 
                   1109: int    errflag;
                   1110: 
                   1111: int    mdaction;                       /* default action for invocation */
                   1112: int    daction;                        /* default action for file system */
                   1113: int    gSflag=FALSE;                   /* force salvage flag ignored mounted */
                   1114: int    gsflag=FALSE;                   /* force salvage flag ignored mounted */
                   1115: int    sflag=FALSE;                    /* force salvage flag   */
                   1116: int    qflag=FALSE;                    /* fsck quiet flag      */
                   1117: int    fflag=FALSE;                    /* fsck fast flag       */
                   1118: 
                   1119: char *tmpfile = NULL;                  /* TMP file for virtual.c */
                   1120: char *checklistfile = "/etc/checklist";        /* default file for list of file */
                   1121:                                        /* systems to fsck. */
                   1122: char *filelist[NFILSYS];               /* list of filesystems */
                   1123: char word[MAXCH];                      /* hold single words */
                   1124: char *fsname;                          /* file system name */
                   1125: 
                   1126: dev_t  rootdev;                        /* root device number */
                   1127: dev_t  fsysrdev;                       /* file system real device number */
                   1128: int    mounted;                        /* flag for mounted file system */
                   1129: 
                   1130: int    changeflg;                      /* file system modified flag */
                   1131: 
                   1132: main(argc, argv)
                   1133: char *argv[];
                   1134: {
                   1135:        int yflag=0, nflag=0;
                   1136:        int retval;
                   1137: 
                   1138:        while (argc>1 && *argv[1]=='-') {
                   1139:                switch (argv[1][1]) {
                   1140:                case 'q':
                   1141:                        qflag = TRUE;
                   1142:                        break;
                   1143:                case 'y':
                   1144:                        yflag = 1;
                   1145:                        break;
                   1146:                case 'n':
                   1147:                        nflag = 1;
                   1148:                        break;
                   1149:                case 'f':
                   1150:                        fflag = TRUE;
                   1151:                        break;
                   1152:                case 'S':
                   1153:                        gSflag = TRUE;
                   1154:                        break;
                   1155:                case 's':
                   1156:                        gsflag = TRUE;
                   1157:                        break;
                   1158:                case 't':
                   1159:                        tmpfile = argv[2];
                   1160:                        argc--;
                   1161:                        argv++;
                   1162:                        break;
                   1163:                default:
                   1164:                        usage();
                   1165:                        break;
                   1166:                }
                   1167:        
                   1168:                argc--;
                   1169:                argv++;
                   1170:        }
                   1171:        
                   1172:        if ( yflag+nflag > 1 )
                   1173:                usage();
                   1174: 
                   1175:        mdaction = ( yflag ? YES :
                   1176:                    nflag ? NO : ASK );
                   1177: 
                   1178:        if ( argc > 1 )
                   1179:                retval = allfsck(argv+1);
                   1180:        else {
                   1181:                getlist();
                   1182:                retval = allfsck(filelist);
                   1183:        }
                   1184:        exit(retval);
                   1185: }
                   1186: 
                   1187: 
                   1188: /*
                   1189:  *     perform fsck on each of the individual filesystem in list
                   1190:  */
                   1191: 
                   1192: allfsck(fsl)
                   1193: register char **fsl;
                   1194: {
                   1195:        int fatal();
                   1196:        int retval = 0;
                   1197: 
                   1198:        sync();
                   1199:        statit("/", fatal);
                   1200:        rootdev = stats.st_dev;
                   1201:        while (*fsl != NULL)
                   1202:                retval |= fsck(*fsl++);
                   1203:        return(retval);
                   1204: }
                   1205: 
                   1206: /* 
                   1207:  *     get the names of the filesystems from the default file
                   1208:  *     checklistfile  (e.g. /etc/checklist)
                   1209:  */
                   1210: 
                   1211: getlist()
                   1212: {
                   1213:        int fd;
                   1214:        int index, size;
                   1215: 
                   1216:        if ( (fd = open(checklistfile, 0)) == (-1) )
                   1217:                fatal("Can't open checklist file: %s", checklistfile);
                   1218: 
                   1219:        index = 0;
                   1220:        while ( ((size = getword(fd)) != 0) && (index < NFILSYS) ) {
                   1221:                 filelist[index] = malloc( size );
                   1222:                strcpy(filelist[index++], word);
                   1223:        }
                   1224: 
                   1225:        if (size != 0) 
                   1226:                fatal("Too many file systems in checklist file: %s",
                   1227:                                                        checklistfile);
                   1228: 
                   1229:        filelist[index] = NULL;
                   1230: 
                   1231:        close(fd);
                   1232: }
                   1233: 
                   1234: /*
                   1235:  *     read in the next "word" from file with descriptor fd
                   1236:  *     return the length of the word.
                   1237:  */
                   1238: 
                   1239: getword(fd)
                   1240: int fd;
                   1241: {
                   1242:        int n = 0, num;
                   1243:        char *cp = word;
                   1244:        char ch;
                   1245: 
                   1246:        while ( ( (num=read(fd, &ch, 1)) == 1 ) &&
                   1247:                ( (ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r') ) );
                   1248: 
                   1249:        if (num != 1)
                   1250:                return(0);
                   1251: 
                   1252:        do {
                   1253:                *cp++ = ch;
                   1254:        } while (  (++n < MAXCH) && (read(fd, &ch, 1) == 1) &&
                   1255:                (ch != ' ') && (ch != '\t') && (ch != '\n') && (ch != '\r') );
                   1256:        
                   1257:        *cp = '\0';
                   1258: 
                   1259:        return(n+1);
                   1260: }
                   1261:        
                   1262: /*
                   1263:  *     perform fsck on the given filesystem
                   1264:  */
                   1265: fsck(name)
                   1266: char *name;
                   1267: {
                   1268:        int retval = 1;
                   1269:        int nonfatal();
                   1270: 
                   1271:        fsname = name;          /* file system name */
                   1272:        errflag = FALSE;
                   1273:        statit(fsname, nonfatal);
                   1274:        fsysrdev = stats.st_rdev;
                   1275:        if ( errflag )
                   1276:                return(retval);
                   1277:        changeflg = FALSE;
                   1278:        init();
                   1279:        if ( sflag = ((gsflag && !mounted) || gSflag) )
                   1280:                printf("Switch \"-s\" selected to automatically rebuild free lists\n");
                   1281:        if (!sflag && gsflag)
                   1282:                printf("Ignoring \"-s\" on mounted file system\n");
                   1283:        if ( !errflag ) {
                   1284:                phase1();       /* check blocks and sizes */
                   1285:                if ( !fflag ) {
                   1286:                        phase2();       /* check pathnames        */
                   1287:                        phase3();       /* check connectivity     */
                   1288:                        phase4();       /* check reference counts */
                   1289:                }
                   1290:                phase5();       /* check free list        */
                   1291:                phase6();       /* salvage free list      */
                   1292:                retval = cleanup();
                   1293:        }
                   1294:        return(retval);
                   1295: }
                   1296: 
                   1297: usage()
                   1298: {
                   1299:        printf("\
                   1300: Usage: /etc/fsck [-y] [-n] [-q] [-f] [-{sS}] [-t TMPFILE] [filesystem ...]\n");
                   1301:        _exit(1);
                   1302: }
                   1303: @
                   1304: 
                   1305: 
                   1306: 1.2
                   1307: log
                   1308: @update provided by epstein
                   1309: @
                   1310: text
                   1311: @d6 1
                   1312: a6 1
                   1313:  *     /etc/fsck [-y] [-n] [-q] [-f] [-s] [-t TMPFILE] [filesystem ...]
                   1314: d21 7
                   1315: a27 3
                   1316:  *     interleaving as well). Option -t sets the temporary file to use
                   1317:  *     for disk caching of necessary tables on filesystems which are too
                   1318:  *     big to do in core. The temporary file defaults to "/dev/rram1",
                   1319: d37 2
                   1320: d76 3
                   1321: d80 1
                   1322: a80 1
                   1323:                        sflag = TRUE;
                   1324: d203 4
                   1325: d224 1
                   1326: a224 1
                   1327: Usage: /etc/fsck [-y] [-n] [-q] [-f] [-s] [-t TMPFILE] [filesystem ...]\n");
                   1328: @
                   1329: 
                   1330: 
                   1331: 1.1
                   1332: log
                   1333: @Initial revision
                   1334: @
                   1335: text
                   1336: @d6 1
                   1337: a6 1
                   1338:  *     /etc/fsck [-y] [-n] [-q] [-f] [-t TMPFILE] [filesystem ...]
                   1339: d17 8
                   1340: a24 4
                   1341:  *     counts. Option -t sets the temporary file to use for disk caching
                   1342:  *     of necessary tables on filesystems which are too big to do in core.
                   1343:  *     The temporary file defaults to "/dev/rram1", which must be there.
                   1344:  *
                   1345: d33 3
                   1346: a35 2
                   1347: int    qflag=FALSE;                    /* fsck quiet flag */
                   1348: int    fflag=FALSE;                    /* fsck fast flag */
                   1349: d70 3
                   1350: d211 1
                   1351: a211 1
                   1352: Usage: /etc/fsck [-y] [-n] [-q] [-f] [-t TMPFILE] [filesystem ...]\n");
                   1353: @
                   1354: g
                   1355: @Initial revision
                   1356: @
                   1357: text
                   1358: @d6 1
                   1359: a6 1
                   1360:  *     /etc/fsck [-y] [-n] [-q] [-f] [-t TMPFILE] [filesystem ...]
                   1361: d17 8
                   1362: a24 4
                   1363:  *     counts. Option -t sets the temporary file to use for disk caching
                   1364:  *     of necessary tables on filesystems which are too big to do in core.
                   1365:  *     The temporary file defaults to "/dev/rram1", which must be there.
                   1366:  *
                   1367: d33 3
                   1368: a35 2
                   1369: int    qflag=FALSfsck/RCS/phase1.c,v   444      3      3       16554  4771205175   7220 head     1.2;
                   1370: access   ;
                   1371: symbols  ;
                   1372: locks    bin:1.2;
                   1373: comment  @ * @;
                   1374: 
                   1375: 
                   1376: 1.2
                   1377: date     91.03.18.18.43.50;  author bin;  state Exp;
                   1378: branches ;
                   1379: next   1.1;
                   1380: 
                   1381: 1.1
                   1382: date     91.02.05.16.36.59;  author bin;  state Exp;
                   1383: branches ;
                   1384: next   ;
                   1385: 
                   1386: 
                   1387: desc
                   1388: @prov by epstein
                   1389: @
                   1390: 
                   1391: 
                   1392: 1.2
                   1393: log
                   1394: @update provided by epstein
                   1395: @
                   1396: text
                   1397: @/*
                   1398:  *     phase 1 of fsck - Check Blocks and Sizes
                   1399:  */
                   1400: 
                   1401: #include "fsck.h"
                   1402: 
                   1403: char   databuf[BSIZE];         /* buffer for blocks */
                   1404: 
                   1405: int    clrflg;                 /* indicates when to clear an inode */
                   1406: int    dupflag;                /* indicates whether there are any dups */
                   1407: 
                   1408: int    numbad;                 /* number of bad blocks in the inode   */
                   1409: int    numdup;                 /* number of duplicate blocks in inode */
                   1410: long   numblks;                /* number of data blks for size check */
                   1411: long   sparsecnt;              /* count for sparse blocks for size check */
                   1412: 
                   1413: /*  The following is a table of the number of direct blocks pointed at by the
                   1414:  *  four types of blocks direct, ..., triple-indirect, to help count sparse
                   1415:  *  blocks.
                   1416:  */
                   1417: 
                   1418: daddr_t        blockcnt[] = {1, (daddr_t)NBN, (daddr_t)NBN*NBN, (daddr_t)NBN*NBN*NBN};
                   1419: 
                   1420: phase1()
                   1421: {
                   1422:        if (!qflag)
                   1423:                printf("Phase 1 : Check Blocks and Sizes\n");
                   1424:        dupflag = FALSE;
                   1425:        inodescan();
                   1426:        if (dupflag)
                   1427:                phase1b();      
                   1428: }
                   1429: 
                   1430: inodescan()
                   1431: {
                   1432:        register daddr_t bn;
                   1433:        register struct dinode *dip;
                   1434:        register ino_t  ino;
                   1435:        int i;
                   1436: 
                   1437:        ino = 1;
                   1438: 
                   1439:        for (bn=INODEI; bn<isize; bn++) {
                   1440:                if (testblock(bn)) {            /* block is bad via inode 1 */
                   1441:                        ino += INOPB;
                   1442:                        continue;
                   1443:                }
                   1444:                bread(bn, databuf);
                   1445:                clrflg = FALSE;
                   1446:                dip = (struct dinode *) databuf;
                   1447:                for (i=0; i<INOPB; i++) {
                   1448:                        candino(dip);
                   1449:                        if (inuse(dip) == TRUE) {
                   1450:                                if (!fflag) 
                   1451:                                        checkmode(dip, ino);
                   1452:                                if ( checkblks(dip, ino) != STOP ) 
                   1453:                                        if ( qflag == FALSE )
                   1454:                                                checksize(dip, ino);
                   1455:                        }
                   1456:                        candino(dip);
                   1457:                        ino++;
                   1458:                        dip++;
                   1459:                }
                   1460:                if (clrflg)
                   1461:                        bwrite(bn, databuf);
                   1462:        }
                   1463: }
                   1464: 
                   1465: /*
                   1466:  *     Determine if the given inode is in use.
                   1467:  */
                   1468: 
                   1469: inuse(dip)
                   1470: register struct dinode *dip;
                   1471: {
                   1472: #ifdef NOT_ALL_ZERO_INODE
                   1473: 
                   1474:        if ( (dip->di_mode != 0) || (dip->di_nlink != 0) )
                   1475:                return(TRUE);
                   1476:        else
                   1477:                return(FALSE);
                   1478: #endif
                   1479: #ifdef ALL_ZERO_INODE
                   1480: 
                   1481:        register char *ptr;
                   1482:        register struct dinode *next;
                   1483: 
                   1484:        ptr = (char *) dip;
                   1485:        next = dip + 1;
                   1486:        while (ptr < next)
                   1487:                if (*ptr++ != 0)
                   1488:                        return(TRUE);
                   1489: 
                   1490:        return(FALSE);
                   1491: #endif
                   1492: }
                   1493: 
                   1494: /*
                   1495:  *     Check the mode of the given inode
                   1496:  */
                   1497: 
                   1498: checkmode(dip, ino)
                   1499: register struct dinode *dip;
                   1500: register ino_t ino;
                   1501: {
                   1502:        register unsigned short mode;
                   1503: 
                   1504:        mode = dip->di_mode & IFMT;
                   1505: 
                   1506:        switch (mode) {
                   1507:        case IFREG:
                   1508:                setflags(ino, IREG);
                   1509:                return;
                   1510:        case IFDIR:
                   1511:                setflags(ino, IDIR);
                   1512:                return;
                   1513:        case IFCHR:
                   1514:                setflags(ino, ICHR);
                   1515:                return;
                   1516:        case IFBLK:
                   1517:                setflags(ino, IBLK);
                   1518:                return;
                   1519:        case IFPIPE:
                   1520:                setflags(ino, IPIPE);
                   1521:                return;
                   1522:        default:
                   1523:                setflags(ino, UNKNOWN);
                   1524:                break;
                   1525:        }
                   1526: 
                   1527:        switch ( query("Unknown File Type i-number = %u (Clear)", ino) ){
                   1528:        case NO:
                   1529:                return;
                   1530:        case YES:
                   1531:                zeroinode(dip);
                   1532:                setflags(ino, UNALLOC);
                   1533:                clrflg = TRUE;
                   1534:                break;
                   1535:        }
                   1536: }
                   1537: 
                   1538: /*
                   1539:  *     Zero the given inode
                   1540:  */
                   1541: 
                   1542: zeroinode(dip)
                   1543: struct dinode *dip;
                   1544: {
                   1545:        register char *ptr;
                   1546:        register struct dinode *next;
                   1547: 
                   1548:        lostsize += dip->di_size;
                   1549:        next = dip+1;
                   1550:        ptr = (char *) dip;
                   1551: 
                   1552:        while (ptr < next)
                   1553:                *ptr++ = 0;
                   1554: 
                   1555: }
                   1556: 
                   1557: /*
                   1558:  *     Check the blocks associated with the given inode to determine
                   1559:  *     if any are bad or duplicate
                   1560:  */
                   1561: 
                   1562: checkblks(dip, ino)
                   1563: struct dinode *dip;
                   1564: ino_t  ino;
                   1565: {
                   1566:        daddr_t addrs[NADDR];
                   1567:        register daddr_t bn;
                   1568:        register int i, lev;
                   1569:        register int mode;
                   1570: 
                   1571:        mode = dip->di_mode & IFMT;
                   1572: 
                   1573:        if ( (mode != IFREG) && (mode != IFDIR) )
                   1574:                return(STOP);
                   1575: 
                   1576:        l3tol(addrs, dip->di_addr, NADDR);
                   1577: 
                   1578:        numbad =                        /* number of bad blocks so far */
                   1579:        numdup =                        /* num dup blocks so far THIS INODE */
                   1580:        numblks =                       /* num used data blocks for size chk */
                   1581:        sparsecnt = 0;                  /* count of missed data blocks  */
                   1582: 
                   1583:        for(i=0; i<NADDR; i++)
                   1584:                for (lev=0; lev<4; lev++) 
                   1585:                        if (i < offsets[lev]) {
                   1586:                                if ( (bn=addrs[i]) != 0 ) {
                   1587:                                        if (doblocks(bn, ino, lev) != OK)
                   1588:                                                return(STOP);
                   1589:                                } else
                   1590:                                        sparsecnt += blockcnt[lev];
                   1591:                                break;
                   1592:                        }
                   1593:        return(OK);
                   1594: }
                   1595: 
                   1596: /*
                   1597:  *     Checks recursively the blocks pointed at via
                   1598:  *     the inode list of blocks.  'bn' is the block number,
                   1599:  *     'ino' is the inode referencing it, and 'lev' is the
                   1600:  *     level 0 == direct ... 3 = triple-indirect
                   1601:  */
                   1602: 
                   1603: doblocks(bn, ino, lev)
                   1604: register daddr_t bn;
                   1605: ino_t  ino;
                   1606: int    lev;
                   1607: {
                   1608:        char buf[BSIZE];
                   1609:        register daddr_t *bnptr;
                   1610:        register char *end;
                   1611:        register int flag;
                   1612: 
                   1613:        if (lev-- == 0) {               /* we have a direct block */
                   1614:                numblks += sparsecnt + 1;
                   1615:                sparsecnt = 0;
                   1616:                return(dodirect(bn, ino));
                   1617:        } else {
                   1618:                end = &buf[BSIZE];
                   1619:                if ( (flag=dodirect(bn, ino)) == OK ) {
                   1620:                        bread(bn, buf);
                   1621:                        bnptr = (long *) buf;
                   1622:                        while ( bnptr < end ) {
                   1623:                                bn = *bnptr++;
                   1624:                                candaddr(bn);
                   1625:                                if ( bn == 0 ) {
                   1626:                                        sparsecnt += blockcnt[lev];
                   1627:                                        continue;
                   1628:                                }
                   1629:                                if ( doblocks(bn, ino, lev) == STOP )
                   1630:                                        return(STOP);
                   1631:                        }
                   1632:                        return(OK);
                   1633:                } else 
                   1634:                        return(flag);
                   1635:        }
                   1636: }
                   1637:                        
                   1638: /*
                   1639:  *     Check the given block to determine if it is bad
                   1640:  *     or if it is a duplicate.  'ino' is the inode referencing it
                   1641:  */
                   1642: 
                   1643: dodirect(bn, ino)
                   1644: register daddr_t bn;
                   1645: register ino_t ino;
                   1646: {
                   1647:        register int flag;
                   1648:        
                   1649:        if ( (flag=checkbad(bn, ino)) == OK ) 
                   1650:                return( checkdup(bn, ino) );
                   1651:        else
                   1652:                return(flag);
                   1653: }
                   1654: 
                   1655: /*
                   1656:  *     Check the given block number for being bad.
                   1657:  */
                   1658: 
                   1659: checkbad(bn, ino)
                   1660: register daddr_t bn;
                   1661: ino_t  ino;
                   1662: {
                   1663:        if ( (bn>=isize) && (bn<fsize) )
                   1664:                return(OK);
                   1665: 
                   1666:        else if ( (bn<isize) && (bn>=INODEI) && (ino == 1) ) {
                   1667:                                                        /* bad block is in  */
                   1668:                totfree++;                              /* the inode blocks */
                   1669:                return(OK);
                   1670:        }
                   1671:                
                   1672:        if (!fflag)
                   1673:                orflags(ino, IBAD_IDUP);
                   1674: 
                   1675:        printf("Bad block %U, i-number = %u\n", bn, ino);
                   1676: 
                   1677:        if (numbad++ < MAXBADOK)
                   1678:                return(BAD_DUP);
                   1679: 
                   1680:        switch ( query("Excessive Bad Blocks i-number = %u (Continue)", ino) ){
                   1681:        case NO:
                   1682:                abort();
                   1683:        case YES:
                   1684:                return(STOP);
                   1685:        }
                   1686: }
                   1687: 
                   1688: 
                   1689: /*
                   1690:  *     Check the given block number for duplicate reference.
                   1691:  */
                   1692: 
                   1693: checkdup(bn, ino)
                   1694: register daddr_t bn;
                   1695: ino_t  ino;
                   1696: {
                   1697:        if ( !testblock(bn) ) {
                   1698:                markblock(bn);
                   1699:                totfree--;
                   1700:                return(OK);
                   1701:        }
                   1702: 
                   1703:        dupflag = TRUE;
                   1704:        if (!fflag)
                   1705:                orflags(ino, IBAD_IDUP);
                   1706:        printf("Dup Block %U, i-number = %u\n", bn, ino);
                   1707: 
                   1708:        if (totdups < DUPTBLSIZE) 
                   1709:                dupblck[totdups++] = bn;
                   1710:        else {
                   1711:                switch ( query("DUP Table Overflow (Continue)") ) {
                   1712:                case NO:
                   1713:                        abort();
                   1714:                case YES:
                   1715:                        return(BAD_DUP);
                   1716:                }
                   1717:        }
                   1718: 
                   1719:        if (numdup++ < MAXDUPOK)
                   1720:                return(BAD_DUP);
                   1721: 
                   1722:        switch ( query("Excessive Dup Blocks i-number = %u (Continue)", ino) ) {
                   1723:        case NO:
                   1724:                abort();
                   1725:        case YES:
                   1726:                return(STOP);
                   1727:        }
                   1728: }
                   1729: 
                   1730: /*
                   1731:  *     Check For Possible File Size Error 
                   1732:  */
                   1733: 
                   1734: checksize(dip, ino)
                   1735: register struct dinode *dip;
                   1736: ino_t  ino;
                   1737: {
                   1738:        register int mode;
                   1739:        register fsize_t size;
                   1740: 
                   1741:        mode = dip->di_mode & IFMT;
                   1742:        size = dip->di_size;
                   1743:        
                   1744:        if ( mode == IFREG )
                   1745:                filesize(ino, size);
                   1746:        else    /* mode == IFDIR */
                   1747:                dirsize(dip, ino, size);
                   1748: }
                   1749: 
                   1750: dirsize(dip, ino, size)
                   1751: struct dinode *dip;
                   1752: ino_t ino;
                   1753: register fsize_t size;
                   1754: {
                   1755:        if ( size <= 0 ) {
                   1756:                switch ( query("\
                   1757: Bad Directory Size, size = %D, i-number = %u (Clear i-node)", size, ino) ) {
                   1758:                case NO:
                   1759:                        break;
                   1760:                case YES:
                   1761:                        zeroinode(dip);
                   1762:                        setflags(ino, UNALLOC);
                   1763:                        clrflg = TRUE;
                   1764:                        return;
                   1765:                }
                   1766:        }
                   1767: 
                   1768:        if ( size < (2*DSIZE) )
                   1769:                printf("Directory Size too small i-number = %u\n", ino);
                   1770: 
                   1771:        if ( size % sizeof(struct direct) != 0 )
                   1772:                printf("Directory Misaligned i-number = %u\n", ino);
                   1773: 
                   1774:        if (sizerr(size))
                   1775:                printf("Possible Directory Size Error i-number = %u\n", ino);
                   1776: }
                   1777: 
                   1778: filesize(ino, size)
                   1779: ino_t ino;
                   1780: register fsize_t size;
                   1781: {
                   1782:        if (sizerr(size))
                   1783:                printf("Possible File Size Error i-number = %u\n", ino);
                   1784: }
                   1785: 
                   1786: sizerr(size)
                   1787: register fsize_t size;
                   1788: {
                   1789:        register fsize_t calc;
                   1790: 
                   1791:        calc = (unsigned long)numblks*BSIZE;
                   1792:        if ( (size > calc) || ( calc >= (size+BSIZE) ) ) 
                   1793:                return(TRUE);
                   1794:        else
                   1795:                return(FALSE);
                   1796: }
                   1797: @
                   1798: 
                   1799: 
                   1800: 1.1
                   1801: log
                   1802: @Initial revision
                   1803: @
                   1804: text
                   1805: @d152 1
                   1806: d252 1
                   1807: a252 1
                   1808: 
                   1809: @
                   1810: saligned i-number = %u\n", ino);
                   1811: 
                   1812:        if (sizerr(size))
                   1813:                printf("Possible Directory Size Error i-number = %u\n", ino);
                   1814: }
                   1815: 
                   1816: filesize(ino, size)
                   1817: ino_t infsck/RCS/phase1b.c,v   444      3      3        4676  4753557476   7362 head     1.1;
                   1818: access   ;
                   1819: symbols  ;
                   1820: locks    ;
                   1821: comment  @ * @;
                   1822: 
                   1823: 
                   1824: 1.1
                   1825: date     91.02.05.16.37.12;  author bin;  state Exp;
                   1826: branches ;
                   1827: next   ;
                   1828: 
                   1829: 
                   1830: desc
                   1831: @prov by epstein
                   1832: @
                   1833: 
                   1834: 
                   1835: 
                   1836: 1.1
                   1837: log
                   1838: @Initial revision
                   1839: @
                   1840: text
                   1841: @/*
                   1842:  *     Phase 1b of fsck - Rescan for more Dups
                   1843:  */
                   1844: 
                   1845: #include "fsck.h"
                   1846: 
                   1847: extern int     numdup;         /* declared in phase1.c */
                   1848: 
                   1849: phase1b()
                   1850: {
                   1851:        if (!qflag)
                   1852:                printf("Phase 1b: Rescan for more Dups\n");
                   1853:        buildtable();
                   1854:        iscanb();
                   1855: }
                   1856: 
                   1857: buildtable()
                   1858: {
                   1859:        unsigned cntr=0, numdiff=0;
                   1860:        daddr_t bn;
                   1861: 
                   1862:        while (cntr<totdups) {
                   1863:                bn = dupblck[cntr++];
                   1864:                if (!testdup(bn)) {
                   1865:                        markdup(bn);
                   1866:                        numdiff++;
                   1867:                }
                   1868:        }
                   1869:        totdups = numdiff;
                   1870: }
                   1871: 
                   1872: iscanb()
                   1873: {
                   1874:        register daddr_t bn;
                   1875:        register struct dinode *dip;
                   1876:        register ino_t  ino;
                   1877:        int i;
                   1878: 
                   1879:        ino = 1;
                   1880: 
                   1881:        for (bn=INODEI; bn<isize; bn++) {
                   1882:                if (testblock(bn)) {            /* block is bad via inode 1 */
                   1883:                        ino += INOPB;
                   1884:                        continue;
                   1885:                }
                   1886:                bread(bn, databuf);
                   1887:                dip = (struct dinode *) databuf;
                   1888:                for (i=0; i<INOPB; i++) {
                   1889:                        candino(dip);
                   1890:                        if (inuse(dip) == TRUE) 
                   1891:                                ckblksb(dip, ino);
                   1892:                        if (totdups == 0)
                   1893:                                return;                 
                   1894:                        ino++;
                   1895:                        dip++;
                   1896:                }
                   1897:        }
                   1898: }
                   1899: 
                   1900: /*
                   1901:  *     Check the blocks associated with the given inode to find the
                   1902:  *     remaining duplicate blocks
                   1903:  */
                   1904: 
                   1905: ckblksb(dip, ino)
                   1906: register struct dinode *dip;
                   1907: register ino_t ino;
                   1908: {
                   1909:        daddr_t addrs[NADDR];
                   1910:        int i, lev;
                   1911:        int mode;
                   1912: 
                   1913:        mode = dip->di_mode & IFMT;
                   1914: 
                   1915:        if ( (mode != IFREG) && (mode != IFDIR) )
                   1916:                return;
                   1917: 
                   1918:        l3tol(addrs, dip->di_addr, NADDR);
                   1919: 
                   1920:        numdup = 0;                     /* num dup blocks so far THIS INODE */
                   1921: 
                   1922:        for(i=0; i<NADDR; i++)
                   1923:                for (lev=0; lev<4; lev++) 
                   1924:                        if (i < offsets[lev]) {
                   1925:                                dblocksb(addrs[i], ino, lev);
                   1926:                                break;
                   1927:                        }
                   1928: }
                   1929: 
                   1930: /*
                   1931:  *     Checks recursively the blocks pointed at via
                   1932:  *     the inode list of blocks.  'bn' is the block number,
                   1933:  *     'ino' is the inode referencing it, and 'lev' is the
                   1934:  *     level 0 == direct ... 3 = triple-indirect
                   1935:  */
                   1936: 
                   1937: dblocksb(bn, ino, lev)
                   1938: daddr_t        bn;
                   1939: ino_t  ino;
                   1940: int    lev;
                   1941: {
                   1942:        char buf[BSIZE];
                   1943:        int  i;
                   1944:        daddr_t *bnptr;
                   1945: 
                   1946:        if (bn == 0)
                   1947:                return(OK);
                   1948:                
                   1949:        switch ( cdupb(bn, ino) ) {
                   1950:        case OK:
                   1951:                if (lev--==0)
                   1952:                        return(OK);
                   1953:                bread(bn, buf);
                   1954:                bnptr = (long *) buf;
                   1955:                for (i=0; i<NBN; i++) {
                   1956:                        bn = bnptr[i];
                   1957:                        candaddr(bn);
                   1958:                        if ( dblocksb(bn, ino, lev) == STOP )
                   1959:                                return(STOP);
                   1960:                }
                   1961:                return(OK);
                   1962:        case STOP:
                   1963:                return(STOP);
                   1964:        }
                   1965: }
                   1966: 
                   1967: /*
                   1968:  *     Check the given block number for duplicate reference.
                   1969:  */
                   1970: 
                   1971: cdupb(bn, ino)
                   1972: daddr_t        bn;
                   1973: ino_t  ino;
                   1974: {
                   1975:        if ( !testdup(bn) ) 
                   1976:                return(OK);
                   1977: 
                   1978:        totdups--;
                   1979:        unmarkdup(bn);
                   1980:        if (!fflag)
                   1981:                orflags(ino, IBAD_IDUP);
                   1982:        printf("Dup Block %U, i-number = %u\n", bn, ino);
                   1983: 
                   1984:        return(STOP);
                   1985: }
                   1986: @
                   1987: )
                   1988:                        return(OK);
                   1989:                bread(bn, buf);
                   1990:                bnptr = (long *) buf;
                   1991:                for (fsck/RCS/phase2.c,v   444      3      3       17750  4771205232   7212 head     1.2;
                   1992: access   ;
                   1993: symbols  ;
                   1994: locks    bin:1.2;
                   1995: comment  @ * @;
                   1996: 
                   1997: 
                   1998: 1.2
                   1999: date     91.03.18.18.44.18;  author bin;  state Exp;
                   2000: branches ;
                   2001: next   1.1;
                   2002: 
                   2003: 1.1
                   2004: date     91.02.05.16.37.24;  author bin;  state Exp;
                   2005: branches ;
                   2006: next   ;
                   2007: 
                   2008: 
                   2009: desc
                   2010: @prov by epstein
                   2011: @
                   2012: 
                   2013: 
                   2014: 1.2
                   2015: log
                   2016: @update provided by epstein
                   2017: @
                   2018: text
                   2019: @/*
                   2020:  *     phase 2 of fsck - Check Pathnames
                   2021:  */
                   2022: 
                   2023: #include "fsck.h"
                   2024: #include <pwd.h>
                   2025: 
                   2026: #define MAXDEPTH 50
                   2027: struct direct *path[MAXDEPTH];
                   2028: int    depth;
                   2029: int    fixflag;                        /* flags when must rewrite databuf  */
                   2030: daddr_t blocknum;                      /* Current block num read in        */
                   2031: 
                   2032: typedef struct list {
                   2033:        struct direct d_entry;
                   2034:        struct list *next;
                   2035: } list;
                   2036: 
                   2037: char   buf2[BSIZE];                    /* buffer for blocks            */
                   2038: daddr_t        cdbn;                           /* current logical block number */
                   2039: 
                   2040: /*     Format errors, args to blkerr() */
                   2041: 
                   2042: #define        NULLNAME        5
                   2043: #define        NULLPAD         6
                   2044: #define SLASHES                7
                   2045: #define DOT            8
                   2046: #define DOTDOT         9
                   2047: 
                   2048: phase2()
                   2049: {
                   2050:        if (!qflag)
                   2051:                printf("Phase 2 : Check Pathnames\n");
                   2052:        checkroot();
                   2053:        depth = 0;
                   2054:        checkpath(ROOTIN);
                   2055: }
                   2056: 
                   2057: 
                   2058: checkroot()
                   2059: {
                   2060:        if ( (flags(ROOTIN)&MODEMASK) == UNALLOC )
                   2061:                fatal("Root i-node is unallocated.  Terminating");
                   2062: 
                   2063:        if ( (flags(ROOTIN)&MODEMASK) != IDIR ) {
                   2064:                switch ( query("Root i-node is not a directory (FIX)") ){
                   2065:                case YES:
                   2066:                        fixroot();
                   2067:                        break;
                   2068:                case NO:
                   2069:                        abort();
                   2070:                }
                   2071:        }
                   2072:        
                   2073:        if ( badblks(ROOTIN) ){
                   2074:                switch ( query("Dup/Bad blocks in root i-node (Continue)") ) {
                   2075:                case YES:
                   2076:                        break;
                   2077:                case NO:
                   2078:                        abort();
                   2079:                }
                   2080:        }
                   2081:        linkincr(ROOTIN);               /* (?) Feature (?) of mkfs is  */
                   2082:                                        /* that root inode of a file   */
                   2083:                                        /* system has a link count one */
                   2084:                                        /* too large.                  */
                   2085: }
                   2086: 
                   2087: fixroot()
                   2088: {
                   2089:        register struct dinode *dip;
                   2090: 
                   2091:        if (!writeflg) 
                   2092:                fatal("File System Read-Only (NO WRITE)\n");
                   2093: 
                   2094:        setflags(ROOTIN, (flags(ROOTIN) & ~MODEMASK) | IDIR);
                   2095: 
                   2096:        /* Save change to disk */
                   2097:        
                   2098:        dip = ptrino(ROOTIN, databuf);
                   2099:        dip->di_mode &= (~IFMT);
                   2100:        dip->di_mode |= IFDIR;
                   2101:        writeino(ROOTIN, databuf);
                   2102: }
                   2103: 
                   2104: #define        myinum  ( (depth>0) ? path[depth-1]->d_ino : ROOTIN )
                   2105: #define popinum        ( (depth>1) ? path[depth-2]->d_ino : ROOTIN )
                   2106: 
                   2107: char *memory = "Can't malloc memory, phase 2";
                   2108: 
                   2109: list *
                   2110: procfiles(addrs, length)
                   2111: daddr_t *addrs;
                   2112: fsize_t length;
                   2113: {
                   2114:        register struct direct *elemnt;
                   2115:        register list *first, *ptr;
                   2116: 
                   2117:        if ((first=ptr=(list *)malloc(sizeof(list)))==NULL)
                   2118:                fatal(memory);
                   2119:        first->d_entry.d_ino = 0;
                   2120:        first->next = NULL;
                   2121:        if ( length < DSIZE )
                   2122:                return( first );
                   2123:        cdbn = 0;
                   2124:        nextblock(addrs);
                   2125:        fixflag = FALSE;
                   2126:        elemnt = (struct direct *) databuf;
                   2127:        cdots(elemnt++, ".", myinum, DOT);
                   2128:        ++numfiles;
                   2129:        if ( (length-=DSIZE) < DSIZE )
                   2130:                return( first );
                   2131:        cdots(elemnt++, "..", popinum, DOTDOT);
                   2132:        ++numfiles;
                   2133:        length -= DSIZE;
                   2134: 
                   2135:        while ( length >= DSIZE ) {
                   2136:                while ( (elemnt<&databuf[BSIZE]) && (length>=DSIZE) ) {
                   2137:                        if (chck(elemnt)==IDIR) {
                   2138:                                copy(elemnt, &ptr->d_entry, 
                   2139:                                                sizeof(struct direct));
                   2140:                                if ((ptr->next=(list *)malloc(sizeof(list))) ==
                   2141:                                        NULL)
                   2142:                                        fatal(memory);
                   2143:                                ptr = ptr->next;
                   2144:                                ptr->d_entry.d_ino = 0;
                   2145:                                ptr->next = NULL;
                   2146:                        }
                   2147:                        elemnt++;
                   2148:                        length -= DSIZE;
                   2149:                }
                   2150:                if (fixflag && (fixblock(addrs) == NUL) )
                   2151:                        fixblkerr();
                   2152:                nextblock(addrs);
                   2153:                fixflag = FALSE;
                   2154:                elemnt = (struct direct *) databuf;
                   2155:        }
                   2156:        return(first);   
                   2157: }
                   2158: 
                   2159: candblock(dptr)
                   2160: register struct direct *dptr;
                   2161: {
                   2162:        register int num, i;
                   2163: 
                   2164:        num = BSIZE/sizeof(struct direct);
                   2165:        for (i=0; i<num; i++)
                   2166:                canino(dptr[i].d_ino);
                   2167: }
                   2168: 
                   2169: nextblock(addrs)
                   2170: register daddr_t *addrs;
                   2171: {
                   2172:        register daddr_t bn;
                   2173: 
                   2174:        if ( (bn=imap(addrs, cdbn++)) == 0 ) {
                   2175:                bclear(databuf, BSIZE);
                   2176:                return;
                   2177:        }
                   2178:        bread(bn, databuf);
                   2179:        candblock(databuf);
                   2180:        blocknum = bn;
                   2181: }
                   2182: 
                   2183: fixblock(addrs)
                   2184: daddr_t *addrs;
                   2185: {
                   2186:        daddr_t bn;
                   2187: 
                   2188:        if ( (bn=imap(addrs, cdbn-1)) == 0 ) 
                   2189:                return(NUL);
                   2190:        candblock(databuf);
                   2191:        bwrite(bn, databuf);
                   2192:        return(TRUE);
                   2193: }
                   2194: 
                   2195: fixblkerr()
                   2196: {
                   2197:        fatal("Fixblock error.");
                   2198: }
                   2199: 
                   2200: copy(from, to, size)
                   2201: register char *from, *to;
                   2202: register int size;
                   2203: {
                   2204:        while (size--)
                   2205:                *to++=*from++;
                   2206: }
                   2207: 
                   2208: cdots(elemnt, dots, ino, type)
                   2209: register struct direct *elemnt;
                   2210: char *dots;
                   2211: ino_t ino;     /* what the inode number should be */
                   2212: int type;
                   2213: {
                   2214:        register char *name = elemnt->d_name;
                   2215:        register ino_t inum;
                   2216: 
                   2217:        inum = elemnt->d_ino;
                   2218:        if ( (strcmp(name, dots) != 0) || (inum != ino) ||
                   2219:                (format(name) != GOOD) ) {
                   2220:                blkerr(type);
                   2221:                return;
                   2222:        }
                   2223:        linkincr(inum);
                   2224: }
                   2225: 
                   2226: format(name)
                   2227: register char *name;
                   2228: {
                   2229:        register char *ptr=name;
                   2230:        register char *end=&name[DIRSIZ];
                   2231: 
                   2232:        while ( (ptr<end) && (*ptr++ != '\0') ) ;
                   2233: 
                   2234:        if ( (ptr-1) == name )
                   2235:                return(NULLNAME);
                   2236:        
                   2237:        if (ptr<end) {
                   2238:                while ( (ptr<end) && (*ptr++ == '\0') ) ;
                   2239:                if (ptr!=end)
                   2240:                        return(NULLPAD);
                   2241:        }
                   2242: 
                   2243:        ptr = name;
                   2244:        while (ptr < end) 
                   2245:                if (*ptr++ == '/')
                   2246:                        return(SLASHES);
                   2247: 
                   2248:        return(GOOD);
                   2249: }
                   2250: 
                   2251:        
                   2252: blkerr(type)
                   2253: int type;
                   2254: {      
                   2255:        char *errname;
                   2256: 
                   2257:        switch(type) {
                   2258:        case NULLNAME:
                   2259:                errname = "Null name";
                   2260:                break;
                   2261:        case NULLPAD:
                   2262:                errname = "Non null padded";
                   2263:                break;
                   2264:        case SLASHES:
                   2265:                errname = "Embedded slashes in";
                   2266:                break;
                   2267:        case DOT:
                   2268:                errname = "Inconsistent .";
                   2269:                break;
                   2270:        case DOTDOT:
                   2271:                errname = "Inconsistent ..";
                   2272:                break;
                   2273:        default:
                   2274:                errname = "Bad";
                   2275:                break;
                   2276:        }
                   2277: 
                   2278:        printf("%s entry in block %U in directory\n", errname, blocknum);
                   2279:        pinfo(myinum);
                   2280:        pname(path[--depth]->d_name);
                   2281:        depth++;
                   2282: }
                   2283: 
                   2284: chck(elemnt)
                   2285: register struct direct *elemnt;
                   2286: {
                   2287:        register ino_t inum;
                   2288:        register char *name;
                   2289:        int type;
                   2290: 
                   2291:        inum = elemnt->d_ino;
                   2292:        if ( inum == 0 )
                   2293:                return(UNALLOC);
                   2294: 
                   2295:        name = elemnt->d_name;
                   2296:        if ( (type=format(name)) != GOOD )
                   2297:                blkerr(type);
                   2298: 
                   2299:        if (inum>ninodes) {
                   2300:                if ( irange(inum, name) ) 
                   2301:                        zeroent(elemnt);
                   2302:                return(UNALLOC);
                   2303:        }
                   2304: 
                   2305:        if ( (flags(inum)&ALLOCMASK)==UNALLOC ) {
                   2306:                if ( unalloc(inum, name) )
                   2307:                        zeroent(elemnt);
                   2308:                return(UNALLOC);
                   2309:        }
                   2310: 
                   2311:        if ( badblks(inum) ) {
                   2312:                if ( baddup(inum, name) ) {
                   2313:                        zeroent(elemnt);
                   2314:                        return(UNALLOC);
                   2315:                }
                   2316:                if ( (flags(inum)&MODEMASK)==IDIR )
                   2317:                        return(UNALLOC);
                   2318:        }
                   2319: 
                   2320:        linkincr(inum);
                   2321:        numfiles++;
                   2322:        return( flags(inum)&MODEMASK );
                   2323: }
                   2324: 
                   2325: zeroent(elemnt)
                   2326: struct direct *elemnt;
                   2327: {
                   2328:        elemnt->d_ino = 0;
                   2329:        fixflag = TRUE;
                   2330: }
                   2331: 
                   2332: pname(name)
                   2333: char *name;
                   2334: {
                   2335:        int i=0;
                   2336: 
                   2337:        while (i<depth) 
                   2338:                prdirsize(path[i++]->d_name);
                   2339:        prdirsize(name);
                   2340:        putchar('\n');
                   2341: }
                   2342: 
                   2343: prdirsize(name)
                   2344: char *name;
                   2345: {
                   2346:        if (name[DIRSIZ-1] == '\0')
                   2347:                printf("/%s", name);
                   2348:        else
                   2349:                printf("/%*s", DIRSIZ, name);
                   2350: }
                   2351: 
                   2352: fsize_t
                   2353: pinfo(inum)
                   2354: ino_t inum;
                   2355: {
                   2356:        register struct dinode *dip;
                   2357:        register struct passwd *pwd;
                   2358: 
                   2359:        if ( (dip=ptrino(inum, buf2)) == NULL ) {
                   2360:                printf("i-number = %u is in a bad inode block.\n", inum);
                   2361:                return(0);
                   2362:        }
                   2363: 
                   2364:        printf("i-number = %u, ", inum);
                   2365:        if ( (pwd=getpwuid(dip->di_uid)) != NULL )
                   2366:                printf("Owner=%s, ", pwd->pw_name);
                   2367:        else
                   2368:                printf("Owner=%u, ", dip->di_uid);
                   2369:        printf(" Mode=0%o\n", dip->di_mode);
                   2370:        printf("Size=%U, Mtime=%s", dip->di_size, ctime(&dip->di_mtime));
                   2371:        return(dip->di_size);
                   2372: }
                   2373: 
                   2374: char *remove = "(Remove)";
                   2375: 
                   2376: irange(inum, name)
                   2377: ino_t inum;
                   2378: char *name;
                   2379: {
                   2380:        printf("I-number is out of range  I=%u\n", inum);
                   2381:        pname(name);
                   2382:        return(action(remove));
                   2383: }
                   2384: 
                   2385: unalloc(inum, name)
                   2386: ino_t inum;
                   2387: char *name;
                   2388: {      
                   2389:        fsize_t size;
                   2390: 
                   2391:        printf("Unallocated\n");
                   2392:        size = pinfo(inum);
                   2393:        pname(name);
                   2394:        if ( (daction != NO) && (size == 0) && (mounted == FALSE) ) {
                   2395:                printf("%s [Forced - Yes]\n", remove);
                   2396:                return(YES);
                   2397:        }
                   2398:        return(action(remove));
                   2399: }
                   2400: 
                   2401: baddup(inum, name)
                   2402: ino_t inum;
                   2403: char *name;
                   2404: {
                   2405:        register int mode = flags(inum)&MODEMASK;
                   2406: 
                   2407:        printf("Bad or Dup blocks in %s\n",(mode==IDIR) ? "Directory" : "File");
                   2408:        pinfo(inum);
                   2409:        pname(name);
                   2410:        return(action(remove));
                   2411: }
                   2412: 
                   2413: checkpath(ino)
                   2414: register ino_t ino;
                   2415: {
                   2416:        static daddr_t  addrs[NADDR];
                   2417:        static struct dinode *dip;
                   2418:        static list *temp;
                   2419:        register list *ptr;
                   2420: 
                   2421:        if ( (flags(ino)&VISITED)==VISITED ) {
                   2422:                circle(ino);
                   2423:                return;
                   2424:        } else
                   2425:                orflags(ino, VISITED);
                   2426: 
                   2427:        dip = ptrino(ino, databuf);
                   2428:        l3tol(addrs, dip->di_addr, NADDR);
                   2429:        
                   2430:        if ( (dip->di_mode&IFMT) != IFDIR )
                   2431:                fatal("Tried to checkpath i-node %u which is not dir.\n", ino);
                   2432: 
                   2433:        ptr = procfiles(addrs, dip->di_size);
                   2434: 
                   2435:        while (ptr->d_entry.d_ino) {
                   2436:                if (depth >= MAXDEPTH)
                   2437:                        toolong();
                   2438:                path[depth++] = &ptr->d_entry;
                   2439:                checkpath(ptr->d_entry.d_ino);
                   2440:                depth--;
                   2441:                temp = ptr;
                   2442:                ptr = ptr->next;
                   2443:                free(temp);
                   2444:        }
                   2445:        free(ptr);
                   2446: }
                   2447: 
                   2448: circle(ino)
                   2449: ino_t ino;
                   2450: {
                   2451:        printf("I-node %u is a multiply referenced directory i-node.\n", ino);
                   2452: }
                   2453: 
                   2454: toolong()
                   2455: {
                   2456:        printf("Name too long.\n");
                   2457:        pname("\0");
                   2458:        abort();
                   2459: }
                   2460: 
                   2461:        
                   2462: @
                   2463: 
                   2464: 
                   2465: 1.1
                   2466: log
                   2467: @Initial revision
                   2468: @
                   2469: text
                   2470: @d102 3
                   2471: d110 3
                   2472: d114 2
                   2473: a115 2
                   2474:        numfiles += 2;
                   2475:        length -= 2*DSIZE;              /* for the . & .. entries */
                   2476: d127 1
                   2477: @
                   2478: r->d_entry.d_ino) {
                   2479:                iffsck/RCS/phase3.c,v   444      3      3       12752  5050254731   7207 head     1.2;
                   2480: branch   ;
                   2481: access   ;
                   2482: symbols  ;
                   2483: locks    bin:1.2;
                   2484: comment  @ * @;
                   2485: 
                   2486: 
                   2487: 1.2
                   2488: date     91.08.08.09.48.33;  author bin;  state Exp;
                   2489: branches ;
                   2490: next     1.1;
                   2491: 
                   2492: 1.1
                   2493: date     91.02.05.16.37.54;  author bin;  state Exp;
                   2494: branches ;
                   2495: next     ;
                   2496: 
                   2497: 
                   2498: desc
                   2499: @prov by epstein (post 310)
                   2500: @
                   2501: 
                   2502: 
                   2503: 1.2
                   2504: log
                   2505: @updated by epstein to properly handle directory allocations.
                   2506: @
                   2507: text
                   2508: @/*
                   2509:  *     phase 3 of fsck - Check Connectivity
                   2510:  */
                   2511: 
                   2512: #include "fsck.h"
                   2513: 
                   2514: char *lostname = "lost+found";
                   2515: 
                   2516: phase3()
                   2517: {
                   2518:        ino_t i;
                   2519: 
                   2520:        if (!qflag)
                   2521:                printf("Phase 3 : Check Connectivity\n");
                   2522:        for (i=FIRSTIN; i<=ninodes; i++) 
                   2523:                if ( ((flags(i)&MODEMASK) == IDIR) &&
                   2524:                     (linkctr(i) == 0) ) {
                   2525:                        orflags(i, UNREFDIR);
                   2526:                        markchildren(i);
                   2527:                }
                   2528: 
                   2529:        for (i=FIRSTIN; i<ninodes; i++)
                   2530:                if ( (flags(i)&(UNREFDIR|CHILDDIR)) == UNREFDIR )
                   2531:                        unrefdir(i);
                   2532: }
                   2533: 
                   2534: markchildren(ino)
                   2535: ino_t ino;
                   2536: {
                   2537:        struct dinode *dip;
                   2538:        struct direct *element;
                   2539:        daddr_t addrs[NADDR];
                   2540:        ino_t inumber;
                   2541:        fsize_t length;
                   2542: 
                   2543:        if ( badblks(ino) )
                   2544:                return;
                   2545:        dip = ptrino(ino, databuf);
                   2546:        if ( (length=dip->di_size) <= 0 )
                   2547:                return;
                   2548:        l3tol(addrs, dip->di_addr, NADDR);
                   2549:        cdbn = 0;
                   2550:        nextblock(addrs);
                   2551:        element = (struct direct *) databuf;
                   2552:        element += 2;           /* skip over . and .. entries */
                   2553:        if ( (length-=2*DSIZE) <= 0 )
                   2554:                return;
                   2555: 
                   2556:        while ( length >= DSIZE ) {
                   2557:                while ( (element<&databuf[BSIZE]) && (length>=DSIZE) ) {
                   2558:                        if ( ((inumber=element->d_ino) != 0) &&
                   2559:                             ((flags(inumber)&MODEMASK)==IDIR) &&
                   2560:                             (inumber!=ino) )
                   2561:                                orflags(inumber, CHILDDIR);
                   2562:                        element++;
                   2563:                        length -= DSIZE;
                   2564:                }
                   2565:                nextblock(addrs);
                   2566:                element = (struct direct *) databuf;
                   2567:        }
                   2568: }
                   2569: 
                   2570: char *reconnect = "(Reconnect)";
                   2571: 
                   2572: unrefdir(ino)
                   2573: ino_t ino;
                   2574: {
                   2575:        printf("Unref Dir\n");
                   2576:        if( (pinfo(ino) == 0) || (daction == NO) || (mounted == TRUE) ) {
                   2577:                if ( action(reconnect) == FALSE )
                   2578:                        return;
                   2579:        } else 
                   2580:                printf("%s FORCED\n", reconnect);
                   2581: 
                   2582:        connect(ino, IDIR);
                   2583: }
                   2584: 
                   2585: #define CONNECT                1
                   2586: #define NOCONNECT      0
                   2587: 
                   2588: connect(ino, type)
                   2589: ino_t ino;
                   2590: int type;
                   2591: {
                   2592:        ino_t lostino;
                   2593:        struct dinode *dip;
                   2594:        daddr_t addrs[NADDR];
                   2595:        fsize_t length;
                   2596:        struct direct *element;
                   2597:        int chgino = FALSE;
                   2598: 
                   2599:        if ( ((lostino=lostfound()) == NUL) ||
                   2600:                 ((flags(lostino)&MODEMASK) != IDIR) ||
                   2601:                        ( badblks(lostino) ) ) {
                   2602:                nolost();
                   2603:                if (type==IDIR)
                   2604:                        traverse(NOCONNECT, ino, lostino);
                   2605:                return(FAILURE);
                   2606:        }
                   2607: 
                   2608:        dip = ptrino(lostino, buf2);
                   2609:        l3tol(addrs, dip->di_addr, NADDR);
                   2610:        length = dip->di_size;
                   2611:        cdbn = 0;
                   2612:        while ( length>=DSIZE ) {
                   2613:                nextblock(addrs);
                   2614:                element = (struct direct *) databuf;
                   2615:                while ( element<&databuf[BSIZE] ) {
                   2616:                        length -= DSIZE;
                   2617:                        if ( element->d_ino == 0 ) {
                   2618:                                element->d_ino = ino;
                   2619:                                strncpy(element->d_name, nameit(ino), DIRSIZ);
                   2620:                                if ( fixblock(addrs) == NUL )
                   2621:                                        fixblkerr();
                   2622:                                linkincr(ino);
                   2623:                                numfiles++;
                   2624:                                if ( length<0 ) {
                   2625:                                        dip->di_size -= length;
                   2626:                                        chgino = TRUE;
                   2627:                                }
                   2628:                                if ( (type == IDIR) &&
                   2629:                                     (connected(ino, lostino)==YES) ) {
                   2630:                                        dip->di_nlink++;
                   2631:                                        writeino(lostino, buf2);
                   2632:                                        traverse(CONNECT, ino, lostino);
                   2633:                                } else if (chgino) {
                   2634:                                        writeino(lostino, buf2);
                   2635:                                }
                   2636:                                return(SUCCESS);
                   2637:                        }
                   2638:                        element++;
                   2639:                }
                   2640:        }
                   2641:        
                   2642:        noroom();
                   2643:        if (type == IDIR)
                   2644:                traverse(NOCONNECT, ino, lostino);
                   2645:        return(FAILURE);
                   2646: }
                   2647: 
                   2648: traverse(flag, ino, lostino)
                   2649: int flag;
                   2650: ino_t ino, lostino;
                   2651: {
                   2652:        struct direct dirlost, nothing, newtree;
                   2653: 
                   2654:        dirinit(&dirlost, lostino, lostname);
                   2655:        dirinit(&nothing, 0, "??");
                   2656:        dirinit(&newtree, ino, nameit(ino));
                   2657:        depth = 0;
                   2658:        if (flag == CONNECT) 
                   2659:                path[depth++] = &dirlost;
                   2660:        else
                   2661:                path[depth++] = &nothing;
                   2662: 
                   2663:        path[depth++] = &newtree;
                   2664:        checkpath(ino);
                   2665: }
                   2666: 
                   2667: dirinit(element, ino, name)
                   2668: struct direct *element;
                   2669: ino_t ino;
                   2670: char *name;
                   2671: {
                   2672:        element->d_ino = ino;
                   2673:        strncpy(element->d_name, name, DIRSIZ);
                   2674: }
                   2675: 
                   2676: connected(ino, lostino)
                   2677: ino_t ino;             /* inumber just reconnected       */
                   2678: ino_t lostino;         /* inumber of lostfound directory */
                   2679: {
                   2680:        struct dinode *dip;
                   2681:        daddr_t addrs[NADDR];
                   2682:        fsize_t length;
                   2683:        struct direct *element;
                   2684: 
                   2685:        if ( badblks(ino) ) {
                   2686:                badconnect(ino);
                   2687:                return(NO);
                   2688:        }
                   2689:        dip = ptrino(ino, databuf);
                   2690:        l3tol(addrs, dip->di_addr, NADDR);
                   2691:        length = dip->di_size;
                   2692:        cdbn = 0;
                   2693:        while ( length >= DSIZE ) {
                   2694:                nextblock(addrs);
                   2695:                element = (struct direct *) databuf;
                   2696:                while ( (element<&databuf[BSIZE]) && (length>=DSIZE) ) {
                   2697:                        if ( strcmp(element->d_name, "..") == 0 ) {
                   2698:                                printf("Dir i-number = %u connected.  ", ino);
                   2699:                                printf("Parent was i-number = %u.\n",
                   2700:                                                        element->d_ino);
                   2701:                                element->d_ino = lostino;
                   2702:                                if ( fixblock(addrs) == NUL )
                   2703:                                        fixblkerr();
                   2704:                                return(YES);
                   2705:                        }
                   2706:                        length -= DSIZE;
                   2707:                        element++;
                   2708:                }
                   2709:        }
                   2710:        noparent(ino);
                   2711:        return(NO);
                   2712: }
                   2713: 
                   2714: badconnect(ino)
                   2715: ino_t ino;
                   2716: {
                   2717:        printf("Dir i-number = %u connected.  It has bad/dup blocks.\n", ino);
                   2718: }
                   2719: 
                   2720: noparent(ino)
                   2721: ino_t ino;
                   2722: {
                   2723:        printf("Dir i-number = %u connected.  It has no .. entry.\n", ino);
                   2724: }
                   2725: 
                   2726: ino_t
                   2727: lostfound()
                   2728: {
                   2729:        static daddr_t addrs[NADDR];
                   2730:        struct dinode *dip;
                   2731:        struct direct *element;
                   2732:        fsize_t length;
                   2733: 
                   2734:        dip = ptrino(ROOTIN, databuf);
                   2735:        l3tol(addrs, dip->di_addr, NADDR);
                   2736:        length = dip->di_size;
                   2737:        cdbn = 0;
                   2738:        while ( length>=DSIZE ) {
                   2739:                nextblock(addrs);
                   2740:                element = (struct direct *) databuf;
                   2741:                while ( (element<&databuf[BSIZE]) && (length>=DSIZE) ) {
                   2742:                        if ( strcmp(element->d_name, lostname) == 0 ) 
                   2743:                                return(element->d_ino);
                   2744:                        length -= DSIZE;
                   2745:                        element++;
                   2746:                }
                   2747:        }
                   2748: 
                   2749:        return(NUL);
                   2750: }
                   2751: 
                   2752: nolost()
                   2753: {
                   2754:        printf("Sorry.  No %s directory.\n", lostname);
                   2755: 
                   2756: }
                   2757: 
                   2758: noroom()
                   2759: {
                   2760:        printf("Sorry.  No space in %s directory.\n", lostname);
                   2761: }
                   2762: 
                   2763: char namebuf[DIRSIZ];
                   2764: 
                   2765: char *
                   2766: nameit(ino)
                   2767: register ino_t ino;
                   2768: {
                   2769:        register int i = DIRSIZ-1;
                   2770: 
                   2771:        namebuf[i] = '\0';
                   2772:        while ( (ino != 0) && (i>0) ) {
                   2773:                namebuf[--i] = '0' + ino%10;
                   2774:                ino = ino/10;
                   2775:        }
                   2776:        return(&namebuf[i]);
                   2777: }
                   2778: @
                   2779: 
                   2780: 
                   2781: 1.1
                   2782: log
                   2783: @Initial revision
                   2784: @
                   2785: text
                   2786: @d109 1
                   2787: a130 1
                   2788:                        length -= DSIZE;
                   2789: @
                   2790: eturn(element->d_ino);fsck/RCS/phase4.c,v   444      3      3       12033  4771205260   7202 head     1.2;
                   2791: access   ;
                   2792: symbols  ;
                   2793: locks    bin:1.2;
                   2794: comment  @ * @;
                   2795: 
                   2796: 
                   2797: 1.2
                   2798: date     91.03.18.18.44.48;  author bin;  state Exp;
                   2799: branches ;
                   2800: next   1.1;
                   2801: 
                   2802: 1.1
                   2803: date     91.02.05.16.38.17;  author bin;  state Exp;
                   2804: branches ;
                   2805: next   ;
                   2806: 
                   2807: 
                   2808: desc
                   2809: @prov by epstein (post 310)
                   2810: @
                   2811: 
                   2812: 
                   2813: 1.2
                   2814: log
                   2815: @update provided by epstein
                   2816: @
                   2817: text
                   2818: @/*
                   2819:  *     phase 4 of fsck - Check Reference Counts
                   2820:  */
                   2821: 
                   2822: #include "fsck.h"
                   2823: 
                   2824: extern char *reconnect;
                   2825: fsize_t        lostsize;
                   2826: 
                   2827: phase4()
                   2828: {
                   2829:        ino_t i;
                   2830:        short actlink;
                   2831: 
                   2832:        if (!qflag)
                   2833:                printf("Phase 4 : Check Reference Counts\n");
                   2834:        for (i=FIRSTIN; i<=ninodes; i++) {
                   2835:                if ( badblks(i) )
                   2836:                        if ( bddp(i) == YES )
                   2837:                                continue;       /* inode zeroed */
                   2838: 
                   2839:                if ( (linkctr(i) == 0) &&
                   2840:                     ((flags(i)&MODEMASK) != IDIR) &&
                   2841:                     ((flags(i)&ALLOCMASK) != UNALLOC) )
                   2842:                        if ( unreflink(i) == YES )
                   2843:                                continue;       /* inode zeroed */
                   2844: 
                   2845:                if ( (linkctr(i) == 0) &&
                   2846:                     ((flags(i)&ALLOCMASK) != UNALLOC)  )
                   2847:                        if ( unrefclr(i) == YES )
                   2848:                                continue;       /* inode zeroed */
                   2849: 
                   2850:                if ( (actlink=getlink(i)) == (-1) ) {
                   2851:                        i += INOPB-1;
                   2852:                        continue;               /* bad inode block */
                   2853:                }
                   2854: 
                   2855:                if ( actlink != linkctr(i) )
                   2856:                        linkprob(i, actlink);   /* fix link count */
                   2857:        }
                   2858: 
                   2859:        freeilist();
                   2860: }
                   2861: 
                   2862: short
                   2863: getlink(inum)
                   2864: register ino_t inum;
                   2865: {
                   2866:        register unsigned offset;
                   2867:        static ibuf[BSIZE];
                   2868:        register struct dinode *dip;
                   2869:        register daddr_t bn;
                   2870: 
                   2871:        offset = iblocko(inum);
                   2872:        if ( (offset==0) || (inum==FIRSTIN) ) {
                   2873:                bn = iblockn(inum);
                   2874:                if ( (testblock(bn)) && (inum!=FIRSTIN) ) 
                   2875:                        return(-1);
                   2876:                bread(bn, ibuf);
                   2877:        }
                   2878:        dip = ((struct dinode *) ibuf) + offset;
                   2879:        candino(dip);
                   2880:        return(dip->di_nlink);
                   2881: }
                   2882: 
                   2883: char *clearit = "(Clear i-node)";
                   2884: 
                   2885: unreflink(ino)
                   2886: ino_t ino;
                   2887: {
                   2888:        fsize_t size;
                   2889: 
                   2890:        if ( (qflag == TRUE) && ((flags(ino)&MODEMASK) == IPIPE) ) {
                   2891:                doclear(ino);
                   2892:                return(YES);
                   2893:        }
                   2894: 
                   2895:        printf("Unref %s\n", typename(ino));
                   2896:        size = pinfo(ino);
                   2897:        if ( (daction != NO) && (size == 0) && (mounted == FALSE) 
                   2898:                && ((flags(ino)&MODEMASK) == IREG) ) {
                   2899:                printf("%s [Forced - Yes]\n", clearit);
                   2900:                doclear(ino);
                   2901:                return(YES);
                   2902:        }
                   2903:        if ( action(reconnect) == TRUE )
                   2904:                if( connect(ino, IREG) == FAILURE )  /* connect back in the */
                   2905:                        return(askclear(ino));       /* non dir inode       */
                   2906:                        
                   2907:        return(NO);
                   2908: }
                   2909: 
                   2910: askclear(ino)
                   2911: ino_t ino;
                   2912: {
                   2913:        if ( action(clearit) == TRUE ) {
                   2914:                doclear(ino);
                   2915:                return(YES);
                   2916:        }
                   2917:        return(NO);
                   2918: }
                   2919: 
                   2920: doclear(ino)
                   2921: ino_t ino;
                   2922: {
                   2923:        struct dinode *dip;
                   2924: 
                   2925:        dip = ptrino(ino, databuf);
                   2926:        zeroinode(dip);
                   2927:        writeino(ino, databuf);
                   2928:        setflags(ino, UNALLOC);
                   2929:        setlinkctr(ino, 0);
                   2930: }
                   2931: 
                   2932: char *adjust = "(Adjust)";
                   2933: 
                   2934: linkprob(ino, actlink)
                   2935: ino_t ino;
                   2936: short actlink;
                   2937: {
                   2938:        printf("Link Count discrepancy in %s\n", typename(ino));
                   2939:        pinfo(ino);
                   2940:        printf("Count = %u, should be %u ", actlink, linkctr(ino));
                   2941:        if ( action(adjust) == TRUE )
                   2942:                chglink(ino);
                   2943: }
                   2944: 
                   2945: chglink(ino)
                   2946: ino_t ino;
                   2947: {
                   2948:        struct dinode *dip;
                   2949: 
                   2950:        dip = ptrino(ino, databuf);
                   2951:        dip->di_nlink = linkctr(ino);
                   2952:        writeino(ino, databuf);
                   2953: }
                   2954:        
                   2955: unrefclr(ino)
                   2956: ino_t ino;
                   2957: {
                   2958:        printf("Unref %s\n", typename(ino));
                   2959:        pinfo(ino);
                   2960:        return(askclear(ino));
                   2961: }
                   2962: 
                   2963: bddp(ino)
                   2964: ino_t ino;
                   2965: {
                   2966:        printf("Bad/Dup blocks in %s\n", typename(ino));
                   2967:        pinfo(ino);
                   2968:        return(askclear(ino));
                   2969: }
                   2970: 
                   2971: char *fixit = "(FIX)";
                   2972: 
                   2973: freeilist()
                   2974: {
                   2975:        ino_t i, count=0;
                   2976:        daddr_t bn;
                   2977: 
                   2978:        for (i=FIRSTIN; i<=ninodes; i++)
                   2979:                if ( (flags(i)&ALLOCMASK) == UNALLOC )
                   2980:                        count++;
                   2981: 
                   2982:        for (bn=INODEI+1; bn<isize; bn++)       /* block # INODEI can't */
                   2983:                if ( testblock(bn) )            /* be bad since ROOTIN  */
                   2984:                        count -= INOPB;         /* is in it, otherwise  */
                   2985:                                                /* big time bad news.   */
                   2986:        if ( sbp->s_tinode != count ) 
                   2987:                if ( (qflag==FALSE) && (daction!=NO) ) {
                   2988:                        printf("Free i-node count wrong in superblock.  ");
                   2989:                        if ( action(fixit) == TRUE ) {
                   2990:                                sbp->s_tinode = count;
                   2991:                                sbpfix = TRUE;
                   2992:                        }
                   2993:                } else {
                   2994:                        sbp->s_tinode = count;
                   2995:                        sbpfix = TRUE;
                   2996:                }
                   2997: 
                   2998:        if ( (daction!=NO) &&
                   2999:             ( (sflag==TRUE) || (sbpfix==TRUE) || (badilist()==BAD) ) )
                   3000:                rebuild();
                   3001: 
                   3002: }
                   3003: 
                   3004: badilist()
                   3005: {
                   3006:        ino_t i, inum;
                   3007:        unsigned numfree;
                   3008:        daddr_t bn;
                   3009: 
                   3010:        if ( (numfree=(unsigned) sbp->s_ninode) > NICINOD )
                   3011:                return(BAD);
                   3012:        for (i=0; i<numfree; i++) {
                   3013:                inum = sbp->s_inode[i];
                   3014:                bn = iblockn(inum);
                   3015:                if ( (testblock(bn)) && (bn!=INODEI) )
                   3016:                        return(BAD);
                   3017:                if ( (inum < FIRSTIN) || (inum > ninodes) )
                   3018:                        return(BAD);
                   3019:                if ( (flags(inum)&ALLOCMASK) != UNALLOC ) 
                   3020:                        return(BAD);
                   3021:                if ( flags(inum)&IFREELIST )
                   3022:                        return(BAD);            /* dup in ifree list */
                   3023:                orflags(inum, IFREELIST);
                   3024:        }
                   3025:        return(GOOD);
                   3026: }
                   3027: 
                   3028: rebuild()
                   3029: {
                   3030:        daddr_t bn;
                   3031:        ino_t i;
                   3032:        int index;
                   3033: 
                   3034:        sbpfix = TRUE;
                   3035:        for (i=FIRSTIN, index=0; (i<=ninodes) && (index<NICINOD); i++) {
                   3036:                if ( (flags(i)&ALLOCMASK) == UNALLOC ) {
                   3037:                        bn = iblockn(i);
                   3038:                        if ( (!testblock(bn)) || (bn==INODEI) )
                   3039:                                index++;
                   3040:                }
                   3041:        }
                   3042:        sbp->s_ninode = index;
                   3043:        for (i=FIRSTIN; (i<=ninodes) && (index>0); i++) {
                   3044:                if ( (flags(i)&ALLOCMASK) == UNALLOC ) {
                   3045:                        bn = iblockn(i);
                   3046:                        if ( (!testblock(bn)) || (bn==INODEI) )
                   3047:                                sbp->s_inode[--index] = i;
                   3048:                }
                   3049:        }
                   3050:        printf("Free i-node list in superblock rebuilt.\n");
                   3051: }
                   3052: @
                   3053: 
                   3054: 
                   3055: 1.1
                   3056: log
                   3057: @Initial revision
                   3058: @
                   3059: text
                   3060: @a16 1
                   3061:        lostsize = 0;
                   3062: a108 1
                   3063:        lostsize += dip->di_size;
                   3064: d181 2
                   3065: a182 1
                   3066:        if ( (daction!=NO) && ((sbpfix==TRUE) || (badilist()==BAD)) ) 
                   3067: d214 2
                   3068: a215 2
                   3069:        ino_t i = FIRSTIN;
                   3070:        int index = 0;
                   3071: d218 1
                   3072: a218 1
                   3073:        while ( (i<=ninodes) && (index<NICINOD) ) {
                   3074: d222 1
                   3075: a222 1
                   3076:                                sbp->s_inode[index++] = i;
                   3077: a223 1
                   3078:                i++;
                   3079: a224 1
                   3080: 
                   3081: d226 7
                   3082: @
                   3083:                bn = iblockn(i);
                   3084:                        if ( (!testblock(bn)) || (bn==INODEI) )
                   3085:                                sbp->s_inode[--index] = i;
                   3086:                }
                   3087:        }
                   3088:        printf("Free i-node list in superblock rebuilt.\n");
                   3089: }
                   3090: @
                   3091: 
                   3092: 
                   3093: 1.1
                   3094: log
                   3095: @Initial revision
                   3096: @
                   3097: text
                   3098: @a16 1
                   3099:        lostsize = 0;
                   3100: a108 1
                   3101:        lostsize += dip->di_size;
                   3102: d181 2
                   3103: a182 1
                   3104:        if ( (daction!=NO) && ((sbpfix==TRUE) || (badilist()==BAD)) ) 
                   3105: d214 2
                   3106: a215 2
                   3107:        ino_t i = FIRSTIN;
                   3108:        int index = 0;
                   3109: d218 1
                   3110: a218 1
                   3111:        while ( (i<=ninodes) && (index<NICINOD) ) {
                   3112: d222 1
                   3113: a222 1
                   3114:                                sbp->s_inode[index++] = i;
                   3115: a223fsck/RCS/phase5.c,v   444      3      3        7463  4771205275   7204 head     1.2;
                   3116: access   ;
                   3117: symbols  ;
                   3118: locks    bin:1.2;
                   3119: comment  @ * @;
                   3120: 
                   3121: 
                   3122: 1.2
                   3123: date     91.03.18.18.45.05;  author bin;  state Exp;
                   3124: branches ;
                   3125: next   1.1;
                   3126: 
                   3127: 1.1
                   3128: date     91.02.05.16.38.33;  author bin;  state Exp;
                   3129: branches ;
                   3130: next   ;
                   3131: 
                   3132: 
                   3133: desc
                   3134: @prov by epstein (phase5.c)
                   3135: @
                   3136: 
                   3137: 
                   3138: 1.2
                   3139: log
                   3140: @update provided by epstein
                   3141: @
                   3142: text
                   3143: @/*
                   3144:  *     phase 5 of fsck - Check Free List
                   3145:  */
                   3146: 
                   3147: #include "fsck.h"
                   3148: 
                   3149: daddr_t        badcnt;                 /* Number of bad blocks in free list */
                   3150: daddr_t dupcnt;                        /* Number of dup blocks in free list */
                   3151: int    badflag;                /* Bad free list flag */
                   3152: int    fixerup;                /* Flag to salvage free list */
                   3153: 
                   3154: phase5()
                   3155: {
                   3156:        struct fblk *fbp;
                   3157:        unsigned size;
                   3158:        
                   3159:        if (!qflag)
                   3160:                printf("Phase 5 : Check Free List\n");
                   3161:        fbp = (struct fblk *) &sbp->s_nfree;
                   3162:        size = (unsigned) ((fsize+NBPC-1)/NBPC) * sizeof(char);
                   3163:        copyV(size);
                   3164:        badcnt = dupcnt = 0;
                   3165:        badflag = FALSE;
                   3166:        freetrav(fbp);
                   3167:        fixerup = FALSE;
                   3168:        if (badflag || sflag) 
                   3169:                asksalvage();
                   3170: }
                   3171: 
                   3172: 
                   3173: #define        IGNORE  3               /* Return Possibilities from chk() */
                   3174: #define        ABORT   4               /* as well as perhaps GOOD and BAD */
                   3175: 
                   3176: freetrav(fbp)
                   3177: struct fblk *fbp;
                   3178: {
                   3179:        daddr_t total=0;
                   3180:        int i, flag;
                   3181: 
                   3182:        while ( fbp->df_nfree != 0 ) {
                   3183:                if ( (unsigned) fbp->df_nfree > NICFREE ) {
                   3184:                        badflag = TRUE;
                   3185:                        printf("Bad freeblock count.\n");
                   3186:                        break;
                   3187:                }
                   3188:                for (i=1; i<fbp->df_nfree; i++) {
                   3189:                        if ( (flag=chk(fbp->df_free[i])) == GOOD ) {
                   3190:                                total++;
                   3191:                                continue;
                   3192:                        }
                   3193:                        if (flag == BAD)
                   3194:                                continue;
                   3195:                        break;          /* break for IGNORE or ABORT    */
                   3196:                }
                   3197:                if ( (flag == IGNORE) || (flag == ABORT) )
                   3198:                        break;
                   3199:                if ( chk(fbp->df_free[0]) != GOOD )
                   3200:                        break;
                   3201:                total++;
                   3202:                bread(fbp->df_free[0], databuf);
                   3203:                fbp = (struct fblk *) databuf;
                   3204:                if ( !canfblk(fbp) ) {
                   3205:                        badflag = TRUE;
                   3206:                        printf("Bad freeblock count.\n");
                   3207:                        break;
                   3208:                }
                   3209:        }
                   3210: 
                   3211: #if 0
                   3212:        printf("Total traversed free blocks     = %U\n", total);         
                   3213:        printf("Total free blocks by Superblock = %U\n", sbp->s_tfree);  
                   3214:        printf("Running total free blocks       = %U\n", totfree);       
                   3215: #endif
                   3216: 
                   3217:        if ( flag == ABORT ) {          /* To Terminate fsck on this    */
                   3218:                badflag = FALSE;        /* File System, because of      */
                   3219:                return;                 /* excessive dup or bad blocks  */
                   3220:        }
                   3221: 
                   3222:        if ( sbp->s_tfree != totfree )
                   3223:                if ( (qflag==FALSE) && (daction!=NO) ) {
                   3224:                        printf("Free Block count wrong in superblock.  ");
                   3225:                        if ( action(fixit) == TRUE ) {
                   3226:                                sbp->s_tfree = totfree;
                   3227:                                sbpfix = TRUE;
                   3228:                        }
                   3229:                } else {
                   3230:                        sbp->s_tfree = totfree;
                   3231:                        sbpfix = TRUE;
                   3232:                }
                   3233: 
                   3234:        report("%U Bad Block%s in Free List\n", badcnt);
                   3235:        report("%U Dup Block%s in Free List\n", dupcnt);
                   3236:        report("%U Block%s missing\n", totfree - total);
                   3237: 
                   3238: }
                   3239: 
                   3240: report(message, num)
                   3241: char *message;
                   3242: daddr_t num;
                   3243: {
                   3244:        if ( num != 0 ) {
                   3245:                printf(message, num, ( (num>1) ? "s" : "" ) );
                   3246:                badflag = TRUE;
                   3247:        }
                   3248: }
                   3249: 
                   3250: chk(bn)
                   3251: register daddr_t bn;
                   3252: {
                   3253:        if ( (bn<isize) || (bn>=fsize) ) {
                   3254:                badflag = TRUE;
                   3255:                if (++badcnt > MAXBADFREE) 
                   3256:                        return( stopit("bad") );
                   3257:                return(BAD);
                   3258:        }
                   3259: 
                   3260:        if ( testdup(bn) ) {
                   3261:                badflag = TRUE;
                   3262:                if (++dupcnt > MAXDUPFREE)
                   3263:                        return( stopit("dup") );
                   3264:                return(BAD);
                   3265:        } else {
                   3266:                markdup(bn);
                   3267:                return(GOOD);
                   3268:        }
                   3269: }
                   3270:                        
                   3271: stopit(type)
                   3272: char *type;
                   3273: {
                   3274:        printf("Excessive %s blocks in free list ", type);
                   3275:        if ( query("(Continue)") == YES )
                   3276:                return(IGNORE);
                   3277:        else
                   3278:                return(ABORT);
                   3279: }
                   3280:                
                   3281:                
                   3282: canfblk(fbp)
                   3283: register struct fblk *fbp;
                   3284: {
                   3285:        register short i;
                   3286: 
                   3287:        canshort(fbp->df_nfree);
                   3288:        if ( (unsigned) fbp->df_nfree > NICFREE )
                   3289:                return(FALSE);
                   3290: 
                   3291:        for (i=0; i<fbp->df_nfree; i++)
                   3292:                candaddr(fbp->df_free[i]);
                   3293:        return(TRUE);
                   3294: }
                   3295: 
                   3296: asksalvage()
                   3297: {
                   3298:        if ( (daction!=NO) && (qflag || sflag) ) {
                   3299:                fixerup = TRUE;
                   3300:                return;
                   3301:        }
                   3302:        if ( action("Bad Free List (SALVAGE)") )
                   3303:                fixerup = TRUE;
                   3304: }
                   3305: @
                   3306: 
                   3307: 
                   3308: 1.1
                   3309: log
                   3310: @Initial revision
                   3311: @
                   3312: text
                   3313: @d26 1
                   3314: a26 1
                   3315:        if (badflag) 
                   3316: d62 5
                   3317: a66 1
                   3318:                canfblk(fbp);
                   3319: d69 5
                   3320: a73 3
                   3321: /*     printf("Total traversed free blocks     = %U\n", total);         */
                   3322: /*     printf("Total free blocks by Superblock = %U\n", sbp->s_tfree);  */
                   3323: /*     printf("Running total free blocks       = %U\n", totfree);       */
                   3324: d146 3
                   3325: d151 2
                   3326: a153 2
                   3327: }
                   3328: 
                   3329: d156 1
                   3330: a156 1
                   3331:        if ( qflag && (daction!=NO) ) {
                   3332: @
                   3333: ( (daction!=NO) && (qflag || sflag) ) {
                   3334:                fixerup = TRUE;
                   3335:                return;
                   3336:        }
                   3337:        if ( action("Bad Free List (SALVAGE)") )
                   3338:                fixerup = TRUE;
                   3339: }
                   3340: @
                   3341: 
                   3342: 
                   3343: 1.1
                   3344: log
                   3345: @Initial revision
                   3346: @
                   3347: text
                   3348: @d26 1
                   3349: a26 1
                   3350:        if (badflag) 
                   3351: d62 5
                   3352: afsck/RCS/phase6.c,v   444      3      3        5736  4771205312   7176 head     1.2;
                   3353: access   ;
                   3354: symbols  ;
                   3355: locks    bin:1.2;
                   3356: comment  @ * @;
                   3357: 
                   3358: 
                   3359: 1.2
                   3360: date     91.03.18.18.45.18;  author bin;  state Exp;
                   3361: branches ;
                   3362: next   1.1;
                   3363: 
                   3364: 1.1
                   3365: date     91.02.05.16.38.52;  author bin;  state Exp;
                   3366: branches ;
                   3367: next   ;
                   3368: 
                   3369: 
                   3370: desc
                   3371: @prov by epstein (post 310)
                   3372: @
                   3373: 
                   3374: 
                   3375: 1.2
                   3376: log
                   3377: @update provided by epstein.
                   3378: @
                   3379: text
                   3380: @/*
                   3381:  *     phase 6 of fsck - Salvage Free List
                   3382:  */
                   3383: 
                   3384: #include "fsck.h"
                   3385: 
                   3386: static unsigned char *maptab;  /* table of interleave offsets  */
                   3387: static daddr_t mapbot;         /* minimum block number to interleave map */
                   3388: static daddr_t maptop;         /* maximum block number to interleave map */
                   3389: static short   m,n;            /* interleave factors   */
                   3390: #define        DEF_N   1               /* default values       */
                   3391: #define        DEF_M   1               
                   3392: daddr_t        freeblks;               /* number free blocks left to write out */
                   3393: daddr_t        blknm;                  /* current block number we are working with */
                   3394: struct fblk *fblkp;            /* pointer to free block list */
                   3395: daddr_t        *dp;                    /* pointer to block entry in free list block */
                   3396: 
                   3397: phase6()
                   3398: {
                   3399:        if (!fixerup) {
                   3400:                return;
                   3401:        }
                   3402: 
                   3403:        if (!qflag)
                   3404:                printf("Phase 6 : Salvage Free List\n");
                   3405:        if ( maketable() == BAD )
                   3406:                return;
                   3407:        writefree();
                   3408:        free(maptab);
                   3409: }
                   3410: 
                   3411: maketable()
                   3412: {
                   3413:        register int i;
                   3414:        register int ratio;
                   3415: 
                   3416:        m = sbp->s_m;
                   3417:        n = sbp->s_n;
                   3418: 
                   3419:        if ( (n > MAXINTN) || (m > n) || (n%m != 0) ) {
                   3420:                printf("Invalid interleave factors in superblock.\n");
                   3421:                printf("Default free-block list spacing assumed.\n");
                   3422:                sbp->s_n = n = DEF_N;
                   3423:                sbp->s_m = m = DEF_M;
                   3424:        }
                   3425: 
                   3426:        if ( (maptab = malloc(n)) == NULL ) {
                   3427:                printf("Can't malloc space for interleave table.\n");
                   3428:                printf("Free-block list is not rebuilt.\n");
                   3429:                return(BAD);
                   3430:        }
                   3431: 
                   3432:        mapbot = (isize + n - 1)/n*n;
                   3433:        maptop = fsize/n*n;
                   3434:        ratio = n/m;
                   3435:        for (i=0; i<n; i++)
                   3436:                maptab[i] = (i/ratio) + (i%ratio)*m;
                   3437: 
                   3438:        return(GOOD);
                   3439: }
                   3440: 
                   3441: writefree()
                   3442: {
                   3443:        register daddr_t bn;
                   3444:        daddr_t blk, bmap();
                   3445:        short num;
                   3446: 
                   3447:        sbpfix = TRUE;
                   3448:        freeblks = totfree;
                   3449:        blknm = SUPERI;
                   3450:        fblkp = (struct fblk *) &sbp->s_nfree;
                   3451:        fblkp->df_nfree = num = (freeblks < NICFREE) ? freeblks : NICFREE;
                   3452:        freeblks -= num;
                   3453:        dp = &fblkp->df_free[num];
                   3454:        for (bn=isize; bn<fsize; bn++) {
                   3455:                blk = bmap(bn);
                   3456:                if ( !testblock(blk) ) 
                   3457:                        if ( addfree(blk) == STOP )
                   3458:                                break;
                   3459:        }
                   3460: }
                   3461: 
                   3462: addfree(bn)
                   3463: daddr_t bn;
                   3464: {
                   3465:        short num;
                   3466: 
                   3467:        *--dp = bn;
                   3468:        if (dp > &fblkp->df_free[0])
                   3469:                return(OK);
                   3470: 
                   3471:        if ( blknm != SUPERI ) {
                   3472:                canwfblk(fblkp);
                   3473:                bwrite(blknm, databuf);
                   3474:        }
                   3475: 
                   3476:        bclear(databuf, BSIZE);
                   3477:        if (freeblks == 0) {
                   3478:                bwrite(bn, databuf);
                   3479:                return(STOP);
                   3480:        }
                   3481:        blknm = bn;
                   3482:        fblkp = (struct fblk *) databuf;
                   3483:        fblkp->df_nfree = num = (freeblks < NICFREE) ? freeblks : NICFREE;
                   3484:        freeblks -= num;
                   3485:        dp = &fblkp->df_free[num];
                   3486:        return(OK);
                   3487: }
                   3488: 
                   3489: daddr_t
                   3490: bmap(blk)
                   3491: register daddr_t blk;
                   3492: {
                   3493:        short i;
                   3494: 
                   3495:        if ( (blk>=mapbot) && (blk<maptop) ) {
                   3496:                i = blk%n;
                   3497:                blk -= i;
                   3498:                blk += maptab[i];
                   3499:        }
                   3500:        return(blk);
                   3501: }
                   3502: 
                   3503: canwfblk(fbp)
                   3504: register struct fblk *fbp;
                   3505: {
                   3506:        register short i;
                   3507: 
                   3508:        for (i=0; i<fbp->df_nfree; i++)
                   3509:                candaddr(fbp->df_free[i]);
                   3510:        canshort(fbp->df_nfree);
                   3511: }
                   3512: @
                   3513: 
                   3514: 
                   3515: 1.1
                   3516: log
                   3517: @Initial revision
                   3518: @
                   3519: text
                   3520: @d7 1
                   3521: a7 1
                   3522: static char    *maptab;        /* table of interleave offsets  */
                   3523: d114 1
                   3524: a114 1
                   3525:        int i;
                   3526: d117 3
                   3527: a119 2
                   3528:                i = ((unsigned)blk)%n;
                   3529:                blk += maptab[i] - i;
                   3530: @
                   3531: rn(OK);
                   3532: }
                   3533: 
                   3534: daddr_t
                   3535: bmap(blk)
                   3536: regisfsck/RCS/printf.c,v   444      3      3        7620  4753557667   7333 head     1.1;
                   3537: access   ;
                   3538: symbols  ;
                   3539: locks    ;
                   3540: comment  @ * @;
                   3541: 
                   3542: 
                   3543: 1.1
                   3544: date     91.02.05.16.39.10;  author bin;  state Exp;
                   3545: branches ;
                   3546: next   ;
                   3547: 
                   3548: 
                   3549: desc
                   3550: @prov by epstein (post310)
                   3551: @
                   3552: 
                   3553: 
                   3554: 
                   3555: 1.1
                   3556: log
                   3557: @Initial revision
                   3558: @
                   3559: text
                   3560: @/*
                   3561:  * Standard output printf using putchar.
                   3562:  * Non-portable things:
                   3563:  * 1) alignment of arguments is assumed to be completely contiguous.
                   3564:  * 2) the smallest number is assumed to negate to itself.
                   3565:  * 3) All of long, int, char*, and double are assumed to
                   3566:  *    be held in an exact number of ints.
                   3567:  */
                   3568: 
                   3569: #define NULL ((char *)0)
                   3570: #define putchar(c) { char b = c; write(1, &b, 1); }
                   3571: #include <sys/mdata.h>
                   3572: 
                   3573: union  alltypes {
                   3574:        char    c;
                   3575:        int     i;
                   3576:        unsigned u;
                   3577:        long    l;
                   3578:        double  d;
                   3579:        char    *s;
                   3580: };
                   3581: 
                   3582: #define        bump(p,s)       (p+=sizeof(s)/sizeof(int))
                   3583: 
                   3584: char   *printi();
                   3585: char   *printl();
                   3586: 
                   3587: static char    null[] = "{NULL}";
                   3588: 
                   3589: printf(args)
                   3590: union alltypes args;
                   3591: {
                   3592:        xprintf(&args);
                   3593: }
                   3594: xprintf(argp)
                   3595: union alltypes *argp;
                   3596: {
                   3597:        register char *cbp;
                   3598:        int *iap;
                   3599:        register c;
                   3600:        char *s;
                   3601:        char *cbs;
                   3602:        char adj, pad;
                   3603:        int prec;
                   3604:        int fwidth;
                   3605:        int pwidth;
                   3606:        register char *fmt;
                   3607:        union alltypes elem;
                   3608:        char cbuf[64];
                   3609: 
                   3610:        iap = (int *)argp;
                   3611:        fmt = *(char **)iap;
                   3612:        bump(iap, char*);
                   3613:        for (;;) {
                   3614:                while((c = *fmt++) != '%') {
                   3615:                        if(c == '\0') {
                   3616:                                return;
                   3617:                        }
                   3618:                        putchar(c);
                   3619:                }
                   3620:                pad = ' ';
                   3621:                fwidth = -1;
                   3622:                prec = -1;
                   3623:                c = *fmt++;
                   3624:                if (c == '-') {
                   3625:                        adj = 1;
                   3626:                        c = *fmt++;
                   3627:                } else
                   3628:                        adj = 0;
                   3629:                if (c == '0') {
                   3630:                        pad = '0';
                   3631:                        c = *fmt++;
                   3632:                }
                   3633:                if (c == '*') {
                   3634:                        fwidth = *iap++;
                   3635:                        c = *fmt++;
                   3636:                } else
                   3637:                        for (fwidth = 0; c>='0' && c<='9'; c = *fmt++)
                   3638:                                fwidth = fwidth*10 + c-'0';
                   3639:                if (c == '.') {
                   3640:                        c = *fmt++;
                   3641:                        if (c == '*') {
                   3642:                                prec = *iap++;
                   3643:                                c = *fmt++;
                   3644:                        } else
                   3645:                                for (prec=0; c>='0' && c<='9'; c=*fmt++)
                   3646:                                        prec = prec*10 + c-'0';
                   3647:                }
                   3648:                if (c == 'l') {
                   3649:                        c = *fmt++;
                   3650:                        if (c=='d' || c=='o' || c=='u' || c=='x')
                   3651:                                c += 'A' - 'a';
                   3652:                }
                   3653:                cbp = cbs = cbuf;
                   3654:                switch (c) {
                   3655: 
                   3656:                case 'd':
                   3657:                        elem.i = *iap++;
                   3658:                        if (elem.i < 0) {
                   3659:                                elem.i = -elem.i;
                   3660:                                *cbp++ = '-';
                   3661:                        }
                   3662:                        cbp = printi(cbp, elem.i, 10);
                   3663:                        break;
                   3664: 
                   3665:                case 'u':
                   3666:                        cbp = printi(cbp, *iap++, 10);
                   3667:                        break;
                   3668:        
                   3669:                case 'o':
                   3670:                        cbp = printi(cbp, *iap++, 8);
                   3671:                        break;
                   3672: 
                   3673:                case 'x':
                   3674:                        cbp = printi(cbp, *iap++, 16);
                   3675:                        break;
                   3676: 
                   3677:                case 'D':
                   3678:                        elem.l = *(long *)iap;
                   3679:                        bump(iap, long);
                   3680:                        if (elem.l < 0) {
                   3681:                                elem.l = -elem.l;
                   3682:                                *cbp++ = '-';
                   3683:                        }
                   3684:                        cbp = printl(cbp, elem.l, 10);
                   3685:                        break;
                   3686: 
                   3687:                case 'U':
                   3688:                        cbp = printl(cbp, *(long *)iap, 10);
                   3689:                        bump(iap, long);
                   3690:                        break;
                   3691: 
                   3692:                case 'O':
                   3693:                        cbp = printl(cbp, *(long *)iap, 8);
                   3694:                        bump(iap, long);
                   3695:                        break;
                   3696: 
                   3697:                case 'X':
                   3698:                        cbp = printl(cbp, *(long *)iap, 16);
                   3699:                        bump(iap, long);
                   3700:                        break;
                   3701: 
                   3702: 
                   3703:                case 's':
                   3704:                        if ((s = *(char **)iap) == NULL)
                   3705:                                s = null;
                   3706:                        bump(iap, char*);
                   3707:                        /*
                   3708:                         * Do %s specially so it can be longer.
                   3709:                         */
                   3710:                        cbp = cbs = s;
                   3711:                        while (*cbp++ != '\0')
                   3712:                                if (prec>=0 && cbp-s>prec)
                   3713:                                        break;
                   3714:                        cbp--;
                   3715:                        break;
                   3716:        
                   3717:                case 'c':
                   3718:                        elem.c = *iap++;
                   3719:                        *cbp++ = elem.c;
                   3720:                        break;
                   3721:        
                   3722:                case 'r':
                   3723:                        xprintf(*(char ***)iap);
                   3724:                        bump(iap, char**);
                   3725:                        break;
                   3726:        
                   3727:                default:
                   3728:                        putchar(c);
                   3729:                        continue;
                   3730:                }
                   3731:                if ((pwidth = fwidth + cbs-cbp) < 0)
                   3732:                        pwidth = 0;
                   3733:                if (!adj)
                   3734:                        while (pwidth-- != 0)
                   3735:                                putchar(pad);
                   3736:                while (cbs < cbp)
                   3737:                        putchar(*cbs++);
                   3738:                if (adj)
                   3739:                        while (pwidth-- != 0)
                   3740:                                putchar(pad);
                   3741:        }
                   3742: }
                   3743: 
                   3744: static char    digits[] = {
                   3745:        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                   3746:        'A', 'B', 'C', 'D', 'E', 'F'
                   3747: };
                   3748: 
                   3749: /*
                   3750:  * Print an unsigned integer in base b.
                   3751:  */
                   3752: static
                   3753: char *
                   3754: printi(cp, n, b)
                   3755: char *cp;
                   3756: register unsigned n;
                   3757: {
                   3758:        register a;
                   3759:        register char *ep;
                   3760:        char pbuf[10];
                   3761: 
                   3762:        ep = &pbuf[10];
                   3763:        *--ep = 0;
                   3764:        for ( ; a = n/b; n=a)
                   3765:                *--ep = digits[n%b];
                   3766:        *--ep = digits[n];
                   3767:        while (*ep)
                   3768:                *cp++ = *ep++;
                   3769:        return (cp);
                   3770: }
                   3771: 
                   3772: /*
                   3773:  * Print an unsigned long in base b.
                   3774:  */
                   3775: static
                   3776: char *
                   3777: printl(cp, n, b)
                   3778: register char *cp;
                   3779: unsigned long n;
                   3780: register b;
                   3781: {
                   3782:        char pbuf[13];
                   3783:        unsigned long a;
                   3784:        register char *ep;
                   3785: 
                   3786:        ep = &pbuf[13];
                   3787:        *--ep = '\0';
                   3788:        for ( ; (a = n/b) != 0; n = a)
                   3789:                *--ep = digits[n%b];
                   3790:        *--ep = digits[n];
                   3791:        while (*ep)
                   3792:                *cp++ = *ep++;
                   3793:        return (cp);
                   3794: }
                   3795: @
                   3796: egister char *ep;
                   3797:        char pbuf[10];
                   3798: 
                   3799:        ep = &pbuf[10];
                   3800:        *--ep = 0;
                   3801:        for ( ; a = n/b; n=a)
                   3802:                *--ep = digits[n%b];
                   3803:        *fsck/RCS/util.c,v   444      3      3       16442  5045006750   7001 head     1.2;
                   3804: branch   ;
                   3805: access   ;
                   3806: symbols  ;
                   3807: locks    bin:1.2;
                   3808: comment  @ * @;
                   3809: 
                   3810: 
                   3811: 1.2
                   3812: date     91.07.29.07.45.21;  author bin;  state Exp;
                   3813: branches ;
                   3814: next     1.1;
                   3815: 
                   3816: 1.1
                   3817: date     91.02.05.16.39.25;  author bin;  state Exp;
                   3818: branches ;
                   3819: next     ;
                   3820: 
                   3821: 
                   3822: desc
                   3823: @prov by epstein (post 310)
                   3824: @
                   3825: 
                   3826: 
                   3827: 1.2
                   3828: log
                   3829: @Updated by epstein for version 321.
                   3830: @
                   3831: text
                   3832: @/*
                   3833:  *     general utility functions for phases of fsck
                   3834:  */
                   3835: 
                   3836: #include "fsck.h"
                   3837: 
                   3838: struct stat stats;                     /* Used by statit() */
                   3839: 
                   3840: statit(name, probfun)
                   3841: char *name;
                   3842: int (*probfun)();
                   3843: {
                   3844:        
                   3845:        if ( stat(name, &stats) == -1 ) {
                   3846:                bclear(&stats, sizeof(struct stat));
                   3847:                (*probfun)("Can not stat %s", name);
                   3848:        }
                   3849: }
                   3850: 
                   3851: 
                   3852: query(x)
                   3853: {
                   3854:        while(1) {
                   3855:                printf("%r [yes/no]: ", &x);
                   3856:        
                   3857:                switch (daction) {
                   3858:                case YES:
                   3859:                        printf("[default - YES]\n");
                   3860:                        return(YES);
                   3861:                        break;
                   3862:                case NO:
                   3863:                        printf("[default - NO]\n");
                   3864:                        return(NO);
                   3865:                        break;
                   3866:                case ASK:
                   3867:                        switch( nextchar() ) {
                   3868:                        case 'Y':
                   3869:                                return(YES);
                   3870:                        case 'N':
                   3871:                                return(NO);
                   3872:                        }
                   3873:                }
                   3874:        }
                   3875: }
                   3876: 
                   3877: action(msg)
                   3878: char *msg;
                   3879: {
                   3880:        switch( query(msg) ) {
                   3881:        case YES:
                   3882:                return(TRUE);
                   3883:        case NO:
                   3884:                return(FALSE);
                   3885:        }
                   3886: }
                   3887: 
                   3888: char
                   3889: nextchar()
                   3890: {
                   3891:        char buff[8];
                   3892:        int i, n, ch;
                   3893: 
                   3894:        if ( ((n=read(0,buff,8)) <= 0) || (n == 8) )
                   3895:                fatal("Invalid Response");
                   3896: 
                   3897:        for(i=0; i<n; i++)
                   3898:                if ( ((ch=buff[i])!=' ') && (ch!='\t') )
                   3899:                        break;
                   3900: 
                   3901:        if ( (ch>='a') && (ch<='z') )
                   3902:                ch += 'A' - 'a';
                   3903: 
                   3904:        return(ch);
                   3905: }
                   3906: 
                   3907: char   *nfile  = "FILE";
                   3908: char   *ndir   = "DIR";
                   3909: char   *nchr   = "Character Special";
                   3910: char   *nblk   = "Block Special";
                   3911: char   *npipe  = "PIPE";
                   3912: char   *nunkwn = "Unknown I-node type";
                   3913: 
                   3914: char *
                   3915: typename(ino)
                   3916: ino_t ino;
                   3917: {
                   3918:        switch( flags(ino)&MODEMASK ) {
                   3919:        case IREG:
                   3920:                return(nfile);
                   3921:        case IDIR:
                   3922:                return(ndir);
                   3923:        case ICHR:
                   3924:                return(nchr);
                   3925:        case IBLK:
                   3926:                return(nblk);
                   3927:        case IPIPE:
                   3928:                return(npipe);
                   3929:        default:
                   3930:                return(nunkwn);
                   3931:        }
                   3932: }
                   3933: 
                   3934: abort()
                   3935: {
                   3936:        fatal("abort.");
                   3937: }
                   3938: 
                   3939: fatal(x)
                   3940: {
                   3941:        printf("fsck: %r\n", &x);
                   3942:        _exit(1);
                   3943: }
                   3944: 
                   3945: nonfatal(x)
                   3946: {
                   3947:        printf("fsck: %r\n", &x);
                   3948:        errflag = TRUE;
                   3949: }
                   3950: 
                   3951: /*
                   3952:  *     Inode Manipulation Routines
                   3953:  *     ptrino: returns a pointer to the wanted inode using the given
                   3954:  *             buffer to read in the block performing canonicalization.
                   3955:  *     writeino: writes the block containing the given inode to the
                   3956:  *             disk performing the necessary canonicalization
                   3957:  *     candino: canonicalize an inode
                   3958:  *
                   3959:  */
                   3960: 
                   3961: struct dinode *
                   3962: ptrino(ino, buf)
                   3963: register ino_t ino;
                   3964: register char *buf;
                   3965: {
                   3966:        register daddr_t bn;
                   3967:        register struct dinode *dip;
                   3968: 
                   3969:        bn = iblockn(ino);
                   3970:        if ( (testblock(bn)) && (bn!=INODEI) )          /* bad inode block */
                   3971:                return(NULL);
                   3972:        bread(bn, buf);
                   3973:        dip = ((struct dinode *) buf) + iblocko(ino);
                   3974:        candino(dip);
                   3975:        return(dip);
                   3976: }
                   3977: 
                   3978: writeino(ino, buf)
                   3979: ino_t ino;
                   3980: char *buf;
                   3981: {
                   3982:        struct dinode *dip;
                   3983: 
                   3984:        dip = ((struct dinode *) buf) + iblocko(ino);
                   3985:        candino(dip);
                   3986:        bwrite((daddr_t) iblockn(ino), buf);
                   3987: }
                   3988: 
                   3989: candino(dip)
                   3990: register struct dinode *dip;
                   3991: {
                   3992:        canshort(dip->di_mode);
                   3993:        canshort(dip->di_nlink);
                   3994:        canshort(dip->di_uid);
                   3995:        canshort(dip->di_gid);
                   3996:        cansize(dip->di_size);
                   3997:        cantime(dip->di_atime);
                   3998:        cantime(dip->di_mtime);
                   3999:        cantime(dip->di_ctime);
                   4000: }
                   4001: 
                   4002: /*
                   4003:  *     Transfer a logical block number for an inode to a
                   4004:  *     physical block number, chasing indirects as necessary.
                   4005:  *     The inefficiency of this method is put up with since
                   4006:  *     this is only used for directory inodes, and they tend
                   4007:  *     not to use indirects.  Pass in 'addrs' which is a pointer
                   4008:  *     to the 13 daddr_s in the inode, and the logical block
                   4009:  *     number you would like.  (Stolen from dcheck.c)
                   4010:  */
                   4011: 
                   4012: static daddr_t ranges[] = {
                   4013:        ND,
                   4014:        ND + (daddr_t)NI*NBN,
                   4015:        ND + (daddr_t)NI*NBN + (daddr_t)NII*NBN*NBN,
                   4016:        ND + (daddr_t)NI*NBN + (daddr_t)NII*NBN*NBN + (daddr_t)NIII*NBN*NBN*NBN
                   4017: };
                   4018: 
                   4019: static char    index[] = {
                   4020:        0,
                   4021:        ND,
                   4022:        ND+NI,
                   4023:        ND+NI+NII
                   4024: };
                   4025: 
                   4026: static daddr_t coeff[] = {
                   4027:        1,      (daddr_t)NBN,   (daddr_t)NBN*NBN,       (daddr_t)NBN*NBN*NBN
                   4028: };
                   4029: 
                   4030: daddr_t
                   4031: imap(addrs, block)
                   4032: daddr_t *addrs;
                   4033: register daddr_t block;
                   4034: {
                   4035:        int i;
                   4036:        register daddr_t bpos;
                   4037:        register daddr_t *bp;
                   4038:        register daddr_t bn;
                   4039: 
                   4040:        for (i=0; i<4; i++)
                   4041:                if (block < ranges[i]) {
                   4042:                        if (i != 0)
                   4043:                                block -= ranges[i-1];
                   4044:                        bpos = block/coeff[i];
                   4045:                        block %= coeff[i];
                   4046:                        bp = &addrs[(int)bpos + index[i]];
                   4047:                        if ( (bn=*bp) != 0 ) {
                   4048:                                /*
                   4049:                                 * Map through indirects here
                   4050:                                 */
                   4051:                                while (i-- > 0) {
                   4052:                                        bread(bn, databuf);
                   4053:                                        bpos = block/coeff[i];
                   4054:                                        block %= coeff[i];
                   4055:                                        bp = (daddr_t *)databuf + bpos;
                   4056:                                        if ( (bn=*bp) == 0 )
                   4057:                                                break;
                   4058:                                        bn = *bp;
                   4059:                                        candaddr(bn);
                   4060:                                }
                   4061:                        }
                   4062:                        return(bn);
                   4063:                }
                   4064:        return(0);
                   4065: }
                   4066: 
                   4067: /*
                   4068:  *     Read the specified block number into the given buffer
                   4069:  */
                   4070: 
                   4071: char *rgblkerr = "Out of Range Block number: %U  (CONTINUE)";
                   4072: char *skblkerr = "Can not Seek: Blk num: %U  (CONTINUE)";
                   4073: char *rdblkerr = "Can not Read: Blk num: %U  (CONTINUE)";
                   4074: char *wtblkerr = "Can not Write: Blk num: %U  (CONTINUE)";
                   4075: 
                   4076: bread(bn, buf)
                   4077: register daddr_t bn;
                   4078: register char *buf;
                   4079: {
                   4080: #ifdef DEBUG
                   4081:        printf("Reading block number: %ld\n", bn);
                   4082: #endif
                   4083:        if (bn<0 || bn >= fsize ) 
                   4084:                switch( query(rgblkerr, bn) ) {  
                   4085:                case YES:
                   4086:                        bclear(buf, BSIZE);
                   4087:                        return;
                   4088:                case NO:
                   4089:                        abort();
                   4090:                }
                   4091: 
                   4092:        if ( (bn<isize) && getcache(bn, buf) ) {
                   4093: #if DEBUG
                   4094:                bdump(buf);
                   4095: #endif
                   4096:                return;
                   4097:        }
                   4098:        
                   4099:        if ( lseek(fsfd, (unsigned long)bn*BSIZE, 0) == (-1L) )
                   4100:                switch( query(skblkerr, bn) ) {
                   4101:                case YES:
                   4102:                        bclear(buf, BSIZE);
                   4103:                        return;
                   4104:                case NO:
                   4105:                        abort();
                   4106:                }
                   4107: 
                   4108:        if ( read(fsfd, buf, BSIZE) != BSIZE ) 
                   4109:                switch( query(rdblkerr, bn) ) {
                   4110:                case YES:
                   4111:                        bclear(buf, BSIZE);
                   4112:                        return;
                   4113:                case NO:
                   4114:                        abort();
                   4115:                }
                   4116: #if DEBUG
                   4117:        bdump(buf);
                   4118: #endif
                   4119: }
                   4120: 
                   4121: /*
                   4122:  *     Write block number bn with data in buf
                   4123:  */
                   4124: 
                   4125: bwrite(bn, buf)
                   4126: daddr_t bn;
                   4127: char *buf;
                   4128: {
                   4129: #ifdef DEBUG
                   4130:        printf("Writing block number: %ld\n", bn);
                   4131: #endif
                   4132:        if (!writeflg)
                   4133:                return;
                   4134: 
                   4135:        if (bn<0 || bn>=fsize) 
                   4136:                switch( query(rgblkerr, bn) ) {
                   4137:                case YES:
                   4138:                        return;
                   4139:                case NO:
                   4140:                        abort();
                   4141:                }
                   4142:        
                   4143:        if ( lseek(fsfd, (fsize_t)BSIZE*bn, 0) == (-1L) )
                   4144:                switch( query(skblkerr, bn) ) {
                   4145:                case YES:
                   4146:                        return;
                   4147:                case NO:
                   4148:                        abort();
                   4149:                }
                   4150: 
                   4151:        if ( write(fsfd, buf, BSIZE) != BSIZE ) 
                   4152:                switch( query(wtblkerr, bn) ) {
                   4153:                case YES:
                   4154:                        return;
                   4155:                case NO:
                   4156:                        abort();
                   4157:                }
                   4158: 
                   4159:        if ( bn <= isize )
                   4160:                chgcache(bn, buf);
                   4161:        changeflg = TRUE;
                   4162: }
                   4163: 
                   4164: /*
                   4165:  *     i-node block area caching routines
                   4166:  */
                   4167: 
                   4168: static char    cache[NBLK * BSIZE];
                   4169: static int     low = 0; high = -1;
                   4170: 
                   4171: getcache(bn, buf)
                   4172: register daddr_t bn;
                   4173: register char *buf;
                   4174: {
                   4175:        int totsize;
                   4176: 
                   4177:        if ( bn > isize )
                   4178:                return(0);
                   4179: 
                   4180:        if ( (bn>=low) && (bn<=high) ) {
                   4181:                blkmove(buf, &cache[BSIZE * (bn-low)]);
                   4182:                return(1);
                   4183:        }
                   4184: 
                   4185:        low = bn;
                   4186:        if ( (high=bn+NBLK-1) > isize )
                   4187:                high = isize;
                   4188:        totsize = BSIZE * (high-low+1);
                   4189: 
                   4190:        if ( (lseek(fsfd, (unsigned long)bn*BSIZE, 0) == (-1L)) ||
                   4191:             (read(fsfd, cache, totsize) != totsize) ) {
                   4192:                low = 0; high = -1;
                   4193:                return(0);
                   4194:        }
                   4195: 
                   4196:        return( getcache(bn, buf) );
                   4197: }
                   4198: 
                   4199: chgcache(bn, buf)
                   4200: register daddr_t bn;
                   4201: register char *buf;
                   4202: {
                   4203:        if ( (bn>=low) && (bn<=high) )
                   4204:                blkmove(&cache[BSIZE * (bn-low)], buf);
                   4205: }
                   4206: 
                   4207: blkmove(to, from)
                   4208: register char *to, *from;
                   4209: {
                   4210:        register int num=BSIZE;
                   4211: 
                   4212:        while ( num-- )
                   4213:                *to++= *from++;
                   4214: }
                   4215: 
                   4216: /*
                   4217:  *     Clear the given block of memory
                   4218:  */
                   4219: 
                   4220: bclear(bp, nb)
                   4221: register char *bp;
                   4222: register unsigned nb;
                   4223: {
                   4224:        if (nb)
                   4225:                do {
                   4226:                        *bp++ = 0;
                   4227:                } while (--nb);
                   4228: }
                   4229: 
                   4230: 
                   4231: /*
                   4232:  *     Determine if the given block is bad
                   4233:  */
                   4234: 
                   4235: bad(bn)
                   4236: daddr_t bn;
                   4237: {
                   4238:        if ( (bn >= isize) && (bn < fsize) )
                   4239:                return(GOOD);
                   4240:        else
                   4241:                return(BAD);
                   4242: }
                   4243: 
                   4244: 
                   4245: #if DEBUG
                   4246: 
                   4247: /*
                   4248:  *     Debug dump a block of data.
                   4249:  */
                   4250: 
                   4251: #define NUMPLIN        16
                   4252: 
                   4253: bdump(buf)
                   4254: register unsigned char *buf;
                   4255: {
                   4256:        register int i;
                   4257: 
                   4258:        for (i=0; i<BSIZE; i++) {
                   4259:                if ( (i % NUMPLIN) == 0 )
                   4260:                        printf("\n0x%04x:  ", i);
                   4261:                printf(" %02x", *buf++);
                   4262:        }
                   4263:        printf("\n\n");
                   4264: }
                   4265: 
                   4266: #endif
                   4267: @
                   4268: 
                   4269: 
                   4270: 1.1
                   4271: log
                   4272: @Initial revision
                   4273: @
                   4274: text
                   4275: @d261 4
                   4276: a264 1
                   4277:        if ( (bn<isize) && getcache(bn, buf) )
                   4278: d266 1
                   4279: d285 3
                   4280: d412 24
                   4281: @
                   4282: iven block is bad
                   4283:  */
                   4284: 
                   4285: bad(bn)
                   4286: daddr_t bn;
                   4287: {
                   4288:        if ( (bn >= isize) && (bn < fsize) )
                   4289:                return(GOOD);
                   4290:        else
                   4291:                return(BAD);
                   4292: }
                   4293: 
                   4294: 
                   4295: #if DEBUG
                   4296: 
                   4297: /*
                   4298:  *     Debug dump a block of data.
                   4299:  */
                   4300: 
                   4301: #define NUMPLIN        16
                   4302: 
                   4303: bdump(buf)
                   4304: register unsignefsck/RCS/virtual.c,v   444      3      3       16557  4753557734   7543 head     1.1;
                   4305: access   ;
                   4306: symbols  ;
                   4307: locks    ;
                   4308: comment  @ * @;
                   4309: 
                   4310: 
                   4311: 1.1
                   4312: date     91.02.05.16.39.42;  author bin;  state Exp;
                   4313: branches ;
                   4314: next   ;
                   4315: 
                   4316: 
                   4317: desc
                   4318: @prov by epstein (post 310)
                   4319: @
                   4320: 
                   4321: 
                   4322: 
                   4323: 1.1
                   4324: log
                   4325: @Initial revision
                   4326: @
                   4327: text
                   4328: @/*
                   4329:  * Virtual memory for fsck. Uses hash algorithm
                   4330:  * rather than LRU to get it up fast.
                   4331:  */
                   4332: #include <assert.h>
                   4333: #include <sys/stat.h>
                   4334: #include "fsck.h"
                   4335: 
                   4336: #define VBLKB 9                        /* bytes in virtual block as power of 2 */
                   4337: #define VBLK (1 << VBLKB)      /* bytes in a virtual block */
                   4338: #define MBKSB 6                        /* number of virtual blocks as power of 2 */
                   4339: #define MBKS (1 << MBKSB)      /* number of virtual blocks */
                   4340: 
                   4341: #define DVTMP "/dev/rram1"     /* Default Virtual Temp Filename */
                   4342: #define DVTMPCLS "/dev/rram1close" /* Default Virtual Temp File Close */
                   4343: #define        MAJORRAM 8              /* Major Device Number for the Ram Disk */
                   4344: 
                   4345: struct mapper {
                   4346:        unsigned dirty:1;
                   4347:        unsigned what_in:15;    /* which block is in memory */
                   4348: };
                   4349: 
                   4350: static unsigned long flagdsp, blkdsp, dupdsp, duplim;
                   4351: static struct mapper map[MBKS];
                   4352: static unsigned char data[MBKS][VBLK];
                   4353: static int tmp;
                   4354: 
                   4355: static char *dvtmp = DVTMP;
                   4356: static char *dvtmpcls = DVTMPCLS;
                   4357: 
                   4358: /*
                   4359:  * Init file system for virtual arrays.
                   4360:  * Data is ordered links, flags, blocks then dups.
                   4361:  */
                   4362: initV(links, flags, blocks, dups)
                   4363: unsigned links, flags, blocks, dups;
                   4364: {
                   4365:        register long bp;
                   4366:        struct stat st;
                   4367:        unsigned datasiz;
                   4368: 
                   4369:        flagdsp = links;
                   4370:        blkdsp = flagdsp + flags;
                   4371:        dupdsp = blkdsp + blocks;
                   4372:        duplim = dupdsp + dups;
                   4373: 
                   4374:        memset(map, 0, sizeof(map));    /* zero ram arrays */
                   4375:        memset(data, 0, sizeof(data));
                   4376: 
                   4377:        tmp = -1;
                   4378: 
                   4379:        datasiz = sizeof(data);
                   4380:        if ( duplim < datasiz )
                   4381:                return;
                   4382: 
                   4383:        if ( tmpfile == NULL ) {
                   4384:                switch ( is_fs(dvtmp) ) {
                   4385:                case -1:
                   4386:                        fatal(
                   4387: "Can't access ram disk \"%s\", use the -t option", dvtmp);
                   4388:                case 0:
                   4389:                        break;
                   4390:                case 1:
                   4391:                        fatal(
                   4392: "Possible file system on ram disk \"%s\", use the -t option", dvtmp);
                   4393:                }
                   4394:                if ( (-1 == stat(dvtmp, &st)) || !(st.st_mode&S_IFCHR) ||
                   4395:                        (major(st.st_rdev) != MAJORRAM) )
                   4396:                                fatal("Ram disk \"%s\" not mknod'ed properly",
                   4397:                                                                dvtmp);
                   4398:                if ( -1 == (tmp = open(dvtmp, 2)) )
                   4399:                        fatal("Cannot open read/write Ram Disk \"%s\"", dvtmp);
                   4400: 
                   4401:                /* Ram disk driver may not promise zeroed start.
                   4402:                 * This code may go later. Extra write not important. */
                   4403:                for(bp = 0; bp < duplim; bp += VBLK) /* zero disk stuff */
                   4404:                        if ( VBLK != write(tmp, data[0], VBLK) )
                   4405:                                fatal("Error writing to tmp file");
                   4406:        } else {
                   4407:                if ( -1 == (tmp = open(tmpfile, 2)) ) {
                   4408:                        if ( -1 == (tmp = creat(tmpfile, 0600)) )
                   4409:                                fatal("Cannot create temp file \"%s\"", 
                   4410:                                                                tmpfile);
                   4411:                        close(tmp);
                   4412:                        tmp = open(tmpfile, 2);
                   4413:                        unlink(tmpfile);
                   4414:                }
                   4415:                if ( -1 == fstat(tmp, &st) )
                   4416:                        fatal("Can't stat temp file \"%s\"", tmpfile);
                   4417:                if ( st.st_dev == fsysrdev )
                   4418:                        fatal("Temp File must not be on file system to fsck");
                   4419:        }
                   4420: }
                   4421: 
                   4422: /*
                   4423:  * cleanup virtual system
                   4424:  */
                   4425: cleanV()
                   4426: {
                   4427:        struct stat st;
                   4428: 
                   4429:        if ( tmp == -1 )                /* No Virtual Temp File Opened  */
                   4430:                return;
                   4431: 
                   4432:        close(tmp);
                   4433:        if ( tmpfile != NULL )          /* Virtual File not Default RAMDisk */
                   4434:                return;
                   4435:                                        /* Virtual File is Default RAMDisk */
                   4436:        if ( (-1 == stat(dvtmpcls, &st)) || !(st.st_mode&S_IFCHR) ||
                   4437:                (major(st.st_rdev) != MAJORRAM) ||
                   4438:                ((minor(st.st_rdev)&0x7F) != 0) )
                   4439:                fatal("Ram disk close \"%s\" not mknod'ed properly", dvtmpcls);
                   4440:        if ( -1 == (tmp = open(dvtmpcls, 2)) )
                   4441:                fatal("Cannot open Ram Disk Close \"%s\"", dvtmpcls);
                   4442:        if ( close(tmp) < 0 )
                   4443:                fatal("Cannot close Ram Disk Close \"%s\"", dvtmpcls);
                   4444: }
                   4445: 
                   4446: /*
                   4447:  * All actions for virtual array
                   4448:  */
                   4449: findblock(bp, action, odata)
                   4450: long bp;               /* data address */
                   4451: enum vact action;      /* what to do */
                   4452: unsigned odata;                /* optional data */
                   4453: {
                   4454:        unsigned which, what_in, byte_no, bit;
                   4455:        unsigned long diskad;
                   4456:        unsigned char *byte;
                   4457:        extern long lseek();
                   4458: 
                   4459:        switch(action) {        /* use displacment to correct part of file */
                   4460:        case testBlock:
                   4461:        case markBlock:
                   4462:        case unmarkBlock:
                   4463:                bit = 1 << (bp & 7);
                   4464:                bp >>= 3;
                   4465:        case grabBlock:         /* 8 at a time for copy */
                   4466:                assert(bp >= 0);
                   4467:                bp += blkdsp;
                   4468:                assert(bp < dupdsp);
                   4469:                break;
                   4470:        case testDup:
                   4471:        case markDup:
                   4472:        case unmarkDup:
                   4473:                bit = 1 << (bp & 7);
                   4474:                bp >>= 3;
                   4475:        case setDup:            /* 8 at a time for copy */
                   4476:                assert(bp >= 0);
                   4477:                bp += dupdsp;
                   4478:                assert(bp < duplim);
                   4479:                break;
                   4480:        case Flags:
                   4481:        case setFlags:
                   4482:        case orFlags:
                   4483:                assert(bp > 0);
                   4484:                bp += flagdsp - 1;
                   4485:                assert(bp < blkdsp);
                   4486:                break;
                   4487:        case linkCtr:
                   4488:        case incLinkctr:
                   4489:        case setLinkctr:
                   4490:                assert(bp > 0);
                   4491:                bp--;
                   4492:                assert(bp < flagdsp);
                   4493:        }
                   4494: 
                   4495:        byte_no = bp & (VBLK - 1);
                   4496:        bp >>= VBLKB;
                   4497:        which = bp & (MBKS - 1);
                   4498:        bp >>= MBKSB;
                   4499:        what_in = bp & 0x7fff;
                   4500: 
                   4501:        if((diskad = map[which].what_in) != what_in)    {
                   4502:                if(map[which].dirty) {
                   4503:                        diskad <<= VBLKB + MBKSB;
                   4504:                        diskad += which << VBLKB;
                   4505:                        if(-1 == lseek(tmp, diskad, 0))
                   4506:                                fatal("Error seeking tmp file");
                   4507:                        if(VBLK != write(tmp, data[which], VBLK))
                   4508:                                fatal("Error writing tmp file");
                   4509:                }
                   4510:                diskad = what_in;
                   4511:                diskad <<= VBLKB + MBKSB;
                   4512:                diskad += which << VBLKB;
                   4513:                if(-1 == lseek(tmp, diskad, 0))
                   4514:                        fatal("Error seeking tmp file");
                   4515:                if(VBLK != read(tmp, data[which], VBLK))
                   4516:                        memset(data[which], 0, VBLK);
                   4517:                map[which].what_in = what_in;
                   4518:                map[which].dirty = 0; /* clean */
                   4519:        }
                   4520:        byte = &data[which][byte_no];
                   4521: 
                   4522:        switch(action) {
                   4523:        case testBlock:
                   4524:        case testDup:
                   4525:                return(*byte & bit);
                   4526:        case markBlock:
                   4527:        case markDup:
                   4528:                map[which].dirty = 1;
                   4529:                return(*byte |= bit);
                   4530:        case unmarkBlock:
                   4531:        case unmarkDup:
                   4532:                map[which].dirty = 1;
                   4533:                return(*byte ^= bit);
                   4534:        case linkCtr:
                   4535:        case Flags:
                   4536:        case grabBlock:
                   4537:                return(*byte);
                   4538:        case setLinkctr:
                   4539:        case setFlags:
                   4540:        case setDup:
                   4541:                map[which].dirty = 1;
                   4542:                return(*byte = odata);
                   4543:        case orFlags:
                   4544:                map[which].dirty = 1;
                   4545:                return(*byte |= odata);
                   4546:        case incLinkctr:
                   4547:                map[which].dirty = 1;
                   4548:                return(++*byte);
                   4549:        default:
                   4550:                fatal("Bad action in virtual system");
                   4551:        }
                   4552: }
                   4553: 
                   4554: /*
                   4555:  * copy virtual memory blockmap to dupmap
                   4556:  * read and write groups to avoid possable thrashing.
                   4557:  */
                   4558: void
                   4559: copyV(size)
                   4560: unsigned size;
                   4561: {
                   4562:        char buf[128];
                   4563:        register int i;
                   4564:        long bp, bs;
                   4565: 
                   4566:        for(bs = bp = 0; bp < size; ) {
                   4567:                for(i = 0; (i < 128) && (bp < size); i++, bp++)
                   4568:                        buf[i] = findblock(bp, grabBlock);
                   4569: 
                   4570:                for(i = 0; (i < 128) && (bs < size); i++, bs++)
                   4571:                        findblock(bs, setDup, buf[i]);
                   4572:        }
                   4573: }
                   4574: 
                   4575: #ifdef TEST
                   4576: fatal(s)
                   4577: char *s;
                   4578: {
                   4579:        fprintf(stderr, "%s\n", s);
                   4580:        exit(1);
                   4581: }
                   4582: 
                   4583: static char buf[80];
                   4584: gbuf()
                   4585: {
                   4586:        if(NULL == gets(buf)) {
                   4587:                unlink("vtmp");
                   4588:                exit(0);
                   4589:        }
                   4590:        return(buf[0]);
                   4591: }
                   4592: 
                   4593: main()
                   4594: {
                   4595:        unsigned long b;
                   4596:        char data;
                   4597: 
                   4598:        initV(10000, 10000, 20000);
                   4599:        for(;;) {
                   4600:                printf("b = block, d = dup, f = flags, l = linkctr\n");
                   4601:                switch(gbuf()) {
                   4602:                case 'l':
                   4603:                        printf("s = set, d = display, i = increment: then loc\n");
                   4604:                        gbuf();
                   4605:                        sscanf(buf + 2, "%ld", &b);
                   4606:                        switch(buf[0]) {
                   4607:                        case 's':
                   4608:                                setlinkctr(b, 0); /* no data */
                   4609:                        case 'd':
                   4610:                                printf("%d\n", linkctr(b));
                   4611:                                break;
                   4612:                        case 'i':
                   4613:                                printf("%d\n", inclinkctr(b));
                   4614:                        }
                   4615:                        break;
                   4616:                case 'f':
                   4617:                        printf("d = display, s = set, o = or: then loc\n");
                   4618:                        gbuf();
                   4619:                        sscanf(buf + 2, "%ld %c", &b, &data);
                   4620:                        switch(buf[0]) {
                   4621:                        case 's':
                   4622:                                setflags(b, data);
                   4623:                        case 'd':
                   4624:                                break;
                   4625:                        case 'o':
                   4626:                                orflags(b, data);
                   4627:                        }
                   4628:                        printf("%c\n", flags(b));
                   4629:                        break;
                   4630:                case 'b':
                   4631:                        printf("t = test, m = mark, u = unmark: then loc\n");
                   4632:                        gbuf();
                   4633:                        sscanf(buf + 2, "%ld", &b);
                   4634:                        switch(buf[0]) {
                   4635:                        case 'm':
                   4636:                                markblock(b);
                   4637:                        case 't':
                   4638:                                break;
                   4639:                        case 'u':
                   4640:                                unmarkblock(b);
                   4641:                        }
                   4642:                        printf("%c\n", testblock(b) ? '1' : '0');
                   4643:                        break;
                   4644:                case 'd':
                   4645:                        printf("t = test, m = mark, u = unmark: then loc\n");
                   4646:                        gbuf();
                   4647:                        sscanf(buf + 2, "%ld", &b);
                   4648:                        switch(buf[0]) {
                   4649:                        case 'm':
                   4650:                                markdup(b);
                   4651:                        case 't':
                   4652:                                break;
                   4653:                        case 'u':
                   4654:                                unmarkdup(b);
                   4655:                        }
                   4656:                        printf("%c\n", testdup(b) ? '1' : '0');
                   4657:                        break;
                   4658:                }
                   4659:        }
                   4660: }
                   4661: #endif
                   4662: 
                   4663: @
                   4664:  loc\n");
                   4665:                        gbuf();
                   4666:                        sscanf(buf + 2, "%ld", &b);
                   4667:                        switch(buf[0]) {
                   4668:                        case 'm':
                   4669:                                markblock(b);
                   4670:                        case 't':
                   4671:                                break;
                   4672:                        case 'u':
                   4673:                                ufsck/READ_ME   644      3      3        1227  4664524112   5766 Ideas for improving the performance of fsck:
                   4674: 
                   4675: (1)  Utilize a different mechanism for storing the (struct direct)
                   4676:      entries throughout phase2.c, to remove implicit memory intensive
                   4677:      redundancy.
                   4678: 
                   4679: (2)  Encode the number of links per i-node count differently, in order
                   4680:      to save space taking advantage of the typical usage under Coherent.
                   4681: 
                   4682: (3)  Arrange space for the tables in a total needed way to avoid later
                   4683:      fragmentation problems affecting the memory requests for successive
                   4684:      file systems.
                   4685: 
                   4686: (4)  Devise a more clever buffering scheme for the blocks containing
                   4687:      i-nodes to understand the differences between phase1, phase2, and
                   4688:      phase4.
                   4689: emove implicit memory intensive
                   4690:      redundancy.
                   4691: 
                   4692: (2)  Encode the number of links per i-node count differently, in order
                   4693:      to save space taking advantage of the typical usage under Coherent.
                   4694: 
                   4695: (3)  Arrange space for the tables in a total needed way to avoid later
                   4696:      fragmentation problems affecting the memory requests for successive
                   4697:      file systems.
                   4698: 
                   4699: (4fsck/cleanup.c   644      3      3        2324  4664524112   6541 /*
                   4700:  *     Cleanup functions for phases of fsck
                   4701:  */
                   4702: 
                   4703: #include "fsck.h"
                   4704: 
                   4705: cleanup()
                   4706: {
                   4707:        int retval = 0;
                   4708: 
                   4709:        if (sbpfix == TRUE) 
                   4710:                writesuper();
                   4711:        prtstats();
                   4712:        if (changeflg == TRUE)
                   4713:                retval = advise();
                   4714:        close(fsfd);
                   4715:        cleanV();
                   4716:        return(retval);
                   4717: }
                   4718: 
                   4719: writesuper()
                   4720: {
                   4721:        register int i;
                   4722: 
                   4723:        canshort(sbp->s_isize);
                   4724:        candaddr(sbp->s_fsize);
                   4725:        canshort(sbp->s_nfree);
                   4726:        for(i=0; i<NICFREE; i++)
                   4727:                candaddr(sbp->s_free[i]);
                   4728:        canshort(sbp->s_ninode);
                   4729:        for(i=0; i<NICINOD; i++)
                   4730:                canino(sbp->s_inode[i]);
                   4731:        cantime(sbp->s_time);
                   4732:        candaddr(sbp->s_tfree);
                   4733:        canino(sbp->s_tinode);
                   4734:        canshort(sbp->s_m);
                   4735:        canshort(sbp->s_n);
                   4736:        canlong(sbp->s_unique);
                   4737: 
                   4738:        bwrite((daddr_t)SUPERI, sbp);
                   4739: }
                   4740: 
                   4741: prtstats()
                   4742: {
                   4743:        if (!fflag)
                   4744:                printf("%u files ", numfiles);
                   4745:        printf("%U blocks ", fsize - isize - totfree);
                   4746:        printf("%U free\n", totfree);
                   4747:        if ( lostsize ) {
                   4748:                lostsize = (lostsize + BSIZE - 1)/BSIZE;
                   4749:                printf("Expect roughly %U missing block%s next\n", lostsize,
                   4750:                                (lostsize!=1) ? "s" : "" );
                   4751:                printf("time fsck is run as a result of inodes ");
                   4752:                printf("being cleared.\n");
                   4753:        }
                   4754: }
                   4755: 
                   4756: advise()
                   4757: {
                   4758:        int retval = 0;
                   4759: 
                   4760:        printf(" ***** File System %s was modified *****\n", fsname);
                   4761:        if ( mounted ) {
                   4762:                printf(" ***** BOOT Coherent (NO SYNC!) *****\n");
                   4763:                retval = 1;
                   4764:        }
                   4765:        return(retval);
                   4766: }
                   4767: blocks ", fsize - isize - totfree);
                   4768:        printf("%U free\n", totfree);
                   4769:        if ( lostsize ) {
                   4770:                lostsize = (lostsize + BSIZE - 1)/BSIZE;
                   4771:                printf("Expect roughly %U missing block%s next\n", lostsize,
                   4772:                                (lostsize!=1) ? "s" : "" );
                   4773:                printf("time fsck is run as a result of inodes ");
                   4774:                printf("being clearedfsck/fsck.h   644      3      3       14003  5033723044   6056 /*
                   4775:  *     Header file for fsck  --  File System Check Program
                   4776:  *
                   4777:  */
                   4778: 
                   4779: #include <canon.h>
                   4780: #include <sys/dir.h>
                   4781: #include <sys/fblk.h>
                   4782: #include <sys/filsys.h>
                   4783: #include <sys/ino.h>
                   4784: #include <sys/stat.h>
                   4785: #include <sys/types.h>
                   4786: #include <time.h>
                   4787: 
                   4788: #if HPCOHERENT
                   4789: typedef long fsize_t;
                   4790: #endif
                   4791: 
                   4792: /*
                   4793:  *     Conditional Compilation Flags
                   4794:  */
                   4795: 
                   4796: #define NOT_ALL_ZERO_INODE     /* Dependent on whether or not an inode */
                   4797: #ifdef         ALL_ZERO_INODE          /* is totally zeroed when unallocated   */
                   4798: #undef ALL_ZERO_INODE          /* or simply a zero mode and zero link  */
                   4799: #endif
                   4800: 
                   4801: 
                   4802: /*
                   4803:  *     Definitions and Externs
                   4804:  */
                   4805: 
                   4806: #define NUL    0               /* true zero ! */
                   4807: #define NULL   ((char *)0)
                   4808: 
                   4809: #define        YES     3               /* default actions */
                   4810: #define        NO      2
                   4811: #define ASK    1
                   4812: 
                   4813: #define        NFILSYS 10              /* max number of file systems */
                   4814: #define        MAXCH   20              /* max length of filesys name */
                   4815: 
                   4816: #define        MAXBADOK        10      /* Max number of bad blocks before excessive */
                   4817: extern int numbad;             /* num bad blocks found so far this inode*/
                   4818: 
                   4819: #define MAXDUPOK       10      /* Max number of dup blocks */
                   4820:                                /* in a single inode before excessive */
                   4821: #define        DUPTBLSIZE      20      /* Max number of dup referenced blocks */
                   4822: extern daddr_t dupblck[];      /* table of duplicate referenced blocks */
                   4823: extern         int totdups;            /* number of dup blocks found so far */
                   4824: 
                   4825: #define MAXBADFREE     10      /* max bad in free list before abort */
                   4826: #define MAXDUPFREE     10      /* max dup in free list before abort */
                   4827: 
                   4828: #define GOOD   1               /* returned by bad() in util.c */
                   4829: #define        BAD     0
                   4830: 
                   4831: #define        TRUE    1               /* errflag possibilities */
                   4832: #define        FALSE   0
                   4833: extern         int     errflag;        /* errflag indicates not to do phases */
                   4834: 
                   4835: #define OK     1               /* used to indicate excessive bad/dup */
                   4836: #define STOP   0               /* blocks in an inode in phase1.c     */
                   4837: #define BAD_DUP        2
                   4838: 
                   4839: #define FIRSTIN        2               /* First real inode number */
                   4840: 
                   4841: #define        ND      10              /* Number of Direct Blocks */
                   4842: #undef NI
                   4843: #define        NI      1
                   4844: #define        NII     1
                   4845: #define        NIII    1
                   4846: #undef NADDR
                   4847: #define        NADDR   (ND+NI+NII+NIII)
                   4848: extern int     offsets[];      /* table of offsets for level of indirection */
                   4849:                                /* for the blocks in an inode */
                   4850: 
                   4851: extern char    nextchar();     /* used in util.c */
                   4852: extern int     fsfd;           /* file system file descriptor */
                   4853: extern         int     mdaction;       /* default action for this invocation */
                   4854: extern         int     daction;        /* default action for current file system */
                   4855: extern  int    writeflg;       /* system write ok or read-only */
                   4856: extern  int    qflag;          /* quiet fsck flag */
                   4857: extern int     fflag;          /* fast fsck flag */
                   4858: extern int     sflag;          /* force free list salvation    */
                   4859: extern daddr_t fsize;          /* file system size in blocks */
                   4860: extern int     isize;          /* first block not in inode list */
                   4861:                                /* isize is NOT unsigned so that comparisons */
                   4862:                                /* with longs will not cast the long to */
                   4863:                                /* unsigned thus producing confusing results */
                   4864: 
                   4865: extern  daddr_t        totfree;        /* running count of total free blocks */
                   4866: extern         unsigned        ninodes;/* Number of inodes in the files system */
                   4867: extern         char    *fsname;        /* file system name */
                   4868: extern  fsize_t  pinfo();      /* returns size of file, in phase2.c */
                   4869: extern ino_t   lostfound();    /* returns inumber of lost+found dir */
                   4870: extern struct dinode *ptrino(); /* returns a ptr to inode, give number */
                   4871: extern         char databuf[];         /* buffer to read in block, used throughout */
                   4872: extern char buf2[];            /* alternate data buffer */
                   4873: extern         daddr_t cdbn;           /* current block number, used by nextblock() */
                   4874: #define DSIZE  (sizeof(struct direct))
                   4875: extern         char *lostname;         /* name of lost+found directory */
                   4876: extern  char *nameit();                /* nameing function for lost dirs and files */
                   4877: extern         int     depth;          /* used during tree traversal in phase2.c */
                   4878: extern  struct direct *path[];         /* used during tree traversal in phase2.c */
                   4879: extern char    *typename();    /* return string to type of inode */
                   4880: extern         struct filsys *sbp;     /* Super Block */
                   4881: extern         int     sbpfix;         /* flag for super block fixes */
                   4882: extern  struct stat stats;     /* used by statit() in util.c */
                   4883: extern dev_t   rootdev;        /* root device number */
                   4884: extern dev_t   fsysrdev;       /* file system real device number */
                   4885: extern int     mounted;        /* flag indicating mountedness of filesystem */
                   4886: extern         int     changeflg;      /* file system modified flag */
                   4887: extern         int     fixerup;        /* flag to rebuild free list */
                   4888: extern char    *fixit;         /* Prompt message phase[45].c */
                   4889: extern         int     numfiles;       /* num files in system */
                   4890: extern daddr_t imap();         /* function for disk block mapping in util.c */
                   4891: extern fsize_t lostsize;       /* Size of files cleared in phase4.c */
                   4892: extern char    *tmpfile;       /* TMP File name for virtual.c */
                   4893: 
                   4894: #define SUCCESS        1               /* used in connect() in phase3.c */
                   4895: #define FAILURE        0
                   4896: 
                   4897: #define        MODEMASK        0x07
                   4898: #define ALLOCMASK      0x06
                   4899: #define UNALLOC                0x00
                   4900: #define UNKNOWN                0x01
                   4901: #define        IDIR            0x02
                   4902: #define        IREG            0x03
                   4903: #define ICHR           0x04
                   4904: #define IBLK           0x05
                   4905: #define IPIPE          0x06
                   4906: #define IBAD_IDUP      0x08
                   4907: #define VISITED                0x10
                   4908: #define UNREFDIR       0x20
                   4909: #define CHILDDIR       0x40
                   4910: #define IFREELIST      0x80
                   4911: 
                   4912: /*
                   4913:  *     Macros for tables
                   4914:  */
                   4915: 
                   4916: #define        LOGNBPC 3               /* Log2 Number of Bits per Character    */
                   4917: 
                   4918: /* Actions for virtual block system */
                   4919: enum vact { testBlock, markBlock, unmarkBlock, grabBlock,
                   4920:            testDup, markDup, unmarkDup, setDup,
                   4921:            Flags, setFlags, orFlags,
                   4922:            linkCtr, incLinkctr, setLinkctr };
                   4923:              
                   4924: #define testblock(bn)  findblock((unsigned long)(bn), testBlock)
                   4925: #define markblock(bn)  findblock((unsigned long)(bn), markBlock)
                   4926: #define unmarkblock(bn) findblock((unsigned long)(bn), unmarkBlock)
                   4927: 
                   4928: #define testdup(bn) findblock((unsigned long)(bn), testDup)
                   4929: #define markdup(bn) findblock((unsigned long)(bn), markDup)
                   4930: #define unmarkdup(bn) findblock((unsigned long)(bn), unmarkDup)
                   4931: 
                   4932: #define flags(ino) findblock((unsigned long)(ino), Flags)
                   4933: #define setflags(ino, data) findblock((unsigned long)(ino), setFlags, data)
                   4934: #define orflags(ino, data)  findblock((unsigned long)(ino), orFlags, data)
                   4935: 
                   4936: #define linkctr(ino) findblock((unsigned long)(ino), linkCtr)
                   4937: #define inclinkctr(ino) findblock((unsigned long)(ino), incLinkctr)
                   4938: #define setlinkctr(ino, data) findblock((unsigned long)(ino), setLinkctr, data)
                   4939: 
                   4940: #define badblks(ino)   ( flags(ino)&IBAD_IDUP )
                   4941: 
                   4942: /*
                   4943:  *     Miscellany
                   4944:  */
                   4945: 
                   4946: #define        NBPC    8                       /* number of bits per character */
                   4947: #define        MAXINTN 255                     /* used for interleave table    */
                   4948:                                        /* in phase6.c                  */
                   4949: /*
                   4950:  *     Stdio Stuff
                   4951:  */
                   4952: 
                   4953: #define putchar(c) { char b = c; write(1, &b, 1); }
                   4954: extern char *malloc();
                   4955: extern char *calloc();
                   4956: 
                   4957: findblock((unsigned long)(ino), linkCtr)
                   4958: #define inclinkctr(ino) findblock((unsigned long)(ino), incLinkctr)
                   4959: #define setlinkctr(ino, data) findblock((unsigned long)(ino), setLinkctr, data)
                   4960: 
                   4961: #define badblks(ino)   ( flags(ino)&IBAD_IDUP )
                   4962: 
                   4963: /*
                   4964:  *     Miscellany
                   4965:  */
                   4966: 
                   4967: #define        NBPC    8                       /* number of bits per character */
                   4968: #define        MAXINTN 255                     /* used for interleave table    */
                   4969:                                        /* in phase6.c                  */
                   4970: /*
                   4971:  *     Stdio Stuff
                   4972:  */
                   4973: 
                   4974: #define putchar(c) { char b = c; write(1, &b, 1); }
                   4975: extern char *malloc();
                   4976: extern char *calloc()fsck/init.c   644      3      3       12651  5041132573   6075 /*
                   4977:  *     Perform initialization for phases of fsck
                   4978:  */
                   4979: #include "fsck.h"
                   4980: #include <mnttab.h>
                   4981: #include <mtab.h>
                   4982: 
                   4983: int    fsfd;                           /* file system file descriptor */
                   4984: int    writeflg;                       /* write ok or read-only flag */
                   4985: daddr_t        fsize = SUPERI+1;               /* file system size in blocks  */
                   4986:                                        /* Allows for read of Super Block */
                   4987: int    isize;                          /* First block not in inode list */
                   4988: daddr_t        totfree;                        /* Running total free block count */
                   4989: unsigned       ninodes;                /* number of inodes */
                   4990: int    numfiles;                       /* number of files in file system */
                   4991: 
                   4992: char   superb[BSIZE];                  /* Super Block */
                   4993: struct filsys *sbp = superb;
                   4994: int    sbpfix;                         /* flag for super block fixes */
                   4995: 
                   4996: int    offsets[] =                     /* table of offsets for the levels */
                   4997:                { ND, ND+NI, ND+NI+NII, /* of indirection of blocks in the */
                   4998:                  ND+NI+NII+NIII };     /* inode block list */
                   4999: 
                   5000: daddr_t        dupblck[DUPTBLSIZE];            /* duplicate referenced blocks */
                   5001: int    totdups;                        /* number of dup blocks so far */
                   5002: 
                   5003: init()
                   5004: {
                   5005:        int mode;
                   5006:        struct stat status;
                   5007:        unsigned short stmode;
                   5008: 
                   5009:        mode = (mdaction == NO) ? 0 : 2;
                   5010: 
                   5011:        if ( (fsfd = open(fsname, mode)) == (-1) ) {
                   5012:                mode = 0;
                   5013:                if ( (fsfd = open(fsname, mode)) == (-1) ) {
                   5014:                        nonfatal("Can't open: %s", fsname);
                   5015:                        return;
                   5016:                }
                   5017:        }
                   5018: 
                   5019:        if (mode == 0) {
                   5020:                daction  = NO;
                   5021:                writeflg = FALSE;
                   5022:        } else {
                   5023:                daction  = mdaction;
                   5024:                writeflg = TRUE;
                   5025:        }
                   5026:        
                   5027:        printf("%s: %s\n", fsname, (mode == 0) ? "(NO WRITE)" : "");
                   5028: 
                   5029:        if ( fstat(fsfd, &status) == (-1) ) {
                   5030:                nonfatal("Can't stat: %s", fsname);
                   5031:                return;
                   5032:        }
                   5033: 
                   5034:        stmode = status.st_mode & S_IFMT;
                   5035:        if ( (stmode != S_IFBLK) && (stmode != S_IFCHR) ) 
                   5036:                switch(query("file is not a block or character device; OK?")){
                   5037:                case YES:
                   5038:                        break;
                   5039:                case NO:
                   5040:                        errflag = TRUE;
                   5041:                        return;
                   5042:                }
                   5043: 
                   5044:        domount();
                   5045:        sbpfix = FALSE;
                   5046:        readsuper();
                   5047:        checksuper();
                   5048:        if ( !errflag )
                   5049:                alloctables();
                   5050: }
                   5051: 
                   5052: /*
                   5053:  *     Read in the super block and canonicalize
                   5054:  */
                   5055: 
                   5056: readsuper()
                   5057: {
                   5058:        register int i;
                   5059: 
                   5060:        bread((daddr_t)SUPERI, superb);
                   5061:        sbp = superb;
                   5062: 
                   5063:        canshort(sbp->s_isize);
                   5064:        candaddr(sbp->s_fsize);
                   5065:        canshort(sbp->s_nfree);
                   5066:        for(i=0; i<NICFREE; i++)
                   5067:                candaddr(sbp->s_free[i]);
                   5068:        canshort(sbp->s_ninode);
                   5069:        for(i=0; i<NICINOD; i++)
                   5070:                canino(sbp->s_inode[i]);
                   5071:        cantime(sbp->s_time);
                   5072:        candaddr(sbp->s_tfree);
                   5073:        canino(sbp->s_tinode);
                   5074:        canshort(sbp->s_m);
                   5075:        canshort(sbp->s_n);
                   5076:        canlong(sbp->s_unique);
                   5077: 
                   5078: }
                   5079: 
                   5080: /*
                   5081:  *     Check super block for obvious inconsistencies
                   5082:  */
                   5083: 
                   5084: checksuper()
                   5085: {
                   5086:        fsize = sbp->s_fsize;
                   5087:        isize = sbp->s_isize;
                   5088:        totfree = fsize - isize;
                   5089:        
                   5090:        if ( (isize<=INODEI) || (isize>=fsize) || (fsize<=INODEI) ) {
                   5091:                badsuper("Size check: fsize %U isize %u", fsize, isize);
                   5092:                errflag = TRUE;
                   5093:        }
                   5094: 
                   5095:        if ( sbp->s_nfree > NICFREE )
                   5096:                badsuper("Too large free block count");
                   5097: 
                   5098:        if ( sbp->s_ninode > NICINOD )
                   5099:                badsuper("Too large free i-node count");
                   5100: }
                   5101: 
                   5102: /*
                   5103:  *     Super Block Error Functions
                   5104:  */
                   5105: 
                   5106: badsuper(x)
                   5107: {
                   5108:        printf("%r\n", &x);
                   5109:        printf("fsck: %s: Bad Super Block: %u\n", fsname, SUPERI);
                   5110: }
                   5111: 
                   5112: /*
                   5113:  *     Allocate the necessary buffers for tables
                   5114:  */
                   5115: 
                   5116: alloctables()
                   5117: {
                   5118:        unsigned num, numl;
                   5119: 
                   5120:        numl = 0;
                   5121:        if (!fflag) {
                   5122:                ninodes = (unsigned) (isize - INODEI) * INOPB;
                   5123:                numl = (unsigned) ninodes;
                   5124:        }
                   5125:        
                   5126:        num = (unsigned) ((fsize+NBPC-1)/NBPC) * sizeof(char);
                   5127:        initV(numl, numl, num, num); /* virtual allocation */
                   5128: 
                   5129:        numfiles =              /* number of files in the file system */
                   5130:        totdups = 0;            /* num dup blocks */
                   5131: }
                   5132: 
                   5133: /*
                   5134:  *     domount() checks the files /etc/mnttab and /etc/mtab to find
                   5135:  *     out where the file system is mounted (if at all).  It then 
                   5136:  *     reports where (and when if possible) it was last mounted.
                   5137:  */
                   5138: char *mnttab_name = "/etc/mnttab";
                   5139: char *mtab_name          = "/etc/mtab";
                   5140: char *bttime_name = "/etc/boottime";
                   5141: 
                   5142: domount()
                   5143: {
                   5144:        int fd;
                   5145:        struct mnttab mnttab;
                   5146:        struct mtab mtab;
                   5147:        register char *name;
                   5148:        struct stat sbuf;
                   5149:        time_t boottime;
                   5150:        int nothing();
                   5151:        char devname[MNTNSIZ+6] = "/dev/";
                   5152: 
                   5153:        mounted = FALSE;
                   5154:        name = fsname;                          /* strip off all initial */
                   5155:        while (*name++ != '\0') ;               /* directories in fsname */
                   5156:        while ( (*--name != '/') && (name>fsname) ) ;
                   5157:        if (*name == '/') name++;
                   5158: 
                   5159:        if ( stat(bttime_name, &sbuf) == -1 )
                   5160:                boottime = (time_t)0;
                   5161:        else
                   5162:                boottime = sbuf.st_mtime;
                   5163:                                
                   5164:        if ( (fd=open(mnttab_name, 0)) != (-1) ) {
                   5165:                while ( read(fd, &mnttab, sizeof(mnttab))==sizeof(mnttab) ) 
                   5166:                        if ( mnttab.mt_dev[0] && mnttab.mt_filsys[0] ) {
                   5167:                                strncpy(&devname[5], mnttab.mt_filsys, MNTNSIZ);
                   5168:                                devname[MNTNSIZ+5] = '\0';
                   5169:                                statit(devname, nothing);
                   5170:                                if (stats.st_rdev != fsysrdev)
                   5171:                                        continue;
                   5172:                                statit(mnttab.mt_dev, nothing);
                   5173:                                mounted = (stats.st_dev == fsysrdev);
                   5174:                                prmnttab(&mnttab, boottime);
                   5175:                                return;
                   5176:                        }
                   5177:        }
                   5178:        if ( (fd=open(mtab_name, 0)) != (-1) ) {
                   5179:                while ( read(fd, &mtab, sizeof(mtab))==sizeof(mtab) ) 
                   5180:                        if ( mtab.mt_name[0] && mtab.mt_special[0] ) {
                   5181:                                strncpy(&devname[5], mtab.mt_special, MNAMSIZ);
                   5182:                                devname[MNAMSIZ+5] = '\0';
                   5183:                                statit(devname, nothing);
                   5184:                                if (stats.st_rdev != fsysrdev)
                   5185:                                        continue;
                   5186:                                statit(mtab.mt_name, nothing);
                   5187:                                mounted = (stats.st_dev == fsysrdev);
                   5188:                                prmtab(&mtab);
                   5189:                                return;
                   5190:                        }
                   5191:        }
                   5192: 
                   5193:        if (fsysrdev == rootdev)
                   5194:                mounted = TRUE;
                   5195:        else
                   5196:                mounted = FALSE;
                   5197: 
                   5198: }
                   5199: 
                   5200: prmnttab(ptr, boottime)
                   5201: struct mnttab *ptr;
                   5202: time_t boottime;
                   5203: {
                   5204:        if (mounted) {
                   5205:                if (boottime < ptr->mt_time)
                   5206:                        boottime = ptr->mt_time;
                   5207:                printf("%s mounted on %.*s as of %s", fsname, MNTNSIZ, 
                   5208:                                        ptr->mt_dev, ctime(&boottime));
                   5209:        } else
                   5210:                printf("%s unmounted.  Last mounted on %.*s -- %s",
                   5211:                                                fsname, MNTNSIZ, ptr->mt_dev,
                   5212:                                                        ctime(&ptr->mt_time));
                   5213: }
                   5214: 
                   5215: 
                   5216: prmtab(ptr)
                   5217: struct mtab *ptr;
                   5218: {
                   5219:        if (mounted)
                   5220:                printf("%s mounted on %.*s\n", fsname, MNAMSIZ, ptr->mt_name);
                   5221:        else
                   5222:                printf("%s unmounted.  Last mounted on %.*s\n", fsname,
                   5223:                                                        MNAMSIZ, ptr->mt_name);
                   5224: }
                   5225: 
                   5226: nothing()
                   5227: {}
                   5228: ) {
                   5229:                if (boottime < ptr->mt_time)
                   5230:                        boottime = ptr->mt_time;
                   5231:                printf("%s mounted on fsck/is_fs.c   644      3      3        3467  4705135657   6236 #include <sys/stat.h>
                   5232: #include <canon.h>
                   5233: #include <sys/filsys.h>
                   5234: 
                   5235: /*
                   5236:  * Check if a special file is a well-formed filesystem.
                   5237:  * This routine is derived from code in "mount.c".
                   5238:  * Return values:
                   5239:  *     -1      Not a device, cannot open, read or seek failed
                   5240:  *     0       No filesystem
                   5241:  *     1       Legal filesystem
                   5242:  */
                   5243: int
                   5244: is_fs(special) char *special;
                   5245: {
                   5246:        static struct filsys f;
                   5247:        struct stat sbuf;
                   5248:        register int fd;
                   5249:        register struct filsys *fp;
                   5250:        register daddr_t *dp;
                   5251:        register ino_t *ip, maxinode;
                   5252: 
                   5253:        if (stat(special, &sbuf) < 0)
                   5254:                return -1;                      /* cannot stat device */
                   5255:        else if ((sbuf.st_mode&S_IFMT) != S_IFBLK
                   5256:              && (sbuf.st_mode&S_IFMT) != S_IFCHR)
                   5257:                return -1;                      /* not a special file */
                   5258:        else if ((fd = open(special, 2)) < 0)
                   5259:                return -1;                      /* cannot open */
                   5260:        else if (lseek(fd, (long)SUPERI*BSIZE, 0) == -1L
                   5261:              || read(fd, &f, sizeof(f)) != sizeof(f)) {
                   5262:                close(fd);
                   5263:                return -1;                      /* seek or read failed */
                   5264:        } else
                   5265:                close(fd);                      /* so far so good */
                   5266: 
                   5267:        /* Canonical stuff. */
                   5268:        fp = &f;
                   5269:        canshort(fp->s_isize);
                   5270:        candaddr(fp->s_fsize);
                   5271:        canshort(fp->s_nfree);
                   5272:        for (dp = &fp->s_free[0]; dp < &fp->s_free[NICFREE]; dp += 1)
                   5273:                candaddr(*dp);
                   5274:        canshort(fp->s_ninode);
                   5275:        for (ip = &fp->s_inode[0]; ip < &fp->s_inode[NICINOD]; ip += 1)
                   5276:                canino(*ip);
                   5277:        candaddr(fp->s_tfree);
                   5278:        canino(fp->s_tinode);
                   5279: 
                   5280:        /* Test for rationality. */
                   5281:        maxinode = (fp->s_isize - INODEI) * INOPB + 1;
                   5282:        if (fp->s_isize >= fp->s_fsize)
                   5283:                return 0;
                   5284:        if ((fp->s_tfree < fp->s_nfree)
                   5285:        ||  (fp->s_tfree >= fp->s_fsize - fp->s_isize + 1))
                   5286:                return 0;
                   5287:        if ((fp->s_tinode < fp->s_ninode) || (fp->s_tinode >= maxinode-1 ))
                   5288:                return 0;
                   5289:        for (dp = &fp->s_free[0]; dp < &fp->s_free[fp->s_nfree]; dp += 1)
                   5290:                if ((*dp < fp->s_isize) || (*dp >= fp->s_fsize))
                   5291:                        return 0;
                   5292:        for (ip = &fp->s_inode[0]; ip < &fp->s_inode[fp->s_ninode]; ip += 1)
                   5293:                if ((*ip < 1) || (*ip > maxinode))
                   5294:                        return 0;
                   5295:        return 1;
                   5296: }
                   5297:  - INODEI) * INOPB + 1;
                   5298:        if (fp->s_isize >= fp->s_fsize)
                   5299:                return 0;
                   5300:        if ((fp->s_tfree < fp->s_nfree)
                   5301:        ||  (fp->s_tfree >= fp->s_fsize - fp->s_isize + 1))
                   5302:                return 0;
                   5303:        if ((fp->s_tinode < fp->s_ninode)fsck/link.c   644      3      3        2762  4664524116   6061 /*
                   5304:  *     Routines to handle the counting of links for each i-node
                   5305:  */
                   5306: 
                   5307: #include "fsck.h"
                   5308: 
                   5309: linkincr(inum)
                   5310: ino_t inum;
                   5311: {
                   5312:        if (inclinkctr(inum) == 0 )
                   5313:                fatal("Too many links in i-node, %d", inum);
                   5314: }
                   5315: 
                   5316: /*
                   5317:  *     The following is the beginning of thinking of how to change
                   5318:  *     the number of bits used in the link count tables from 8-per
                   5319:  *     i-node to 2-per i-node, with additional tables for those
                   5320:  *     i-nodes with more than 2 links.  The changes would be to the
                   5321:  *     definition of i_lnks, the macro linkctr(), the function linkincr(),
                   5322:  *     and in init.c, the allocation of table space.
                   5323:  */
                   5324: 
                   5325: #ifdef NEWLINKSTUFFF
                   5326: 
                   5327: char   *linkmap;       /* table of inodes with one link */
                   5328: 
                   5329: #define testlink(in)   ( linkmap[((unsigned)bn)>>(LOGNBPC-1)] & \
                   5330:                          3 << (((unsigned)bn)&(NBPC>>1)) )
                   5331: #define marklink(in)   ( linkmap[((unsigned)bn)>>(LOGNBPC-1)] |= \
                   5332:                          1 << (((unsigned)bn)&(NBPC-2)) )
                   5333: #define unmarklink(in) ( linkmap[((unsigned)bn)>>(LOGNBPC-1)] ^= \
                   5334:                          1 << (((unsigned)bn)&(NBPC-2)) )
                   5335: 
                   5336: linkcntr(inum)
                   5337: ino_t inum;
                   5338: {
                   5339:        index = ((unsigned) inum) >> (LOGNBPC-1) ;
                   5340:        distance = ((unsigned) inum) & ((NBPC>>1) - 1) ;
                   5341:        mask = 3 << distance;
                   5342:        answer = ( linkmap[index] & mask ) >> distance;
                   5343: 
                   5344:        if ( answer < 3 )
                   5345:                return(answer);
                   5346: 
                   5347:        hash = inum & 0xFF;
                   5348:        bucket = &linktable[hash];
                   5349:        bktinum = bucket->inumb;
                   5350: 
                   5351:        if ( bktinum == inum ) {
                   5352:                answer = bucket->numlink;
                   5353:                if ( answer == 0xFF )
                   5354:                        return( bigcntr(inum) );
                   5355:                else
                   5356:                        return( answer + 3 );
                   5357:        }
                   5358: 
                   5359:        if ( bktinum > inum )
                   5360:                fatal("internal linktable corruption.");
                   5361: 
                   5362:        
                   5363: }
                   5364: 
                   5365: linkincr(inum)
                   5366: ino_t inum;
                   5367: {
                   5368: }
                   5369: 
                   5370: #endif
                   5371: num) >> (LOGNBfsck/main.c   644      3      3       12436  5041134504   6053 /*                                       
                   5372:  * fsck  --  File System Check Program
                   5373:  * an interactive file system check and repair program.
                   5374:  *
                   5375:  * Usage:
                   5376:  *     /etc/fsck [-y] [-n] [-q] [-f] [-{sS}] [-t TMPFILE] [filesystem ...]
                   5377:  *     audit and interactively repair inconsistent conditions for
                   5378:  *     file systems.  Options -y and -n indicate an assumed response
                   5379:  *     to all questions asked by fsck.  Default is to prompt operator
                   5380:  *     for yes/no response.  Option -q is to quiet fsck from printing
                   5381:  *     certain messages, i.e. no size check messages, unreferenced
                   5382:  *     pipes will be silently removed, and counts in the superblock
                   5383:  *     will be automatically fixed and free list salvaged, if necessary.
                   5384:  *     Option -f is for a 'fast' check of the file system, i.e. only
                   5385:  *     check blocks, sizes, superblock counts, and the free list.
                   5386:  *     (-f) does not check pathnames, connectivity, or reference
                   5387:  *     counts.  Option -s forces the reconstruction (or salvaging) of
                   5388:  *     both the free inode list and the free block list, even if there
                   5389:  *     are no file system problems.  This will reorder the free block
                   5390:  *     list in the best order to limit additional fragmentation (respecting
                   5391:  *     interleaving as well).  Note: Option -s will be ignored on mounted
                   5392:  *     file systems.  The option -S acts in the same manner as -s except
                   5393:  *     that it will not be ignored on mounted file systems.  Beware: -S
                   5394:  *     on mounted file systems should only be used if you intend to reboot
                   5395:  *     NO SYNC immediately afterwards.  Option -t sets the temporary file
                   5396:  *     to use for disk caching of necessary tables on filesystems which are
                   5397:  *     too big to do in core. The temporary file defaults to "/dev/rram1",
                   5398:  *     which must be there.
                   5399:  */
                   5400: 
                   5401: #include "fsck.h"
                   5402: 
                   5403: int    errflag;
                   5404: 
                   5405: int    mdaction;                       /* default action for invocation */
                   5406: int    daction;                        /* default action for file system */
                   5407: int    gSflag=FALSE;                   /* force salvage flag ignored mounted */
                   5408: int    gsflag=FALSE;                   /* force salvage flag ignored mounted */
                   5409: int    sflag=FALSE;                    /* force salvage flag   */
                   5410: int    qflag=FALSE;                    /* fsck quiet flag      */
                   5411: int    fflag=FALSE;                    /* fsck fast flag       */
                   5412: 
                   5413: char *tmpfile = NULL;                  /* TMP file for virtual.c */
                   5414: char *checklistfile = "/etc/checklist";        /* default file for list of file */
                   5415:                                        /* systems to fsck. */
                   5416: char *filelist[NFILSYS];               /* list of filesystems */
                   5417: char word[MAXCH];                      /* hold single words */
                   5418: char *fsname;                          /* file system name */
                   5419: 
                   5420: dev_t  rootdev;                        /* root device number */
                   5421: dev_t  fsysrdev;                       /* file system real device number */
                   5422: int    mounted;                        /* flag for mounted file system */
                   5423: 
                   5424: int    changeflg;                      /* file system modified flag */
                   5425: 
                   5426: main(argc, argv)
                   5427: char *argv[];
                   5428: {
                   5429:        int yflag=0, nflag=0;
                   5430:        int retval;
                   5431: 
                   5432:        while (argc>1 && *argv[1]=='-') {
                   5433:                switch (argv[1][1]) {
                   5434:                case 'q':
                   5435:                        qflag = TRUE;
                   5436:                        break;
                   5437:                case 'y':
                   5438:                        yflag = 1;
                   5439:                        break;
                   5440:                case 'n':
                   5441:                        nflag = 1;
                   5442:                        break;
                   5443:                case 'f':
                   5444:                        fflag = TRUE;
                   5445:                        break;
                   5446:                case 'S':
                   5447:                        gSflag = TRUE;
                   5448:                        break;
                   5449:                case 's':
                   5450:                        gsflag = TRUE;
                   5451:                        break;
                   5452:                case 't':
                   5453:                        tmpfile = argv[2];
                   5454:                        argc--;
                   5455:                        argv++;
                   5456:                        break;
                   5457:                default:
                   5458:                        usage();
                   5459:                        break;
                   5460:                }
                   5461:        
                   5462:                argc--;
                   5463:                argv++;
                   5464:        }
                   5465:        
                   5466:        if ( yflag+nflag > 1 )
                   5467:                usage();
                   5468: 
                   5469:        mdaction = ( yflag ? YES :
                   5470:                    nflag ? NO : ASK );
                   5471: 
                   5472:        if ( argc > 1 )
                   5473:                retval = allfsck(argv+1);
                   5474:        else {
                   5475:                getlist();
                   5476:                retval = allfsck(filelist);
                   5477:        }
                   5478:        exit(retval);
                   5479: }
                   5480: 
                   5481: 
                   5482: /*
                   5483:  *     perform fsck on each of the individual filesystem in list
                   5484:  */
                   5485: 
                   5486: allfsck(fsl)
                   5487: register char **fsl;
                   5488: {
                   5489:        int fatal();
                   5490:        int retval = 0;
                   5491: 
                   5492:        sync();
                   5493:        statit("/", fatal);
                   5494:        rootdev = stats.st_dev;
                   5495:        while (*fsl != NULL)
                   5496:                retval |= fsck(*fsl++);
                   5497:        return(retval);
                   5498: }
                   5499: 
                   5500: /* 
                   5501:  *     get the names of the filesystems from the default file
                   5502:  *     checklistfile  (e.g. /etc/checklist)
                   5503:  */
                   5504: 
                   5505: getlist()
                   5506: {
                   5507:        int fd;
                   5508:        int index, size;
                   5509: 
                   5510:        if ( (fd = open(checklistfile, 0)) == (-1) )
                   5511:                fatal("Can't open checklist file: %s", checklistfile);
                   5512: 
                   5513:        index = 0;
                   5514:        while ( ((size = getword(fd)) != 0) && (index < NFILSYS) ) {
                   5515:                 filelist[index] = malloc( size );
                   5516:                strcpy(filelist[index++], word);
                   5517:        }
                   5518: 
                   5519:        if (size != 0) 
                   5520:                fatal("Too many file systems in checklist file: %s",
                   5521:                                                        checklistfile);
                   5522: 
                   5523:        filelist[index] = NULL;
                   5524: 
                   5525:        close(fd);
                   5526: }
                   5527: 
                   5528: /*
                   5529:  *     read in the next "word" from file with descriptor fd
                   5530:  *     return the length of the word.
                   5531:  */
                   5532: 
                   5533: getword(fd)
                   5534: int fd;
                   5535: {
                   5536:        int n = 0, num;
                   5537:        char *cp = word;
                   5538:        char ch;
                   5539: 
                   5540:        while ( ( (num=read(fd, &ch, 1)) == 1 ) &&
                   5541:                ( (ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r') ) );
                   5542: 
                   5543:        if (num != 1)
                   5544:                return(0);
                   5545: 
                   5546:        do {
                   5547:                *cp++ = ch;
                   5548:        } while (  (++n < MAXCH) && (read(fd, &ch, 1) == 1) &&
                   5549:                (ch != ' ') && (ch != '\t') && (ch != '\n') && (ch != '\r') );
                   5550:        
                   5551:        *cp = '\0';
                   5552: 
                   5553:        return(n+1);
                   5554: }
                   5555:        
                   5556: /*
                   5557:  *     perform fsck on the given filesystem
                   5558:  */
                   5559: fsck(name)
                   5560: char *name;
                   5561: {
                   5562:        int retval = 1;
                   5563:        int nonfatal();
                   5564: 
                   5565:        fsname = name;          /* file system name */
                   5566:        errflag = FALSE;
                   5567:        statit(fsname, nonfatal);
                   5568:        fsysrdev = stats.st_rdev;
                   5569:        if ( errflag )
                   5570:                return(retval);
                   5571:        changeflg = FALSE;
                   5572:        init();
                   5573:        if ( sflag = ((gsflag && !mounted) || gSflag) )
                   5574:                printf("Switch \"-s\" selected to automatically rebuild free lists\n");
                   5575:        if (!sflag && gsflag)
                   5576:                printf("Ignoring \"-s\" on mounted file system\n");
                   5577:        if ( !errflag ) {
                   5578:                phase1();       /* check blocks and sizes */
                   5579:                if ( !fflag ) {
                   5580:                        phase2();       /* check pathnames        */
                   5581:                        phase3();       /* check connectivity     */
                   5582:                        phase4();       /* check reference counts */
                   5583:                }
                   5584:                phase5();       /* check free list        */
                   5585:                phase6();       /* salvage free list      */
                   5586:                retval = cleanup();
                   5587:        }
                   5588:        return(retval);
                   5589: }
                   5590: 
                   5591: usage()
                   5592: {
                   5593:        printf("\
                   5594: Usage: /etc/fsck [-y] [-n] [-q] [-f] [-{sS}] [-t TMPFILE] [filesystem ...]\n");
                   5595:        _exit(1);
                   5596: }
                   5597: sflag && gsflag)
                   5598:                printf("Ignoring \"-s\" on mounted file system\n");
                   5599:        if ( !errflag ) {
                   5600:                phase1();       /* check blocks and sizes */
                   5601:                if ( !fflag ) {
                   5602:                        phase2();       /* check pathnames        */
                   5603:                        phase3();       /* check connectivity fsck/objects/   755      3      3           0  5045007474   6312 fsck/objects/main.o   644      3      3        4453  5045007122   7477 &0&pI&VW��F��F��~&��v
                   5604: �|�=-t��~
                   5605: �}�E&��B�CC.;��u`.�gSfnqsty~vo`��h�6&�;�F�&�4�F�&�-�8&�%�0&��2&��~
                   5606: �E�:�N�F
                   5607: ��r�N�F
                   5608: �c��F�F�=&~�Z�~�t���~�t���&��~&~�F
                   5609: @@P��Xh����F�P�����_^�VW��v�F����hhM��������<t�����5�=&��   F���F��_^�VW�j�6<�����F�=��u
�6<hO�����F��v��b���F��t-�~�
                   5610: }'�~���P�u�����h�~��F������\����Ã~�t
�6<hm�G����~���Dž�v��3����_^�VW��F��F�j&�F�P�v�����F�=&u�~� t�~�   t݀~�
                   5611: t׀~�
tу~�&t+��M�~��F��F����F��F�=},j&�F�P�v�����=&u�~� t�~� t�~�
                   5612: t�~�
u��~���F�@�_^�VW��F�&�F��hP�t������>ur��[��>2t�>t�>0t�&�+��4�t        h��2����>4u�>2t  h������>u���>8u       ���&��������������F��F��_^�VWU��h������j&������_^�>/etc/checklist/Can't open checklist file: %sToo many file systems in checklist file: %sSwitch "-s" selected to automatically rebuild free lists
                   5613: Ignoring "-s" on mounted file system
                   5614: Usage: /etc/fsck [-y] [-n] [-q] [-f] [-{sS}] [-t TMPFILE] [filesystem ...]
                   5615: daction_errflag_strcpy_main_fsck_ncleanup_stats_tmpfile_:open_init_gsflag_2fsysrdev_malloc_exit_fsname_getword_�&getlist_@&mounted_word_sync_fflag_8phase1_phase2_rootdev_phase3_phase4_phase5_phase6_fatal_qflag_6sflag_4mdaction_printf_nonfatal_gSflag_0usage_close__exit_statit_checklistfile_<read_filelist_changeflg_allfsck_�$<00% 2 R T V X Z \ ^$b$x$�$�$�0�0�0�'�0�'�)0�7�
7&'&$&7&&'&' &0/&$J&7M&$\&$_&7b&0p&7�&'�&)'�&'�&)7�&$�&$�&7�&'�&)7�&$'�&7�&(7>('}'�&'�!7�&'�'�'�&'�*7�  $�'�$�$�$�7� $�$�$�7� '�&7�$�7�7�7777    $7 7&%0usage_close__exit_statit_checklistfile_<read_filelist_changeflg_allfsck_�$<00% 2 R T V X Z \fsck/objects/init.o   644      3      3        6460  5045007137   7524 &L�&�jVW�"�>u+����F�P�6������=��u*�F��v��6������=��u�6h`������~�u������&�~�uhw�h��6ho�t����F�P�6�f���=��u      �6h�렋F�%��Fށ~�`t�~� th��8���=t=������>u�&��&�_^�VW�hjj&������P�>P�u�u������>P�E�U+���@}-����P�F�����>P�u
                   5616: �u�����~��E�U
                   5617: F��+���d}F���>P���&���&�����>P���&���&���&���&�n����>P���&���&���&���&�T����>P���&���&�_^�VWU��>P�E�U�L�N����؋ʡL�N+�ѣ��>~"��;N|;Ls�>N|   "�>Lw�6�6N�6Lh��8���&�>P�E=@~ h�����>P��&=d~   h�����_^�VWU��FPh����j&�6h�~����_^�VW��F��>u�HH����F�jj�L�N��-&��RP�;����F�PP�v��v��*���+����_^�VW��Ɔ.�/Ɔ/�dƆ0�eƆ1�vƆ2�/Ɔ3���6��F�=u�N���=/t;6w�</u&F��X�P�6^�����=��udžT�džV����n���p���T���V�j�6Z�����F�=��u�jF�F�P�v��|���=Fun�~�t�~�t�j �F�P��3�P�Z���ƆS�hC��.�P�G����;u�hC�F�P�1����;u�&�+����V���T��F�P����j�6\������F�=��t}jB��v�P�v������=Buh��v�t�~�t�j �F�P��3�P�����ƆS�hC��.�P�����;u�hC��v�P�����;u�&�+����v�P�����;u�&���_^�VWU��>t=�~�F
                   5618: �V;UD|;EBs�~�EB�UD�F
                   5619: �V�F
                   5620: P�#���P�vj �6h[��FBP����P�vj �6hw�����
                   5621: �_^�VWU��>t�vj �6h���vj �6h�������_^�VWU���_^�
                   5622: 
7CMCan't open: %s%s: %s
                   5623: (NO WRITE)Can't stat: %sfile is not a block or character device; OK?Size check: fsize %U isize %uToo large free block countToo large free i-node count%r
                   5624: fsck: %s: Bad Super Block: %u
                   5625: /etc/mnttab/etc/mtab/etc/boottime%s mounted on %.*s as of %s%s unmounted.  Last mounted on %.*s -- %s%s mounted on %.*s
                   5626: %s unmounted.  Last mounted on %.*s
                   5627: fsize_Lfstat_daction_errflag_numfiles_fsfd_mtab_name_\isize_writeflg_dupblck_Pprmnttab_�checksuper_�&stats_ninodes_open_init_fsysrdev_query_nothing_Ctotfree_fsname_offsets_Rstat_mounted__canl_bread_fflag_lrdivrootdev_bttime_name_^sbp_Pprmtab_mnttab_name_Zalloctables_�domount_�initV_readsuper_�sbpfix_mdaction_superb_ctime_strncpy_printf_nonfatal_totdups_badsuper_dstatit_read_'P''&'7'#'477'='F$I7L+0R'\'b'i&'l'p${$�'�$�7�*'�7�&'�$�$�7�0�'�%0�0�'�0�'�'�'7&$
&'&'$&7&$#&$9&$E&7N&$k&7v&$}&7�&$�&7�&$�&$�&$�&$�&'�&$�&$�&'�&'�&'�&'�&$�&$$$'$ $$$'0*'1$7$B0E$L$X0[$n7q*'z$}7�*'�'�'�
$�$�7�7�#'�,'�$Z$\$^'''%$679$e7h0v7�/7�) �7�.'�'� �7�.'�'�'�0�0�$�7&7/7<) G7O.'U'Y ^7f.'l'p'|0�'�'�'�'�'�7�('�$�7�('$7
                   5628: *''&$)'4$77:*�&'�$�$�7�0�'�%0�0�'�0�'�'�'7&$
&'&'$&7&$#&$9&$E&7N&$k&7v&$}&7�&$�&7�&$�&$�&$�&$�&'�&$�&$�&'�&'�&'�&'�&$�&$$$'$ $$$'0*'1$7$B0E$L$X0[$nfsck/objects/phase1.o   644      3      3        7042  5045007155   7737 &��&4>VWU��>u   h���������>t����_^�VW��&�F��F���;V�
}�;F�w�j�v��v������t
���F�&�V���h�v��v��������F��~�}MV�e���V�b��=&u*�>uWV�l��WV�7&���t�>uWV�p��V�(���G��@�F�뭃>u�|�h�v��v������j��_^�VWU��v�<u�|t�&�+��_^�VW��v�~
                   5629: �%��F��G&�CC.;��u:.�g
                   5630:  @`�{&s&o&w&]&jj        ��+�RP�����Qj��j��j��j��j&j       ��+�RP�t���Wh��j���=t"=uV���jj      ��+�RP�I����&�_^�VWU��^�G�W
                   5631: &�F@���v;�v��F����_^�VW�:�^�%��FƁ~��t�~�@t+��j
�FP�F�P�����+�������+���
}Z+���}P����;�}C����݋G̋WΉFȉV��tW�v
                   5632: R�v��.��=&t댋���������&�G�F롸&�_^�VW��F�N�u3��&��&���v�v
                   5633: �v�������v�v
                   5634: �v�������=&ur���P�v
                   5635: �v��������;�vT�ރ���W�F�V
                   5636: RP������F�V
                   5637: �u�^��������&���v�v�v
                   5638: �v�A����u�+��       �&������_^�VWU��vV�v
                   5639: �v�����=&uV�v
                   5640: �v��������_^�VWU���;V
                   5641: |r;Fwm�F�V
                   5642: ;|_;sY�&��>ujj
                   5643: �F+�RP�����v�v
                   5644: �vh��������=
                   5645: }��N�vh�����=t8=t6�6��;V
                   5646: |�;Fv��~
                   5647: |��~r��~&u��&��v���+��_^�VWU��j�v
                   5648: �v�����uj&�v
                   5649: �v�n����.&��&��&�>ujj
                   5650: �F+�RP�@����v�v
                   5651: �vh=�.����>}B�>����F�V
                   5652: ������=
                   5653: }��7�vhx�����=t!=t�hZ�����=t=t�����������+��_^�VW��v�%����D�T
                   5654: �F��V����u
RP�v
                   5655: �����v��v��v
                   5656: V����_^�VWU��~xu"�~u�v
                   5657: �v�vh��Z���=t=tK�~rw�~ s�v
                   5658: h��6����Ft�v
                   5659: h
                   5660: �#����v�v�^���t.�v
                   5661: h.����� �v�����jj        �F
                   5662: +�RP������&�_^�VWU���v�v
                   5663: ����t�vh[������_^�VW����       �������F��V��F�V
                   5664: ;V�|;F�w�F�V
                   5665: ��;V�|
                   5666: ;F�w�&�+��_^�&�@ Phase 1 : Check Blocks and Sizes
                   5667: Unknown File Type i-number = %u (Clear)Bad block %U, i-number = %u
                   5668: Excessive Bad Blocks i-number = %u (Continue)Dup Block %U, i-number = %u
                   5669: DUP Table Overflow (Continue)Excessive Dup Blocks i-number = %u (Continue)Bad Directory Size, size = %D, i-number = %u (Clear i-node)Directory Size too small i-number = %u
                   5670: Directory Misaligned i-number = %u
                   5671: Possible Directory Size Error i-number = %u
                   5672: Possible File Size Error i-number = %u
                   5673: fsize_checkmode_"&dupflag_inuse_&isize_phase1b_dupblck_checkbad_�checkblks_�&findblock_l3tol_inodescan_,query_numbad_totfree_checksize_Adirsize_�offsets_clrflg_numblks__canl_lostsize_bread_fflag_phase1_checkdup_pqflag_bwrite_dodirect_�zeroinode_�&blockcnt_�doblocks_�totdups_printf_sparsecnt_databuf_abort_numdup_filesize_"candino_sizerr_G'$
7!'0' 7&'@0K0S7^    'u#7~'�'�#7�'0�'�0�0�'�0�7�''�0�'�#7�0� 7& S& U& W& Y& [&7h& 7�&    $�&7�&0�&7�& '�&'�&'�&07'
                   5674: '1"'5"'8'<'?%'B
'X0|$�$�'�"'�"'�"'�"'�'�'�"'�"0�0�0�775$L$P'T"'X"0i0�0�'�'�'�0�'�7�    $7!'
'
$"7%'7'\'a0e7h$7~   7�    '�'�0�'�'�7�     $�7�!'� '� '� '�'�'�%'�%$
                   5675: 7
$7"74$79$0i0{$�7�$�7�!$�7�!0�$�7�!07        '0.$;7>!'N'R'�#7�'0�'�0�0�'�0�7�''�0�'�#7�0� 7& S& U& W& Y& [&7h&      7�&    $�&7�&0�&7�& '�&'�&'�&07'
                   5676: '1"'5"'8'<'?%'B
'X0|$�$�'�"'�"'�"'�"'�'�'�"'�"0�0�0�775$L$P'T"'X"0i0�0�'�'�'�0�'�7�    $7!'
'
$"7%'7'\'a0e7h$7~   7�    '�'�0�'�'�7�     $�7�!'� '� '� '�'�'�%'�%$
                   5677: 7
$7"74$79$0i0{$�7�$�7�!$�7�!0�$�7�!fsck/objects/phase1b.o   644      3      3        2472  5045007170  10100 &�>�&�VWU��>u       h��������_�_^�VW��F��F��F�;s8�~��F��������F��V�jRP�����u�j�v��v������F�뿋F���_^�VW��&�F��F���;V�|l;F�vgj�v��v��X����t
���F�&�V���h�v��v��8�����F��~�}�V�#���V����=&uWV����>t  G��@�F����_^�VW�:�v�~
                   5678: �%��FƁ~��t�~�@u^j
�DP�F�P�������F��~�
}=�F��~�}-�^���F�;�}�v�W�^�����w��w������F����F���_^�VW��FF
                   5679: u�&��v�v
                   5680: �v����tr=&uo�F�N�t؍��P�v
                   5681: �v�0����������dž�������}������������U�F�V
                   5682: RP������F�V
                   5683: �v�vRP�t����t�����+��_^�VWU��j�v
                   5684: �v������u�&�>�j�v
                   5685: �v�����>ujj
                   5686: �F+�RP�����v�v
                   5687: �vh�����+��_^�Phase 1b: Rescan for more Dups
                   5688: Dup Block %U, i-number = %u
                   5689: inuse_isize_phase1b_dupblck_findblock_l3tol_iscanb_zoffsets__canl_bread_fflag_dblocksb_�&qflag_cdupb_+totdups_printf_databuf_buildtable_numdup_ckblksb_&candino_'$
700'4'C'G7T7f't'�&7�'�7�      '�7�7�0�'�75&'<&'`&0w&0�&0�&7�&     7079'I7T'[
                   5690: 7l${7~findblock_l3tol_iscanb_zoffsets__canl_bread_fflag_dblocksb_�&qflag_cdupb_fsck/objects/phase2.o   644      3      3       11604  5045007207   7755 &��8�|VWU��>u    h��������j�}���_^�VWU��jjj���������u  h�����jjj����%=th�����=t
                   5691: =u�=���jjj�|�������th    �k���=t=t��Y�j�T����_^�VWU��>u    h.      �;���jjj�/���%��
Pj      jj����hj�������$��@hj������_^�VW�j������F����u
                   5692: �6��������E�~s�Z&w  �~
                   5693: s�O&���v�b&����j�>~�K�㋟�7�jhm       �ƃ�P�����n
                   5694: �^�F
                   5695: �V�؋ʃ�s��w��s��j     �>&~�KK�㋟�7�jho     �ƃ�P��&����n
                   5696: �^�~ws��~
                   5697: s���sd�~wr\�~
                   5698: rVV����=u=j�v�V�S&��j������^��G�u
                   5699: �6������^��G�F��^���G���n
                   5700: �^떃>t�v����u���v�4�����V����_^�VW��v� �F�;~�~�F����_^�VW��v���&�RPV�#����F��V��uhh�
����%h�v��v������h�����F��V����_^�VW���-&��RP�v������F��V��u+��h�K���h�v��v������&�_^�VWU��hr �����_^�VW��v�~
                   5701: �F�N�t��G�F���F���^�����_^�VW��v�|��F��v
                   5702: W�=����u�F�;FuW���=&t�v�p��v������_^�VW��v���D�F�;~�s��G�?u��I;�u��3;~�s;~�s��G�?t�;~�t����;~�s
��G�?/u���&�_^�VW��F-=w6����.��nx����F��  �!�F��  ��F��  ��F��  ��F��  ��F��  �6�6�v�h�   �O����>~�>O�狽�5�j�w&����>�狅@@P������_^�VW��v�<�u+���D�F�P������F�=&tP�6���;>v�v�W�&���t�V�����j��+�RP��������u   �v�W�&��j��+�RP��������t'�v�W��&���u�j��+�RP�t���%=u�f�W�b����j��+�RP�P���%�_^�VWU��~��&�_^�VW��F��F�;}�~��F��狅@@P�$�����v����F�
                   5703: j&�F�Pj&������_^�VWU��~�}
uWh�    �������vjh� ������_^�VWU��h�v�������u�vh�  ����+����Y�vh'
                   5704: �����t�������t�5h7
                   5705: ��thB
                   5706: �f����4hM
                   5707: �[����D8P�Q���P�t
                   5708: �thX
                   5709: �A����D�T
                   5710: �_^�VWU���vhs
                   5711: �&����v
                   5712: ������6������_^�VW�h�
                   5713: �����v�=����F��V��v
                   5714: �����>t!�F�F�u�>u�6�h�
                   5715: �������
                   5716: �6������_^�VWU��j�F+�RP����%����uh�
                   5717: �h�
                   5718: h�
                   5719: �����v������v
                   5720: �A����6��g����_^�VWU��vj��+�RP�M���%=uV��jj
                   5721: ��+�RP�.���hV�$�����j
PhT�������%�=@t
                   5722: Vh�
                   5723: ��������w
                   5724: �whT��������=t7�>2|�M���㉿�5�`�����>��}�6�������W�����_^�VWU���vh�����_^�VWU��hA�{���hQ�B����l��_^�P      j
                   5725: Phase 2 : Check Pathnames
                   5726: Root i-node is unallocated.  TerminatingRoot i-node is not a directory (FIX)Dup/Bad blocks in root i-node (Continue)File System Read-Only (NO WRITE)
                   5727: Can't malloc memory, phase 2...Fixblock error.Null nameNon null paddedEmbedded slashes inInconsistent .Inconsistent ..Bad%s entry in block %U in directory
                   5728: /%s/%*si-number = %u is in a bad inode block.
                   5729: i-number = %u, Owner=%s, Owner=%u,  Mode=0%o
                   5730: Size=%U, Mtime=%s(Remove)I-number is out of range  I=%u
                   5731: Unallocated
                   5732: %s [Forced - Yes]
                   5733: Bad or Dup blocks in %s
                   5734: DirectoryFileTried to checkpath i-node %u which is not dir.
                   5735: I-node %u is a multiply referenced directory i-node.
                   5736: Name too long.
                   5737: candblock_�fixflag_free_daction_numfiles_writeflg_imap_getpwuid_bclear_write_checkpath_�findblock_path_dl3tol_unalloc_�buf2_baddup_Qninodes_writeino_circle_eirange_�query_malloc_copy_~mounted_action_bread_toolong_zblkerr_Tcheckroot_*phase2_zeroent_�procfiles_&fatal_format_�fixblkerr_lnextblock_�fixroot_�qflag_bwrite_remove_�pname_�ctime_fixblock_!printf_depth_databuf_cdbn_abort_strcmp_chck_�memory_�linkincr_blocknum_prdirsize_pinfo_Fptrino_cdots_�'&$
7,0'-0!76$D7G!7S$a7d0t7y07�$�7�7�07�4'�$�7�!7�7�'�.7�8'�.7&$�7&$$&7'&!0<&0G&'K&/'Q&/0Y&'`&&'e&.'k&-'r&-'y&$�&0�&'�&0�&0�&'�&-'�&-'�&$�&0�&'�&0�&0'.00)71$B7E!'n&0w0�0�'�&'�.0�'�/'�/'�/'�/7�'�.7�'�.7'.0'5'5'(/',/7:'N.0Q'W.7`'$r7u!7�10�0�7�4 l n p r t v${$�$�$�$�$�'�5'�5$�7�,'�-'�-'�0�'�-'�-'�0�'�-00
0'#0,077G0Y7f0x7�0�7�4'�7�'�&'�-'�0�0�7     $*7-,$:7=,'L7R8$a7d,$s7v,7$�$�7�,$�7�,7�*$�7�,$�$�7�,0�$�7�$�7�,00'',$3$679,$E7H7`$p$u$x7{,0�0�$�7�7�0�0�7�'�.7�8%�%�7�
%�$&7!%%0'%-0+'/-'3-'90>'E-%I%P7S7\$n7q,$�7�,$�0�7�0$r7u!7�10�0�7�4 l n p r t v${$�$�$�$�$�'�5'�5$�7�,'�-'�-'�0�'�-'�-'�0�'�-00
fsck/objects/phase3.o   644      3      3        6464  5050255263   7751 &l6&4 FVW��>u       h{������F��F�;wFj+�RP�����%=u-j�F�+�RP�����uj j
                   5738: �F�+�RP�����v��<���F���F��F�;s"j+�RP����%`= u   �v�� &���F����_^�VW�>j�F+�RP�P�������t��h�v�9����F��~��E�U
                   5739: �F‰V��y��u�u��j
�F�P�F�P�������F�P������F��F� �n� �^��F‹V��x~u�tx�~�wrp�~�rj�~�sR�~�wrJ�~�rD�~���F��t*j+�RP����%=u�F�;Ftj@j
                   5740: +�RP�t����F��n��^�맍F�P�\����F���_^�VWU��h��C����v�:����t�>t�>&u�6n�����u��6nh�����j�v����_^�VW�@�F��I�F��t+j+�RP�����%=uj�F�+�RP���������t��&&h�v������F�j
P�F�P�����~��E�U
                   5741: �FĉV����~�ws���~�s���F�P�^����F��~�sփn��^��~ƒ=t��F�j�v�W��P�F�@@P�"����F�P�����u���v������~�y�FċVƋ~�)EU
                   5742: �F�&�~
                   5743: u3�v��v�&��=u"�~��Eh�v�������v��vj&�@����~�th�v������&� �F��:���~
                   5744: u�v��vj�   ��+��_^�VW�0�6l�v�F�P�s��h�j�F�P�d���v
                   5745: �o��P�v
                   5746: �F�P�M����~&u�>���F��
�>���F����>���FЉ��v
                   5747: ������_^�VWU��F
                   5748: �~�j�v�F@@P������_^�VW�<j�F+�RP��������t �v����h�v�����F�j
P�F�P�����~��E�U
                   5749: �FƉV����~�ws��~�r}�F�P�R����F��~�sك~�wrу~�r�h��F�@@P�)����u8�vh������~��5h������F
                   5750: �~ĉ�F�P������u������n��^��F���v�����_^�VWU���vh������_^�VWU���vh1�����_^�VW�hj�����F�j
Ph������~��E�U
                   5751: �F��V����~�wrR�~�rLh��P����F��~�s݃~�wrՃ~�r��6l�F�@@P�&����u�~����n��^��F���+��_^�VWU���6lhd������_^�VWU���6lh~������_^�VWU��v�
ƅ�t&�~"O�ߋ�+�.�6j��0����+�.�6j���֍��_^�
                   5752: p�lost+foundPhase 3 : Check Connectivity
                   5753: (Reconnect)Unref Dir
                   5754: %s FORCED
                   5755: ??..Dir i-number = %u connected.  Parent was i-number = %u.
                   5756: Dir i-number = %u connected.  It has bad/dup blocks.
                   5757: Dir i-number = %u connected.  It has no .. entry.
                   5758: Sorry.  No %s directory.
                   5759: Sorry.  No space in %s directory.
                   5760: daction_numfiles_lostname_lnoparent_Iconnect_checkpath_traverse_�findblock_path_l3tol_buf2_ninodes_writeino_dirinit_connected_6markchildren_�mounted_nameit_(action_reconnect_nphase3_fixblkerr_nextblock_qflag_badconnect_4fixblock_strncpy_printf_depth_cdbn_databuf_strcmp_noroom_linkincr_pinfo_ptrino_namebuf_lostfound_^nolost_�unrefdir_�&$l'$7' 7+7B7W0`'t70�7�0�'�7�#0�0�7�      '&&'&7&'&'G&7l&7�&7�&'�&$n$�&7�&7�&"'�&'�&$�&7�&$�&$�&7�&0�&07#7:0H0K'N
                   5761: 7T#7g      '}'�0�0�7�'�'�0�0�7�7�7�7�!'�&0&'7
                   5762: 7=0K'Y
                   5763: 7_0n0q0�$�0�$�0�0�0�'�'�'�'�'�'�'�'�'77-7F0W0Z']7c#7v       '�'�0�7�'�'�$�7�$�7�$�7�770($=7@$R7U'e7j#%y7|      '�'�%�7�'�'�$�7�$$7    $$7'5$ J'S$ \'d$0�0�7�    '&&'&7&'&'G&7l&7�&7�&'�&$n$�&7�&7�&"'�&'�&$�&7�&$�&$�&7�&0�&07#7:0H0K'N
                   5764: 7T#7g      '}'�0�0�7�'�'�0�0�7�7�7�7�!'�&0&'fsck/objects/phase4.o   644      3      3        6171  5045007242   7741 &H&�VW��>u     hN������F��F�;v��j+�RP���������t�v��F��=u�F���j�F�+�RP�����u<j�F�+�RP����%=t%j�F�+�RP�|�������t�v�����=t�j�F�+�RP�W����u(j�F�+�RP�D�������t�v����=u�q��v��?���F�=��u�F��Y�j�F�+�RP����;F�u�B��v��v��&���3���_^�VW��v����%���t��u=��������AA��+҉F��V�jRP�����t
                   5765: ��t����'hV�v��v���������V�F�P�{����^��G�_^�VW��>&u&j�F+�RP�U���%=u�v������v�5���Ph�+����v�"����F��V��>t1�u-�>u&j�F+�RP�����%=u�6Hh��������6�����=&uj�v������u�v������_^�VWU���6H����=&u�v�������_^�VW�h�v�y����F�P�o���h�v�c���jj �F+�RP�R���jj
�F+�RP�A����_^�VWU���v�/���Ph��%����v����j�F+�RP�
���P�v
                   5766: h������6J�����=&u        �v����_^�VW�h�v������F�j�F+�RP������~��Eh�v�����_^�VWU���v����Ph������v�����v������_^�VWU���v�n���Ph��d����v�[����v�����_^�VW��F��F��F�;wj+�RP�)�������u�F��F����F��F���;V�|%;F�v j�v��v�������t�n��F�&�V��Ћ>���&;F�t7�>u�>th�����6L����=&u�F��>���&�&�>t�>&t�>&t��u���_^�VW�
                   5767: �>��&�F�=dv+���F��F�;F�r��~���>��
                   5768: &�F��~������GG��+҉F��V�jRP�����t�~�u��~�u��~�r��F�;w�j+�RP���������u�j�F�+�RP��������ǀt�o�h�j
                   5769: �F�+�RP�����F��a��&�_^�VW��&�F��F��F�;wQ�~�d}Kj+�RP��������u2�~������GG��+҉F��V�jRP�Z����t�~�u    �~�u�F��F�릋F��>��&�F��F�;wa�~�~[j+�RP��������uB�~������GG��+҉F��V�jRP������t�~�u�~�u�N��~���>�F���
                   5770: &�F��h,�����_^�p��Phase 4 : Check Reference Counts
                   5771: (Clear i-node)Unref %s
                   5772: %s [Forced - Yes]
                   5773: (Adjust)Link Count discrepancy in %s
                   5774: Count = %u, should be %u Unref %s
                   5775: Bad/Dup blocks in %s
                   5776: (FIX)Free i-node count wrong in superblock.  Free i-node list in superblock rebuilt.
                   5777: linkprob_�unrefclr_Ydaction_typename_isize_fixit_Lclearit_Hrebuild_Qconnect_findblock_getlink_&ninodes_writeino_mounted_lostsize_action_bread_reconnect_sbp_phase4_askclear_Ofreeilist_�adjust_Jqflag_badilist_�sbpfix_sflag_unreflink_�&zeroinode_printf_databuf_doclear_xbddp_�ptrino_pinfo_candino_chglink_'$7' 0%7. 0?7X 7k    7�    0�7� 7�    0�0�0�0�7�        0&0&0&0&7T&        %h&7q&%|&7�&#$H'�&7�&    0�&0�&7�&$�&7�&7�&"'�&'�&
7  $$7'!7$740A$V7Y0g'7�!7�'�7�7�   7�    $J7�$�7�7�"7�       $�7�$70'&7,!7>       'J7P7b$i7l7u"0~7�$�7�7�"0�$L'�7�        '�7
       '&'3':$@7C$J7M'\'d'j'q'x0~0�'�0�0�'�7�      '7       7"    007? 0H'Y'l7}       7�    '�'�7�  7    '-$<7?%7.     0?7X 7k    7�    0�7� 7�    0�0�0�0�7�        0&0&0&0&7T&        %h&7q&%|&7�&#$H'�&7�&    0�&0�&7�&$�&7�&7�&"'�&'�&
7  $$7'!7$740A$V7Y0g'7�!7�'�7�7�   7�    $J7�$�7�7�"7�       $�7�$70'&7,!7>       'J7P7b$i7l7u"0~7�$�7�7�"0�$L'�7�        '�7
       '&'3':$@7C$J7M'\'dfsck/objects/phase5.o   644      3      3        4231  5045007255   7741 &�&D�&VW��>u      h��������F�jj����-&��RP������F�P����+��У�����v������>u�>t���_^�VW��F��F��~�=u��=@v�&h��N�����F�&�~�F�;}0�~���~�u�u�Y&���F�=&u
�F�&�V��F��̃~�t��~�tU�~�tO�~�u�u�#&��=&u;�F�&�V�h�~�u�u������F�v��&���t�N��&h��]��~�u      ���>���&���&;u;t?�>u�>th��s����6�i���=&u���>���&���&�&�6�6h��0���6�6h�����+F�V�RPh+����_^�VWU��F
                   5778: Ft+�~|�~
                   5779: &vh?�hA�v�v
                   5780: �v������&�_^�VWU���;V
                   5781: |;Fw�F�V
                   5782: ;|9;r3�&�&�����|��
                   5783: vhB�Y���P+��Lj�v
                   5784: �v�g����t)�&�&�����|˃�
                   5785: v�hF�j�v
                   5786: �v�,����&�_^�VWU���vhJ����hl����=u����_^�VW��v�<@v+��2+�;<})����ƉF�������w�w������^��G�WG�Ӹ&�_^�VWU��>t�>u�>u
hw�����t�&�_^�Phase 5 : Check Free List
                   5787: Bad freeblock count.
                   5788: Bad freeblock count.
                   5789: Free Block count wrong in superblock.  %U Bad Block%s in Free List
                   5790: %U Dup Block%s in Free List
                   5791: %U Block%s missing
                   5792: sbaddupExcessive %s blocks in free list (Continue)Bad Free List (SALVAGE)fsize_daction_asksalvage_Qstopit_�isize_fixit_findblock_badcnt_query_chk_2totfree__canl_action_bread_badflag_lrdivfixerup_sbp_phase5_qflag_sbpfix_sflag_dupcnt_canfblk_       copyV_printf_databuf_report_�&freetrav_�'$7''$'(797C'M'Q'T'X'\0d'k'q'x0~0�'�$�7�0�0�0
&' &7,&
'4&0:&0D&'H&$M&0P&'Z&0_&'c&'o&
                   5793: 'u&
                   5794: '{&'�&&$�&7�&'�&7�&'�&
                   5795: '�&
                   5796: '�&'�&'�&'�&$�&0�&'�&'�&$�&0�&'�&
                   5797: '�&
                   5798: $�&0�&$$7#'*'8'O'W']'c'h'm'q$�0�7�'�'�'�'�'�$�7�$�7�$�7�79'X&'_'f$l7o'z  copyV_printf_databuf_report_�&freetrav_�'$7''$'(797C'M'Q'T'X'\0d'k'q'x0~0�'�$�7�0�0�0
&' &7,&
'4&0:&0D&'H&$M&0P&'Z&0_&'c&'o&
                   5799: 'u&
                   5800: '{&'�&&$�&7�&'�&7�&'�&
                   5801: '�&
                   5802: '�&'�&'�&'�&$�&0�&'�&'�&$�&0�&'�&
                   5803: '�&
                   5804: $�fsck/objects/phase6.o   644      3      3        4104  5045007271   7737 &b�0�&VWU��>t$�>u      hb�������t
�&�6 ������_^�VWU�����&�*���&�,�>,��*;,�,��>*�t*h����h������&�,����&�&�*���&�6,�g���� �uh��W���h��N���+��w�,H��>,�.,�ȋ���"�$�,�RP�RP�6�6����RP�����&�(�,��>*��+�;6,}�� �ƙ�����.*�ȋƙ����F�۸&�_^�VW�
                   5805: �&�����&����>|      �>@s���@�F��>��F��)���@@����F��V��F��V�;|@;s:�v��v������F��V�jRP�/����u�v��v�����t
                   5806: �F�&�V���_^�VW��.�>�F�V
                   5807: ��U�@@;s��>u�>&t�6����h�6�6����hh�����uh�v
                   5808: �v����+��M�F�V
                   5809: ����>|    �>@s���@�F��>��F��)���@@��&�_^�VW��F�V
                   5810: ;$|G;"rA�F�V
                   5811: ;(|3;&s-�,�RP�v
                   5812: �v�����F��)FV
                   5813: �> ��*�&FV
                   5814: �F�V
                   5815: �_^�VW��v+�;<})����ƉF�������w�w�����^��G�WG���_^�Phase 6 : Salvage Free List
                   5816: Invalid interleave factors in superblock.
                   5817: Default free-block list spacing assumed.
                   5818: Can't malloc space for interleave table.
                   5819: Free-block list is not rebuilt.
                   5820: fsize_free_isize_maketable_4bclear_findblock_malloc_totfree__canl_lrdivlrremfixerup_sbp_phase6_canwfblk_%addfree_�&qflag_sbpfix_bwrite_lrmulwritefree_4&freeblks_fblkp_printf_dp_blknm_databuf_bmap_�''$700$%(7+&';%B%I%M%T%X%]%b$i7l$r7u%~'�%�%�7�%�$�7�$�7�'�%�%�%�%�%�%�'�'�7� 7�%�%�%�%&%
                   5821: &%&%&'<&'A&'E&'H&'L&'P&'V&'[&'a&'e&'n&'t&'�&'�&'�&'�&'�&'�&'�&0�&7�&0�&'�&'''0' '''.01'7';'?7B'K7N'T'X']7f'v'z'~'�'�'�'�'�'�'�'�%�%�%�%�%�7�
                   5822: %7Lm_databuf_bmap_�''$700$%(7+&';%B%I%M%T%X%]%b$i7l$r7u%~'�%�%�7�%�$�7�$�7�'�%�%�%�%�%�%�'�'�7�  7�%�%�%�%&%
                   5823: &%&%&'<&'A&'E&'H&'L&'P&'V&'[&'a&'e&'n&'t&'�&'�&'�&'�&'�&'�&'�&0�&7�&0�&'�&'''0' '''.01'7';'?7B'K7N'T'X']7f'v'z'~fsck/objects/cleanup.o   644      3      3        2674  5045007303  10206 &�&��&&VW��F��>&u�$���>&u�&�F��6���������F��_^�VW��>�u�u�����>�E�U+���@}-�����F�����>�u
                   5824: �u�����~��E�U
                   5825: F��+���d}F���>���&���&�Z����>���&���&���&���&�@����>���&���&���&���&�&����>���&���&Wjj&�����_^�VWU��>u
�6h�&��������؋ʡ�+��+RPh�&������6�6h�&�����t`jh����-&��RP�������>u�>&th0�h2�6�6h�d���h3�[���h[�R����_^�VW��F��6hk�6����>th��&����F�&�F��_^�%u files %U blocks %U free
                   5826: Expect roughly %U missing block%s next
                   5827: stime fsck is run as a result of inodes being cleared.
                   5828:  ***** File System %s was modified *****
                   5829:  ***** BOOT Coherent (NO SYNC!) *****
                   5830: fsize_numfiles_fsfd_isize_cleanup_totfree_fsname_mounted_advise_�&lostsize__canl_fflag_lrdivsbp_prtstats_�sbpfix_bwrite_printf_close_cleanV_writesuper_9changeflg_'
00'0 ''7*70'A
7J
                   5831: 'Q
'g
's
7|
                   5832: '�
7�
                   5833: '�
7�
                   5834: '�
7�
                   5835: '�
7�'�'&&$ &7&'&'&'&'&&'*&$/&72&'9&'=&$@&7C&'I&    'M&    'W&    '[&    7l&'r&       'v&    'z&    '�&    $�&$�&'�&      '�&    $�&7�&$�&7�&$�&7�&'�&$�&7�&'�&$�&7�&fflag_lrdivsbp_fsck/objects/util.o   644      3      3        7635  5045007407   7543 &��&�IVWU��h�v�����=��ujh�_���vh
                   5836: �V
                   5837: ���_^�VWU��FPh������H=w�����.��Uti[h(������h9������6=Nt=Yt�본�_^�VWU���v����=t
                   5838: =u�&�+��_^�VW�j�F�Pj�B����F��~�~�u       hI����F��F�;F�}����E���F�= t�~�       u�F��݃~�a|
                   5839: �~�z�n� �F��_^�VWU��j�F+�RP�����%-=w,����.��>&M&H&R&W&\&���������
���������_^�VWU��h�����_^�VWU��FPh��w���j&�o����_^�VWU��FPh��Y����&�_^�VW��v�~
                   5840: ��������AA��+҉F��V�jRP�#����t�~�u�~�t+��'W�v��v��
                   5841: ������%��ljF�P�G���F��_^�VW��F��%��F
                   5842: �F�P�!���v
                   5843: �~�����GG��+�RP����_^�VWU��v�t
                   5844: �t�����D�T
                   5845: �t6�t4�����D4�T6�t:�t8�o����D8�T:�t>�t<�]����D<�T>�_^�VW�
                   5846: �F��~�|�<&�~����F
                   5847: �V;��|~�&;��r�&�~�t�~�O��������)F
                   5848: V�F����P�v�v
                   5849: ������F��V��~����������v�v
                   5850: ������F
                   5851: �V�^��������F����F����T�F��V��u��F��N���h�v��v�����F����P�v�v
                   5852: �m����F��V��~����������v�v
                   5853: �M����F
                   5854: �V�F�������T�F��V��t��T�F��V�RP�����F��V��r��F��V��
                   5855: �F���+����_^�VWU��v�~
                   5856: x�F�V
                   5857: ;|0;r*�v
                   5858: �v�6������=t=uhV�2�������;V
                   5859: |;FvV�v
                   5860: �v�&���t�j�F�V
                   5861: �      ������RP�6�n������Ǚ�؋ʃ��u$���u�v
                   5862: �v�6�|���=t=t����hV�6�.���=t �v
                   5863: �v�6�J���=t=u�M��n��_^�VWU��>u���~
                   5864: x�F�V
                   5865: ;|(;r"�v
                   5866: �v�6������=t
                   5867: =u����j�F�V
                   5868: �      ������RP�6�������Ǚ�؋ʃ��u$���u�v
                   5869: �v�6����=t=t^����h�v�6�[���=t�v
                   5870: �v�6�w���=t=t*�����;V
                   5871: |;Fr�v�v
                   5872: �v�&���&�_^�VW��v��;V
                   5873: |
                   5874: ;Fs+�����;V
                   5875: |A;Fw<��;V
                   5876: |1;Fr,���؋ʋF�V
                   5877: +�ѹ  ������T       PV�����&��F��F�V
                   5878: ��-&���;~���+@��  �F�j�F�V
                   5879: �      ������RP�6�R������Ǚ�؋ʃ��u���t�v�hT     �6�/���;F�t�����&�V�v
                   5880: �v�����_^�VWU��v��;V
                   5881: |;;Fw6��;V
                   5882: |+;Fr&V���؋ʋF�V
                   5883: +�ѹ  ������T       P����_^�VW��v�~
                   5884: �F��F��N��t��F�F���G���^�����_^�VWU��v�~
                   5885: �t    ��F�Ou��_^�VWU���;V
                   5886: |;Fw�F�V
                   5887: ;|;s�&�+��_^�Z_cu��
                   5888: ��@�@ 
                   5889: &�@ ��        -       ��Can not stat %s%r [yes/no]: [default - YES]
                   5890: [default - NO]
                   5891: Invalid ResponseFILEDIRCharacter SpecialBlock SpecialPIPEUnknown I-node typeabort.fsck: %r
                   5892: fsck: %r
                   5893: Out of Range Block number: %U  (CONTINUE)Can not Seek: Blk num: %U  (CONTINUE)Can not Read: Blk num: %U  (CONTINUE)Can not Write: Blk num: %U  (CONTINUE)fsize_nunkwn_�daction_fsfd_errflag_typename_&writeflg_isize_chgcache_�bad_�imap_�nblk_�bclear_}write_nchr_�findblock_wtblkerr_ndir_�stats_blkmove_Kwriteino_getcache_�query_1lldivstat__canl_bread_action_�lrremfatal_z&bwrite_�nfile_�nonfatal_�&printf_lseek_databuf_rdblkerr_abort_h&_exit_statit_rgblkerr_�candino_\ptrino_�&npipe_�read_nextchar_�changeflg_high_skblkerr_'7'0$%$;7>!'D S U W Y$\7_!$j7m!0u0�7�,$�0�$�$�$�$�$�$�7%& <& >& @& B& D& F&$I&$N&$S&$X&$]&$b&$n&0q&$�&7�&!7�&&$�&7�&!'�&7�&0�&0090S7k7}7�7�0�$�0�$�0�$�$�$7$#$'70$@0b0o'r#0{$�7�$�$�7�'�#7�0�0�$�$$$''&$2050I0O0R'U0l0v'�7�"$�0�0�'�7�,$�0�0�0�'0''#$/020B0G'^7a"$�0�0�'�7�
$�0�0�'�0�'�.'�0$$$$4%O0T0]$c$x'|'�$�$�$�'�7�"%�'�7�,$�$�0�0�$$$#%>0B'�'�'�$�0�$�$�$�$�$�$�7%& <& >& @& B& D& F&$I&$N&$S&$X&$]&$b&$n&0q&$�&7�&!7�&&$�&7�&!'�&7�fsck/objects/fsck.o   644      3      3          54  5045007416   7440 &   644      3      3          54  5045007416   7440 fsck/objects/printf.o   644      3      3        2543  5045007431  10056 &LdoVWU��FP����_^�VW�Y�F�F��^���F��F��^��F�����=%t�u���LjF�j&�F�Pj&�������F� �F����F����^��F�������-u�F�&�^��F�������F���0u�F�0�^��F�������*u�^��F���F�^��F������,�F���0|"��9kF�
                   5894: �ȋ��-0�F�^��F������ك�.uU�^��F�������*u�^��F���F��^��F������,�F���0|"��9kF�
                   5895: �ȋ��-0�F��^��F������ك�lu"�^��F�������dt��ot
                   5896: ��ut��xu�� �F��F����ǻ�&�CC.;��t��.�gDOUXcdorsux�&M4Q��&�&�U�&�&�^��F���F�~�}�؉F��F�-j
                   5897: �v�V�b&������j
                   5898: �^��F��7��j��j��^���W�F�V�F��~�y���؃��F�V��F�-j
                   5899: �v��v�V�&���j
                   5900: �^��w�7V�p&�����F��fj��j��^���F��u�F�L�F��F��F�����F�?t�~�|��+F�;F�~�N�&�^��F���F��F�F蘈��^��7�g����F��F�F�+ƉF��}�F��~�u �F��N��t�F��F�j&�F�Pj&������;v�v�^��F���F�j&�F�Pj&��������~�u���F��N��u���F��F�j&�F�Pj&��������_^�VW��v
                   5901: �F��F��N��^����+��v���t �N��F��F��+��v�ڊ�T��^������N��^���T���^��?t�F�F�F��F����^���F�_^�VW��v�~�n��N�^���ǙRP�v�v
                   5902: �(����F�V��t4�N�F�F�ǙRP�v�v
                   5903: �����؊�T��^��F�V�F
                   5904: �V��N�F�F�F
                   5905: �؊�T��^��^�?t
��F�F��F�����_^�{NULL}0123456789ABCDEFwrite_xprintf_vrdivvrremprintf_0
                   5906: 0@7P t&0�& �& �& �& �& �& �& �& �& �& �& �&0�&0�&0-0@$d0�7�700!72$v$�7�7�$$)���_^�VW��v
                   5907: �F��F��N��^����+��v���t �N��F��F��+��v�ڊ�T��^������N��^���T���^��?t�F�F�F��F����^���F�_^�VW��v�~�n��N�^���ǙRP�v�vfsck/objects/link.o   644      3      3         273  5045007443   7472 &(<
VWU��j�F+�RP������u�vh(������_^�Too many links in i-node, %dfindblock_fatal_linkincr_7$7&fsck/objects/virtual.o   644      3      3       10046  5045007462  10263 &�r���&$VW�$�F+ңF�H�F
                   5908: +�FH�J�L�F+�JL�N�P�F+�NP�R�Th�jhV����h�jh������֋���F���F�+�;Tv�x&r        ;Rv�m&�>t���6��a���@=w%����.�������6�h���6�h!�6����F�P�6��(���=��t�F� t�F���%�=t
�6�hZ�&���j�6�������֋=��u
�6�h~������F��F��F��V�;Trv�;Rr�hh��6֋����=t  h������F��V��j�6�����֋=��uEh�&�6�r����֋=��u
�6h��]����6֋�S���j�6�G����֋�6�:����F�P�6֋�,���=��u
�6h������F�;u   h������_^�VW��>֋�u��6֋������>ux�F�P�6������=��t�F� t�F���%�=u�F�t
�6�h!     ����j�6������֋=��u
�6�hK        �����6֋�|����}
�6�hk      �k����_^�VW��F=
v��&����.������ZZZ����???�F�V
                   5909: %+ҋ��&����������F���F�V
                   5910: �������F�V
                   5911: �~
                   5912: yh�  h�h�   h�      �����j&������J�L&FV
                   5913: �F�V
                   5914: ;Pws�[&;Ns�R&h� h�h�   h�      �5&�F�V
                   5915: %+ҋ��&����������F���F�V
                   5916: �������F�V
                   5917: �~
                   5918: yh
                   5919: h�h�  h�      �_���j&�W����N�P&FV
                   5920: �F�V
                   5921: ;Tws��;Rs��h6
                   5922: h�h)
                   5923: h
                   5924: ��~
                   5925: xu �~uha
                   5926: h�hT
                   5927: h8
                   5928: �&���j&������F�H-&��&FV
                   5929: �F�V
                   5930: ;Lwrr;Jrlh�
                   5931: h�h
                   5932: hc
                   5933: �P�~
                   5934: xu �~uh�
                   5935: h�h�
                   5936: h�
                   5937: ����j&�����n&�^
                   5938: �F�V
                   5939: ;Hwr ;Frh�
                   5940: h�h�
                   5941: h�
                   5942: �n���j&�f����F�V
                   5943: %�&+҉F��      �F�V
                   5944: �������F�V
                   5945: %?+҉F���F�V
                   5946: �������F�V
                   5947: %�+҉F��F�V��v��拼V������+҉F�V�;V�u;F�u�*&�~�����V&tr��F�V��������F�V��~���    ��+�&F�V�R�v��v��6֋�����؋ʃ��u���u        h�
                   5948: ����h�F��� �P�6֋����=t      h�
                   5949: �s����F�+҉F�V���������F�V��~���  ��+�&F�V�R�v��v��6֋�8����؋ʃ��u���u        h�!���h�F���       �P�6֋�
                   5950: ���=thj�F���    �P������~���F���%����V&   �V�~��灥V����V�F���       F���F�F=
v�����.��^z���z����������~�*�#F���~��灥V����V&�F��~��*��r�~��灥V����V&�F��~�0�ߋ~��ڋ~��灥V����V&�F�~����~��灥V����V&�F뤋~��灥V����V&�~���h)������_^�VWȈ+��Љ�|���~���x���z��F+�;�~�ws�;�|�w�+����}7�F+�;�~�wr*;�|�v$���j��~���|��!����E�F��|�&��~���+����}��F+�;�z�wr�;�x�v�����E��Pj��z���x������F��x�&��z����_^���/dev/rram1/dev/rram1closeCan't access ram disk "%s", use the -t optionPossible file system on ram disk "%s", use the -t optionRam disk "%s" not mknod'ed properlyCannot open read/write Ram Disk "%s"Error writing to tmp fileCannot create temp file "%s"Can't stat temp file "%s"Temp File must not be on file system to fsckRam disk close "%s" not mknod'ed properlyCannot open Ram Disk Close "%s"Cannot close Ram Disk Close "%s"%s: %d: assert(%s) failed.
                   5951: ../virtual.cp%s: %d: assert(%s) failed.
                   5952: ../virtual.cp%s: %d: assert(%s) failed.
                   5953: ../virtual.cp%s: %d: assert(%s) failed.
                   5954: ../virtual.cp%s: %d: assert(%s) failed.
                   5955: ../virtual.cp%s: %d: assert(%s) failed.
                   5956: ../virtual.cp%s: %d: assert(%s) failed.
                   5957: ../virtual.cp%s: %d: assert(%s) failed.
                   5958: ../virtual.cpError seeking tmp fileError writing tmp fileError seeking tmp fileBad action in virtual systemfstat_write_findblock_�tmpfile_open_fsysrdev_exit_stat_fatal_initV_memset_creat_copyV_unlink_printf_lseek_is_fs_close_cleanV_�&read_$�$�%%%%% %$%-%1%4%8%A%E%H%L%T7W
                   5959: %b7e
                   5960: %l%|0�%�0�'�0�$�7� � � � �$�$�$�$�7�$�7�$�$�7�$&7   &%&$&$&7&%5&0<&%@&0E&%K&%O&7R&&$]&7`&'t&7w&%}&'�&7�&%�&'�&$�&7�&%�&7�&'�&7�&%�&'�&7�&
%�&7�&'�&$�&7�&'�&$�&7�&%0
%7'$&7)$Q$T7W$`7c%i$r$u7x%7�$�$�7�0� � � � � � � � � � � � � � � �$$$77%%%)%90@%D0I$L$R$U0X$�$�$�7�7�%�%�%�0�%�0�$�$�$�0�$�$�$�7�7%%%%%-$2$8$;$N$T$W7Z7b%w%$�$�$�7�7�%�0%%L7O$c7f%u%z7}&$�7�%�7�$�7�%�%�7�%
                   5961: 7
                   5962: %"%(%1%7%E0S \ ^ ` b d f h j l n p r t v x0�%�%�%�%�%�%�%�%�%�%$70D0M0y0�$�&7�&%0
%7'$&7)$Q$T7W$`7c%i$r$u7x%7�$�$�7�0� � � � � � � � � � � � � � � �$$$77%%%)%90@%D0I$L$R$U0X$�$�$�7�7�%�%�%�0�%�0�$�$�$�0�$�$�$�7�7%%%%%-$2$8$;$N$T$W7Z7b%w%$�$�$�7�7�%�0%%L7O$c7f%u%z7}&$�7�%�7�$�7�%�%�7�%
                   5963: 7
                   5964: %"%(%1%7%E0S \ ^ ` b d f h j l n p r t v x0�%�%�%�%�fsck/objects/is_fs.o   644      3      3        1347  5045007474   7667 &�&�&�EVW�$�F�P�v������}�����&�F�%�=`t�F�%�= u�j�v��������|�jjhV�����Ћ™�؋ʃ��u���th�&h�&V����=�&t      V�����V�|�����&�u�u�m����E�U�E�F��ρ�&�F�;�s�^��w�7�F����^���W�F��׍�
                   5965: &�Fދρ��&�F�;�s�F������&���&�������&���&�����@�F܋+�;Uwr
                   5966: ;Er+����E�;��&|�;��&w�+ҋ؋ʋE�U+��&�;��&r�w;��&vċ��&;�&r��F���;��&v��E�F��E���;F�v2�^��+�;Wrw�;w��^���W;U~�v�|;Er�l��F�뾍�
                   5967: &�Fދ�&���
                   5968: &;F�v�^ދ=&s�B�;F�v�:��F��ո&�_^�open_stat__canl_lseek_is_fs_close_read_7&0797M%i7m7y7�%�7�7�7�0&0�&0�&0�&0�&��^���W�F��׍�
                   5969: &�Fދρ��&�F�;�s�F������&���&�������&���&�����@�F܋+�;Uwr
                   5970: ;Er+����E�;��&|�;��&w�+ҋ؋ʋE�U+��&�;��&r�w;��&vċ��&;�&r��F���;��&v��E�F��E���;F�v2�^��+�;Wrw�;w��^���W;U~�v�|;Er�l��F�뾍�
                   5971: &�Fދ�&���
                   5972: &;F�v�^ދ=&s�Bfsck/phase1.c   644      3      3       16004  4767515610   6322 /*
                   5973:  *     phase 1 of fsck - Check Blocks and Sizes
                   5974:  */
                   5975: 
                   5976: #include "fsck.h"
                   5977: 
                   5978: char   databuf[BSIZE];         /* buffer for blocks */
                   5979: 
                   5980: int    clrflg;                 /* indicates when to clear an inode */
                   5981: int    dupflag;                /* indicates whether there are any dups */
                   5982: 
                   5983: int    numbad;                 /* number of bad blocks in the inode   */
                   5984: int    numdup;                 /* number of duplicate blocks in inode */
                   5985: long   numblks;                /* number of data blks for size check */
                   5986: long   sparsecnt;              /* count for sparse blocks for size check */
                   5987: 
                   5988: /*  The following is a table of the number of direct blocks pointed at by the
                   5989:  *  four types of blocks direct, ..., triple-indirect, to help count sparse
                   5990:  *  blocks.
                   5991:  */
                   5992: 
                   5993: daddr_t        blockcnt[] = {1, (daddr_t)NBN, (daddr_t)NBN*NBN, (daddr_t)NBN*NBN*NBN};
                   5994: 
                   5995: phase1()
                   5996: {
                   5997:        if (!qflag)
                   5998:                printf("Phase 1 : Check Blocks and Sizes\n");
                   5999:        dupflag = FALSE;
                   6000:        inodescan();
                   6001:        if (dupflag)
                   6002:                phase1b();      
                   6003: }
                   6004: 
                   6005: inodescan()
                   6006: {
                   6007:        register daddr_t bn;
                   6008:        register struct dinode *dip;
                   6009:        register ino_t  ino;
                   6010:        int i;
                   6011: 
                   6012:        ino = 1;
                   6013: 
                   6014:        for (bn=INODEI; bn<isize; bn++) {
                   6015:                if (testblock(bn)) {            /* block is bad via inode 1 */
                   6016:                        ino += INOPB;
                   6017:                        continue;
                   6018:                }
                   6019:                bread(bn, databuf);
                   6020:                clrflg = FALSE;
                   6021:                dip = (struct dinode *) databuf;
                   6022:                for (i=0; i<INOPB; i++) {
                   6023:                        candino(dip);
                   6024:                        if (inuse(dip) == TRUE) {
                   6025:                                if (!fflag) 
                   6026:                                        checkmode(dip, ino);
                   6027:                                if ( checkblks(dip, ino) != STOP ) 
                   6028:                                        if ( qflag == FALSE )
                   6029:                                                checksize(dip, ino);
                   6030:                        }
                   6031:                        candino(dip);
                   6032:                        ino++;
                   6033:                        dip++;
                   6034:                }
                   6035:                if (clrflg)
                   6036:                        bwrite(bn, databuf);
                   6037:        }
                   6038: }
                   6039: 
                   6040: /*
                   6041:  *     Determine if the given inode is in use.
                   6042:  */
                   6043: 
                   6044: inuse(dip)
                   6045: register struct dinode *dip;
                   6046: {
                   6047: #ifdef NOT_ALL_ZERO_INODE
                   6048: 
                   6049:        if ( (dip->di_mode != 0) || (dip->di_nlink != 0) )
                   6050:                return(TRUE);
                   6051:        else
                   6052:                return(FALSE);
                   6053: #endif
                   6054: #ifdef ALL_ZERO_INODE
                   6055: 
                   6056:        register char *ptr;
                   6057:        register struct dinode *next;
                   6058: 
                   6059:        ptr = (char *) dip;
                   6060:        next = dip + 1;
                   6061:        while (ptr < next)
                   6062:                if (*ptr++ != 0)
                   6063:                        return(TRUE);
                   6064: 
                   6065:        return(FALSE);
                   6066: #endif
                   6067: }
                   6068: 
                   6069: /*
                   6070:  *     Check the mode of the given inode
                   6071:  */
                   6072: 
                   6073: checkmode(dip, ino)
                   6074: register struct dinode *dip;
                   6075: register ino_t ino;
                   6076: {
                   6077:        register unsigned short mode;
                   6078: 
                   6079:        mode = dip->di_mode & IFMT;
                   6080: 
                   6081:        switch (mode) {
                   6082:        case IFREG:
                   6083:                setflags(ino, IREG);
                   6084:                return;
                   6085:        case IFDIR:
                   6086:                setflags(ino, IDIR);
                   6087:                return;
                   6088:        case IFCHR:
                   6089:                setflags(ino, ICHR);
                   6090:                return;
                   6091:        case IFBLK:
                   6092:                setflags(ino, IBLK);
                   6093:                return;
                   6094:        case IFPIPE:
                   6095:                setflags(ino, IPIPE);
                   6096:                return;
                   6097:        default:
                   6098:                setflags(ino, UNKNOWN);
                   6099:                break;
                   6100:        }
                   6101: 
                   6102:        switch ( query("Unknown File Type i-number = %u (Clear)", ino) ){
                   6103:        case NO:
                   6104:                return;
                   6105:        case YES:
                   6106:                zeroinode(dip);
                   6107:                setflags(ino, UNALLOC);
                   6108:                clrflg = TRUE;
                   6109:                break;
                   6110:        }
                   6111: }
                   6112: 
                   6113: /*
                   6114:  *     Zero the given inode
                   6115:  */
                   6116: 
                   6117: zeroinode(dip)
                   6118: struct dinode *dip;
                   6119: {
                   6120:        register char *ptr;
                   6121:        register struct dinode *next;
                   6122: 
                   6123:        lostsize += dip->di_size;
                   6124:        next = dip+1;
                   6125:        ptr = (char *) dip;
                   6126: 
                   6127:        while (ptr < next)
                   6128:                *ptr++ = 0;
                   6129: 
                   6130: }
                   6131: 
                   6132: /*
                   6133:  *     Check the blocks associated with the given inode to determine
                   6134:  *     if any are bad or duplicate
                   6135:  */
                   6136: 
                   6137: checkblks(dip, ino)
                   6138: struct dinode *dip;
                   6139: ino_t  ino;
                   6140: {
                   6141:        daddr_t addrs[NADDR];
                   6142:        register daddr_t bn;
                   6143:        register int i, lev;
                   6144:        register int mode;
                   6145: 
                   6146:        mode = dip->di_mode & IFMT;
                   6147: 
                   6148:        if ( (mode != IFREG) && (mode != IFDIR) )
                   6149:                return(STOP);
                   6150: 
                   6151:        l3tol(addrs, dip->di_addr, NADDR);
                   6152: 
                   6153:        numbad =                        /* number of bad blocks so far */
                   6154:        numdup =                        /* num dup blocks so far THIS INODE */
                   6155:        numblks =                       /* num used data blocks for size chk */
                   6156:        sparsecnt = 0;                  /* count of missed data blocks  */
                   6157: 
                   6158:        for(i=0; i<NADDR; i++)
                   6159:                for (lev=0; lev<4; lev++) 
                   6160:                        if (i < offsets[lev]) {
                   6161:                                if ( (bn=addrs[i]) != 0 ) {
                   6162:                                        if (doblocks(bn, ino, lev) != OK)
                   6163:                                                return(STOP);
                   6164:                                } else
                   6165:                                        sparsecnt += blockcnt[lev];
                   6166:                                break;
                   6167:                        }
                   6168:        return(OK);
                   6169: }
                   6170: 
                   6171: /*
                   6172:  *     Checks recursively the blocks pointed at via
                   6173:  *     the inode list of blocks.  'bn' is the block number,
                   6174:  *     'ino' is the inode referencing it, and 'lev' is the
                   6175:  *     level 0 == direct ... 3 = triple-indirect
                   6176:  */
                   6177: 
                   6178: doblocks(bn, ino, lev)
                   6179: register daddr_t bn;
                   6180: ino_t  ino;
                   6181: int    lev;
                   6182: {
                   6183:        char buf[BSIZE];
                   6184:        register daddr_t *bnptr;
                   6185:        register char *end;
                   6186:        register int flag;
                   6187: 
                   6188:        if (lev-- == 0) {               /* we have a direct block */
                   6189:                numblks += sparsecnt + 1;
                   6190:                sparsecnt = 0;
                   6191:                return(dodirect(bn, ino));
                   6192:        } else {
                   6193:                end = &buf[BSIZE];
                   6194:                if ( (flag=dodirect(bn, ino)) == OK ) {
                   6195:                        bread(bn, buf);
                   6196:                        bnptr = (long *) buf;
                   6197:                        while ( bnptr < end ) {
                   6198:                                bn = *bnptr++;
                   6199:                                candaddr(bn);
                   6200:                                if ( bn == 0 ) {
                   6201:                                        sparsecnt += blockcnt[lev];
                   6202:                                        continue;
                   6203:                                }
                   6204:                                if ( doblocks(bn, ino, lev) == STOP )
                   6205:                                        return(STOP);
                   6206:                        }
                   6207:                        return(OK);
                   6208:                } else 
                   6209:                        return(flag);
                   6210:        }
                   6211: }
                   6212:                        
                   6213: /*
                   6214:  *     Check the given block to determine if it is bad
                   6215:  *     or if it is a duplicate.  'ino' is the inode referencing it
                   6216:  */
                   6217: 
                   6218: dodirect(bn, ino)
                   6219: register daddr_t bn;
                   6220: register ino_t ino;
                   6221: {
                   6222:        register int flag;
                   6223:        
                   6224:        if ( (flag=checkbad(bn, ino)) == OK ) 
                   6225:                return( checkdup(bn, ino) );
                   6226:        else
                   6227:                return(flag);
                   6228: }
                   6229: 
                   6230: /*
                   6231:  *     Check the given block number for being bad.
                   6232:  */
                   6233: 
                   6234: checkbad(bn, ino)
                   6235: register daddr_t bn;
                   6236: ino_t  ino;
                   6237: {
                   6238:        if ( (bn>=isize) && (bn<fsize) )
                   6239:                return(OK);
                   6240: 
                   6241:        else if ( (bn<isize) && (bn>=INODEI) && (ino == 1) ) {
                   6242:                                                        /* bad block is in  */
                   6243:                totfree++;                              /* the inode blocks */
                   6244:                return(OK);
                   6245:        }
                   6246:                
                   6247:        if (!fflag)
                   6248:                orflags(ino, IBAD_IDUP);
                   6249: 
                   6250:        printf("Bad block %U, i-number = %u\n", bn, ino);
                   6251: 
                   6252:        if (numbad++ < MAXBADOK)
                   6253:                return(BAD_DUP);
                   6254: 
                   6255:        switch ( query("Excessive Bad Blocks i-number = %u (Continue)", ino) ){
                   6256:        case NO:
                   6257:                abort();
                   6258:        case YES:
                   6259:                return(STOP);
                   6260:        }
                   6261: }
                   6262: 
                   6263: 
                   6264: /*
                   6265:  *     Check the given block number for duplicate reference.
                   6266:  */
                   6267: 
                   6268: checkdup(bn, ino)
                   6269: register daddr_t bn;
                   6270: ino_t  ino;
                   6271: {
                   6272:        if ( !testblock(bn) ) {
                   6273:                markblock(bn);
                   6274:                totfree--;
                   6275:                return(OK);
                   6276:        }
                   6277: 
                   6278:        dupflag = TRUE;
                   6279:        if (!fflag)
                   6280:                orflags(ino, IBAD_IDUP);
                   6281:        printf("Dup Block %U, i-number = %u\n", bn, ino);
                   6282: 
                   6283:        if (totdups < DUPTBLSIZE) 
                   6284:                dupblck[totdups++] = bn;
                   6285:        else {
                   6286:                switch ( query("DUP Table Overflow (Continue)") ) {
                   6287:                case NO:
                   6288:                        abort();
                   6289:                case YES:
                   6290:                        return(BAD_DUP);
                   6291:                }
                   6292:        }
                   6293: 
                   6294:        if (numdup++ < MAXDUPOK)
                   6295:                return(BAD_DUP);
                   6296: 
                   6297:        switch ( query("Excessive Dup Blocks i-number = %u (Continue)", ino) ) {
                   6298:        case NO:
                   6299:                abort();
                   6300:        case YES:
                   6301:                return(STOP);
                   6302:        }
                   6303: }
                   6304: 
                   6305: /*
                   6306:  *     Check For Possible File Size Error 
                   6307:  */
                   6308: 
                   6309: checksize(dip, ino)
                   6310: register struct dinode *dip;
                   6311: ino_t  ino;
                   6312: {
                   6313:        register int mode;
                   6314:        register fsize_t size;
                   6315: 
                   6316:        mode = dip->di_mode & IFMT;
                   6317:        size = dip->di_size;
                   6318:        
                   6319:        if ( mode == IFREG )
                   6320:                filesize(ino, size);
                   6321:        else    /* mode == IFDIR */
                   6322:                dirsize(dip, ino, size);
                   6323: }
                   6324: 
                   6325: dirsize(dip, ino, size)
                   6326: struct dinode *dip;
                   6327: ino_t ino;
                   6328: register fsize_t size;
                   6329: {
                   6330:        if ( size <= 0 ) {
                   6331:                switch ( query("\
                   6332: Bad Directory Size, size = %D, i-number = %u (Clear i-node)", size, ino) ) {
                   6333:                case NO:
                   6334:                        break;
                   6335:                case YES:
                   6336:                        zeroinode(dip);
                   6337:                        setflags(ino, UNALLOC);
                   6338:                        clrflg = TRUE;
                   6339:                        return;
                   6340:                }
                   6341:        }
                   6342: 
                   6343:        if ( size < (2*DSIZE) )
                   6344:                printf("Directory Size too small i-number = %u\n", ino);
                   6345: 
                   6346:        if ( size % sizeof(struct direct) != 0 )
                   6347:                printf("Directory Misaligned i-number = %u\n", ino);
                   6348: 
                   6349:        if (sizerr(size))
                   6350:                printf("Possible Directory Size Error i-number = %u\n", ino);
                   6351: }
                   6352: 
                   6353: filesize(ino, size)
                   6354: ino_t ino;
                   6355: register fsize_t size;
                   6356: {
                   6357:        if (sizerr(size))
                   6358:                printf("Possible File Size Error i-number = %u\n", ino);
                   6359: }
                   6360: 
                   6361: sizerr(size)
                   6362: register fsize_t size;
                   6363: {
                   6364:        register fsize_t calc;
                   6365: 
                   6366:        calc = (unsigned long)numblks*BSIZE;
                   6367:        if ( (size > calc) || ( calc >= (size+BSIZE) ) ) 
                   6368:                return(TRUE);
                   6369:        else
                   6370:                return(FALSE);
                   6371: }
                   6372: f ( size % sizeof(struct direct) != 0 )
                   6373:                printf("Directory Misaligned i-number = %u\n", ino);
                   6374: 
                   6375:        if (sizerr(size))
                   6376:                printf("Possible Directory Size Error i-number = %u\n", ino);
                   6377: }
                   6378: 
                   6379: filesize(ino, size)
                   6380: ino_t ino;
                   6381: register fsize_t size;
                   6382: {
                   6383:        if (sizerr(size))
                   6384:                printf("Possible File Size Error i-number = %u\n", ino);
                   6385: }
                   6386: 
                   6387: sizerr(size)
                   6388: register fsize_t size;
                   6389: {
                   6390:        register fsize_t calc;
                   6391: 
                   6392:        calc = (unsigned long)numblks*BSIZE;
                   6393:        if ( (size > calc) || ( calc >= (size+BSIZE) ) ) 
                   6394:                return(TRUE);
                   6395:        else
                   6396:                return(FALSE)fsck/phase1b.c   644      3      3        4361  4664524116   6444 /*
                   6397:  *     Phase 1b of fsck - Rescan for more Dups
                   6398:  */
                   6399: 
                   6400: #include "fsck.h"
                   6401: 
                   6402: extern int     numdup;         /* declared in phase1.c */
                   6403: 
                   6404: phase1b()
                   6405: {
                   6406:        if (!qflag)
                   6407:                printf("Phase 1b: Rescan for more Dups\n");
                   6408:        buildtable();
                   6409:        iscanb();
                   6410: }
                   6411: 
                   6412: buildtable()
                   6413: {
                   6414:        unsigned cntr=0, numdiff=0;
                   6415:        daddr_t bn;
                   6416: 
                   6417:        while (cntr<totdups) {
                   6418:                bn = dupblck[cntr++];
                   6419:                if (!testdup(bn)) {
                   6420:                        markdup(bn);
                   6421:                        numdiff++;
                   6422:                }
                   6423:        }
                   6424:        totdups = numdiff;
                   6425: }
                   6426: 
                   6427: iscanb()
                   6428: {
                   6429:        register daddr_t bn;
                   6430:        register struct dinode *dip;
                   6431:        register ino_t  ino;
                   6432:        int i;
                   6433: 
                   6434:        ino = 1;
                   6435: 
                   6436:        for (bn=INODEI; bn<isize; bn++) {
                   6437:                if (testblock(bn)) {            /* block is bad via inode 1 */
                   6438:                        ino += INOPB;
                   6439:                        continue;
                   6440:                }
                   6441:                bread(bn, databuf);
                   6442:                dip = (struct dinode *) databuf;
                   6443:                for (i=0; i<INOPB; i++) {
                   6444:                        candino(dip);
                   6445:                        if (inuse(dip) == TRUE) 
                   6446:                                ckblksb(dip, ino);
                   6447:                        if (totdups == 0)
                   6448:                                return;                 
                   6449:                        ino++;
                   6450:                        dip++;
                   6451:                }
                   6452:        }
                   6453: }
                   6454: 
                   6455: /*
                   6456:  *     Check the blocks associated with the given inode to find the
                   6457:  *     remaining duplicate blocks
                   6458:  */
                   6459: 
                   6460: ckblksb(dip, ino)
                   6461: register struct dinode *dip;
                   6462: register ino_t ino;
                   6463: {
                   6464:        daddr_t addrs[NADDR];
                   6465:        int i, lev;
                   6466:        int mode;
                   6467: 
                   6468:        mode = dip->di_mode & IFMT;
                   6469: 
                   6470:        if ( (mode != IFREG) && (mode != IFDIR) )
                   6471:                return;
                   6472: 
                   6473:        l3tol(addrs, dip->di_addr, NADDR);
                   6474: 
                   6475:        numdup = 0;                     /* num dup blocks so far THIS INODE */
                   6476: 
                   6477:        for(i=0; i<NADDR; i++)
                   6478:                for (lev=0; lev<4; lev++) 
                   6479:                        if (i < offsets[lev]) {
                   6480:                                dblocksb(addrs[i], ino, lev);
                   6481:                                break;
                   6482:                        }
                   6483: }
                   6484: 
                   6485: /*
                   6486:  *     Checks recursively the blocks pointed at via
                   6487:  *     the inode list of blocks.  'bn' is the block number,
                   6488:  *     'ino' is the inode referencing it, and 'lev' is the
                   6489:  *     level 0 == direct ... 3 = triple-indirect
                   6490:  */
                   6491: 
                   6492: dblocksb(bn, ino, lev)
                   6493: daddr_t        bn;
                   6494: ino_t  ino;
                   6495: int    lev;
                   6496: {
                   6497:        char buf[BSIZE];
                   6498:        int  i;
                   6499:        daddr_t *bnptr;
                   6500: 
                   6501:        if (bn == 0)
                   6502:                return(OK);
                   6503:                
                   6504:        switch ( cdupb(bn, ino) ) {
                   6505:        case OK:
                   6506:                if (lev--==0)
                   6507:                        return(OK);
                   6508:                bread(bn, buf);
                   6509:                bnptr = (long *) buf;
                   6510:                for (i=0; i<NBN; i++) {
                   6511:                        bn = bnptr[i];
                   6512:                        candaddr(bn);
                   6513:                        if ( dblocksb(bn, ino, lev) == STOP )
                   6514:                                return(STOP);
                   6515:                }
                   6516:                return(OK);
                   6517:        case STOP:
                   6518:                return(STOP);
                   6519:        }
                   6520: }
                   6521: 
                   6522: /*
                   6523:  *     Check the given block number for duplicate reference.
                   6524:  */
                   6525: 
                   6526: cdupb(bn, ino)
                   6527: daddr_t        bn;
                   6528: ino_t  ino;
                   6529: {
                   6530:        if ( !testdup(bn) ) 
                   6531:                return(OK);
                   6532: 
                   6533:        totdups--;
                   6534:        unmarkdup(bn);
                   6535:        if (!fflag)
                   6536:                orflags(ino, IBAD_IDUP);
                   6537:        printf("Dup Block %U, i-number = %u\n", bn, ino);
                   6538: 
                   6539:        return(STOP);
                   6540: }
                   6541: =0)
                   6542:                        return(OK);
                   6543:                bread(bn, buf);
                   6544:                bnptr = (long *) buf;
                   6545:                for (i=0; i<NBN; i++) {
                   6546:                        bn = bnptr[i];
                   6547:                        candaddr(bn);
                   6548:                        if ( dblocksb(bn, ino, lev) == STOP )
                   6549:                                return(STOP);
                   6550:                }
                   6551:                return(OK);
                   6552:        case STOP:
                   6553:                return(STOP);
                   6554:        }
                   6555: }
                   6556: 
                   6557: /*
                   6558:  *     Check the given block number forfsck/phase2.c   644      3      3       17061  4767515401   6325 /*
                   6559:  *     phase 2 of fsck - Check Pathnames
                   6560:  */
                   6561: 
                   6562: #include "fsck.h"
                   6563: #include <pwd.h>
                   6564: 
                   6565: #define MAXDEPTH 50
                   6566: struct direct *path[MAXDEPTH];
                   6567: int    depth;
                   6568: int    fixflag;                        /* flags when must rewrite databuf  */
                   6569: daddr_t blocknum;                      /* Current block num read in        */
                   6570: 
                   6571: typedef struct list {
                   6572:        struct direct d_entry;
                   6573:        struct list *next;
                   6574: } list;
                   6575: 
                   6576: char   buf2[BSIZE];                    /* buffer for blocks            */
                   6577: daddr_t        cdbn;                           /* current logical block number */
                   6578: 
                   6579: /*     Format errors, args to blkerr() */
                   6580: 
                   6581: #define        NULLNAME        5
                   6582: #define        NULLPAD         6
                   6583: #define SLASHES                7
                   6584: #define DOT            8
                   6585: #define DOTDOT         9
                   6586: 
                   6587: phase2()
                   6588: {
                   6589:        if (!qflag)
                   6590:                printf("Phase 2 : Check Pathnames\n");
                   6591:        checkroot();
                   6592:        depth = 0;
                   6593:        checkpath(ROOTIN);
                   6594: }
                   6595: 
                   6596: 
                   6597: checkroot()
                   6598: {
                   6599:        if ( (flags(ROOTIN)&MODEMASK) == UNALLOC )
                   6600:                fatal("Root i-node is unallocated.  Terminating");
                   6601: 
                   6602:        if ( (flags(ROOTIN)&MODEMASK) != IDIR ) {
                   6603:                switch ( query("Root i-node is not a directory (FIX)") ){
                   6604:                case YES:
                   6605:                        fixroot();
                   6606:                        break;
                   6607:                case NO:
                   6608:                        abort();
                   6609:                }
                   6610:        }
                   6611:        
                   6612:        if ( badblks(ROOTIN) ){
                   6613:                switch ( query("Dup/Bad blocks in root i-node (Continue)") ) {
                   6614:                case YES:
                   6615:                        break;
                   6616:                case NO:
                   6617:                        abort();
                   6618:                }
                   6619:        }
                   6620:        linkincr(ROOTIN);               /* (?) Feature (?) of mkfs is  */
                   6621:                                        /* that root inode of a file   */
                   6622:                                        /* system has a link count one */
                   6623:                                        /* too large.                  */
                   6624: }
                   6625: 
                   6626: fixroot()
                   6627: {
                   6628:        register struct dinode *dip;
                   6629: 
                   6630:        if (!writeflg) 
                   6631:                fatal("File System Read-Only (NO WRITE)\n");
                   6632: 
                   6633:        setflags(ROOTIN, (flags(ROOTIN) & ~MODEMASK) | IDIR);
                   6634: 
                   6635:        /* Save change to disk */
                   6636:        
                   6637:        dip = ptrino(ROOTIN, databuf);
                   6638:        dip->di_mode &= (~IFMT);
                   6639:        dip->di_mode |= IFDIR;
                   6640:        writeino(ROOTIN, databuf);
                   6641: }
                   6642: 
                   6643: #define        myinum  ( (depth>0) ? path[depth-1]->d_ino : ROOTIN )
                   6644: #define popinum        ( (depth>1) ? path[depth-2]->d_ino : ROOTIN )
                   6645: 
                   6646: char *memory = "Can't malloc memory, phase 2";
                   6647: 
                   6648: list *
                   6649: procfiles(addrs, length)
                   6650: daddr_t *addrs;
                   6651: fsize_t length;
                   6652: {
                   6653:        register struct direct *elemnt;
                   6654:        register list *first, *ptr;
                   6655: 
                   6656:        if ((first=ptr=(list *)malloc(sizeof(list)))==NULL)
                   6657:                fatal(memory);
                   6658:        first->d_entry.d_ino = 0;
                   6659:        first->next = NULL;
                   6660:        if ( length < DSIZE )
                   6661:                return( first );
                   6662:        cdbn = 0;
                   6663:        nextblock(addrs);
                   6664:        fixflag = FALSE;
                   6665:        elemnt = (struct direct *) databuf;
                   6666:        cdots(elemnt++, ".", myinum, DOT);
                   6667:        ++numfiles;
                   6668:        if ( (length-=DSIZE) < DSIZE )
                   6669:                return( first );
                   6670:        cdots(elemnt++, "..", popinum, DOTDOT);
                   6671:        ++numfiles;
                   6672:        length -= DSIZE;
                   6673: 
                   6674:        while ( length >= DSIZE ) {
                   6675:                while ( (elemnt<&databuf[BSIZE]) && (length>=DSIZE) ) {
                   6676:                        if (chck(elemnt)==IDIR) {
                   6677:                                copy(elemnt, &ptr->d_entry, 
                   6678:                                                sizeof(struct direct));
                   6679:                                if ((ptr->next=(list *)malloc(sizeof(list))) ==
                   6680:                                        NULL)
                   6681:                                        fatal(memory);
                   6682:                                ptr = ptr->next;
                   6683:                                ptr->d_entry.d_ino = 0;
                   6684:                                ptr->next = NULL;
                   6685:                        }
                   6686:                        elemnt++;
                   6687:                        length -= DSIZE;
                   6688:                }
                   6689:                if (fixflag && (fixblock(addrs) == NUL) )
                   6690:                        fixblkerr();
                   6691:                nextblock(addrs);
                   6692:                fixflag = FALSE;
                   6693:                elemnt = (struct direct *) databuf;
                   6694:        }
                   6695:        return(first);   
                   6696: }
                   6697: 
                   6698: candblock(dptr)
                   6699: register struct direct *dptr;
                   6700: {
                   6701:        register int num, i;
                   6702: 
                   6703:        num = BSIZE/sizeof(struct direct);
                   6704:        for (i=0; i<num; i++)
                   6705:                canino(dptr[i].d_ino);
                   6706: }
                   6707: 
                   6708: nextblock(addrs)
                   6709: register daddr_t *addrs;
                   6710: {
                   6711:        register daddr_t bn;
                   6712: 
                   6713:        if ( (bn=imap(addrs, cdbn++)) == 0 ) {
                   6714:                bclear(databuf, BSIZE);
                   6715:                return;
                   6716:        }
                   6717:        bread(bn, databuf);
                   6718:        candblock(databuf);
                   6719:        blocknum = bn;
                   6720: }
                   6721: 
                   6722: fixblock(addrs)
                   6723: daddr_t *addrs;
                   6724: {
                   6725:        daddr_t bn;
                   6726: 
                   6727:        if ( (bn=imap(addrs, cdbn-1)) == 0 ) 
                   6728:                return(NUL);
                   6729:        candblock(databuf);
                   6730:        bwrite(bn, databuf);
                   6731:        return(TRUE);
                   6732: }
                   6733: 
                   6734: fixblkerr()
                   6735: {
                   6736:        fatal("Fixblock error.");
                   6737: }
                   6738: 
                   6739: copy(from, to, size)
                   6740: register char *from, *to;
                   6741: register int size;
                   6742: {
                   6743:        while (size--)
                   6744:                *to++=*from++;
                   6745: }
                   6746: 
                   6747: cdots(elemnt, dots, ino, type)
                   6748: register struct direct *elemnt;
                   6749: char *dots;
                   6750: ino_t ino;     /* what the inode number should be */
                   6751: int type;
                   6752: {
                   6753:        register char *name = elemnt->d_name;
                   6754:        register ino_t inum;
                   6755: 
                   6756:        inum = elemnt->d_ino;
                   6757:        if ( (strcmp(name, dots) != 0) || (inum != ino) ||
                   6758:                (format(name) != GOOD) ) {
                   6759:                blkerr(type);
                   6760:                return;
                   6761:        }
                   6762:        linkincr(inum);
                   6763: }
                   6764: 
                   6765: format(name)
                   6766: register char *name;
                   6767: {
                   6768:        register char *ptr=name;
                   6769:        register char *end=&name[DIRSIZ];
                   6770: 
                   6771:        while ( (ptr<end) && (*ptr++ != '\0') ) ;
                   6772: 
                   6773:        if ( (ptr-1) == name )
                   6774:                return(NULLNAME);
                   6775:        
                   6776:        if (ptr<end) {
                   6777:                while ( (ptr<end) && (*ptr++ == '\0') ) ;
                   6778:                if (ptr!=end)
                   6779:                        return(NULLPAD);
                   6780:        }
                   6781: 
                   6782:        ptr = name;
                   6783:        while (ptr < end) 
                   6784:                if (*ptr++ == '/')
                   6785:                        return(SLASHES);
                   6786: 
                   6787:        return(GOOD);
                   6788: }
                   6789: 
                   6790:        
                   6791: blkerr(type)
                   6792: int type;
                   6793: {      
                   6794:        char *errname;
                   6795: 
                   6796:        switch(type) {
                   6797:        case NULLNAME:
                   6798:                errname = "Null name";
                   6799:                break;
                   6800:        case NULLPAD:
                   6801:                errname = "Non null padded";
                   6802:                break;
                   6803:        case SLASHES:
                   6804:                errname = "Embedded slashes in";
                   6805:                break;
                   6806:        case DOT:
                   6807:                errname = "Inconsistent .";
                   6808:                break;
                   6809:        case DOTDOT:
                   6810:                errname = "Inconsistent ..";
                   6811:                break;
                   6812:        default:
                   6813:                errname = "Bad";
                   6814:                break;
                   6815:        }
                   6816: 
                   6817:        printf("%s entry in block %U in directory\n", errname, blocknum);
                   6818:        pinfo(myinum);
                   6819:        pname(path[--depth]->d_name);
                   6820:        depth++;
                   6821: }
                   6822: 
                   6823: chck(elemnt)
                   6824: register struct direct *elemnt;
                   6825: {
                   6826:        register ino_t inum;
                   6827:        register char *name;
                   6828:        int type;
                   6829: 
                   6830:        inum = elemnt->d_ino;
                   6831:        if ( inum == 0 )
                   6832:                return(UNALLOC);
                   6833: 
                   6834:        name = elemnt->d_name;
                   6835:        if ( (type=format(name)) != GOOD )
                   6836:                blkerr(type);
                   6837: 
                   6838:        if (inum>ninodes) {
                   6839:                if ( irange(inum, name) ) 
                   6840:                        zeroent(elemnt);
                   6841:                return(UNALLOC);
                   6842:        }
                   6843: 
                   6844:        if ( (flags(inum)&ALLOCMASK)==UNALLOC ) {
                   6845:                if ( unalloc(inum, name) )
                   6846:                        zeroent(elemnt);
                   6847:                return(UNALLOC);
                   6848:        }
                   6849: 
                   6850:        if ( badblks(inum) ) {
                   6851:                if ( baddup(inum, name) ) {
                   6852:                        zeroent(elemnt);
                   6853:                        return(UNALLOC);
                   6854:                }
                   6855:                if ( (flags(inum)&MODEMASK)==IDIR )
                   6856:                        return(UNALLOC);
                   6857:        }
                   6858: 
                   6859:        linkincr(inum);
                   6860:        numfiles++;
                   6861:        return( flags(inum)&MODEMASK );
                   6862: }
                   6863: 
                   6864: zeroent(elemnt)
                   6865: struct direct *elemnt;
                   6866: {
                   6867:        elemnt->d_ino = 0;
                   6868:        fixflag = TRUE;
                   6869: }
                   6870: 
                   6871: pname(name)
                   6872: char *name;
                   6873: {
                   6874:        int i=0;
                   6875: 
                   6876:        while (i<depth) 
                   6877:                prdirsize(path[i++]->d_name);
                   6878:        prdirsize(name);
                   6879:        putchar('\n');
                   6880: }
                   6881: 
                   6882: prdirsize(name)
                   6883: char *name;
                   6884: {
                   6885:        if (name[DIRSIZ-1] == '\0')
                   6886:                printf("/%s", name);
                   6887:        else
                   6888:                printf("/%*s", DIRSIZ, name);
                   6889: }
                   6890: 
                   6891: fsize_t
                   6892: pinfo(inum)
                   6893: ino_t inum;
                   6894: {
                   6895:        register struct dinode *dip;
                   6896:        register struct passwd *pwd;
                   6897: 
                   6898:        if ( (dip=ptrino(inum, buf2)) == NULL ) {
                   6899:                printf("i-number = %u is in a bad inode block.\n", inum);
                   6900:                return(0);
                   6901:        }
                   6902: 
                   6903:        printf("i-number = %u, ", inum);
                   6904:        if ( (pwd=getpwuid(dip->di_uid)) != NULL )
                   6905:                printf("Owner=%s, ", pwd->pw_name);
                   6906:        else
                   6907:                printf("Owner=%u, ", dip->di_uid);
                   6908:        printf(" Mode=0%o\n", dip->di_mode);
                   6909:        printf("Size=%U, Mtime=%s", dip->di_size, ctime(&dip->di_mtime));
                   6910:        return(dip->di_size);
                   6911: }
                   6912: 
                   6913: char *remove = "(Remove)";
                   6914: 
                   6915: irange(inum, name)
                   6916: ino_t inum;
                   6917: char *name;
                   6918: {
                   6919:        printf("I-number is out of range  I=%u\n", inum);
                   6920:        pname(name);
                   6921:        return(action(remove));
                   6922: }
                   6923: 
                   6924: unalloc(inum, name)
                   6925: ino_t inum;
                   6926: char *name;
                   6927: {      
                   6928:        fsize_t size;
                   6929: 
                   6930:        printf("Unallocated\n");
                   6931:        size = pinfo(inum);
                   6932:        pname(name);
                   6933:        if ( (daction != NO) && (size == 0) && (mounted == FALSE) ) {
                   6934:                printf("%s [Forced - Yes]\n", remove);
                   6935:                return(YES);
                   6936:        }
                   6937:        return(action(remove));
                   6938: }
                   6939: 
                   6940: baddup(inum, name)
                   6941: ino_t inum;
                   6942: char *name;
                   6943: {
                   6944:        register int mode = flags(inum)&MODEMASK;
                   6945: 
                   6946:        printf("Bad or Dup blocks in %s\n",(mode==IDIR) ? "Directory" : "File");
                   6947:        pinfo(inum);
                   6948:        pname(name);
                   6949:        return(action(remove));
                   6950: }
                   6951: 
                   6952: checkpath(ino)
                   6953: register ino_t ino;
                   6954: {
                   6955:        static daddr_t  addrs[NADDR];
                   6956:        static struct dinode *dip;
                   6957:        static list *temp;
                   6958:        register list *ptr;
                   6959: 
                   6960:        if ( (flags(ino)&VISITED)==VISITED ) {
                   6961:                circle(ino);
                   6962:                return;
                   6963:        } else
                   6964:                orflags(ino, VISITED);
                   6965: 
                   6966:        dip = ptrino(ino, databuf);
                   6967:        l3tol(addrs, dip->di_addr, NADDR);
                   6968:        
                   6969:        if ( (dip->di_mode&IFMT) != IFDIR )
                   6970:                fatal("Tried to checkpath i-node %u which is not dir.\n", ino);
                   6971: 
                   6972:        ptr = procfiles(addrs, dip->di_size);
                   6973: 
                   6974:        while (ptr->d_entry.d_ino) {
                   6975:                if (depth >= MAXDEPTH)
                   6976:                        toolong();
                   6977:                path[depth++] = &ptr->d_entry;
                   6978:                checkpath(ptr->d_entry.d_ino);
                   6979:                depth--;
                   6980:                temp = ptr;
                   6981:                ptr = ptr->next;
                   6982:                free(temp);
                   6983:        }
                   6984:        free(ptr);
                   6985: }
                   6986: 
                   6987: circle(ino)
                   6988: ino_t ino;
                   6989: {
                   6990:        printf("I-node %u is a multiply referenced directory i-node.\n", ino);
                   6991: }
                   6992: 
                   6993: toolong()
                   6994: {
                   6995:        printf("Name too long.\n");
                   6996:        pname("\0");
                   6997:        abort();
                   6998: }
                   6999: 
                   7000:        
                   7001: i_mode&IFMT) != IFDIR )
                   7002:                fatal("Tried to checkpath i-node %u which is not dir.\n", ino);
                   7003: 
                   7004:        ptr = procfiles(addrs, dip->di_size);
                   7005: 
                   7006:        while (ptr->d_entry.d_ino) {
                   7007:                if (depth >= MAXDEPTH)
                   7008:                        toolong();
                   7009:                path[depth++] = &ptr->d_entry;
                   7010:                checkpath(ptr->d_entry.d_ino);
                   7011:                depth--;
                   7012:                temp = ptr;
                   7013:                ptr = ptr->next;
                   7014:                free(temp);
                   7015:        }
                   7016:        free(ptr);
                   7017: }
                   7018: 
                   7019: circle(ino)
                   7020: ino_t ino;
                   7021: {
                   7022:        printf("I-node %u is a multiply referenced directory i-node.\n", ino);
                   7023: }
                   7024: 
                   7025: toolong()
                   7026: {
                   7027:        printf("fsck/phase3.c   644      3      3       12066  5050254732   6317 /*
                   7028:  *     phase 3 of fsck - Check Connectivity
                   7029:  */
                   7030: 
                   7031: #include "fsck.h"
                   7032: 
                   7033: char *lostname = "lost+found";
                   7034: 
                   7035: phase3()
                   7036: {
                   7037:        ino_t i;
                   7038: 
                   7039:        if (!qflag)
                   7040:                printf("Phase 3 : Check Connectivity\n");
                   7041:        for (i=FIRSTIN; i<=ninodes; i++) 
                   7042:                if ( ((flags(i)&MODEMASK) == IDIR) &&
                   7043:                     (linkctr(i) == 0) ) {
                   7044:                        orflags(i, UNREFDIR);
                   7045:                        markchildren(i);
                   7046:                }
                   7047: 
                   7048:        for (i=FIRSTIN; i<ninodes; i++)
                   7049:                if ( (flags(i)&(UNREFDIR|CHILDDIR)) == UNREFDIR )
                   7050:                        unrefdir(i);
                   7051: }
                   7052: 
                   7053: markchildren(ino)
                   7054: ino_t ino;
                   7055: {
                   7056:        struct dinode *dip;
                   7057:        struct direct *element;
                   7058:        daddr_t addrs[NADDR];
                   7059:        ino_t inumber;
                   7060:        fsize_t length;
                   7061: 
                   7062:        if ( badblks(ino) )
                   7063:                return;
                   7064:        dip = ptrino(ino, databuf);
                   7065:        if ( (length=dip->di_size) <= 0 )
                   7066:                return;
                   7067:        l3tol(addrs, dip->di_addr, NADDR);
                   7068:        cdbn = 0;
                   7069:        nextblock(addrs);
                   7070:        element = (struct direct *) databuf;
                   7071:        element += 2;           /* skip over . and .. entries */
                   7072:        if ( (length-=2*DSIZE) <= 0 )
                   7073:                return;
                   7074: 
                   7075:        while ( length >= DSIZE ) {
                   7076:                while ( (element<&databuf[BSIZE]) && (length>=DSIZE) ) {
                   7077:                        if ( ((inumber=element->d_ino) != 0) &&
                   7078:                             ((flags(inumber)&MODEMASK)==IDIR) &&
                   7079:                             (inumber!=ino) )
                   7080:                                orflags(inumber, CHILDDIR);
                   7081:                        element++;
                   7082:                        length -= DSIZE;
                   7083:                }
                   7084:                nextblock(addrs);
                   7085:                element = (struct direct *) databuf;
                   7086:        }
                   7087: }
                   7088: 
                   7089: char *reconnect = "(Reconnect)";
                   7090: 
                   7091: unrefdir(ino)
                   7092: ino_t ino;
                   7093: {
                   7094:        printf("Unref Dir\n");
                   7095:        if( (pinfo(ino) == 0) || (daction == NO) || (mounted == TRUE) ) {
                   7096:                if ( action(reconnect) == FALSE )
                   7097:                        return;
                   7098:        } else 
                   7099:                printf("%s FORCED\n", reconnect);
                   7100: 
                   7101:        connect(ino, IDIR);
                   7102: }
                   7103: 
                   7104: #define CONNECT                1
                   7105: #define NOCONNECT      0
                   7106: 
                   7107: connect(ino, type)
                   7108: ino_t ino;
                   7109: int type;
                   7110: {
                   7111:        ino_t lostino;
                   7112:        struct dinode *dip;
                   7113:        daddr_t addrs[NADDR];
                   7114:        fsize_t length;
                   7115:        struct direct *element;
                   7116:        int chgino = FALSE;
                   7117: 
                   7118:        if ( ((lostino=lostfound()) == NUL) ||
                   7119:                 ((flags(lostino)&MODEMASK) != IDIR) ||
                   7120:                        ( badblks(lostino) ) ) {
                   7121:                nolost();
                   7122:                if (type==IDIR)
                   7123:                        traverse(NOCONNECT, ino, lostino);
                   7124:                return(FAILURE);
                   7125:        }
                   7126: 
                   7127:        dip = ptrino(lostino, buf2);
                   7128:        l3tol(addrs, dip->di_addr, NADDR);
                   7129:        length = dip->di_size;
                   7130:        cdbn = 0;
                   7131:        while ( length>=DSIZE ) {
                   7132:                nextblock(addrs);
                   7133:                element = (struct direct *) databuf;
                   7134:                while ( element<&databuf[BSIZE] ) {
                   7135:                        length -= DSIZE;
                   7136:                        if ( element->d_ino == 0 ) {
                   7137:                                element->d_ino = ino;
                   7138:                                strncpy(element->d_name, nameit(ino), DIRSIZ);
                   7139:                                if ( fixblock(addrs) == NUL )
                   7140:                                        fixblkerr();
                   7141:                                linkincr(ino);
                   7142:                                numfiles++;
                   7143:                                if ( length<0 ) {
                   7144:                                        dip->di_size -= length;
                   7145:                                        chgino = TRUE;
                   7146:                                }
                   7147:                                if ( (type == IDIR) &&
                   7148:                                     (connected(ino, lostino)==YES) ) {
                   7149:                                        dip->di_nlink++;
                   7150:                                        writeino(lostino, buf2);
                   7151:                                        traverse(CONNECT, ino, lostino);
                   7152:                                } else if (chgino) {
                   7153:                                        writeino(lostino, buf2);
                   7154:                                }
                   7155:                                return(SUCCESS);
                   7156:                        }
                   7157:                        element++;
                   7158:                }
                   7159:        }
                   7160:        
                   7161:        noroom();
                   7162:        if (type == IDIR)
                   7163:                traverse(NOCONNECT, ino, lostino);
                   7164:        return(FAILURE);
                   7165: }
                   7166: 
                   7167: traverse(flag, ino, lostino)
                   7168: int flag;
                   7169: ino_t ino, lostino;
                   7170: {
                   7171:        struct direct dirlost, nothing, newtree;
                   7172: 
                   7173:        dirinit(&dirlost, lostino, lostname);
                   7174:        dirinit(&nothing, 0, "??");
                   7175:        dirinit(&newtree, ino, nameit(ino));
                   7176:        depth = 0;
                   7177:        if (flag == CONNECT) 
                   7178:                path[depth++] = &dirlost;
                   7179:        else
                   7180:                path[depth++] = &nothing;
                   7181: 
                   7182:        path[depth++] = &newtree;
                   7183:        checkpath(ino);
                   7184: }
                   7185: 
                   7186: dirinit(element, ino, name)
                   7187: struct direct *element;
                   7188: ino_t ino;
                   7189: char *name;
                   7190: {
                   7191:        element->d_ino = ino;
                   7192:        strncpy(element->d_name, name, DIRSIZ);
                   7193: }
                   7194: 
                   7195: connected(ino, lostino)
                   7196: ino_t ino;             /* inumber just reconnected       */
                   7197: ino_t lostino;         /* inumber of lostfound directory */
                   7198: {
                   7199:        struct dinode *dip;
                   7200:        daddr_t addrs[NADDR];
                   7201:        fsize_t length;
                   7202:        struct direct *element;
                   7203: 
                   7204:        if ( badblks(ino) ) {
                   7205:                badconnect(ino);
                   7206:                return(NO);
                   7207:        }
                   7208:        dip = ptrino(ino, databuf);
                   7209:        l3tol(addrs, dip->di_addr, NADDR);
                   7210:        length = dip->di_size;
                   7211:        cdbn = 0;
                   7212:        while ( length >= DSIZE ) {
                   7213:                nextblock(addrs);
                   7214:                element = (struct direct *) databuf;
                   7215:                while ( (element<&databuf[BSIZE]) && (length>=DSIZE) ) {
                   7216:                        if ( strcmp(element->d_name, "..") == 0 ) {
                   7217:                                printf("Dir i-number = %u connected.  ", ino);
                   7218:                                printf("Parent was i-number = %u.\n",
                   7219:                                                        element->d_ino);
                   7220:                                element->d_ino = lostino;
                   7221:                                if ( fixblock(addrs) == NUL )
                   7222:                                        fixblkerr();
                   7223:                                return(YES);
                   7224:                        }
                   7225:                        length -= DSIZE;
                   7226:                        element++;
                   7227:                }
                   7228:        }
                   7229:        noparent(ino);
                   7230:        return(NO);
                   7231: }
                   7232: 
                   7233: badconnect(ino)
                   7234: ino_t ino;
                   7235: {
                   7236:        printf("Dir i-number = %u connected.  It has bad/dup blocks.\n", ino);
                   7237: }
                   7238: 
                   7239: noparent(ino)
                   7240: ino_t ino;
                   7241: {
                   7242:        printf("Dir i-number = %u connected.  It has no .. entry.\n", ino);
                   7243: }
                   7244: 
                   7245: ino_t
                   7246: lostfound()
                   7247: {
                   7248:        static daddr_t addrs[NADDR];
                   7249:        struct dinode *dip;
                   7250:        struct direct *element;
                   7251:        fsize_t length;
                   7252: 
                   7253:        dip = ptrino(ROOTIN, databuf);
                   7254:        l3tol(addrs, dip->di_addr, NADDR);
                   7255:        length = dip->di_size;
                   7256:        cdbn = 0;
                   7257:        while ( length>=DSIZE ) {
                   7258:                nextblock(addrs);
                   7259:                element = (struct direct *) databuf;
                   7260:                while ( (element<&databuf[BSIZE]) && (length>=DSIZE) ) {
                   7261:                        if ( strcmp(element->d_name, lostname) == 0 ) 
                   7262:                                return(element->d_ino);
                   7263:                        length -= DSIZE;
                   7264:                        element++;
                   7265:                }
                   7266:        }
                   7267: 
                   7268:        return(NUL);
                   7269: }
                   7270: 
                   7271: nolost()
                   7272: {
                   7273:        printf("Sorry.  No %s directory.\n", lostname);
                   7274: 
                   7275: }
                   7276: 
                   7277: noroom()
                   7278: {
                   7279:        printf("Sorry.  No space in %s directory.\n", lostname);
                   7280: }
                   7281: 
                   7282: char namebuf[DIRSIZ];
                   7283: 
                   7284: char *
                   7285: nameit(ino)
                   7286: register ino_t ino;
                   7287: {
                   7288:        register int i = DIRSIZ-1;
                   7289: 
                   7290:        namebuf[i] = '\0';
                   7291:        while ( (ino != 0) && (i>0) ) {
                   7292:                namebuf[--i] = '0' + ino%10;
                   7293:                ino = ino/10;
                   7294:        }
                   7295:        return(&namebuf[i]);
                   7296: }
                   7297: length>=DSIZE) ) {
                   7298:                        if ( strcmp(element->d_name, lostname) == 0 ) 
                   7299:                                return(element->d_ino);
                   7300:                        length -= DSIZE;
                   7301:                        element++;
                   7302:                }
                   7303:        }
                   7304: 
                   7305:        return(NUL);
                   7306: }
                   7307: 
                   7308: nolost()
                   7309: {
                   7310:        printf("Sorry.  No %s directory.\n", lostname);
                   7311: 
                   7312: }
                   7313: 
                   7314: noroom()
                   7315: {
                   7316:        printf("Sorry.  No space in %s directory.\n", lostname);
                   7317: }
                   7318: 
                   7319: char namebuf[DIRSIZ];
                   7320: 
                   7321: char *
                   7322: nameit(ino)
                   7323: register ino_t ino;
                   7324: {
                   7325:        register int i = DIRSIZ-1;
                   7326: 
                   7327:        namebuf[i] = '\0';
                   7328:        while ( (ino != 0) && (i>0) ) {
                   7329:                namebuf[--i] = '0'fsck/phase4.c   644      3      3       10602  4767744166   6335 /*
                   7330:  *     phase 4 of fsck - Check Reference Counts
                   7331:  */
                   7332: 
                   7333: #include "fsck.h"
                   7334: 
                   7335: extern char *reconnect;
                   7336: fsize_t        lostsize;
                   7337: 
                   7338: phase4()
                   7339: {
                   7340:        ino_t i;
                   7341:        short actlink;
                   7342: 
                   7343:        if (!qflag)
                   7344:                printf("Phase 4 : Check Reference Counts\n");
                   7345:        for (i=FIRSTIN; i<=ninodes; i++) {
                   7346:                if ( badblks(i) )
                   7347:                        if ( bddp(i) == YES )
                   7348:                                continue;       /* inode zeroed */
                   7349: 
                   7350:                if ( (linkctr(i) == 0) &&
                   7351:                     ((flags(i)&MODEMASK) != IDIR) &&
                   7352:                     ((flags(i)&ALLOCMASK) != UNALLOC) )
                   7353:                        if ( unreflink(i) == YES )
                   7354:                                continue;       /* inode zeroed */
                   7355: 
                   7356:                if ( (linkctr(i) == 0) &&
                   7357:                     ((flags(i)&ALLOCMASK) != UNALLOC)  )
                   7358:                        if ( unrefclr(i) == YES )
                   7359:                                continue;       /* inode zeroed */
                   7360: 
                   7361:                if ( (actlink=getlink(i)) == (-1) ) {
                   7362:                        i += INOPB-1;
                   7363:                        continue;               /* bad inode block */
                   7364:                }
                   7365: 
                   7366:                if ( actlink != linkctr(i) )
                   7367:                        linkprob(i, actlink);   /* fix link count */
                   7368:        }
                   7369: 
                   7370:        freeilist();
                   7371: }
                   7372: 
                   7373: short
                   7374: getlink(inum)
                   7375: register ino_t inum;
                   7376: {
                   7377:        register unsigned offset;
                   7378:        static ibuf[BSIZE];
                   7379:        register struct dinode *dip;
                   7380:        register daddr_t bn;
                   7381: 
                   7382:        offset = iblocko(inum);
                   7383:        if ( (offset==0) || (inum==FIRSTIN) ) {
                   7384:                bn = iblockn(inum);
                   7385:                if ( (testblock(bn)) && (inum!=FIRSTIN) ) 
                   7386:                        return(-1);
                   7387:                bread(bn, ibuf);
                   7388:        }
                   7389:        dip = ((struct dinode *) ibuf) + offset;
                   7390:        candino(dip);
                   7391:        return(dip->di_nlink);
                   7392: }
                   7393: 
                   7394: char *clearit = "(Clear i-node)";
                   7395: 
                   7396: unreflink(ino)
                   7397: ino_t ino;
                   7398: {
                   7399:        fsize_t size;
                   7400: 
                   7401:        if ( (qflag == TRUE) && ((flags(ino)&MODEMASK) == IPIPE) ) {
                   7402:                doclear(ino);
                   7403:                return(YES);
                   7404:        }
                   7405: 
                   7406:        printf("Unref %s\n", typename(ino));
                   7407:        size = pinfo(ino);
                   7408:        if ( (daction != NO) && (size == 0) && (mounted == FALSE) 
                   7409:                && ((flags(ino)&MODEMASK) == IREG) ) {
                   7410:                printf("%s [Forced - Yes]\n", clearit);
                   7411:                doclear(ino);
                   7412:                return(YES);
                   7413:        }
                   7414:        if ( action(reconnect) == TRUE )
                   7415:                if( connect(ino, IREG) == FAILURE )  /* connect back in the */
                   7416:                        return(askclear(ino));       /* non dir inode       */
                   7417:                        
                   7418:        return(NO);
                   7419: }
                   7420: 
                   7421: askclear(ino)
                   7422: ino_t ino;
                   7423: {
                   7424:        if ( action(clearit) == TRUE ) {
                   7425:                doclear(ino);
                   7426:                return(YES);
                   7427:        }
                   7428:        return(NO);
                   7429: }
                   7430: 
                   7431: doclear(ino)
                   7432: ino_t ino;
                   7433: {
                   7434:        struct dinode *dip;
                   7435: 
                   7436:        dip = ptrino(ino, databuf);
                   7437:        zeroinode(dip);
                   7438:        writeino(ino, databuf);
                   7439:        setflags(ino, UNALLOC);
                   7440:        setlinkctr(ino, 0);
                   7441: }
                   7442: 
                   7443: char *adjust = "(Adjust)";
                   7444: 
                   7445: linkprob(ino, actlink)
                   7446: ino_t ino;
                   7447: short actlink;
                   7448: {
                   7449:        printf("Link Count discrepancy in %s\n", typename(ino));
                   7450:        pinfo(ino);
                   7451:        printf("Count = %u, should be %u ", actlink, linkctr(ino));
                   7452:        if ( action(adjust) == TRUE )
                   7453:                chglink(ino);
                   7454: }
                   7455: 
                   7456: chglink(ino)
                   7457: ino_t ino;
                   7458: {
                   7459:        struct dinode *dip;
                   7460: 
                   7461:        dip = ptrino(ino, databuf);
                   7462:        dip->di_nlink = linkctr(ino);
                   7463:        writeino(ino, databuf);
                   7464: }
                   7465:        
                   7466: unrefclr(ino)
                   7467: ino_t ino;
                   7468: {
                   7469:        printf("Unref %s\n", typename(ino));
                   7470:        pinfo(ino);
                   7471:        return(askclear(ino));
                   7472: }
                   7473: 
                   7474: bddp(ino)
                   7475: ino_t ino;
                   7476: {
                   7477:        printf("Bad/Dup blocks in %s\n", typename(ino));
                   7478:        pinfo(ino);
                   7479:        return(askclear(ino));
                   7480: }
                   7481: 
                   7482: char *fixit = "(FIX)";
                   7483: 
                   7484: freeilist()
                   7485: {
                   7486:        ino_t i, count=0;
                   7487:        daddr_t bn;
                   7488: 
                   7489:        for (i=FIRSTIN; i<=ninodes; i++)
                   7490:                if ( (flags(i)&ALLOCMASK) == UNALLOC )
                   7491:                        count++;
                   7492: 
                   7493:        for (bn=INODEI+1; bn<isize; bn++)       /* block # INODEI can't */
                   7494:                if ( testblock(bn) )            /* be bad since ROOTIN  */
                   7495:                        count -= INOPB;         /* is in it, otherwise  */
                   7496:                                                /* big time bad news.   */
                   7497:        if ( sbp->s_tinode != count ) 
                   7498:                if ( (qflag==FALSE) && (daction!=NO) ) {
                   7499:                        printf("Free i-node count wrong in superblock.  ");
                   7500:                        if ( action(fixit) == TRUE ) {
                   7501:                                sbp->s_tinode = count;
                   7502:                                sbpfix = TRUE;
                   7503:                        }
                   7504:                } else {
                   7505:                        sbp->s_tinode = count;
                   7506:                        sbpfix = TRUE;
                   7507:                }
                   7508: 
                   7509:        if ( (daction!=NO) &&
                   7510:             ( (sflag==TRUE) || (sbpfix==TRUE) || (badilist()==BAD) ) )
                   7511:                rebuild();
                   7512: 
                   7513: }
                   7514: 
                   7515: badilist()
                   7516: {
                   7517:        ino_t i, inum;
                   7518:        unsigned numfree;
                   7519:        daddr_t bn;
                   7520: 
                   7521:        if ( (numfree=(unsigned) sbp->s_ninode) > NICINOD )
                   7522:                return(BAD);
                   7523:        for (i=0; i<numfree; i++) {
                   7524:                inum = sbp->s_inode[i];
                   7525:                bn = iblockn(inum);
                   7526:                if ( (testblock(bn)) && (bn!=INODEI) )
                   7527:                        return(BAD);
                   7528:                if ( (inum < FIRSTIN) || (inum > ninodes) )
                   7529:                        return(BAD);
                   7530:                if ( (flags(inum)&ALLOCMASK) != UNALLOC ) 
                   7531:                        return(BAD);
                   7532:                if ( flags(inum)&IFREELIST )
                   7533:                        return(BAD);            /* dup in ifree list */
                   7534:                orflags(inum, IFREELIST);
                   7535:        }
                   7536:        return(GOOD);
                   7537: }
                   7538: 
                   7539: rebuild()
                   7540: {
                   7541:        daddr_t bn;
                   7542:        ino_t i;
                   7543:        int index;
                   7544: 
                   7545:        sbpfix = TRUE;
                   7546:        for (i=FIRSTIN, index=0; (i<=ninodes) && (index<NICINOD); i++) {
                   7547:                if ( (flags(i)&ALLOCMASK) == UNALLOC ) {
                   7548:                        bn = iblockn(i);
                   7549:                        if ( (!testblock(bn)) || (bn==INODEI) )
                   7550:                                index++;
                   7551:                }
                   7552:        }
                   7553:        sbp->s_ninode = index;
                   7554:        for (i=FIRSTIN; (i<=ninodes) && (index>0); i++) {
                   7555:                if ( (flags(i)&ALLOCMASK) == UNALLOC ) {
                   7556:                        bn = iblockn(i);
                   7557:                        if ( (!testblock(bn)) || (bn==INODEI) )
                   7558:                                sbp->s_inode[--index] = i;
                   7559:                }
                   7560:        }
                   7561:        printf("Free i-node list in superblock rebuilt.\n");
                   7562: }
                   7563: t bn;
                   7564:        ino_t i;
                   7565:        int index;
                   7566: 
                   7567:        sbpfix = TRUE;
                   7568:        for (i=FIRSTIN, index=0; (i<=ninodes) && (index<NICINOD); i++) {
                   7569:                if ( (flags(ifsck/phase5.c   644      3      3        6203  4767744635   6321 /*
                   7570:  *     phase 5 of fsck - Check Free List
                   7571:  */
                   7572: 
                   7573: #include "fsck.h"
                   7574: 
                   7575: daddr_t        badcnt;                 /* Number of bad blocks in free list */
                   7576: daddr_t dupcnt;                        /* Number of dup blocks in free list */
                   7577: int    badflag;                /* Bad free list flag */
                   7578: int    fixerup;                /* Flag to salvage free list */
                   7579: 
                   7580: phase5()
                   7581: {
                   7582:        struct fblk *fbp;
                   7583:        unsigned size;
                   7584:        
                   7585:        if (!qflag)
                   7586:                printf("Phase 5 : Check Free List\n");
                   7587:        fbp = (struct fblk *) &sbp->s_nfree;
                   7588:        size = (unsigned) ((fsize+NBPC-1)/NBPC) * sizeof(char);
                   7589:        copyV(size);
                   7590:        badcnt = dupcnt = 0;
                   7591:        badflag = FALSE;
                   7592:        freetrav(fbp);
                   7593:        fixerup = FALSE;
                   7594:        if (badflag || sflag) 
                   7595:                asksalvage();
                   7596: }
                   7597: 
                   7598: 
                   7599: #define        IGNORE  3               /* Return Possibilities from chk() */
                   7600: #define        ABORT   4               /* as well as perhaps GOOD and BAD */
                   7601: 
                   7602: freetrav(fbp)
                   7603: struct fblk *fbp;
                   7604: {
                   7605:        daddr_t total=0;
                   7606:        int i, flag;
                   7607: 
                   7608:        while ( fbp->df_nfree != 0 ) {
                   7609:                if ( (unsigned) fbp->df_nfree > NICFREE ) {
                   7610:                        badflag = TRUE;
                   7611:                        printf("Bad freeblock count.\n");
                   7612:                        break;
                   7613:                }
                   7614:                for (i=1; i<fbp->df_nfree; i++) {
                   7615:                        if ( (flag=chk(fbp->df_free[i])) == GOOD ) {
                   7616:                                total++;
                   7617:                                continue;
                   7618:                        }
                   7619:                        if (flag == BAD)
                   7620:                                continue;
                   7621:                        break;          /* break for IGNORE or ABORT    */
                   7622:                }
                   7623:                if ( (flag == IGNORE) || (flag == ABORT) )
                   7624:                        break;
                   7625:                if ( chk(fbp->df_free[0]) != GOOD )
                   7626:                        break;
                   7627:                total++;
                   7628:                bread(fbp->df_free[0], databuf);
                   7629:                fbp = (struct fblk *) databuf;
                   7630:                if ( !canfblk(fbp) ) {
                   7631:                        badflag = TRUE;
                   7632:                        printf("Bad freeblock count.\n");
                   7633:                        break;
                   7634:                }
                   7635:        }
                   7636: 
                   7637: #if 0
                   7638:        printf("Total traversed free blocks     = %U\n", total);         
                   7639:        printf("Total free blocks by Superblock = %U\n", sbp->s_tfree);  
                   7640:        printf("Running total free blocks       = %U\n", totfree);       
                   7641: #endif
                   7642: 
                   7643:        if ( flag == ABORT ) {          /* To Terminate fsck on this    */
                   7644:                badflag = FALSE;        /* File System, because of      */
                   7645:                return;                 /* excessive dup or bad blocks  */
                   7646:        }
                   7647: 
                   7648:        if ( sbp->s_tfree != totfree )
                   7649:                if ( (qflag==FALSE) && (daction!=NO) ) {
                   7650:                        printf("Free Block count wrong in superblock.  ");
                   7651:                        if ( action(fixit) == TRUE ) {
                   7652:                                sbp->s_tfree = totfree;
                   7653:                                sbpfix = TRUE;
                   7654:                        }
                   7655:                } else {
                   7656:                        sbp->s_tfree = totfree;
                   7657:                        sbpfix = TRUE;
                   7658:                }
                   7659: 
                   7660:        report("%U Bad Block%s in Free List\n", badcnt);
                   7661:        report("%U Dup Block%s in Free List\n", dupcnt);
                   7662:        report("%U Block%s missing\n", totfree - total);
                   7663: 
                   7664: }
                   7665: 
                   7666: report(message, num)
                   7667: char *message;
                   7668: daddr_t num;
                   7669: {
                   7670:        if ( num != 0 ) {
                   7671:                printf(message, num, ( (num>1) ? "s" : "" ) );
                   7672:                badflag = TRUE;
                   7673:        }
                   7674: }
                   7675: 
                   7676: chk(bn)
                   7677: register daddr_t bn;
                   7678: {
                   7679:        if ( (bn<isize) || (bn>=fsize) ) {
                   7680:                badflag = TRUE;
                   7681:                if (++badcnt > MAXBADFREE) 
                   7682:                        return( stopit("bad") );
                   7683:                return(BAD);
                   7684:        }
                   7685: 
                   7686:        if ( testdup(bn) ) {
                   7687:                badflag = TRUE;
                   7688:                if (++dupcnt > MAXDUPFREE)
                   7689:                        return( stopit("dup") );
                   7690:                return(BAD);
                   7691:        } else {
                   7692:                markdup(bn);
                   7693:                return(GOOD);
                   7694:        }
                   7695: }
                   7696:                        
                   7697: stopit(type)
                   7698: char *type;
                   7699: {
                   7700:        printf("Excessive %s blocks in free list ", type);
                   7701:        if ( query("(Continue)") == YES )
                   7702:                return(IGNORE);
                   7703:        else
                   7704:                return(ABORT);
                   7705: }
                   7706:                
                   7707:                
                   7708: canfblk(fbp)
                   7709: register struct fblk *fbp;
                   7710: {
                   7711:        register short i;
                   7712: 
                   7713:        canshort(fbp->df_nfree);
                   7714:        if ( (unsigned) fbp->df_nfree > NICFREE )
                   7715:                return(FALSE);
                   7716: 
                   7717:        for (i=0; i<fbp->df_nfree; i++)
                   7718:                candaddr(fbp->df_free[i]);
                   7719:        return(TRUE);
                   7720: }
                   7721: 
                   7722: asksalvage()
                   7723: {
                   7724:        if ( (daction!=NO) && (qflag || sflag) ) {
                   7725:                fixerup = TRUE;
                   7726:                return;
                   7727:        }
                   7728:        if ( action("Bad Free List (SALVAGE)") )
                   7729:                fixerup = TRUE;
                   7730: }
                   7731: tf("Excessive %s blocks in free list ", type);
                   7732:        if ( query("(Continue)") == YES )
                   7733:                return(IGNORE);
                   7734:        else
                   7735:                return(ABORT);
                   7736: }
                   7737:                
                   7738:                
                   7739: canfblk(fbp)
                   7740: register struct fblk *fbp;
                   7741: {
                   7742:        register short i;
                   7743: 
                   7744:        canshort(fbp->df_nfree);
                   7745:        if ( (unsigned) fbp->df_nfree > NICFREE )
                   7746:                return(FALSE);
                   7747: 
                   7748:        for (i=0; i<fbp->df_nfree; i++)
                   7749:                candaddr(fbp->df_free[i]);
                   7750:        return(TRUE);
                   7751: }
                   7752: 
                   7753: asksalvage()
                   7754: {
                   7755:        if ( fsck/phase6.c   644      3      3        4752  4767014240   6307 /*
                   7756:  *     phase 6 of fsck - Salvage Free List
                   7757:  */
                   7758: 
                   7759: #include "fsck.h"
                   7760: 
                   7761: static unsigned char *maptab;  /* table of interleave offsets  */
                   7762: static daddr_t mapbot;         /* minimum block number to interleave map */
                   7763: static daddr_t maptop;         /* maximum block number to interleave map */
                   7764: static short   m,n;            /* interleave factors   */
                   7765: #define        DEF_N   1               /* default values       */
                   7766: #define        DEF_M   1               
                   7767: daddr_t        freeblks;               /* number free blocks left to write out */
                   7768: daddr_t        blknm;                  /* current block number we are working with */
                   7769: struct fblk *fblkp;            /* pointer to free block list */
                   7770: daddr_t        *dp;                    /* pointer to block entry in free list block */
                   7771: 
                   7772: phase6()
                   7773: {
                   7774:        if (!fixerup) {
                   7775:                return;
                   7776:        }
                   7777: 
                   7778:        if (!qflag)
                   7779:                printf("Phase 6 : Salvage Free List\n");
                   7780:        if ( maketable() == BAD )
                   7781:                return;
                   7782:        writefree();
                   7783:        free(maptab);
                   7784: }
                   7785: 
                   7786: maketable()
                   7787: {
                   7788:        register int i;
                   7789:        register int ratio;
                   7790: 
                   7791:        m = sbp->s_m;
                   7792:        n = sbp->s_n;
                   7793: 
                   7794:        if ( (n > MAXINTN) || (m > n) || (n%m != 0) ) {
                   7795:                printf("Invalid interleave factors in superblock.\n");
                   7796:                printf("Default free-block list spacing assumed.\n");
                   7797:                sbp->s_n = n = DEF_N;
                   7798:                sbp->s_m = m = DEF_M;
                   7799:        }
                   7800: 
                   7801:        if ( (maptab = malloc(n)) == NULL ) {
                   7802:                printf("Can't malloc space for interleave table.\n");
                   7803:                printf("Free-block list is not rebuilt.\n");
                   7804:                return(BAD);
                   7805:        }
                   7806: 
                   7807:        mapbot = (isize + n - 1)/n*n;
                   7808:        maptop = fsize/n*n;
                   7809:        ratio = n/m;
                   7810:        for (i=0; i<n; i++)
                   7811:                maptab[i] = (i/ratio) + (i%ratio)*m;
                   7812: 
                   7813:        return(GOOD);
                   7814: }
                   7815: 
                   7816: writefree()
                   7817: {
                   7818:        register daddr_t bn;
                   7819:        daddr_t blk, bmap();
                   7820:        short num;
                   7821: 
                   7822:        sbpfix = TRUE;
                   7823:        freeblks = totfree;
                   7824:        blknm = SUPERI;
                   7825:        fblkp = (struct fblk *) &sbp->s_nfree;
                   7826:        fblkp->df_nfree = num = (freeblks < NICFREE) ? freeblks : NICFREE;
                   7827:        freeblks -= num;
                   7828:        dp = &fblkp->df_free[num];
                   7829:        for (bn=isize; bn<fsize; bn++) {
                   7830:                blk = bmap(bn);
                   7831:                if ( !testblock(blk) ) 
                   7832:                        if ( addfree(blk) == STOP )
                   7833:                                break;
                   7834:        }
                   7835: }
                   7836: 
                   7837: addfree(bn)
                   7838: daddr_t bn;
                   7839: {
                   7840:        short num;
                   7841: 
                   7842:        *--dp = bn;
                   7843:        if (dp > &fblkp->df_free[0])
                   7844:                return(OK);
                   7845: 
                   7846:        if ( blknm != SUPERI ) {
                   7847:                canwfblk(fblkp);
                   7848:                bwrite(blknm, databuf);
                   7849:        }
                   7850: 
                   7851:        bclear(databuf, BSIZE);
                   7852:        if (freeblks == 0) {
                   7853:                bwrite(bn, databuf);
                   7854:                return(STOP);
                   7855:        }
                   7856:        blknm = bn;
                   7857:        fblkp = (struct fblk *) databuf;
                   7858:        fblkp->df_nfree = num = (freeblks < NICFREE) ? freeblks : NICFREE;
                   7859:        freeblks -= num;
                   7860:        dp = &fblkp->df_free[num];
                   7861:        return(OK);
                   7862: }
                   7863: 
                   7864: daddr_t
                   7865: bmap(blk)
                   7866: register daddr_t blk;
                   7867: {
                   7868:        short i;
                   7869: 
                   7870:        if ( (blk>=mapbot) && (blk<maptop) ) {
                   7871:                i = blk%n;
                   7872:                blk -= i;
                   7873:                blk += maptab[i];
                   7874:        }
                   7875:        return(blk);
                   7876: }
                   7877: 
                   7878: canwfblk(fbp)
                   7879: register struct fblk *fbp;
                   7880: {
                   7881:        register short i;
                   7882: 
                   7883:        for (i=0; i<fbp->df_nfree; i++)
                   7884:                candaddr(fbp->df_free[i]);
                   7885:        canshort(fbp->df_nfree);
                   7886: }
                   7887: uf);
                   7888:                return(STOP);
                   7889:        fsck/printf.c   644      3      3        7271  4664524124   6425 /*
                   7890:  * Standard output printf using putchar.
                   7891:  * Non-portable things:
                   7892:  * 1) alignment of arguments is assumed to be completely contiguous.
                   7893:  * 2) the smallest number is assumed to negate to itself.
                   7894:  * 3) All of long, int, char*, and double are assumed to
                   7895:  *    be held in an exact number of ints.
                   7896:  */
                   7897: 
                   7898: #define NULL ((char *)0)
                   7899: #define putchar(c) { char b = c; write(1, &b, 1); }
                   7900: #include <sys/mdata.h>
                   7901: 
                   7902: union  alltypes {
                   7903:        char    c;
                   7904:        int     i;
                   7905:        unsigned u;
                   7906:        long    l;
                   7907:        double  d;
                   7908:        char    *s;
                   7909: };
                   7910: 
                   7911: #define        bump(p,s)       (p+=sizeof(s)/sizeof(int))
                   7912: 
                   7913: char   *printi();
                   7914: char   *printl();
                   7915: 
                   7916: static char    null[] = "{NULL}";
                   7917: 
                   7918: printf(args)
                   7919: union alltypes args;
                   7920: {
                   7921:        xprintf(&args);
                   7922: }
                   7923: xprintf(argp)
                   7924: union alltypes *argp;
                   7925: {
                   7926:        register char *cbp;
                   7927:        int *iap;
                   7928:        register c;
                   7929:        char *s;
                   7930:        char *cbs;
                   7931:        char adj, pad;
                   7932:        int prec;
                   7933:        int fwidth;
                   7934:        int pwidth;
                   7935:        register char *fmt;
                   7936:        union alltypes elem;
                   7937:        char cbuf[64];
                   7938: 
                   7939:        iap = (int *)argp;
                   7940:        fmt = *(char **)iap;
                   7941:        bump(iap, char*);
                   7942:        for (;;) {
                   7943:                while((c = *fmt++) != '%') {
                   7944:                        if(c == '\0') {
                   7945:                                return;
                   7946:                        }
                   7947:                        putchar(c);
                   7948:                }
                   7949:                pad = ' ';
                   7950:                fwidth = -1;
                   7951:                prec = -1;
                   7952:                c = *fmt++;
                   7953:                if (c == '-') {
                   7954:                        adj = 1;
                   7955:                        c = *fmt++;
                   7956:                } else
                   7957:                        adj = 0;
                   7958:                if (c == '0') {
                   7959:                        pad = '0';
                   7960:                        c = *fmt++;
                   7961:                }
                   7962:                if (c == '*') {
                   7963:                        fwidth = *iap++;
                   7964:                        c = *fmt++;
                   7965:                } else
                   7966:                        for (fwidth = 0; c>='0' && c<='9'; c = *fmt++)
                   7967:                                fwidth = fwidth*10 + c-'0';
                   7968:                if (c == '.') {
                   7969:                        c = *fmt++;
                   7970:                        if (c == '*') {
                   7971:                                prec = *iap++;
                   7972:                                c = *fmt++;
                   7973:                        } else
                   7974:                                for (prec=0; c>='0' && c<='9'; c=*fmt++)
                   7975:                                        prec = prec*10 + c-'0';
                   7976:                }
                   7977:                if (c == 'l') {
                   7978:                        c = *fmt++;
                   7979:                        if (c=='d' || c=='o' || c=='u' || c=='x')
                   7980:                                c += 'A' - 'a';
                   7981:                }
                   7982:                cbp = cbs = cbuf;
                   7983:                switch (c) {
                   7984: 
                   7985:                case 'd':
                   7986:                        elem.i = *iap++;
                   7987:                        if (elem.i < 0) {
                   7988:                                elem.i = -elem.i;
                   7989:                                *cbp++ = '-';
                   7990:                        }
                   7991:                        cbp = printi(cbp, elem.i, 10);
                   7992:                        break;
                   7993: 
                   7994:                case 'u':
                   7995:                        cbp = printi(cbp, *iap++, 10);
                   7996:                        break;
                   7997:        
                   7998:                case 'o':
                   7999:                        cbp = printi(cbp, *iap++, 8);
                   8000:                        break;
                   8001: 
                   8002:                case 'x':
                   8003:                        cbp = printi(cbp, *iap++, 16);
                   8004:                        break;
                   8005: 
                   8006:                case 'D':
                   8007:                        elem.l = *(long *)iap;
                   8008:                        bump(iap, long);
                   8009:                        if (elem.l < 0) {
                   8010:                                elem.l = -elem.l;
                   8011:                                *cbp++ = '-';
                   8012:                        }
                   8013:                        cbp = printl(cbp, elem.l, 10);
                   8014:                        break;
                   8015: 
                   8016:                case 'U':
                   8017:                        cbp = printl(cbp, *(long *)iap, 10);
                   8018:                        bump(iap, long);
                   8019:                        break;
                   8020: 
                   8021:                case 'O':
                   8022:                        cbp = printl(cbp, *(long *)iap, 8);
                   8023:                        bump(iap, long);
                   8024:                        break;
                   8025: 
                   8026:                case 'X':
                   8027:                        cbp = printl(cbp, *(long *)iap, 16);
                   8028:                        bump(iap, long);
                   8029:                        break;
                   8030: 
                   8031: 
                   8032:                case 's':
                   8033:                        if ((s = *(char **)iap) == NULL)
                   8034:                                s = null;
                   8035:                        bump(iap, char*);
                   8036:                        /*
                   8037:                         * Do %s specially so it can be longer.
                   8038:                         */
                   8039:                        cbp = cbs = s;
                   8040:                        while (*cbp++ != '\0')
                   8041:                                if (prec>=0 && cbp-s>prec)
                   8042:                                        break;
                   8043:                        cbp--;
                   8044:                        break;
                   8045:        
                   8046:                case 'c':
                   8047:                        elem.c = *iap++;
                   8048:                        *cbp++ = elem.c;
                   8049:                        break;
                   8050:        
                   8051:                case 'r':
                   8052:                        xprintf(*(char ***)iap);
                   8053:                        bump(iap, char**);
                   8054:                        break;
                   8055:        
                   8056:                default:
                   8057:                        putchar(c);
                   8058:                        continue;
                   8059:                }
                   8060:                if ((pwidth = fwidth + cbs-cbp) < 0)
                   8061:                        pwidth = 0;
                   8062:                if (!adj)
                   8063:                        while (pwidth-- != 0)
                   8064:                                putchar(pad);
                   8065:                while (cbs < cbp)
                   8066:                        putchar(*cbs++);
                   8067:                if (adj)
                   8068:                        while (pwidth-- != 0)
                   8069:                                putchar(pad);
                   8070:        }
                   8071: }
                   8072: 
                   8073: static char    digits[] = {
                   8074:        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                   8075:        'A', 'B', 'C', 'D', 'E', 'F'
                   8076: };
                   8077: 
                   8078: /*
                   8079:  * Print an unsigned integer in base b.
                   8080:  */
                   8081: static
                   8082: char *
                   8083: printi(cp, n, b)
                   8084: char *cp;
                   8085: register unsigned n;
                   8086: {
                   8087:        register a;
                   8088:        register char *ep;
                   8089:        char pbuf[10];
                   8090: 
                   8091:        ep = &pbuf[10];
                   8092:        *--ep = 0;
                   8093:        for ( ; a = n/b; n=a)
                   8094:                *--ep = digits[n%b];
                   8095:        *--ep = digits[n];
                   8096:        while (*ep)
                   8097:                *cp++ = *ep++;
                   8098:        return (cp);
                   8099: }
                   8100: 
                   8101: /*
                   8102:  * Print an unsigned long in base b.
                   8103:  */
                   8104: static
                   8105: char *
                   8106: printl(cp, n, b)
                   8107: register char *cp;
                   8108: unsigned long n;
                   8109: register b;
                   8110: {
                   8111:        char pbuf[13];
                   8112:        unsigned long a;
                   8113:        register char *ep;
                   8114: 
                   8115:        ep = &pbuf[13];
                   8116:        *--ep = '\0';
                   8117:        for ( ; (a = n/b) != 0; n = a)
                   8118:                *--ep = digits[n%b];
                   8119:        *--ep = digits[n];
                   8120:        while (*ep)
                   8121:                *cp++ = *ep++;
                   8122:        return (cp);
                   8123: }
                   8124:        register char *ep;
                   8125:        char pbuf[10];
                   8126: 
                   8127:        ep = &pbuf[10];
                   8128:        *--ep = 0;
                   8129:        for ( ; a = n/b; n=a)
                   8130:                *--ep = digits[n%b];
                   8131:        *--ep = digits[n];
                   8132:        while (*ep)
                   8133:                *cp++ = *ep++;
                   8134:        return (cp);
                   8135: }
                   8136: 
                   8137: /*
                   8138:  * Print an unsigned long in base b.
                   8139:  */
                   8140: static
                   8141: char *
                   8142: printl(cp, n, b)
                   8143: register char *cp;
                   8144: unsigned long n;
                   8145: register b;
                   8146: {
                   8147:        char pbuf[13];
                   8148:        unsignfsck/util.c   644      3      3       15535  5033710270   6110 /*
                   8149:  *     general utility functions for phases of fsck
                   8150:  */
                   8151: 
                   8152: #include "fsck.h"
                   8153: 
                   8154: struct stat stats;                     /* Used by statit() */
                   8155: 
                   8156: statit(name, probfun)
                   8157: char *name;
                   8158: int (*probfun)();
                   8159: {
                   8160:        
                   8161:        if ( stat(name, &stats) == -1 ) {
                   8162:                bclear(&stats, sizeof(struct stat));
                   8163:                (*probfun)("Can not stat %s", name);
                   8164:        }
                   8165: }
                   8166: 
                   8167: 
                   8168: query(x)
                   8169: {
                   8170:        while(1) {
                   8171:                printf("%r [yes/no]: ", &x);
                   8172:        
                   8173:                switch (daction) {
                   8174:                case YES:
                   8175:                        printf("[default - YES]\n");
                   8176:                        return(YES);
                   8177:                        break;
                   8178:                case NO:
                   8179:                        printf("[default - NO]\n");
                   8180:                        return(NO);
                   8181:                        break;
                   8182:                case ASK:
                   8183:                        switch( nextchar() ) {
                   8184:                        case 'Y':
                   8185:                                return(YES);
                   8186:                        case 'N':
                   8187:                                return(NO);
                   8188:                        }
                   8189:                }
                   8190:        }
                   8191: }
                   8192: 
                   8193: action(msg)
                   8194: char *msg;
                   8195: {
                   8196:        switch( query(msg) ) {
                   8197:        case YES:
                   8198:                return(TRUE);
                   8199:        case NO:
                   8200:                return(FALSE);
                   8201:        }
                   8202: }
                   8203: 
                   8204: char
                   8205: nextchar()
                   8206: {
                   8207:        char buff[8];
                   8208:        int i, n, ch;
                   8209: 
                   8210:        if ( ((n=read(0,buff,8)) <= 0) || (n == 8) )
                   8211:                fatal("Invalid Response");
                   8212: 
                   8213:        for(i=0; i<n; i++)
                   8214:                if ( ((ch=buff[i])!=' ') && (ch!='\t') )
                   8215:                        break;
                   8216: 
                   8217:        if ( (ch>='a') && (ch<='z') )
                   8218:                ch += 'A' - 'a';
                   8219: 
                   8220:        return(ch);
                   8221: }
                   8222: 
                   8223: char   *nfile  = "FILE";
                   8224: char   *ndir   = "DIR";
                   8225: char   *nchr   = "Character Special";
                   8226: char   *nblk   = "Block Special";
                   8227: char   *npipe  = "PIPE";
                   8228: char   *nunkwn = "Unknown I-node type";
                   8229: 
                   8230: char *
                   8231: typename(ino)
                   8232: ino_t ino;
                   8233: {
                   8234:        switch( flags(ino)&MODEMASK ) {
                   8235:        case IREG:
                   8236:                return(nfile);
                   8237:        case IDIR:
                   8238:                return(ndir);
                   8239:        case ICHR:
                   8240:                return(nchr);
                   8241:        case IBLK:
                   8242:                return(nblk);
                   8243:        case IPIPE:
                   8244:                return(npipe);
                   8245:        default:
                   8246:                return(nunkwn);
                   8247:        }
                   8248: }
                   8249: 
                   8250: abort()
                   8251: {
                   8252:        fatal("abort.");
                   8253: }
                   8254: 
                   8255: fatal(x)
                   8256: {
                   8257:        printf("fsck: %r\n", &x);
                   8258:        _exit(1);
                   8259: }
                   8260: 
                   8261: nonfatal(x)
                   8262: {
                   8263:        printf("fsck: %r\n", &x);
                   8264:        errflag = TRUE;
                   8265: }
                   8266: 
                   8267: /*
                   8268:  *     Inode Manipulation Routines
                   8269:  *     ptrino: returns a pointer to the wanted inode using the given
                   8270:  *             buffer to read in the block performing canonicalization.
                   8271:  *     writeino: writes the block containing the given inode to the
                   8272:  *             disk performing the necessary canonicalization
                   8273:  *     candino: canonicalize an inode
                   8274:  *
                   8275:  */
                   8276: 
                   8277: struct dinode *
                   8278: ptrino(ino, buf)
                   8279: register ino_t ino;
                   8280: register char *buf;
                   8281: {
                   8282:        register daddr_t bn;
                   8283:        register struct dinode *dip;
                   8284: 
                   8285:        bn = iblockn(ino);
                   8286:        if ( (testblock(bn)) && (bn!=INODEI) )          /* bad inode block */
                   8287:                return(NULL);
                   8288:        bread(bn, buf);
                   8289:        dip = ((struct dinode *) buf) + iblocko(ino);
                   8290:        candino(dip);
                   8291:        return(dip);
                   8292: }
                   8293: 
                   8294: writeino(ino, buf)
                   8295: ino_t ino;
                   8296: char *buf;
                   8297: {
                   8298:        struct dinode *dip;
                   8299: 
                   8300:        dip = ((struct dinode *) buf) + iblocko(ino);
                   8301:        candino(dip);
                   8302:        bwrite((daddr_t) iblockn(ino), buf);
                   8303: }
                   8304: 
                   8305: candino(dip)
                   8306: register struct dinode *dip;
                   8307: {
                   8308:        canshort(dip->di_mode);
                   8309:        canshort(dip->di_nlink);
                   8310:        canshort(dip->di_uid);
                   8311:        canshort(dip->di_gid);
                   8312:        cansize(dip->di_size);
                   8313:        cantime(dip->di_atime);
                   8314:        cantime(dip->di_mtime);
                   8315:        cantime(dip->di_ctime);
                   8316: }
                   8317: 
                   8318: /*
                   8319:  *     Transfer a logical block number for an inode to a
                   8320:  *     physical block number, chasing indirects as necessary.
                   8321:  *     The inefficiency of this method is put up with since
                   8322:  *     this is only used for directory inodes, and they tend
                   8323:  *     not to use indirects.  Pass in 'addrs' which is a pointer
                   8324:  *     to the 13 daddr_s in the inode, and the logical block
                   8325:  *     number you would like.  (Stolen from dcheck.c)
                   8326:  */
                   8327: 
                   8328: static daddr_t ranges[] = {
                   8329:        ND,
                   8330:        ND + (daddr_t)NI*NBN,
                   8331:        ND + (daddr_t)NI*NBN + (daddr_t)NII*NBN*NBN,
                   8332:        ND + (daddr_t)NI*NBN + (daddr_t)NII*NBN*NBN + (daddr_t)NIII*NBN*NBN*NBN
                   8333: };
                   8334: 
                   8335: static char    index[] = {
                   8336:        0,
                   8337:        ND,
                   8338:        ND+NI,
                   8339:        ND+NI+NII
                   8340: };
                   8341: 
                   8342: static daddr_t coeff[] = {
                   8343:        1,      (daddr_t)NBN,   (daddr_t)NBN*NBN,       (daddr_t)NBN*NBN*NBN
                   8344: };
                   8345: 
                   8346: daddr_t
                   8347: imap(addrs, block)
                   8348: daddr_t *addrs;
                   8349: register daddr_t block;
                   8350: {
                   8351:        int i;
                   8352:        register daddr_t bpos;
                   8353:        register daddr_t *bp;
                   8354:        register daddr_t bn;
                   8355: 
                   8356:        for (i=0; i<4; i++)
                   8357:                if (block < ranges[i]) {
                   8358:                        if (i != 0)
                   8359:                                block -= ranges[i-1];
                   8360:                        bpos = block/coeff[i];
                   8361:                        block %= coeff[i];
                   8362:                        bp = &addrs[(int)bpos + index[i]];
                   8363:                        if ( (bn=*bp) != 0 ) {
                   8364:                                /*
                   8365:                                 * Map through indirects here
                   8366:                                 */
                   8367:                                while (i-- > 0) {
                   8368:                                        bread(bn, databuf);
                   8369:                                        bpos = block/coeff[i];
                   8370:                                        block %= coeff[i];
                   8371:                                        bp = (daddr_t *)databuf + bpos;
                   8372:                                        if ( (bn=*bp) == 0 )
                   8373:                                                break;
                   8374:                                        bn = *bp;
                   8375:                                        candaddr(bn);
                   8376:                                }
                   8377:                        }
                   8378:                        return(bn);
                   8379:                }
                   8380:        return(0);
                   8381: }
                   8382: 
                   8383: /*
                   8384:  *     Read the specified block number into the given buffer
                   8385:  */
                   8386: 
                   8387: char *rgblkerr = "Out of Range Block number: %U  (CONTINUE)";
                   8388: char *skblkerr = "Can not Seek: Blk num: %U  (CONTINUE)";
                   8389: char *rdblkerr = "Can not Read: Blk num: %U  (CONTINUE)";
                   8390: char *wtblkerr = "Can not Write: Blk num: %U  (CONTINUE)";
                   8391: 
                   8392: bread(bn, buf)
                   8393: register daddr_t bn;
                   8394: register char *buf;
                   8395: {
                   8396: #ifdef DEBUG
                   8397:        printf("Reading block number: %ld\n", bn);
                   8398: #endif
                   8399:        if (bn<0 || bn >= fsize ) 
                   8400:                switch( query(rgblkerr, bn) ) {  
                   8401:                case YES:
                   8402:                        bclear(buf, BSIZE);
                   8403:                        return;
                   8404:                case NO:
                   8405:                        abort();
                   8406:                }
                   8407: 
                   8408:        if ( (bn<isize) && getcache(bn, buf) ) {
                   8409: #if DEBUG
                   8410:                bdump(buf);
                   8411: #endif
                   8412:                return;
                   8413:        }
                   8414:        
                   8415:        if ( lseek(fsfd, (unsigned long)bn*BSIZE, 0) == (-1L) )
                   8416:                switch( query(skblkerr, bn) ) {
                   8417:                case YES:
                   8418:                        bclear(buf, BSIZE);
                   8419:                        return;
                   8420:                case NO:
                   8421:                        abort();
                   8422:                }
                   8423: 
                   8424:        if ( read(fsfd, buf, BSIZE) != BSIZE ) 
                   8425:                switch( query(rdblkerr, bn) ) {
                   8426:                case YES:
                   8427:                        bclear(buf, BSIZE);
                   8428:                        return;
                   8429:                case NO:
                   8430:                        abort();
                   8431:                }
                   8432: #if DEBUG
                   8433:        bdump(buf);
                   8434: #endif
                   8435: }
                   8436: 
                   8437: /*
                   8438:  *     Write block number bn with data in buf
                   8439:  */
                   8440: 
                   8441: bwrite(bn, buf)
                   8442: daddr_t bn;
                   8443: char *buf;
                   8444: {
                   8445: #ifdef DEBUG
                   8446:        printf("Writing block number: %ld\n", bn);
                   8447: #endif
                   8448:        if (!writeflg)
                   8449:                return;
                   8450: 
                   8451:        if (bn<0 || bn>=fsize) 
                   8452:                switch( query(rgblkerr, bn) ) {
                   8453:                case YES:
                   8454:                        return;
                   8455:                case NO:
                   8456:                        abort();
                   8457:                }
                   8458:        
                   8459:        if ( lseek(fsfd, (fsize_t)BSIZE*bn, 0) == (-1L) )
                   8460:                switch( query(skblkerr, bn) ) {
                   8461:                case YES:
                   8462:                        return;
                   8463:                case NO:
                   8464:                        abort();
                   8465:                }
                   8466: 
                   8467:        if ( write(fsfd, buf, BSIZE) != BSIZE ) 
                   8468:                switch( query(wtblkerr, bn) ) {
                   8469:                case YES:
                   8470:                        return;
                   8471:                case NO:
                   8472:                        abort();
                   8473:                }
                   8474: 
                   8475:        if ( bn <= isize )
                   8476:                chgcache(bn, buf);
                   8477:        changeflg = TRUE;
                   8478: }
                   8479: 
                   8480: /*
                   8481:  *     i-node block area caching routines
                   8482:  */
                   8483: 
                   8484: static char    cache[NBLK * BSIZE];
                   8485: static int     low = 0; high = -1;
                   8486: 
                   8487: getcache(bn, buf)
                   8488: register daddr_t bn;
                   8489: register char *buf;
                   8490: {
                   8491:        int totsize;
                   8492: 
                   8493:        if ( bn > isize )
                   8494:                return(0);
                   8495: 
                   8496:        if ( (bn>=low) && (bn<=high) ) {
                   8497:                blkmove(buf, &cache[BSIZE * (bn-low)]);
                   8498:                return(1);
                   8499:        }
                   8500: 
                   8501:        low = bn;
                   8502:        if ( (high=bn+NBLK-1) > isize )
                   8503:                high = isize;
                   8504:        totsize = BSIZE * (high-low+1);
                   8505: 
                   8506:        if ( (lseek(fsfd, (unsigned long)bn*BSIZE, 0) == (-1L)) ||
                   8507:             (read(fsfd, cache, totsize) != totsize) ) {
                   8508:                low = 0; high = -1;
                   8509:                return(0);
                   8510:        }
                   8511: 
                   8512:        return( getcache(bn, buf) );
                   8513: }
                   8514: 
                   8515: chgcache(bn, buf)
                   8516: register daddr_t bn;
                   8517: register char *buf;
                   8518: {
                   8519:        if ( (bn>=low) && (bn<=high) )
                   8520:                blkmove(&cache[BSIZE * (bn-low)], buf);
                   8521: }
                   8522: 
                   8523: blkmove(to, from)
                   8524: register char *to, *from;
                   8525: {
                   8526:        register int num=BSIZE;
                   8527: 
                   8528:        while ( num-- )
                   8529:                *to++= *from++;
                   8530: }
                   8531: 
                   8532: /*
                   8533:  *     Clear the given block of memory
                   8534:  */
                   8535: 
                   8536: bclear(bp, nb)
                   8537: register char *bp;
                   8538: register unsigned nb;
                   8539: {
                   8540:        if (nb)
                   8541:                do {
                   8542:                        *bp++ = 0;
                   8543:                } while (--nb);
                   8544: }
                   8545: 
                   8546: 
                   8547: /*
                   8548:  *     Determine if the given block is bad
                   8549:  */
                   8550: 
                   8551: bad(bn)
                   8552: daddr_t bn;
                   8553: {
                   8554:        if ( (bn >= isize) && (bn < fsize) )
                   8555:                return(GOOD);
                   8556:        else
                   8557:                return(BAD);
                   8558: }
                   8559: 
                   8560: 
                   8561: #if DEBUG
                   8562: 
                   8563: /*
                   8564:  *     Debug dump a block of data.
                   8565:  */
                   8566: 
                   8567: #define NUMPLIN        16
                   8568: 
                   8569: bdump(buf)
                   8570: register unsigned char *buf;
                   8571: {
                   8572:        register int i;
                   8573: 
                   8574:        for (i=0; i<BSIZE; i++) {
                   8575:                if ( (i % NUMPLIN) == 0 )
                   8576:                        printf("\n0x%04x:  ", i);
                   8577:                printf(" %02x", *buf++);
                   8578:        }
                   8579:        printf("\n\n");
                   8580: }
                   8581: 
                   8582: #endif
                   8583: ister char *bp;
                   8584: register unsigned nb;
                   8585: {
                   8586:        if (nb)
                   8587:                do {
                   8588:                        *bp++ = 0;
                   8589:                } while (--nb);
                   8590: }
                   8591: 
                   8592: 
                   8593: /*
                   8594:  *     Determine if the given block is bad
                   8595:  */
                   8596: 
                   8597: bad(bn)
                   8598: daddr_t bn;
                   8599: {
                   8600:        ifsck/virtual.c   644      3      3       16227  4767016247   6640 /*
                   8601:  * Virtual memory for fsck. Uses hash algorithm
                   8602:  * rather than LRU to get it up fast.
                   8603:  */
                   8604: #include <assert.h>
                   8605: #include <sys/stat.h>
                   8606: #include "fsck.h"
                   8607: 
                   8608: #define VBLKB 9                        /* bytes in virtual block as power of 2 */
                   8609: #define VBLK (1 << VBLKB)      /* bytes in a virtual block */
                   8610: #define MBKSB 6                        /* number of virtual blocks as power of 2 */
                   8611: #define MBKS (1 << MBKSB)      /* number of virtual blocks */
                   8612: 
                   8613: #define DVTMP "/dev/rram1"     /* Default Virtual Temp Filename */
                   8614: #define DVTMPCLS "/dev/rram1close" /* Default Virtual Temp File Close */
                   8615: #define        MAJORRAM 8              /* Major Device Number for the Ram Disk */
                   8616: 
                   8617: struct mapper {
                   8618:        unsigned dirty:1;
                   8619:        unsigned what_in:15;    /* which block is in memory */
                   8620: };
                   8621: 
                   8622: static unsigned long flagdsp, blkdsp, dupdsp, duplim;
                   8623: static struct mapper map[MBKS];
                   8624: static unsigned char data[MBKS][VBLK];
                   8625: static int tmp;
                   8626: 
                   8627: static char *dvtmp = DVTMP;
                   8628: static char *dvtmpcls = DVTMPCLS;
                   8629: 
                   8630: /*
                   8631:  * Init file system for virtual arrays.
                   8632:  * Data is ordered links, flags, blocks then dups.
                   8633:  */
                   8634: initV(links, flags, blocks, dups)
                   8635: unsigned links, flags, blocks, dups;
                   8636: {
                   8637:        register long bp;
                   8638:        struct stat st;
                   8639:        unsigned datasiz;
                   8640: 
                   8641:        flagdsp = links;
                   8642:        blkdsp = flagdsp + flags;
                   8643:        dupdsp = blkdsp + blocks;
                   8644:        duplim = dupdsp + dups;
                   8645: 
                   8646:        memset(map, 0, sizeof(map));    /* zero ram arrays */
                   8647:        memset(data, 0, sizeof(data));
                   8648: 
                   8649:        tmp = -1;
                   8650: 
                   8651:        datasiz = sizeof(data);
                   8652:        if ( duplim < datasiz )
                   8653:                return;
                   8654: 
                   8655:        if ( tmpfile == NULL ) {
                   8656:                switch ( is_fs(dvtmp) ) {
                   8657:                case -1:
                   8658:                        fatal(
                   8659: "Can't access ram disk \"%s\", use the -t option", dvtmp);
                   8660:                case 0:
                   8661:                        break;
                   8662:                case 1:
                   8663:                        fatal(
                   8664: "Possible file system on ram disk \"%s\", use the -t option", dvtmp);
                   8665:                }
                   8666:                if ( (-1 == stat(dvtmp, &st)) || !(st.st_mode&S_IFCHR) ||
                   8667:                        (major(st.st_rdev) != MAJORRAM) )
                   8668:                                fatal("Ram disk \"%s\" not mknod'ed properly",
                   8669:                                                                dvtmp);
                   8670:                if ( -1 == (tmp = open(dvtmp, 2)) )
                   8671:                        fatal("Cannot open read/write Ram Disk \"%s\"", dvtmp);
                   8672: 
                   8673:                /* Ram disk driver may not promise zeroed start.
                   8674:                 * This code may go later. Extra write not important. */
                   8675:                for(bp = 0; bp < duplim; bp += VBLK) /* zero disk stuff */
                   8676:                        if ( VBLK != write(tmp, data[0], VBLK) )
                   8677:                                fatal("Error writing to tmp file");
                   8678:        } else {
                   8679:                if ( -1 == (tmp = open(tmpfile, 2)) ) {
                   8680:                        if ( -1 == (tmp = creat(tmpfile, 0600)) )
                   8681:                                fatal("Cannot create temp file \"%s\"", 
                   8682:                                                                tmpfile);
                   8683:                        close(tmp);
                   8684:                        tmp = open(tmpfile, 2);
                   8685:                        unlink(tmpfile);
                   8686:                }
                   8687:                if ( -1 == fstat(tmp, &st) )
                   8688:                        fatal("Can't stat temp file \"%s\"", tmpfile);
                   8689:                if ( st.st_dev == fsysrdev )
                   8690:                        fatal("Temp File must not be on file system to fsck");
                   8691:        }
                   8692: }
                   8693: 
                   8694: /*
                   8695:  * cleanup virtual system
                   8696:  */
                   8697: cleanV()
                   8698: {
                   8699:        struct stat st;
                   8700: 
                   8701:        if ( tmp == -1 )                /* No Virtual Temp File Opened  */
                   8702:                return;
                   8703: 
                   8704:        close(tmp);
                   8705:        if ( tmpfile != NULL )          /* Virtual File not Default RAMDisk */
                   8706:                return;
                   8707:                                        /* Virtual File is Default RAMDisk */
                   8708:        if ( (-1 == stat(dvtmpcls, &st)) || !(st.st_mode&S_IFCHR) ||
                   8709:                (major(st.st_rdev) != MAJORRAM) ||
                   8710:                ((minor(st.st_rdev)&0x7F) != 0) )
                   8711:                fatal("Ram disk close \"%s\" not mknod'ed properly", dvtmpcls);
                   8712:        if ( -1 == (tmp = open(dvtmpcls, 2)) )
                   8713:                fatal("Cannot open Ram Disk Close \"%s\"", dvtmpcls);
                   8714:        if ( close(tmp) < 0 )
                   8715:                fatal("Cannot close Ram Disk Close \"%s\"", dvtmpcls);
                   8716: }
                   8717: 
                   8718: /*
                   8719:  * All actions for virtual array
                   8720:  */
                   8721: findblock(bp, action, odata)
                   8722: long bp;               /* data address */
                   8723: enum vact action;      /* what to do */
                   8724: unsigned odata;                /* optional data */
                   8725: {
                   8726:        unsigned which, what_in, byte_no, bit;
                   8727:        unsigned long diskad;
                   8728:        unsigned char *byte;
                   8729:        extern long lseek();
                   8730: 
                   8731:        switch(action) {        /* use displacment to correct part of file */
                   8732:        case testBlock:
                   8733:        case markBlock:
                   8734:        case unmarkBlock:
                   8735:                bit = 1 << (bp & 7);
                   8736:                bp >>= 3;
                   8737:        case grabBlock:         /* 8 at a time for copy */
                   8738:                assert(bp >= 0);
                   8739:                bp += blkdsp;
                   8740:                assert(bp < dupdsp);
                   8741:                break;
                   8742:        case testDup:
                   8743:        case markDup:
                   8744:        case unmarkDup:
                   8745:                bit = 1 << (bp & 7);
                   8746:                bp >>= 3;
                   8747:        case setDup:            /* 8 at a time for copy */
                   8748:                assert(bp >= 0);
                   8749:                bp += dupdsp;
                   8750:                assert(bp < duplim);
                   8751:                break;
                   8752:        case Flags:
                   8753:        case setFlags:
                   8754:        case orFlags:
                   8755:                assert(bp > 0);
                   8756:                bp += flagdsp - 1;
                   8757:                assert(bp < blkdsp);
                   8758:                break;
                   8759:        case linkCtr:
                   8760:        case incLinkctr:
                   8761:        case setLinkctr:
                   8762:                assert(bp > 0);
                   8763:                bp--;
                   8764:                assert(bp < flagdsp);
                   8765:        }
                   8766: 
                   8767:        byte_no = bp & (VBLK - 1);
                   8768:        bp >>= VBLKB;
                   8769:        which = bp & (MBKS - 1);
                   8770:        bp >>= MBKSB;
                   8771:        what_in = bp & 0x7fff;
                   8772: 
                   8773:        if((diskad = map[which].what_in) != what_in)    {
                   8774:                if(map[which].dirty) {
                   8775:                        diskad <<= VBLKB + MBKSB;
                   8776:                        diskad += which << VBLKB;
                   8777:                        if(-1 == lseek(tmp, diskad, 0))
                   8778:                                fatal("Error seeking tmp file");
                   8779:                        if(VBLK != write(tmp, data[which], VBLK))
                   8780:                                fatal("Error writing tmp file");
                   8781:                }
                   8782:                diskad = what_in;
                   8783:                diskad <<= VBLKB + MBKSB;
                   8784:                diskad += which << VBLKB;
                   8785:                if(-1 == lseek(tmp, diskad, 0))
                   8786:                        fatal("Error seeking tmp file");
                   8787:                if(VBLK != read(tmp, data[which], VBLK))
                   8788:                        memset(data[which], 0, VBLK);
                   8789:                map[which].what_in = what_in;
                   8790:                map[which].dirty = 0; /* clean */
                   8791:        }
                   8792:        byte = &data[which][byte_no];
                   8793: 
                   8794:        switch(action) {
                   8795:        case testBlock:
                   8796:        case testDup:
                   8797:                return(*byte & bit);
                   8798:        case markBlock:
                   8799:        case markDup:
                   8800:                map[which].dirty = 1;
                   8801:                return(*byte |= bit);
                   8802:        case unmarkBlock:
                   8803:        case unmarkDup:
                   8804:                map[which].dirty = 1;
                   8805:                return(*byte ^= bit);
                   8806:        case linkCtr:
                   8807:        case Flags:
                   8808:        case grabBlock:
                   8809:                return(*byte);
                   8810:        case setLinkctr:
                   8811:        case setFlags:
                   8812:        case setDup:
                   8813:                map[which].dirty = 1;
                   8814:                return(*byte = odata);
                   8815:        case orFlags:
                   8816:                map[which].dirty = 1;
                   8817:                return(*byte |= odata);
                   8818:        case incLinkctr:
                   8819:                map[which].dirty = 1;
                   8820:                return(++*byte);
                   8821:        default:
                   8822:                fatal("Bad action in virtual system");
                   8823:        }
                   8824: }
                   8825: 
                   8826: /*
                   8827:  * copy virtual memory blockmap to dupmap
                   8828:  * read and write groups to avoid possable thrashing.
                   8829:  */
                   8830: void
                   8831: copyV(size)
                   8832: unsigned size;
                   8833: {
                   8834:        char buf[128];
                   8835:        register int i;
                   8836:        long bp, bs;
                   8837: 
                   8838:        for(bs = bp = 0; bp < size; ) {
                   8839:                for(i = 0; (i < 128) && (bp < size); i++, bp++)
                   8840:                        buf[i] = findblock(bp, grabBlock);
                   8841: 
                   8842:                for(i = 0; (i < 128) && (bs < size); i++, bs++)
                   8843:                        findblock(bs, setDup, buf[i]);
                   8844:        }
                   8845: }
                   8846: 
                   8847: #ifdef TEST
                   8848: fatal(s)
                   8849: char *s;
                   8850: {
                   8851:        fprintf(stderr, "%s\n", s);
                   8852:        exit(1);
                   8853: }
                   8854: 
                   8855: static char buf[80];
                   8856: gbuf()
                   8857: {
                   8858:        if(NULL == gets(buf)) {
                   8859:                unlink("vtmp");
                   8860:                exit(0);
                   8861:        }
                   8862:        return(buf[0]);
                   8863: }
                   8864: 
                   8865: main()
                   8866: {
                   8867:        unsigned long b;
                   8868:        char data;
                   8869: 
                   8870:        initV(10000, 10000, 20000);
                   8871:        for(;;) {
                   8872:                printf("b = block, d = dup, f = flags, l = linkctr\n");
                   8873:                switch(gbuf()) {
                   8874:                case 'l':
                   8875:                        printf("s = set, d = display, i = increment: then loc\n");
                   8876:                        gbuf();
                   8877:                        sscanf(buf + 2, "%ld", &b);
                   8878:                        switch(buf[0]) {
                   8879:                        case 's':
                   8880:                                setlinkctr(b, 0); /* no data */
                   8881:                        case 'd':
                   8882:                                printf("%d\n", linkctr(b));
                   8883:                                break;
                   8884:                        case 'i':
                   8885:                                printf("%d\n", inclinkctr(b));
                   8886:                        }
                   8887:                        break;
                   8888:                case 'f':
                   8889:                        printf("d = display, s = set, o = or: then loc\n");
                   8890:                        gbuf();
                   8891:                        sscanf(buf + 2, "%ld %c", &b, &data);
                   8892:                        switch(buf[0]) {
                   8893:                        case 's':
                   8894:                                setflags(b, data);
                   8895:                        case 'd':
                   8896:                                break;
                   8897:                        case 'o':
                   8898:                                orflags(b, data);
                   8899:                        }
                   8900:                        printf("%c\n", flags(b));
                   8901:                        break;
                   8902:                case 'b':
                   8903:                        printf("t = test, m = mark, u = unmark: then loc\n");
                   8904:                        gbuf();
                   8905:                        sscanf(buf + 2, "%ld", &b);
                   8906:                        switch(buf[0]) {
                   8907:                        case 'm':
                   8908:                                markblock(b);
                   8909:                        case 't':
                   8910:                                break;
                   8911:                        case 'u':
                   8912:                                unmarkblock(b);
                   8913:                        }
                   8914:                        printf("%c\n", testblock(b) ? '1' : '0');
                   8915:                        break;
                   8916:                case 'd':
                   8917:                        printf("t = test, m = mark, u = unmark: then loc\n");
                   8918:                        gbuf();
                   8919:                        sscanf(buf + 2, "%ld", &b);
                   8920:                        switch(buf[0]) {
                   8921:                        case 'm':
                   8922:                                markdup(b);
                   8923:                        case 't':
                   8924:                                break;
                   8925:                        case 'u':
                   8926:                                unmarkdup(b);
                   8927:                        }
                   8928:                        printf("%c\n", testdup(b) ? '1' : '0');
                   8929:                        break;
                   8930:                }
                   8931:        }
                   8932: }
                   8933: #endif
                   8934: 
                   8935: en loc\n");
                   8936:                        gbuf();
                   8937:                        sscanf(buf + 2, "%ld", &b);
                   8938:                        switch(buf[0]) {
                   8939:                        case 'm':
                   8940:                                markblock(b);
                   8941:                        case 't':
                   8942:                                break;
                   8943:                        case 'u':
                   8944:                                unmarkblock(b);
                   8945:                        }
                   8946:                        printf("%c\n", testblock(b) ? '1' : '0');
                   8947:                        break;
                   8948:                case 'd':
                   8949:                        printf("t = test, m = mark, u = unmark: then loc\n");
                   8950:                        gbuf();
                   8951:                        sscanf(buf + 2, "%ld", &b);
                   8952:                        switch(buf[0]) {
                   8953:                        case 

unix.superglobalmegacorp.com

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