1*6837Smckusick static char sccsid[] = "@(#)main.c 2.6 (Berkeley) 05/17/82"; 24428Smckusic 34236Smckusick #include <stdio.h> 44236Smckusick #include <ctype.h> 56489Smckusick #ifndef SIMFS 66489Smckusick #include <sys/param.h> 76489Smckusick #include <sys/fs.h> 86489Smckusick #include <sys/inode.h> 96634Smckusick #include <dir.h> 106489Smckusick #else 114236Smckusick #include "../h/param.h" 124236Smckusick #include "../h/fs.h" 134236Smckusick #include "../h/inode.h" 146489Smckusick #include "../h/ndir.h" 156489Smckusick #endif 166489Smckusick #include <sys/stat.h> 174236Smckusick #include <fstab.h> 184236Smckusick 194236Smckusick typedef int (*SIG_TYP)(); 204236Smckusick 215347Smckusic #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) 225347Smckusic #define MAXINOPB (MAXBSIZE / sizeof (struct dinode)) 235325Smckusic #define SPERB (MAXBSIZE / sizeof(short)) 244236Smckusick 254236Smckusick #define MAXDUP 10 /* limit on dup blks (per inode) */ 264236Smckusick #define MAXBAD 10 /* limit on bad blks (per inode) */ 274236Smckusick 284236Smckusick #define USTATE 0 /* inode not allocated */ 294236Smckusick #define FSTATE 01 /* inode is file */ 304236Smckusick #define DSTATE 02 /* inode is directory */ 314236Smckusick #define CLEAR 03 /* inode is to be cleared */ 324236Smckusick 334236Smckusick typedef struct dinode DINODE; 344236Smckusick typedef struct direct DIRECT; 354236Smckusick 364236Smckusick #define ALLOC ((dp->di_mode & IFMT) != 0) 375877Smckusic #define DIRCT ((dp->di_mode & IFMT) == IFDIR) 384236Smckusick #define REG ((dp->di_mode & IFMT) == IFREG) 394236Smckusick #define BLK ((dp->di_mode & IFMT) == IFBLK) 404236Smckusick #define CHR ((dp->di_mode & IFMT) == IFCHR) 41*6837Smckusick #define LNK ((dp->di_mode & IFMT) == IFLNK) 426285Smckusick #define SPECIAL (BLK || CHR) 434236Smckusick 444465Smckusic ino_t startinum; /* blk num of first in raw area */ 454236Smckusick 464236Smckusick struct bufarea { 474236Smckusick struct bufarea *b_next; /* must be first */ 484236Smckusick daddr_t b_bno; 494236Smckusick int b_size; 504236Smckusick union { 515325Smckusic char b_buf[MAXBSIZE]; /* buffer space */ 524236Smckusick short b_lnks[SPERB]; /* link counts */ 535325Smckusic daddr_t b_indir[MAXNINDIR]; /* indirect block */ 544236Smckusick struct fs b_fs; /* super block */ 554236Smckusick struct cg b_cg; /* cylinder group */ 565325Smckusic struct dinode b_dinode[MAXINOPB]; /* inode block */ 574236Smckusick } b_un; 584236Smckusick char b_dirty; 594236Smckusick }; 604236Smckusick 614236Smckusick typedef struct bufarea BUFAREA; 624236Smckusick 634236Smckusick BUFAREA inoblk; /* inode blocks */ 644236Smckusick BUFAREA fileblk; /* other blks in filesys */ 654236Smckusick BUFAREA sblk; /* file system superblock */ 664236Smckusick BUFAREA cgblk; 674236Smckusick 684236Smckusick #define initbarea(x) (x)->b_dirty = 0;(x)->b_bno = (daddr_t)-1 694236Smckusick #define dirty(x) (x)->b_dirty = 1 704236Smckusick #define inodirty() inoblk.b_dirty = 1 714236Smckusick #define sbdirty() sblk.b_dirty = 1 724236Smckusick #define cgdirty() cgblk.b_dirty = 1 734236Smckusick 744236Smckusick #define dirblk fileblk.b_un 754236Smckusick #define sblock sblk.b_un.b_fs 764236Smckusick #define cgrp cgblk.b_un.b_cg 774236Smckusick 784236Smckusick struct filecntl { 794236Smckusick int rfdes; 804236Smckusick int wfdes; 814236Smckusick int mod; 824236Smckusick } dfile; /* file descriptors for filesys */ 834236Smckusick 844236Smckusick #define DUPTBLSIZE 100 /* num of dup blocks to remember */ 854236Smckusick daddr_t duplist[DUPTBLSIZE]; /* dup block table */ 864236Smckusick daddr_t *enddup; /* next entry in dup table */ 874236Smckusick daddr_t *muldup; /* multiple dups part of table */ 884236Smckusick 89*6837Smckusick #define MAXLNCNT 50 /* num zero link cnts to remember */ 904236Smckusick ino_t badlncnt[MAXLNCNT]; /* table of inos with zero link cnts */ 914236Smckusick ino_t *badlnp; /* next entry in table */ 924236Smckusick 934236Smckusick char rawflg; 944236Smckusick char nflag; /* assume a no response */ 954236Smckusick char yflag; /* assume a yes response */ 964236Smckusick int bflag; /* location of alternate super block */ 975381Smckusic int debug; /* output debugging info */ 984236Smckusick char preen; /* just fix normal inconsistencies */ 994236Smckusick char rplyflag; /* any questions asked? */ 1004236Smckusick char hotroot; /* checking root device */ 1014236Smckusick char fixcg; /* corrupted free list bit maps */ 1024236Smckusick 1036314Smckusick char *blockmap; /* ptr to primary blk allocation map */ 1044236Smckusick char *freemap; /* ptr to secondary blk allocation map */ 1054236Smckusick char *statemap; /* ptr to inode state table */ 1064236Smckusick short *lncntp; /* ptr to link count table */ 1074236Smckusick 1084236Smckusick char *pathp; /* pointer to pathname position */ 1094236Smckusick char *thisname; /* ptr to current pathname component */ 1104236Smckusick char *srchname; /* name being searched for in dir */ 1115877Smckusic char pathname[BUFSIZ]; 1124236Smckusick 1134236Smckusick char *lfname = "lost+found"; 1144236Smckusick 1154236Smckusick ino_t inum; /* inode we are currently working on */ 1166634Smckusick ino_t dnum; /* directory inode currently being worked on */ 1174236Smckusick ino_t imax; /* number of inodes */ 1184236Smckusick ino_t parentdir; /* i number of parent directory */ 1194236Smckusick ino_t lastino; /* hiwater mark of inodes */ 1204236Smckusick ino_t lfdir; /* lost & found directory */ 1214236Smckusick ino_t orphan; /* orphaned inode */ 1224236Smckusick 1234236Smckusick off_t filsize; /* num blks seen in file */ 1244236Smckusick off_t maxblk; /* largest logical blk in file */ 1256314Smckusick off_t bmapsz; /* num chars in blockmap */ 1264236Smckusick 1274236Smckusick daddr_t n_ffree; /* number of small free blocks */ 1284236Smckusick daddr_t n_bfree; /* number of large free blocks */ 1294236Smckusick daddr_t n_blks; /* number of blocks used */ 1304236Smckusick daddr_t n_files; /* number of files seen */ 1314236Smckusick daddr_t n_index; 1324236Smckusick daddr_t n_bad; 1334236Smckusick daddr_t fmax; /* number of blocks in the volume */ 1344236Smckusick 1354236Smckusick daddr_t badblk; 1364236Smckusick daddr_t dupblk; 1374236Smckusick 1384236Smckusick int inosumbad; 1394236Smckusick int offsumbad; 1404465Smckusic int frsumbad; 1416491Smckusick int sbsumbad; 1424236Smckusick 1434236Smckusick #define zapino(x) (*(x) = zino) 1444236Smckusick struct dinode zino; 1454236Smckusick 1464236Smckusick #define setlncnt(x) (lncntp[inum] = x) 1474236Smckusick #define getlncnt() (lncntp[inum]) 1484236Smckusick #define declncnt() (--lncntp[inum]) 1494236Smckusick 1506314Smckusick #define setbmap(x) setbit(blockmap, x) 1516314Smckusick #define getbmap(x) isset(blockmap, x) 1526314Smckusick #define clrbmap(x) clrbit(blockmap, x) 1534236Smckusick 1544236Smckusick #define setfmap(x) setbit(freemap, x) 1554236Smckusick #define getfmap(x) isset(freemap, x) 1564236Smckusick #define clrfmap(x) clrbit(freemap, x) 1574236Smckusick 1584236Smckusick #define setstate(x) (statemap[inum] = x) 1594236Smckusick #define getstate() statemap[inum] 1604236Smckusick 1614236Smckusick #define DATA 1 1624236Smckusick #define ADDR 0 1634236Smckusick 1644236Smckusick #define ALTERD 010 1654236Smckusick #define KEEPON 04 1664236Smckusick #define SKIP 02 1674236Smckusick #define STOP 01 1684236Smckusick 1694236Smckusick int (*signal())(); 1704236Smckusick long lseek(); 1714236Smckusick time_t time(); 1724236Smckusick DINODE *ginode(); 1734236Smckusick BUFAREA *getblk(); 1744236Smckusick int dirscan(); 1754236Smckusick int findino(); 1764236Smckusick int catch(); 1774236Smckusick int mkentry(); 1784236Smckusick int chgdd(); 1794236Smckusick int pass1(), pass1b(), pass2(), pass4(), pass5(); 1804236Smckusick int (*pfunc)(); 1814236Smckusick char *rawname(), *rindex(), *unrawname(); 1824606Smckusic extern int inside[], around[]; 1835325Smckusic extern unsigned char *fragtbl[]; 1844236Smckusick 1854236Smckusick char *devname; 1864236Smckusick 1874236Smckusick main(argc, argv) 1884715Smckusic int argc; 1894715Smckusic char *argv[]; 1904236Smckusick { 1914236Smckusick struct fstab *fsp; 1924236Smckusick int pid, passno, anygtr, sumstatus; 1934236Smckusick 1944236Smckusick sync(); 1954236Smckusick while (--argc > 0 && **++argv == '-') { 1964236Smckusick switch (*++*argv) { 1974236Smckusick 1984236Smckusick case 'p': 1994236Smckusick preen++; 2004236Smckusick break; 2014236Smckusick 2024236Smckusick case 'b': 2034236Smckusick bflag = atoi(argv[0]+1); 2044236Smckusick printf("Alternate super block location: %d\n", bflag); 2054236Smckusick break; 2064236Smckusick 2075381Smckusic case 'd': 2085381Smckusic debug++; 2095381Smckusic break; 2105381Smckusic 2114236Smckusick case 'n': /* default no answer flag */ 2124236Smckusick case 'N': 2134236Smckusick nflag++; 2144236Smckusick yflag = 0; 2154236Smckusick break; 2164236Smckusick 2174236Smckusick case 'y': /* default yes answer flag */ 2184236Smckusick case 'Y': 2194236Smckusick yflag++; 2204236Smckusick nflag = 0; 2214236Smckusick break; 2224236Smckusick 2234236Smckusick default: 2244236Smckusick errexit("%c option?\n", **argv); 2254236Smckusick } 2264236Smckusick } 2274236Smckusick if (signal(SIGINT, SIG_IGN) != SIG_IGN) 2284236Smckusick signal(SIGINT, catch); 2294236Smckusick if (argc) { 2304236Smckusick while (argc-- > 0) { 2314236Smckusick hotroot = 0; 2324236Smckusick check(*argv++); 2334236Smckusick } 2344236Smckusick exit(0); 2354236Smckusick } 2364236Smckusick sumstatus = 0; 2374236Smckusick passno = 1; 2384236Smckusick do { 2394236Smckusick anygtr = 0; 2404236Smckusick if (setfsent() == 0) 2414236Smckusick errexit("Can't open checklist file: %s\n", FSTAB); 2424236Smckusick while ((fsp = getfsent()) != 0) { 2434236Smckusick if (strcmp(fsp->fs_type, FSTAB_RW) && 2444236Smckusick strcmp(fsp->fs_type, FSTAB_RO)) 2454236Smckusick continue; 2464236Smckusick if (preen == 0 || 2474236Smckusick passno == 1 && fsp->fs_passno == passno) { 2484236Smckusick if (blockcheck(fsp->fs_spec) == 0 && preen) 2494236Smckusick exit(8); 2504236Smckusick } else if (fsp->fs_passno > passno) 2514236Smckusick anygtr = 1; 2524236Smckusick else if (fsp->fs_passno == passno) { 2534236Smckusick pid = fork(); 2544236Smckusick if (pid < 0) { 2554236Smckusick perror("fork"); 2564236Smckusick exit(8); 2574236Smckusick } 2584236Smckusick if (pid == 0) 2594236Smckusick if (blockcheck(fsp->fs_spec)==0) 2604236Smckusick exit(8); 2614236Smckusick else 2624236Smckusick exit(0); 2634236Smckusick } 2644236Smckusick } 2654236Smckusick if (preen) { 2664236Smckusick int status; 2674236Smckusick while (wait(&status) != -1) 2684236Smckusick sumstatus |= status; 2694236Smckusick } 2704236Smckusick passno++; 2714236Smckusick } while (anygtr); 2724236Smckusick if (sumstatus) 2734236Smckusick exit(8); 2744236Smckusick endfsent(); 2754236Smckusick exit(0); 2764236Smckusick } 2774236Smckusick 2784236Smckusick blockcheck(name) 2794236Smckusick char *name; 2804236Smckusick { 2816489Smckusick struct stat stslash, stblock, stchar; 2824236Smckusick char *raw; 2834236Smckusick int looped = 0; 2844236Smckusick 2854236Smckusick hotroot = 0; 2864236Smckusick if (stat("/", &stslash) < 0){ 2874236Smckusick error("Can't stat root\n"); 2884236Smckusick return (0); 2894236Smckusick } 2904236Smckusick retry: 2914236Smckusick if (stat(name, &stblock) < 0){ 2924236Smckusick error("Can't stat %s\n", name); 2934236Smckusick return (0); 2944236Smckusick } 2954236Smckusick if (stblock.st_mode & S_IFBLK) { 2964236Smckusick raw = rawname(name); 2974236Smckusick if (stat(raw, &stchar) < 0){ 2984236Smckusick error("Can't stat %s\n", raw); 2994236Smckusick return (0); 3004236Smckusick } 3014236Smckusick if (stchar.st_mode & S_IFCHR) { 3024236Smckusick if (stslash.st_dev == stblock.st_rdev) { 3034236Smckusick hotroot++; 3044236Smckusick raw = unrawname(name); 3054236Smckusick } 3064236Smckusick check(raw); 3074236Smckusick return (1); 3084236Smckusick } else { 3094236Smckusick error("%s is not a character device\n", raw); 3104236Smckusick return (0); 3114236Smckusick } 3124236Smckusick } else if (stblock.st_mode & S_IFCHR) { 3134236Smckusick if (looped) { 3144236Smckusick error("Can't make sense out of name %s\n", name); 3154236Smckusick return (0); 3164236Smckusick } 3174236Smckusick name = unrawname(name); 3184236Smckusick looped++; 3194236Smckusick goto retry; 3204236Smckusick } 3214236Smckusick error("Can't make sense out of name %s\n", name); 3224236Smckusick return (0); 3234236Smckusick } 3244236Smckusick 3254236Smckusick char * 3264236Smckusick unrawname(cp) 3274236Smckusick char *cp; 3284236Smckusick { 3294236Smckusick char *dp = rindex(cp, '/'); 3306489Smckusick struct stat stb; 3314236Smckusick 3324236Smckusick if (dp == 0) 3334236Smckusick return (cp); 3344236Smckusick if (stat(cp, &stb) < 0) 3354236Smckusick return (cp); 3364236Smckusick if ((stb.st_mode&S_IFMT) != S_IFCHR) 3374236Smckusick return (cp); 3384236Smckusick if (*(dp+1) != 'r') 3394236Smckusick return (cp); 3404236Smckusick strcpy(dp+1, dp+2); 3414236Smckusick return (cp); 3424236Smckusick } 3434236Smckusick 3444236Smckusick char * 3454236Smckusick rawname(cp) 3464236Smckusick char *cp; 3474236Smckusick { 3484236Smckusick static char rawbuf[32]; 3494236Smckusick char *dp = rindex(cp, '/'); 3504236Smckusick 3514236Smckusick if (dp == 0) 3524236Smckusick return (0); 3534236Smckusick *dp = 0; 3544236Smckusick strcpy(rawbuf, cp); 3554236Smckusick *dp = '/'; 3564236Smckusick strcat(rawbuf, "/r"); 3574236Smckusick strcat(rawbuf, dp+1); 3584236Smckusick return (rawbuf); 3594236Smckusick } 3604236Smckusick 3614236Smckusick check(dev) 3624236Smckusick char *dev; 3634236Smckusick { 3644236Smckusick register DINODE *dp; 3654236Smckusick register ino_t *blp; 3664236Smckusick register int i, n; 3674236Smckusick ino_t savino; 3684236Smckusick int b, c; 3694236Smckusick daddr_t d, s; 3704236Smckusick 3714236Smckusick devname = dev; 3724236Smckusick if (setup(dev) == 0) { 3734236Smckusick if (preen) 3744236Smckusick pfatal("CAN'T CHECK DEVICE."); 3754236Smckusick return; 3764236Smckusick } 3774236Smckusick /* 1 */ 378*6837Smckusick if (preen == 0) { 379*6837Smckusick printf("** Last Mounted on %s\n", sblock.fs_fsmnt); 3804236Smckusick if (hotroot) 3814236Smckusick printf("** Root file system\n"); 3824236Smckusick printf("** Phase 1 - Check Blocks and Sizes\n"); 3834236Smckusick } 3844236Smckusick pfunc = pass1; 3854236Smckusick inum = 0; 3866533Smckusick n_blks += howmany(sblock.fs_cssize, sblock.fs_fsize); 3874236Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 3885381Smckusic if (getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize) == 0) 3894236Smckusick continue; 3906533Smckusick if (debug && cgrp.cg_magic != CG_MAGIC) 3916533Smckusick printf("cg %d: bad magic number\n", c); 3924236Smckusick n = 0; 3934465Smckusic for (i = 0; i < sblock.fs_ipg; i++, inum++) { 3944465Smckusic dp = ginode(); 3954465Smckusic if (dp == NULL) 3964465Smckusic continue; 3975944Smckusic n++; 3984236Smckusick if (ALLOC) { 3994236Smckusick if (!isset(cgrp.cg_iused, i)) { 4005381Smckusic if (debug) 4015381Smckusic printf("%d bad, not used\n", 4025381Smckusic inum); 4034236Smckusick inosumbad++; 4044236Smckusick } 4055944Smckusic n--; 4064236Smckusick lastino = inum; 4074236Smckusick if (ftypeok(dp) == 0) { 4084236Smckusick pfatal("UNKNOWN FILE TYPE I=%u", inum); 4094236Smckusick if (reply("CLEAR") == 1) { 4104236Smckusick zapino(dp); 4114236Smckusick inodirty(); 4124236Smckusick inosumbad++; 4134236Smckusick } 4144236Smckusick continue; 4154236Smckusick } 4164236Smckusick n_files++; 4174236Smckusick if (setlncnt(dp->di_nlink) <= 0) { 4184236Smckusick if (badlnp < &badlncnt[MAXLNCNT]) 4194236Smckusick *badlnp++ = inum; 4204236Smckusick else { 4214236Smckusick pfatal("LINK COUNT TABLE OVERFLOW"); 4224236Smckusick if (reply("CONTINUE") == 0) 4234236Smckusick errexit(""); 4244236Smckusick } 4254236Smckusick } 4265877Smckusic setstate(DIRCT ? DSTATE : FSTATE); 4274236Smckusick badblk = dupblk = 0; filsize = 0; maxblk = 0; 4284236Smckusick ckinode(dp, ADDR); 4294236Smckusick } else { 4304236Smckusick if (isset(cgrp.cg_iused, i)) { 4315381Smckusic if (debug) 4325381Smckusic printf("%d bad, marked used\n", 4335381Smckusic inum); 4344236Smckusick inosumbad++; 4354465Smckusic n--; 4364236Smckusick } 4374236Smckusick if (dp->di_mode != 0) { 4384236Smckusick pfatal("PARTIALLY ALLOCATED INODE I=%u", inum); 4394236Smckusick if (reply("CLEAR") == 1) { 4404236Smckusick zapino(dp); 4414236Smckusick inodirty(); 4424236Smckusick inosumbad++; 4434236Smckusick } 4444236Smckusick } 4454236Smckusick } 4464236Smckusick } 4474789Smckusic if (n != cgrp.cg_cs.cs_nifree) { 4485381Smckusic if (debug) 4495944Smckusic printf("cg[%d].cg_cs.cs_nifree is %d; calc %d\n", 4505381Smckusic c, cgrp.cg_cs.cs_nifree, n); 4514236Smckusick inosumbad++; 4524236Smckusick } 4536491Smckusick if (cgrp.cg_cs.cs_nbfree != sblock.fs_cs(&sblock, c).cs_nbfree 4546491Smckusick || cgrp.cg_cs.cs_nffree != sblock.fs_cs(&sblock, c).cs_nffree 4556491Smckusick || cgrp.cg_cs.cs_nifree != sblock.fs_cs(&sblock, c).cs_nifree 4566491Smckusick || cgrp.cg_cs.cs_ndir != sblock.fs_cs(&sblock, c).cs_ndir) 4576491Smckusick sbsumbad++; 4584236Smckusick } 4594236Smckusick /* 1b */ 4604236Smckusick if (enddup != &duplist[0]) { 4614236Smckusick if (preen) 4624236Smckusick pfatal("INTERNAL ERROR: dups with -p"); 4634236Smckusick printf("** Phase 1b - Rescan For More DUPS\n"); 4644236Smckusick pfunc = pass1b; 4654236Smckusick inum = 0; 4664236Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 4674465Smckusic for (i = 0; i < sblock.fs_ipg; i++, inum++) { 4684465Smckusic dp = ginode(); 4694465Smckusic if (dp == NULL) 4704465Smckusic continue; 4714236Smckusick if (getstate() != USTATE && 4724236Smckusick (ckinode(dp, ADDR) & STOP)) 4734236Smckusick goto out1b; 4744465Smckusic } 4754236Smckusick } 4764236Smckusick } 4774236Smckusick out1b: 4784465Smckusic flush(&dfile, &inoblk); 4794236Smckusick /* 2 */ 4804236Smckusick if (preen == 0) 4814236Smckusick printf("** Phase 2 - Check Pathnames\n"); 4824236Smckusick inum = ROOTINO; 4834236Smckusick thisname = pathp = pathname; 4844236Smckusick pfunc = pass2; 4854236Smckusick switch (getstate()) { 4864236Smckusick 4874236Smckusick case USTATE: 4884236Smckusick errexit("ROOT INODE UNALLOCATED. TERMINATING.\n"); 4894236Smckusick 4904236Smckusick case FSTATE: 4914236Smckusick pfatal("ROOT INODE NOT DIRECTORY"); 4924236Smckusick if (reply("FIX") == 0 || (dp = ginode()) == NULL) 4934236Smckusick errexit(""); 4944236Smckusick dp->di_mode &= ~IFMT; 4954236Smckusick dp->di_mode |= IFDIR; 4964236Smckusick inodirty(); 4974236Smckusick inosumbad++; 4984236Smckusick setstate(DSTATE); 4994236Smckusick /* fall into ... */ 5004236Smckusick 5014236Smckusick case DSTATE: 5024236Smckusick descend(); 5034236Smckusick break; 5044236Smckusick 5054236Smckusick case CLEAR: 5064236Smckusick pfatal("DUPS/BAD IN ROOT INODE"); 5074236Smckusick printf("\n"); 5084236Smckusick if (reply("CONTINUE") == 0) 5094236Smckusick errexit(""); 5104236Smckusick setstate(DSTATE); 5114236Smckusick descend(); 5124236Smckusick } 5134236Smckusick /* 3 */ 5144236Smckusick if (preen == 0) 5154236Smckusick printf("** Phase 3 - Check Connectivity\n"); 5164236Smckusick for (inum = ROOTINO; inum <= lastino; inum++) { 5174236Smckusick if (getstate() == DSTATE) { 5184236Smckusick pfunc = findino; 5194236Smckusick srchname = ".."; 5204236Smckusick savino = inum; 5214236Smckusick do { 5224236Smckusick orphan = inum; 5234236Smckusick if ((dp = ginode()) == NULL) 5244236Smckusick break; 5254236Smckusick filsize = dp->di_size; 5264236Smckusick parentdir = 0; 5274236Smckusick ckinode(dp, DATA); 5284236Smckusick if ((inum = parentdir) == 0) 5294236Smckusick break; 5304236Smckusick } while (getstate() == DSTATE); 5314236Smckusick inum = orphan; 5324236Smckusick if (linkup() == 1) { 5334236Smckusick thisname = pathp = pathname; 5344236Smckusick *pathp++ = '?'; 5354236Smckusick pfunc = pass2; 5364236Smckusick descend(); 5374236Smckusick } 5384236Smckusick inum = savino; 5394236Smckusick } 5404236Smckusick } 5414236Smckusick /* 4 */ 5424236Smckusick if (preen == 0) 5434236Smckusick printf("** Phase 4 - Check Reference Counts\n"); 5444236Smckusick pfunc = pass4; 5454236Smckusick for (inum = ROOTINO; inum <= lastino; inum++) { 5464236Smckusick switch (getstate()) { 5474236Smckusick 5484236Smckusick case FSTATE: 5494236Smckusick if (n = getlncnt()) 5504236Smckusick adjust((short)n); 5514236Smckusick else { 5524236Smckusick for (blp = badlncnt;blp < badlnp; blp++) 5534236Smckusick if (*blp == inum) { 5544236Smckusick clri("UNREF", 1); 5554236Smckusick break; 5564236Smckusick } 5574236Smckusick } 5584236Smckusick break; 5594236Smckusick 5604236Smckusick case DSTATE: 5614236Smckusick clri("UNREF", 1); 5624236Smckusick break; 5634236Smckusick 5644236Smckusick case CLEAR: 5654236Smckusick clri("BAD/DUP", 1); 5664236Smckusick break; 5674236Smckusick } 5684236Smckusick } 5695337Smckusic if (imax - ROOTINO - n_files != sblock.fs_cstotal.cs_nifree) { 5704236Smckusick pwarn("FREE INODE COUNT WRONG IN SUPERBLK"); 5714236Smckusick if (preen) 5724236Smckusick printf(" (FIXED)\n"); 5734236Smckusick if (preen || reply("FIX") == 1) { 5745944Smckusic sblock.fs_cstotal.cs_nifree = imax - ROOTINO - n_files; 5754236Smckusick sbdirty(); 5764236Smckusick } 5774236Smckusick } 5784236Smckusick flush(&dfile, &fileblk); 5794236Smckusick 5804236Smckusick /* 5 */ 5814236Smckusick if (preen == 0) 5824236Smckusick printf("** Phase 5 - Check Cyl groups\n"); 5836314Smckusick copy(blockmap, freemap, (unsigned)bmapsz); 5844236Smckusick dupblk = 0; 5855381Smckusic n_index = sblock.fs_ncg * (cgdmin(&sblock, 0) - cgtod(&sblock, 0)); 5864236Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 5875381Smckusic daddr_t cbase = cgbase(&sblock, c); 5884236Smckusick short bo[MAXCPG][NRPOS]; 5895371Smckusic long botot[MAXCPG]; 5905325Smckusic long frsum[MAXFRAG]; 5914465Smckusic int blk; 5924465Smckusic 5935371Smckusic for (n = 0; n < sblock.fs_cpg; n++) { 5945371Smckusic botot[n] = 0; 5954236Smckusick for (i = 0; i < NRPOS; i++) 5964236Smckusick bo[n][i] = 0; 5975371Smckusic } 5985325Smckusic for (i = 0; i < sblock.fs_frag; i++) { 5994465Smckusic frsum[i] = 0; 6004465Smckusic } 6014465Smckusic /* 6026533Smckusick * need to account for the super blocks 6034465Smckusic * which appear (inaccurately) bad 6044465Smckusic */ 6056533Smckusick n_bad += cgtod(&sblock, c) - cgsblock(&sblock, c); 6065381Smckusic if (getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize) == 0) 6074236Smckusick continue; 6086533Smckusick if (debug && cgrp.cg_magic != CG_MAGIC) 6096533Smckusick printf("cg %d: bad magic number\n", c); 6105325Smckusic for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) { 6115325Smckusic if (isblock(&sblock, cgrp.cg_free, b/sblock.fs_frag)) { 6125325Smckusic if (pass5(cbase+b, sblock.fs_frag) == STOP) 6134236Smckusick goto out5; 6144236Smckusick /* this is clumsy ... */ 6155325Smckusic n_ffree -= sblock.fs_frag; 6164236Smckusick n_bfree++; 6175371Smckusic botot[cbtocylno(&sblock, b)]++; 6185363Smckusic bo[cbtocylno(&sblock, b)] 6195363Smckusic [cbtorpos(&sblock, b)]++; 6204465Smckusic } else { 6215325Smckusic for (d = 0; d < sblock.fs_frag; d++) 6224236Smckusick if (isset(cgrp.cg_free, b+d)) 6234236Smckusick if (pass5(cbase+b+d,1) == STOP) 6244236Smckusick goto out5; 6254465Smckusic blk = ((cgrp.cg_free[b / NBBY] >> (b % NBBY)) & 6265325Smckusic (0xff >> (NBBY - sblock.fs_frag))); 6274465Smckusic if (blk != 0) 6285325Smckusic fragacct(&sblock, blk, frsum, 1); 6294465Smckusic } 6304236Smckusick } 6315325Smckusic for (i = 0; i < sblock.fs_frag; i++) { 6324465Smckusic if (cgrp.cg_frsum[i] != frsum[i]) { 6335381Smckusic if (debug) 6345381Smckusic printf("cg[%d].cg_frsum[%d] have %d calc %d\n", 6355381Smckusic c, i, cgrp.cg_frsum[i], frsum[i]); 6364465Smckusic frsumbad++; 6374465Smckusic } 6384465Smckusic } 6395371Smckusic for (n = 0; n < sblock.fs_cpg; n++) { 6405371Smckusic if (botot[n] != cgrp.cg_btot[n]) { 6415381Smckusic if (debug) 6425381Smckusic printf("cg[%d].cg_btot[%d] have %d calc %d\n", 6435381Smckusic c, n, cgrp.cg_btot[n], botot[n]); 6445371Smckusic offsumbad++; 6455371Smckusic } 6464236Smckusick for (i = 0; i < NRPOS; i++) 6474236Smckusick if (bo[n][i] != cgrp.cg_b[n][i]) { 6485381Smckusic if (debug) 6495381Smckusic printf("cg[%d].cg_b[%d][%d] have %d calc %d\n", 6505381Smckusic c, n, i, cgrp.cg_b[n][i], 6515381Smckusic bo[n][i]); 6524236Smckusick offsumbad++; 6534236Smckusick } 6545371Smckusic } 6554236Smckusick } 6564236Smckusick out5: 6574236Smckusick if (dupblk) 6584236Smckusick pwarn("%d DUP BLKS IN BIT MAPS\n", dupblk); 6594236Smckusick if (fixcg == 0) { 6605325Smckusic if ((b = n_blks+n_ffree+sblock.fs_frag*n_bfree+n_index+n_bad) != fmax) { 6614236Smckusick pwarn("%ld BLK(S) MISSING\n", fmax - b); 6624236Smckusick fixcg = 1; 6636491Smckusick } else if (inosumbad + offsumbad + frsumbad + sbsumbad) { 6646491Smckusick pwarn("SUMMARY INFORMATION %s%s%s%sBAD\n", 6654236Smckusick inosumbad ? "(INODE FREE) " : "", 6664465Smckusic offsumbad ? "(BLOCK OFFSETS) " : "", 6676491Smckusick frsumbad ? "(FRAG SUMMARIES) " : "", 6686491Smckusick sbsumbad ? "(SUPER BLOCK SUMMARIES) " : ""); 6694236Smckusick fixcg = 1; 6704789Smckusic } else if (n_ffree != sblock.fs_cstotal.cs_nffree || 6714789Smckusic n_bfree != sblock.fs_cstotal.cs_nbfree) { 6724236Smckusick pwarn("FREE BLK COUNT(S) WRONG IN SUPERBLK"); 6734236Smckusick if (preen) 6744236Smckusick printf(" (FIXED)\n"); 6754236Smckusick if (preen || reply("FIX") == 1) { 6764789Smckusic sblock.fs_cstotal.cs_nffree = n_ffree; 6774789Smckusic sblock.fs_cstotal.cs_nbfree = n_bfree; 6784236Smckusick sbdirty(); 6794236Smckusick } 6804236Smckusick } 6814236Smckusick } 6824236Smckusick if (fixcg) { 6834236Smckusick pwarn("BAD CYLINDER GROUPS"); 6844236Smckusick if (preen) 6854236Smckusick printf(" (SALVAGED)\n"); 6864236Smckusick else if (reply("SALVAGE") == 0) 6874236Smckusick fixcg = 0; 6884236Smckusick } 6894236Smckusick 6904236Smckusick if (fixcg) { 6914236Smckusick if (preen == 0) 6924236Smckusick printf("** Phase 6 - Salvage Cylinder Groups\n"); 6934236Smckusick makecg(); 6944789Smckusic n_ffree = sblock.fs_cstotal.cs_nffree; 6954789Smckusic n_bfree = sblock.fs_cstotal.cs_nbfree; 6964236Smckusick } 6974236Smckusick 6984236Smckusick pwarn("%d files, %d used, %d free (%d frags, %d blocks)\n", 6996533Smckusick n_files, n_blks - howmany(sblock.fs_cssize, sblock.fs_fsize), 7005325Smckusic n_ffree + sblock.fs_frag * n_bfree, n_ffree, n_bfree); 7014236Smckusick if (dfile.mod) { 7024236Smckusick time(&sblock.fs_time); 7034236Smckusick sbdirty(); 7044236Smckusick } 7054236Smckusick ckfini(); 7064236Smckusick sync(); 7074236Smckusick if (dfile.mod && preen == 0) 7084236Smckusick printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); 7096314Smckusick free(blockmap); 7104236Smckusick free(freemap); 7114236Smckusick free(statemap); 7124236Smckusick free(lncntp); 7134236Smckusick } 7144236Smckusick 7154236Smckusick /* VARARGS1 */ 7164236Smckusick error(s1, s2, s3, s4) 7174715Smckusic char *s1; 7184236Smckusick { 7194236Smckusick 7204236Smckusick printf(s1, s2, s3, s4); 7214236Smckusick } 7224236Smckusick 7234236Smckusick /* VARARGS1 */ 7244236Smckusick errexit(s1, s2, s3, s4) 7254715Smckusic char *s1; 7264236Smckusick { 7274236Smckusick error(s1, s2, s3, s4); 7284236Smckusick exit(8); 7294236Smckusick } 7304236Smckusick 7314236Smckusick /* 7324236Smckusick * An inconsistency occured which shouldn't during normal operations. 7334236Smckusick * Die if preening, otw just printf. 7344236Smckusick */ 7354236Smckusick /* VARARGS1 */ 7364236Smckusick pfatal(s, a1, a2, a3) 7374236Smckusick char *s; 7384236Smckusick { 7394236Smckusick 7404236Smckusick if (preen) { 7414236Smckusick printf("%s: ", devname); 7424236Smckusick printf(s, a1, a2, a3); 7434236Smckusick printf("\n"); 7444236Smckusick preendie(); 7454236Smckusick } 7464236Smckusick printf(s, a1, a2, a3); 7474236Smckusick } 7484236Smckusick 7494236Smckusick preendie() 7504236Smckusick { 7514236Smckusick 7524236Smckusick printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", devname); 7534236Smckusick exit(8); 7544236Smckusick } 7554236Smckusick 7564236Smckusick /* 7574236Smckusick * Pwarn is like printf when not preening, 7584236Smckusick * or a warning (preceded by filename) when preening. 7594236Smckusick */ 7604236Smckusick /* VARARGS1 */ 761*6837Smckusick pwarn(s, a1, a2, a3, a4, a5, a6) 7624236Smckusick char *s; 7634236Smckusick { 7644236Smckusick 7654236Smckusick if (preen) 7664236Smckusick printf("%s: ", devname); 767*6837Smckusick printf(s, a1, a2, a3, a4, a5, a6); 7684236Smckusick } 7694236Smckusick 7704236Smckusick ckinode(dp, flg) 7714236Smckusick DINODE *dp; 7724236Smckusick register flg; 7734236Smckusick { 7744236Smckusick register daddr_t *ap; 7754236Smckusick register ret; 7765956Smckusic int (*func)(), n, ndb, size, offset; 7776634Smckusick ino_t number = inum; 7786634Smckusick DINODE dino; 7794236Smckusick 7804236Smckusick if (SPECIAL) 7814236Smckusick return (KEEPON); 7826634Smckusick dino = *dp; 7834236Smckusick func = (flg == ADDR) ? pfunc : dirscan; 7846634Smckusick ndb = howmany(dino.di_size, sblock.fs_bsize); 7856634Smckusick for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) { 7866634Smckusick if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0) 7875956Smckusic size = numfrags(&sblock, fragroundup(&sblock, offset)); 7884236Smckusick else 7895325Smckusic size = sblock.fs_frag; 7906634Smckusick dnum = number; 7914236Smckusick if (*ap && (ret = (*func)(*ap, size)) & STOP) 7924236Smckusick return (ret); 7934236Smckusick } 7946634Smckusick for (ap = &dino.di_ib[0], n = 1; n <= 2; ap++, n++) { 7956634Smckusick dnum = number; 7966634Smckusick if (*ap && (ret = iblock(*ap, n, flg, dino.di_size - sblock.fs_bsize * NDADDR)) & STOP) 7974236Smckusick return (ret); 7984236Smckusick } 7994236Smckusick return (KEEPON); 8004236Smckusick } 8014236Smckusick 8024236Smckusick iblock(blk, ilevel, flg, isize) 8034236Smckusick daddr_t blk; 8044236Smckusick register ilevel; 8054236Smckusick int isize; 8064236Smckusick { 8074236Smckusick register daddr_t *ap; 8084236Smckusick register daddr_t *aplim; 8094428Smckusic register int i, n; 8104236Smckusick int (*func)(), nif; 8114236Smckusick BUFAREA ib; 8124236Smckusick 8134236Smckusick if (flg == ADDR) { 8144236Smckusick func = pfunc; 8155325Smckusic if (((n = (*func)(blk, sblock.fs_frag)) & KEEPON) == 0) 8164236Smckusick return (n); 8174236Smckusick } else 8184236Smckusick func = dirscan; 8194236Smckusick if (outrange(blk)) /* protect thyself */ 8204236Smckusick return (SKIP); 8214236Smckusick initbarea(&ib); 8225325Smckusic if (getblk(&ib, blk, sblock.fs_bsize) == NULL) 8234236Smckusick return (SKIP); 8244236Smckusick ilevel--; 8254428Smckusic if (ilevel == 0) { 8265956Smckusic nif = lblkno(&sblock, isize) + 1; 8274428Smckusic } else /* ilevel == 1 */ { 8285325Smckusic nif = isize / (sblock.fs_bsize * NINDIR(&sblock)) + 1; 8294428Smckusic } 8305325Smckusic if (nif > NINDIR(&sblock)) 8315325Smckusic nif = NINDIR(&sblock); 8324428Smckusic aplim = & ib.b_un.b_indir[nif]; 8334428Smckusic for (ap = ib.b_un.b_indir, i = 1; ap < aplim; ap++, i++) 8344236Smckusick if (*ap) { 8354236Smckusick if (ilevel > 0) 8365325Smckusic n = iblock(*ap, ilevel, flg, isize - i * NINDIR(&sblock) * sblock.fs_bsize); 8374236Smckusick else 8385325Smckusic n = (*func)(*ap, sblock.fs_frag); 8394236Smckusick if (n & STOP) 8404236Smckusick return (n); 8414236Smckusick } 8424236Smckusick return (KEEPON); 8434236Smckusick } 8444236Smckusick 8454236Smckusick pass1(blk, size) 8464236Smckusick daddr_t blk; 8474236Smckusick int size; 8484236Smckusick { 8494236Smckusick register daddr_t *dlp; 8504236Smckusick int res = KEEPON; 8514236Smckusick 8524236Smckusick for (; size > 0; blk++, size--) { 8534236Smckusick if (outrange(blk)) { 8544236Smckusick blkerr("BAD", blk); 8554236Smckusick if (++badblk >= MAXBAD) { 8564236Smckusick printf("EXCESSIVE BAD BLKS I=%u", inum); 8574236Smckusick if (reply("CONTINUE") == 0) 8584236Smckusick errexit(""); 8594236Smckusick return (STOP); 8604236Smckusick } 8614236Smckusick res = SKIP; 8624236Smckusick } else if (getbmap(blk)) { 8634236Smckusick blkerr("DUP", blk); 8644236Smckusick if (++dupblk >= MAXDUP) { 8654236Smckusick printf("EXCESSIVE DUP BLKS I=%u", inum); 8664236Smckusick if (reply("CONTINUE") == 0) 8674236Smckusick errexit(""); 8684236Smckusick return (STOP); 8694236Smckusick } 8704236Smckusick if (enddup >= &duplist[DUPTBLSIZE]) { 8714236Smckusick printf("DUP TABLE OVERFLOW."); 8724236Smckusick if (reply("CONTINUE") == 0) 8734236Smckusick errexit(""); 8744236Smckusick return (STOP); 8754236Smckusick } 8764236Smckusick for (dlp = duplist; dlp < muldup; dlp++) 8774236Smckusick if (*dlp == blk) { 8784236Smckusick *enddup++ = blk; 8794236Smckusick break; 8804236Smckusick } 8814236Smckusick if (dlp >= muldup) { 8824236Smckusick *enddup++ = *muldup; 8834236Smckusick *muldup++ = blk; 8844236Smckusick } 8854236Smckusick } else { 8864236Smckusick n_blks++; 8874236Smckusick setbmap(blk); 8884236Smckusick } 8894236Smckusick filsize++; 8904236Smckusick } 8914236Smckusick return (res); 8924236Smckusick } 8934236Smckusick 8944236Smckusick pass1b(blk, size) 8954236Smckusick daddr_t blk; 8964236Smckusick int size; 8974236Smckusick { 8984236Smckusick register daddr_t *dlp; 8994236Smckusick int res = KEEPON; 9004236Smckusick 9014236Smckusick for (; size > 0; blk++, size--) { 9024236Smckusick if (outrange(blk)) 9034236Smckusick res = SKIP; 9044236Smckusick for (dlp = duplist; dlp < muldup; dlp++) 9054236Smckusick if (*dlp == blk) { 9064236Smckusick blkerr("DUP", blk); 9074236Smckusick *dlp = *--muldup; 9084236Smckusick *muldup = blk; 9094236Smckusick if (muldup == duplist) 9104236Smckusick return (STOP); 9114236Smckusick } 9124236Smckusick } 9134236Smckusick return (res); 9144236Smckusick } 9154236Smckusick 9164236Smckusick pass2(dirp) 9174236Smckusick register DIRECT *dirp; 9184236Smckusick { 9194236Smckusick register char *p; 9204236Smckusick register n; 9214236Smckusick DINODE *dp; 9224236Smckusick 9234236Smckusick if ((inum = dirp->d_ino) == 0) 9244236Smckusick return (KEEPON); 9254236Smckusick thisname = pathp; 9265877Smckusic for (p = dirp->d_name; p < &dirp->d_name[MAXNAMLEN]; ) 9274236Smckusick if ((*pathp++ = *p++) == 0) { 9284236Smckusick --pathp; 9294236Smckusick break; 9304236Smckusick } 9314236Smckusick *pathp = 0; 9324236Smckusick n = 0; 9334715Smckusic if (inum > imax || inum <= 0) 9344236Smckusick n = direrr("I OUT OF RANGE"); 9354236Smckusick else { 9364236Smckusick again: 9374236Smckusick switch (getstate()) { 9384236Smckusick case USTATE: 9394236Smckusick n = direrr("UNALLOCATED"); 9404236Smckusick break; 9414236Smckusick 9424236Smckusick case CLEAR: 9434236Smckusick if ((n = direrr("DUP/BAD")) == 1) 9444236Smckusick break; 9454236Smckusick if ((dp = ginode()) == NULL) 9464236Smckusick break; 9475877Smckusic setstate(DIRCT ? DSTATE : FSTATE); 9484236Smckusick goto again; 9494236Smckusick 9504236Smckusick case FSTATE: 9514236Smckusick declncnt(); 9524236Smckusick break; 9534236Smckusick 9544236Smckusick case DSTATE: 9554236Smckusick declncnt(); 9564236Smckusick descend(); 9574236Smckusick break; 9584236Smckusick } 9594236Smckusick } 9604236Smckusick pathp = thisname; 9614236Smckusick if (n == 0) 9624236Smckusick return (KEEPON); 9634236Smckusick dirp->d_ino = 0; 9644236Smckusick return (KEEPON|ALTERD); 9654236Smckusick } 9664236Smckusick 9674236Smckusick pass4(blk, size) 9684715Smckusic daddr_t blk; 9694236Smckusick { 9704236Smckusick register daddr_t *dlp; 9714236Smckusick int res = KEEPON; 9724236Smckusick 9734236Smckusick for (; size > 0; blk++, size--) { 9744236Smckusick if (outrange(blk)) 9754236Smckusick res = SKIP; 9764236Smckusick else if (getbmap(blk)) { 9774236Smckusick for (dlp = duplist; dlp < enddup; dlp++) 9784236Smckusick if (*dlp == blk) { 9794236Smckusick *dlp = *--enddup; 9804236Smckusick return (KEEPON); 9814236Smckusick } 9824236Smckusick clrbmap(blk); 9834236Smckusick n_blks--; 9844236Smckusick } 9854236Smckusick } 9864236Smckusick return (res); 9874236Smckusick } 9884236Smckusick 9894236Smckusick pass5(blk, size) 9904236Smckusick daddr_t blk; 9914236Smckusick int size; 9924236Smckusick { 9934236Smckusick int res = KEEPON; 9944236Smckusick 9954236Smckusick for (; size > 0; blk++, size--) { 9964236Smckusick if (outrange(blk)) { 9974236Smckusick fixcg = 1; 9984236Smckusick if (preen) 9994236Smckusick pfatal("BAD BLOCKS IN BIT MAPS."); 10004236Smckusick if (++badblk >= MAXBAD) { 10014236Smckusick printf("EXCESSIVE BAD BLKS IN BIT MAPS."); 10024236Smckusick if (reply("CONTINUE") == 0) 10034236Smckusick errexit(""); 10044236Smckusick return (STOP); 10054236Smckusick } 10064236Smckusick } else if (getfmap(blk)) { 10074236Smckusick fixcg = 1; 10084236Smckusick if (++dupblk >= DUPTBLSIZE) { 10094236Smckusick printf("EXCESSIVE DUP BLKS IN BIT MAPS."); 10104236Smckusick if (reply("CONTINUE") == 0) 10114236Smckusick errexit(""); 10124236Smckusick return (STOP); 10134236Smckusick } 10144236Smckusick } else { 10154236Smckusick n_ffree++; 10164236Smckusick setfmap(blk); 10174236Smckusick } 10184236Smckusick } 10194236Smckusick return (res); 10204236Smckusick } 10214236Smckusick 10224236Smckusick outrange(blk) 10234236Smckusick daddr_t blk; 10244236Smckusick { 10254236Smckusick register int c; 10264236Smckusick 10275381Smckusic c = dtog(&sblock, blk); 10286533Smckusick if ((unsigned)blk >= fmax) { 10294236Smckusick return (1); 10304428Smckusic } 10314236Smckusick return (0); 10324236Smckusick } 10334236Smckusick 10344236Smckusick blkerr(s, blk) 10354236Smckusick daddr_t blk; 10364236Smckusick char *s; 10374236Smckusick { 10384236Smckusick pfatal("%ld %s I=%u", blk, s, inum); 10394236Smckusick printf("\n"); 10404236Smckusick setstate(CLEAR); /* mark for possible clearing */ 10414236Smckusick } 10424236Smckusick 10434236Smckusick descend() 10444236Smckusick { 10454236Smckusick register DINODE *dp; 10464236Smckusick register char *savname; 10474236Smckusick off_t savsize; 10484236Smckusick 10494236Smckusick setstate(FSTATE); 10504236Smckusick if ((dp = ginode()) == NULL) 10514236Smckusick return; 10524236Smckusick savname = thisname; 10534236Smckusick *pathp++ = '/'; 10544236Smckusick savsize = filsize; 10554236Smckusick filsize = dp->di_size; 10564236Smckusick ckinode(dp, DATA); 10574236Smckusick thisname = savname; 10584236Smckusick *--pathp = 0; 10594236Smckusick filsize = savsize; 10604236Smckusick } 10614236Smckusick 10625877Smckusic struct dirstuff { 10635877Smckusic int loc; 10645877Smckusic int blkno; 10655877Smckusic int blksiz; 10666634Smckusick ino_t number; 1067*6837Smckusick int fix; 10685877Smckusic }; 10695877Smckusic 10704236Smckusick dirscan(blk, nf) 10714715Smckusic daddr_t blk; 10724715Smckusic int nf; 10734236Smckusick { 10745877Smckusic register DIRECT *dp; 10755877Smckusic struct dirstuff dirp; 10766251Smckusick int blksiz, dsize, n; 10776251Smckusick char dbuf[DIRBLKSIZ]; 10784236Smckusick 10794236Smckusick if (outrange(blk)) { 10805325Smckusic filsize -= sblock.fs_bsize; 10814236Smckusick return (SKIP); 10824236Smckusick } 10835877Smckusic blksiz = nf * sblock.fs_fsize; 10845877Smckusic dirp.loc = 0; 10855877Smckusic dirp.blkno = blk; 10865877Smckusic dirp.blksiz = blksiz; 1087*6837Smckusick if (dirp.number != dnum) { 1088*6837Smckusick dirp.number = dnum; 1089*6837Smckusick dirp.fix = 0; 1090*6837Smckusick } 10915877Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 10926251Smckusick dsize = dp->d_reclen; 10936251Smckusick copy(dp, dbuf, dsize); 10946251Smckusick if ((n = (*pfunc)(dbuf)) & ALTERD) { 10955877Smckusic if (getblk(&fileblk, blk, blksiz) != NULL) { 10966251Smckusick copy(dbuf, dp, dsize); 10974715Smckusic dirty(&fileblk); 10984236Smckusick sbdirty(); 10994236Smckusick } else 11004236Smckusick n &= ~ALTERD; 11014236Smckusick } 11025877Smckusic if (n & STOP) 11034236Smckusick return (n); 11044236Smckusick } 11054236Smckusick return (filsize > 0 ? KEEPON : STOP); 11064236Smckusick } 11074236Smckusick 11085877Smckusic /* 11095877Smckusic * get next entry in a directory. 11105877Smckusic */ 11115877Smckusic DIRECT * 11125877Smckusic readdir(dirp) 11135877Smckusic register struct dirstuff *dirp; 11145877Smckusic { 11156251Smckusick register DIRECT *dp, *ndp; 1116*6837Smckusick long size; 11175877Smckusic 11185877Smckusic if (getblk(&fileblk, dirp->blkno, dirp->blksiz) == NULL) { 11195877Smckusic filsize -= dirp->blksiz - dirp->loc; 11205877Smckusic return NULL; 11215877Smckusic } 1122*6837Smckusick while (dirp->loc % DIRBLKSIZ == 0 && filsize > 0 && 1123*6837Smckusick dirp->loc < dirp->blksiz) { 11245935Smckusic dp = (DIRECT *)(dirblk.b_buf + dirp->loc); 1125*6837Smckusick if (dp->d_ino < imax && 1126*6837Smckusick dp->d_namlen <= MAXNAMLEN && dp->d_namlen >= 0 && 1127*6837Smckusick dp->d_reclen > 0 && dp->d_reclen <= DIRBLKSIZ) 1128*6837Smckusick break; 1129*6837Smckusick dirp->loc += DIRBLKSIZ; 1130*6837Smckusick filsize -= DIRBLKSIZ; 1131*6837Smckusick if (dirp->fix == 0) { 11326634Smckusick pwarn("DIRECTORY %D CORRUPTED", dirp->number); 1133*6837Smckusick dirp->fix = 1; 1134*6837Smckusick if (preen) { 11356251Smckusick printf(" (SALVAGED)\n"); 1136*6837Smckusick dirp->fix = 2; 1137*6837Smckusick } else if (reply("SALVAGE") != 0) 1138*6837Smckusick dirp->fix = 2; 1139*6837Smckusick } 1140*6837Smckusick if (dirp->fix < 2) 11415877Smckusic continue; 1142*6837Smckusick dp->d_reclen = DIRBLKSIZ; 1143*6837Smckusick dp->d_ino = 0; 1144*6837Smckusick dp->d_namlen = 0; 1145*6837Smckusick dirty(&fileblk); 1146*6837Smckusick } 1147*6837Smckusick if (filsize <= 0 || dirp->loc >= dirp->blksiz) 1148*6837Smckusick return NULL; 1149*6837Smckusick dp = (DIRECT *)(dirblk.b_buf + dirp->loc); 1150*6837Smckusick dirp->loc += dp->d_reclen; 1151*6837Smckusick filsize -= dp->d_reclen; 1152*6837Smckusick ndp = (DIRECT *)(dirblk.b_buf + dirp->loc); 1153*6837Smckusick if (dirp->loc < dirp->blksiz && filsize > 0 && 1154*6837Smckusick (ndp->d_ino >= imax || 1155*6837Smckusick ndp->d_namlen > MAXNAMLEN || ndp->d_namlen < 0 || 1156*6837Smckusick ndp->d_reclen <= 0 || 1157*6837Smckusick ndp->d_reclen > DIRBLKSIZ - (dirp->loc % DIRBLKSIZ))) { 1158*6837Smckusick size = DIRBLKSIZ - (dirp->loc % DIRBLKSIZ); 1159*6837Smckusick dirp->loc += size; 1160*6837Smckusick filsize -= size; 1161*6837Smckusick if (dirp->fix == 0) { 1162*6837Smckusick pwarn("DIRECTORY %D CORRUPTED", dirp->number); 1163*6837Smckusick dirp->fix = 1; 1164*6837Smckusick if (preen) { 1165*6837Smckusick printf(" (SALVAGED)\n"); 1166*6837Smckusick dirp->fix = 2; 1167*6837Smckusick } else if (reply("SALVAGE") != 0) 1168*6837Smckusick dirp->fix = 2; 11696251Smckusick } 1170*6837Smckusick if (dirp->fix > 2) { 1171*6837Smckusick dp->d_reclen += size; 1172*6837Smckusick dirty(&fileblk); 1173*6837Smckusick } 11745877Smckusic } 1175*6837Smckusick return (dp); 11765877Smckusic } 11775877Smckusic 11784236Smckusick direrr(s) 11794715Smckusic char *s; 11804236Smckusick { 11814236Smckusick register DINODE *dp; 11824236Smckusick 11834236Smckusick pwarn("%s ", s); 11844236Smckusick pinode(); 11854236Smckusick printf("\n"); 11864236Smckusick if ((dp = ginode()) != NULL && ftypeok(dp)) 11875877Smckusic pfatal("%s=%s", DIRCT?"DIR":"FILE", pathname); 11884236Smckusick else 11894236Smckusick pfatal("NAME=%s", pathname); 11904236Smckusick return (reply("REMOVE")); 11914236Smckusick } 11924236Smckusick 11934236Smckusick adjust(lcnt) 11944465Smckusic register short lcnt; 11954236Smckusick { 11964236Smckusick register DINODE *dp; 11974236Smckusick 11984236Smckusick if ((dp = ginode()) == NULL) 11994236Smckusick return; 12004236Smckusick if (dp->di_nlink == lcnt) { 12014236Smckusick if (linkup() == 0) 12024236Smckusick clri("UNREF", 0); 12034236Smckusick } 12044236Smckusick else { 12054236Smckusick pwarn("LINK COUNT %s", 12065877Smckusic (lfdir==inum)?lfname:(DIRCT?"DIR":"FILE")); 12074236Smckusick pinode(); 12084236Smckusick printf(" COUNT %d SHOULD BE %d", 12094236Smckusick dp->di_nlink, dp->di_nlink-lcnt); 12104236Smckusick if (preen) { 12114236Smckusick if (lcnt < 0) { 12124236Smckusick printf("\n"); 12134236Smckusick preendie(); 12144236Smckusick } 12154236Smckusick printf(" (ADJUSTED)\n"); 12164236Smckusick } 12174236Smckusick if (preen || reply("ADJUST") == 1) { 12184236Smckusick dp->di_nlink -= lcnt; 12194236Smckusick inodirty(); 12204236Smckusick } 12214236Smckusick } 12224236Smckusick } 12234236Smckusick 12244236Smckusick clri(s, flg) 12254715Smckusic char *s; 12264236Smckusick { 12274236Smckusick register DINODE *dp; 12284236Smckusick 12294236Smckusick if ((dp = ginode()) == NULL) 12304236Smckusick return; 12314236Smckusick if (flg == 1) { 12325877Smckusic pwarn("%s %s", s, DIRCT?"DIR":"FILE"); 12334236Smckusick pinode(); 12344236Smckusick } 12354236Smckusick if (preen || reply("CLEAR") == 1) { 12364236Smckusick if (preen) 12374236Smckusick printf(" (CLEARED)\n"); 12384236Smckusick n_files--; 12394236Smckusick pfunc = pass4; 12404236Smckusick ckinode(dp, ADDR); 12414236Smckusick zapino(dp); 12424465Smckusic setstate(USTATE); 12434236Smckusick inodirty(); 12444236Smckusick inosumbad++; 12454236Smckusick } 12464236Smckusick } 12474236Smckusick 12484236Smckusick setup(dev) 12494715Smckusic char *dev; 12504236Smckusick { 12514236Smckusick dev_t rootdev; 12526489Smckusick struct stat statb; 12534236Smckusick int super = bflag ? bflag : SBLOCK; 12546533Smckusick int i, j, size; 12556533Smckusick int c, d, cgd; 12564236Smckusick 12574236Smckusick bflag = 0; 12584236Smckusick if (stat("/", &statb) < 0) 12594236Smckusick errexit("Can't stat root\n"); 12604236Smckusick rootdev = statb.st_dev; 12614236Smckusick if (stat(dev, &statb) < 0) { 12624236Smckusick error("Can't stat %s\n", dev); 12634236Smckusick return (0); 12644236Smckusick } 12654236Smckusick rawflg = 0; 12664236Smckusick if ((statb.st_mode & S_IFMT) == S_IFBLK) 12674236Smckusick ; 12684236Smckusick else if ((statb.st_mode & S_IFMT) == S_IFCHR) 12694236Smckusick rawflg++; 12704236Smckusick else { 12714236Smckusick if (reply("file is not a block or character device; OK") == 0) 12724236Smckusick return (0); 12734236Smckusick } 12744236Smckusick if (rootdev == statb.st_rdev) 12754236Smckusick hotroot++; 12764236Smckusick if ((dfile.rfdes = open(dev, 0)) < 0) { 12774236Smckusick error("Can't open %s\n", dev); 12784236Smckusick return (0); 12794236Smckusick } 12804236Smckusick if (preen == 0) 12814236Smckusick printf("** %s", dev); 12824236Smckusick if (nflag || (dfile.wfdes = open(dev, 1)) < 0) { 12834236Smckusick dfile.wfdes = -1; 12844236Smckusick if (preen) 12854236Smckusick pfatal("NO WRITE ACCESS"); 12864236Smckusick printf(" (NO WRITE)"); 12874236Smckusick } 12884236Smckusick if (preen == 0) 12894236Smckusick printf("\n"); 12906491Smckusick fixcg = 0; inosumbad = 0; offsumbad = 0; frsumbad = 0; sbsumbad = 0; 12914236Smckusick dfile.mod = 0; 12924236Smckusick n_files = n_blks = n_ffree = n_bfree = 0; 12934236Smckusick muldup = enddup = &duplist[0]; 12944236Smckusick badlnp = &badlncnt[0]; 12954236Smckusick lfdir = 0; 12964236Smckusick rplyflag = 0; 12974236Smckusick initbarea(&sblk); 12984236Smckusick initbarea(&fileblk); 12994236Smckusick initbarea(&inoblk); 13004236Smckusick initbarea(&cgblk); 13016491Smckusick /* 13026491Smckusick * Read in the super block and its summary info. 13036491Smckusick */ 13045347Smckusic if (bread(&dfile, &sblock, super, SBSIZE) == 0) 13054236Smckusick return (0); 13064465Smckusic sblk.b_bno = super; 13075347Smckusic sblk.b_size = SBSIZE; 13085363Smckusic /* 13095363Smckusic * run a few consistency checks of the super block 13105363Smckusic */ 13114236Smckusick if (sblock.fs_magic != FS_MAGIC) 13124236Smckusick { badsb("MAGIC NUMBER WRONG"); return (0); } 13134236Smckusick if (sblock.fs_ncg < 1) 13144236Smckusick { badsb("NCG OUT OF RANGE"); return (0); } 13154236Smckusick if (sblock.fs_cpg < 1 || sblock.fs_cpg > MAXCPG) 13164236Smckusick { badsb("CPG OUT OF RANGE"); return (0); } 13174236Smckusick if (sblock.fs_nsect < 1) 13184236Smckusick { badsb("NSECT < 1"); return (0); } 13194236Smckusick if (sblock.fs_ntrak < 1) 13204236Smckusick { badsb("NTRAK < 1"); return (0); } 13215363Smckusic if (sblock.fs_spc != sblock.fs_nsect * sblock.fs_ntrak) 13225363Smckusic { badsb("SPC DOES NOT JIVE w/NTRAK*NSECT"); return (0); } 13235363Smckusic if (sblock.fs_ipg % INOPB(&sblock)) 13245363Smckusic { badsb("INODES NOT MULTIPLE OF A BLOCK"); return (0); } 13255381Smckusic if (cgdmin(&sblock, 0) >= sblock.fs_cpg * sblock.fs_spc / NSPF(&sblock)) 13264236Smckusick { badsb("IMPLIES MORE INODE THAN DATA BLOCKS"); return (0); } 13275363Smckusic if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || 13285363Smckusic (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) 13294236Smckusick { badsb("NCYL DOES NOT JIVE WITH NCG*CPG"); return (0); } 13305325Smckusic if (sblock.fs_fpg != sblock.fs_cpg * sblock.fs_spc / NSPF(&sblock)) 13314236Smckusick { badsb("FPG DOES NOT JIVE WITH CPG & SPC"); return (0); } 13325363Smckusic if (sblock.fs_size * NSPF(&sblock) <= 13335363Smckusic (sblock.fs_ncyl - 1) * sblock.fs_spc) 13344236Smckusick { badsb("SIZE PREPOSTEROUSLY SMALL"); return (0); } 13355363Smckusic if (sblock.fs_size * NSPF(&sblock) > sblock.fs_ncyl * sblock.fs_spc) 13364236Smckusick { badsb("SIZE PREPOSTEROUSLY LARGE"); return (0); } 13374236Smckusick /* rest we COULD repair... */ 13385956Smckusic if (sblock.fs_cgsize != fragroundup(&sblock, 13395956Smckusic sizeof(struct cg) + howmany(sblock.fs_fpg, NBBY))) 13404236Smckusick { badsb("CGSIZE INCORRECT"); return (0); } 13416533Smckusick if (sblock.fs_cssize != 13426533Smckusick fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum))) 13434236Smckusick { badsb("CSSIZE INCORRECT"); return (0); } 13444236Smckusick fmax = sblock.fs_size; 13454236Smckusick imax = sblock.fs_ncg * sblock.fs_ipg; 13466533Smckusick n_bad = cgsblock(&sblock, 0); /* boot block plus dedicated sblock */ 13475363Smckusic /* 13486533Smckusick * read in the summary info. 13495363Smckusic */ 13506533Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 13516533Smckusick size = sblock.fs_cssize - i < sblock.fs_bsize ? 13526533Smckusick sblock.fs_cssize - i : sblock.fs_bsize; 13536533Smckusick sblock.fs_csp[j] = (struct csum *)calloc(1, size); 13546533Smckusick bread(&dfile, (char *)sblock.fs_csp[j], 13556533Smckusick fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 13566533Smckusick size); 13576533Smckusick } 13586533Smckusick /* 13596533Smckusick * allocate and initialize the necessary maps 13606533Smckusick */ 13614236Smckusick bmapsz = roundup(howmany(fmax, NBBY), sizeof(short)); 13626314Smckusick blockmap = (char *)calloc(bmapsz, sizeof (char)); 13636547Smckusick if (blockmap == NULL) { 13646547Smckusick printf("cannot alloc %d bytes for blockmap\n", bmapsz); 13656547Smckusick exit(1); 13666547Smckusick } 13674236Smckusick freemap = (char *)calloc(bmapsz, sizeof (char)); 13686547Smckusick if (freemap == NULL) { 13696547Smckusick printf("cannot alloc %d bytes for freemap\n", bmapsz); 13706547Smckusick exit(1); 13716547Smckusick } 13724236Smckusick statemap = (char *)calloc(imax+1, sizeof(char)); 13736547Smckusick if (statemap == NULL) { 13746547Smckusick printf("cannot alloc %d bytes for statemap\n", imax + 1); 13756547Smckusick exit(1); 13766547Smckusick } 13774236Smckusick lncntp = (short *)calloc(imax+1, sizeof(short)); 13786547Smckusick if (lncntp == NULL) { 13796547Smckusick printf("cannot alloc %d bytes for lncntp\n", 13806547Smckusick (imax + 1) * sizeof(short)); 13816547Smckusick exit(1); 13826547Smckusick } 13836533Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 13846533Smckusick cgd = cgdmin(&sblock, c); 13856533Smckusick if (c == 0) { 13866533Smckusick d = cgbase(&sblock, c); 13876533Smckusick cgd += howmany(sblock.fs_cssize, sblock.fs_fsize); 13886533Smckusick } else 13896533Smckusick d = cgsblock(&sblock, c); 13906533Smckusick for (; d < cgd; d++) 13916533Smckusick setbmap(d); 13926533Smckusick } 13934236Smckusick 13944465Smckusic startinum = imax + 1; 13954236Smckusick return (1); 13964236Smckusick 13974236Smckusick badsb: 13984236Smckusick ckfini(); 13994236Smckusick return (0); 14004236Smckusick } 14014236Smckusick 14024236Smckusick badsb(s) 14034236Smckusick char *s; 14044236Smckusick { 14054236Smckusick 14064236Smckusick if (preen) 14074236Smckusick printf("%s: ", devname); 14084236Smckusick printf("BAD SUPER BLOCK: %s\n", s); 14094236Smckusick pwarn("USE -b OPTION TO FSCK TO SPECIFY LOCATION OF AN ALTERNATE\n"); 14104236Smckusick pfatal("SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck(8).\n"); 14114236Smckusick } 14124236Smckusick 14134236Smckusick DINODE * 14144236Smckusick ginode() 14154236Smckusick { 14164236Smckusick daddr_t iblk; 14174236Smckusick 14186547Smckusick if (inum < ROOTINO || inum > imax) { 14196547Smckusick if (debug && (inum < 0 || inum > imax)) 14206547Smckusick printf("inum out of range (%d)\n", inum); 14214236Smckusick return (NULL); 14226547Smckusick } 14235325Smckusic if (inum < startinum || inum >= startinum + INOPB(&sblock)) { 14245381Smckusic iblk = itod(&sblock, inum); 14255325Smckusic if (getblk(&inoblk, iblk, sblock.fs_bsize) == NULL) { 14264236Smckusick return (NULL); 14274236Smckusick } 14285325Smckusic startinum = (inum / INOPB(&sblock)) * INOPB(&sblock); 14294236Smckusick } 14305325Smckusic return (&inoblk.b_un.b_dinode[inum % INOPB(&sblock)]); 14314236Smckusick } 14324236Smckusick 14334236Smckusick ftypeok(dp) 14344236Smckusick DINODE *dp; 14354236Smckusick { 14364236Smckusick switch (dp->di_mode & IFMT) { 14374236Smckusick 14384236Smckusick case IFDIR: 14394236Smckusick case IFREG: 14404236Smckusick case IFBLK: 14414236Smckusick case IFCHR: 14426285Smckusick case IFLNK: 14434236Smckusick return (1); 14444236Smckusick 14454236Smckusick default: 14464236Smckusick return (0); 14474236Smckusick } 14484236Smckusick } 14494236Smckusick 14504236Smckusick reply(s) 14514236Smckusick char *s; 14524236Smckusick { 14534236Smckusick char line[80]; 14544236Smckusick 14554236Smckusick if (preen) 14564236Smckusick pfatal("INTERNAL ERROR: GOT TO reply()"); 14574236Smckusick rplyflag = 1; 14584236Smckusick printf("\n%s? ", s); 14594236Smckusick if (nflag || dfile.wfdes < 0) { 14604236Smckusick printf(" no\n\n"); 14614236Smckusick return (0); 14624236Smckusick } 14634236Smckusick if (yflag) { 14644236Smckusick printf(" yes\n\n"); 14654236Smckusick return (1); 14664236Smckusick } 14674236Smckusick if (getline(stdin, line, sizeof(line)) == EOF) 14684236Smckusick errexit("\n"); 14694236Smckusick printf("\n"); 14704236Smckusick if (line[0] == 'y' || line[0] == 'Y') 14714236Smckusick return (1); 14724236Smckusick else 14734236Smckusick return (0); 14744236Smckusick } 14754236Smckusick 14764236Smckusick getline(fp, loc, maxlen) 14774236Smckusick FILE *fp; 14784236Smckusick char *loc; 14794236Smckusick { 14804236Smckusick register n; 14814236Smckusick register char *p, *lastloc; 14824236Smckusick 14834236Smckusick p = loc; 14844236Smckusick lastloc = &p[maxlen-1]; 14854236Smckusick while ((n = getc(fp)) != '\n') { 14864236Smckusick if (n == EOF) 14874236Smckusick return (EOF); 14884236Smckusick if (!isspace(n) && p < lastloc) 14894236Smckusick *p++ = n; 14904236Smckusick } 14914236Smckusick *p = 0; 14924236Smckusick return (p - loc); 14934236Smckusick } 14944236Smckusick 14954236Smckusick BUFAREA * 14964236Smckusick getblk(bp, blk, size) 14974236Smckusick daddr_t blk; 14984236Smckusick register BUFAREA *bp; 14994236Smckusick int size; 15004236Smckusick { 15014236Smckusick register struct filecntl *fcp; 15025325Smckusic daddr_t dblk; 15034236Smckusick 15044236Smckusick fcp = &dfile; 15055325Smckusic dblk = fsbtodb(&sblock, blk); 15065325Smckusic if (bp->b_bno == dblk) 15074236Smckusick return (bp); 15084236Smckusick flush(fcp, bp); 15095325Smckusic if (bread(fcp, bp->b_un.b_buf, dblk, size) != 0) { 15105325Smckusic bp->b_bno = dblk; 15114236Smckusick bp->b_size = size; 15124236Smckusick return (bp); 15134236Smckusick } 15144236Smckusick bp->b_bno = (daddr_t)-1; 15154236Smckusick return (NULL); 15164236Smckusick } 15174236Smckusick 15184236Smckusick flush(fcp, bp) 15194236Smckusick struct filecntl *fcp; 15204236Smckusick register BUFAREA *bp; 15214236Smckusick { 15224236Smckusick 15234236Smckusick if (bp->b_dirty) 15244236Smckusick bwrite(fcp, bp->b_un.b_buf, bp->b_bno, bp->b_size); 15254236Smckusick bp->b_dirty = 0; 15264236Smckusick } 15274236Smckusick 15284236Smckusick rwerr(s, blk) 15294236Smckusick char *s; 15304236Smckusick daddr_t blk; 15314236Smckusick { 15324236Smckusick 15334236Smckusick if (preen == 0) 15344236Smckusick printf("\n"); 15354236Smckusick pfatal("CANNOT %s: BLK %ld", s, blk); 15364236Smckusick if (reply("CONTINUE") == 0) 15374236Smckusick errexit("Program terminated\n"); 15384236Smckusick } 15394236Smckusick 15404236Smckusick ckfini() 15414236Smckusick { 15424236Smckusick 15434236Smckusick flush(&dfile, &fileblk); 15444236Smckusick flush(&dfile, &sblk); 15454465Smckusic if (sblk.b_bno != SBLOCK) { 15464465Smckusic sblk.b_bno = SBLOCK; 15474465Smckusic sbdirty(); 15484465Smckusic flush(&dfile, &sblk); 15494465Smckusic } 15504236Smckusick flush(&dfile, &inoblk); 15514236Smckusick close(dfile.rfdes); 15524236Smckusick close(dfile.wfdes); 15534236Smckusick } 15544236Smckusick 15554236Smckusick pinode() 15564236Smckusick { 15574236Smckusick register DINODE *dp; 15584236Smckusick register char *p; 15595877Smckusic char uidbuf[BUFSIZ]; 15604236Smckusick char *ctime(); 15614236Smckusick 15624236Smckusick printf(" I=%u ", inum); 15634236Smckusick if ((dp = ginode()) == NULL) 15644236Smckusick return; 15654236Smckusick printf(" OWNER="); 15664236Smckusick if (getpw((int)dp->di_uid, uidbuf) == 0) { 15674236Smckusick for (p = uidbuf; *p != ':'; p++); 15684236Smckusick *p = 0; 15694236Smckusick printf("%s ", uidbuf); 15704236Smckusick } 15714236Smckusick else { 15724236Smckusick printf("%d ", dp->di_uid); 15734236Smckusick } 15744236Smckusick printf("MODE=%o\n", dp->di_mode); 15754236Smckusick if (preen) 15764236Smckusick printf("%s: ", devname); 15774236Smckusick printf("SIZE=%ld ", dp->di_size); 15784236Smckusick p = ctime(&dp->di_mtime); 15794236Smckusick printf("MTIME=%12.12s %4.4s ", p+4, p+20); 15804236Smckusick } 15814236Smckusick 15824236Smckusick copy(fp, tp, size) 15834236Smckusick register char *tp, *fp; 15844236Smckusick unsigned size; 15854236Smckusick { 15864236Smckusick 15874236Smckusick while (size--) 15884236Smckusick *tp++ = *fp++; 15894236Smckusick } 15904236Smckusick 15914236Smckusick makecg() 15924236Smckusick { 15934465Smckusic int c, blk; 15946533Smckusick daddr_t dbase, d, dlower, dupper, dmax; 15954236Smckusick long i, j, s; 15964236Smckusick register struct csum *cs; 15974465Smckusic register DINODE *dp; 15984236Smckusick 15994789Smckusic sblock.fs_cstotal.cs_nbfree = 0; 16004789Smckusic sblock.fs_cstotal.cs_nffree = 0; 16014789Smckusic sblock.fs_cstotal.cs_nifree = 0; 16024789Smckusic sblock.fs_cstotal.cs_ndir = 0; 16034236Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 16045381Smckusic dbase = cgbase(&sblock, c); 16054236Smckusick dmax = dbase + sblock.fs_fpg; 16065409Smckusic if (dmax > sblock.fs_size) { 16075944Smckusic for ( ; dmax >= sblock.fs_size; dmax--) 16085401Smckusic clrbit(cgrp.cg_free, dmax - dbase); 16095409Smckusic dmax++; 16105409Smckusic } 16116533Smckusick dlower = cgsblock(&sblock, c) - dbase; 16126533Smckusick dupper = cgdmin(&sblock, c) - dbase; 16135325Smckusic cs = &sblock.fs_cs(&sblock, c); 16144236Smckusick cgrp.cg_time = time(0); 16154236Smckusick cgrp.cg_magic = CG_MAGIC; 16164236Smckusick cgrp.cg_cgx = c; 16174236Smckusick cgrp.cg_ncyl = sblock.fs_cpg; 16184236Smckusick cgrp.cg_niblk = sblock.fs_ipg; 16194236Smckusick cgrp.cg_ndblk = dmax - dbase; 16204789Smckusic cgrp.cg_cs.cs_ndir = 0; 16214789Smckusic cgrp.cg_cs.cs_nffree = 0; 16224789Smckusic cgrp.cg_cs.cs_nbfree = 0; 16234789Smckusic cgrp.cg_cs.cs_nifree = 0; 16246533Smckusick cgrp.cg_rotor = 0; 16256533Smckusick cgrp.cg_frotor = 0; 16264258Smckusic cgrp.cg_irotor = 0; 16275325Smckusic for (i = 0; i < sblock.fs_frag; i++) 16284465Smckusic cgrp.cg_frsum[i] = 0; 16294236Smckusick inum = sblock.fs_ipg * c; 16304465Smckusic for (i = 0; i < sblock.fs_ipg; inum++, i++) { 16315944Smckusic cgrp.cg_cs.cs_nifree++; 16325944Smckusic clrbit(cgrp.cg_iused, i); 16334465Smckusic dp = ginode(); 16344465Smckusic if (dp == NULL) 16354465Smckusic continue; 16364465Smckusic if (ALLOC) { 16375877Smckusic if (DIRCT) 16384789Smckusic cgrp.cg_cs.cs_ndir++; 16395944Smckusic cgrp.cg_cs.cs_nifree--; 16404465Smckusic setbit(cgrp.cg_iused, i); 16414465Smckusic continue; 16424465Smckusic } 16434236Smckusick } 16444236Smckusick while (i < MAXIPG) { 16454236Smckusick clrbit(cgrp.cg_iused, i); 16464236Smckusick i++; 16474236Smckusick } 16485944Smckusic if (c == 0) 16495944Smckusic for (i = 0; i < ROOTINO; i++) { 16505944Smckusic setbit(cgrp.cg_iused, i); 16515944Smckusic cgrp.cg_cs.cs_nifree--; 16525944Smckusic } 16535371Smckusic for (s = 0; s < MAXCPG; s++) { 16545371Smckusic cgrp.cg_btot[s] = 0; 16554236Smckusick for (i = 0; i < NRPOS; i++) 16564236Smckusick cgrp.cg_b[s][i] = 0; 16575371Smckusic } 16584236Smckusick if (c == 0) { 16596533Smckusick dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); 16604236Smckusick } 16616533Smckusick for (d = dlower; d < dupper; d++) 16624236Smckusick clrbit(cgrp.cg_free, d); 16636533Smckusick for (d = 0; (d + sblock.fs_frag) <= dmax - dbase; 16646533Smckusick d += sblock.fs_frag) { 16654236Smckusick j = 0; 16665325Smckusic for (i = 0; i < sblock.fs_frag; i++) { 16676533Smckusick if (!getbmap(dbase + d + i)) { 16686533Smckusick setbit(cgrp.cg_free, d + i); 16694236Smckusick j++; 16704236Smckusick } else 16714236Smckusick clrbit(cgrp.cg_free, d+i); 16724236Smckusick } 16735325Smckusic if (j == sblock.fs_frag) { 16744789Smckusic cgrp.cg_cs.cs_nbfree++; 16755371Smckusic cgrp.cg_btot[cbtocylno(&sblock, d)]++; 16765363Smckusic cgrp.cg_b[cbtocylno(&sblock, d)] 16775363Smckusic [cbtorpos(&sblock, d)]++; 16784465Smckusic } else if (j > 0) { 16794789Smckusic cgrp.cg_cs.cs_nffree += j; 16806533Smckusick blk = blkmap(&sblock, cgrp.cg_free, d); 16815325Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 16824465Smckusic } 16834236Smckusick } 16844465Smckusic for (j = d; d < dmax - dbase; d++) { 16856533Smckusick if (!getbmap(dbase + d)) { 16864236Smckusick setbit(cgrp.cg_free, d); 16874789Smckusic cgrp.cg_cs.cs_nffree++; 16884236Smckusick } else 16894236Smckusick clrbit(cgrp.cg_free, d); 16904236Smckusick } 16914465Smckusic if (j != d) { 16926533Smckusick blk = blkmap(&sblock, cgrp.cg_free, j); 16935325Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 16944465Smckusic } 16955325Smckusic for (; d < MAXBPG(&sblock); d++) 16964236Smckusick clrbit(cgrp.cg_free, d); 16974789Smckusic sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree; 16984789Smckusic sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree; 16994789Smckusic sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree; 17004789Smckusic sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir; 17014789Smckusic *cs = cgrp.cg_cs; 17025381Smckusic bwrite(&dfile, &cgrp, fsbtodb(&sblock, cgtod(&sblock, c)), 17035956Smckusic sblock.fs_cgsize); 17044236Smckusick } 17056533Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 17066533Smckusick bwrite(&dfile, (char *)sblock.fs_csp[j], 17076533Smckusick fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 17086533Smckusick sblock.fs_cssize - i < sblock.fs_bsize ? 17096533Smckusick sblock.fs_cssize - i : sblock.fs_bsize); 17105097Smckusic } 17114236Smckusick sblock.fs_ronly = 0; 17124236Smckusick sblock.fs_fmod = 0; 17134236Smckusick sbdirty(); 17144236Smckusick } 17154236Smckusick 17164465Smckusic /* 17174465Smckusic * update the frsum fields to reflect addition or deletion 17184465Smckusic * of some frags 17194465Smckusic */ 17205325Smckusic fragacct(fs, fragmap, fraglist, cnt) 17215325Smckusic struct fs *fs; 17224470Smckusic int fragmap; 17234789Smckusic long fraglist[]; 17244465Smckusic int cnt; 17254465Smckusic { 17264465Smckusic int inblk; 17274465Smckusic register int field, subfield; 17284465Smckusic register int siz, pos; 17294465Smckusic 17305325Smckusic inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1); 17314465Smckusic fragmap <<= 1; 17325325Smckusic for (siz = 1; siz < fs->fs_frag; siz++) { 17336290Smckusick if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) 17344465Smckusic continue; 17354465Smckusic field = around[siz]; 17364465Smckusic subfield = inside[siz]; 17375325Smckusic for (pos = siz; pos <= fs->fs_frag; pos++) { 17384465Smckusic if ((fragmap & field) == subfield) { 17394465Smckusic fraglist[siz] += cnt; 17404465Smckusic pos += siz; 17414465Smckusic field <<= siz; 17424465Smckusic subfield <<= siz; 17434465Smckusic } 17444465Smckusic field <<= 1; 17454465Smckusic subfield <<= 1; 17464465Smckusic } 17474465Smckusic } 17484465Smckusic } 17494465Smckusic 17504236Smckusick findino(dirp) 17514236Smckusick register DIRECT *dirp; 17524236Smckusick { 17534236Smckusick if (dirp->d_ino == 0) 17544236Smckusick return (KEEPON); 17555877Smckusic if (!strcmp(dirp->d_name, srchname)) { 17565877Smckusic if (dirp->d_ino >= ROOTINO && dirp->d_ino <= imax) 17575877Smckusic parentdir = dirp->d_ino; 17585877Smckusic return (STOP); 17594236Smckusick } 17604236Smckusick return (KEEPON); 17614236Smckusick } 17624236Smckusick 17634236Smckusick mkentry(dirp) 17644236Smckusick register DIRECT *dirp; 17654236Smckusick { 17664236Smckusick register ino_t in; 17674236Smckusick register char *p; 17686251Smckusick DIRECT newent; 17696251Smckusick int newlen, oldlen; 17704236Smckusick 17716251Smckusick newent.d_namlen = 11; 17726251Smckusick newlen = DIRSIZ(&newent); 17736251Smckusick if (dirp->d_ino != 0) 17746251Smckusick oldlen = DIRSIZ(dirp); 17756251Smckusick else 17766251Smckusick oldlen = 0; 17776251Smckusick if (dirp->d_reclen - oldlen < newlen) 17784236Smckusick return (KEEPON); 17796251Smckusick newent.d_reclen = dirp->d_reclen - oldlen; 17806251Smckusick dirp->d_reclen = oldlen; 17816251Smckusick dirp = (struct direct *)(((char *)dirp) + oldlen); 17824236Smckusick dirp->d_ino = orphan; 17836251Smckusick dirp->d_reclen = newent.d_reclen; 17846251Smckusick p = &dirp->d_name[2]; 17856251Smckusick for (in = imax; in > 0; in /= 10) 17866251Smckusick p++; 17876251Smckusick *--p = 0; 17886251Smckusick dirp->d_namlen = p - dirp->d_name; 17894236Smckusick in = orphan; 17904236Smckusick while (p > dirp->d_name) { 17914236Smckusick *--p = (in % 10) + '0'; 17924236Smckusick in /= 10; 17934236Smckusick } 17944236Smckusick *p = '#'; 17954236Smckusick return (ALTERD|STOP); 17964236Smckusick } 17974236Smckusick 17984236Smckusick chgdd(dirp) 17994236Smckusick register DIRECT *dirp; 18004236Smckusick { 18014236Smckusick if (dirp->d_name[0] == '.' && dirp->d_name[1] == '.' && 18024236Smckusick dirp->d_name[2] == 0) { 18034236Smckusick dirp->d_ino = lfdir; 18044236Smckusick return (ALTERD|STOP); 18054236Smckusick } 18064236Smckusick return (KEEPON); 18074236Smckusick } 18084236Smckusick 18094236Smckusick linkup() 18104236Smckusick { 18114236Smckusick register DINODE *dp; 18124236Smckusick register lostdir; 18134236Smckusick register ino_t pdir; 18144236Smckusick 18154236Smckusick if ((dp = ginode()) == NULL) 18164236Smckusick return (0); 18175877Smckusic lostdir = DIRCT; 18184236Smckusick pdir = parentdir; 18194236Smckusick pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); 18204236Smckusick pinode(); 18214236Smckusick if (preen && dp->di_size == 0) 18224236Smckusick return (0); 18234236Smckusick if (preen) 18244236Smckusick printf(" (RECONNECTED)\n"); 18254236Smckusick else 18264236Smckusick if (reply("RECONNECT") == 0) 18274236Smckusick return (0); 18284236Smckusick orphan = inum; 18294236Smckusick if (lfdir == 0) { 18304236Smckusick inum = ROOTINO; 18314236Smckusick if ((dp = ginode()) == NULL) { 18324236Smckusick inum = orphan; 18334236Smckusick return (0); 18344236Smckusick } 18354236Smckusick pfunc = findino; 18364236Smckusick srchname = lfname; 18374236Smckusick filsize = dp->di_size; 18384236Smckusick parentdir = 0; 18394236Smckusick ckinode(dp, DATA); 18404236Smckusick inum = orphan; 18414236Smckusick if ((lfdir = parentdir) == 0) { 18424236Smckusick pfatal("SORRY. NO lost+found DIRECTORY"); 18434236Smckusick printf("\n\n"); 18444236Smckusick return (0); 18454236Smckusick } 18464236Smckusick } 18474236Smckusick inum = lfdir; 18485877Smckusic if ((dp = ginode()) == NULL || !DIRCT || getstate() != FSTATE) { 18494236Smckusick inum = orphan; 18504236Smckusick pfatal("SORRY. NO lost+found DIRECTORY"); 18514236Smckusick printf("\n\n"); 18524236Smckusick return (0); 18534236Smckusick } 18545956Smckusic if (fragoff(&sblock, dp->di_size)) { 18555956Smckusic dp->di_size = fragroundup(&sblock, dp->di_size); 18564236Smckusick inodirty(); 18574236Smckusick } 18584236Smckusick filsize = dp->di_size; 18594236Smckusick inum = orphan; 18604236Smckusick pfunc = mkentry; 18614236Smckusick if ((ckinode(dp, DATA) & ALTERD) == 0) { 18624236Smckusick pfatal("SORRY. NO SPACE IN lost+found DIRECTORY"); 18634236Smckusick printf("\n\n"); 18644236Smckusick return (0); 18654236Smckusick } 18664236Smckusick declncnt(); 18674236Smckusick if (lostdir) { 18684236Smckusick pfunc = chgdd; 18694236Smckusick dp = ginode(); 18704236Smckusick filsize = dp->di_size; 18714236Smckusick ckinode(dp, DATA); 18724236Smckusick inum = lfdir; 18734236Smckusick if ((dp = ginode()) != NULL) { 18744236Smckusick dp->di_nlink++; 18754236Smckusick inodirty(); 18764236Smckusick setlncnt(getlncnt()+1); 18774236Smckusick } 18784236Smckusick inum = orphan; 18794236Smckusick pwarn("DIR I=%u CONNECTED. ", orphan); 18804236Smckusick printf("PARENT WAS I=%u\n", pdir); 18814236Smckusick if (preen == 0) 18824236Smckusick printf("\n"); 18834236Smckusick } 18844236Smckusick return (1); 18854236Smckusick } 18864236Smckusick 18874236Smckusick bread(fcp, buf, blk, size) 18884236Smckusick daddr_t blk; 18894236Smckusick register struct filecntl *fcp; 18904236Smckusick register size; 18914236Smckusick char *buf; 18924236Smckusick { 18935325Smckusic if (lseek(fcp->rfdes, blk * DEV_BSIZE, 0) < 0) 18944236Smckusick rwerr("SEEK", blk); 18954236Smckusick else if (read(fcp->rfdes, buf, size) == size) 18964236Smckusick return (1); 18974236Smckusick rwerr("READ", blk); 18984236Smckusick return (0); 18994236Smckusick } 19004236Smckusick 19014236Smckusick bwrite(fcp, buf, blk, size) 19024236Smckusick daddr_t blk; 19034236Smckusick register struct filecntl *fcp; 19044236Smckusick register size; 19054236Smckusick char *buf; 19064236Smckusick { 19074236Smckusick 19084236Smckusick if (fcp->wfdes < 0) 19094236Smckusick return (0); 19105325Smckusic if (lseek(fcp->wfdes, blk * DEV_BSIZE, 0) < 0) 19114236Smckusick rwerr("SEEK", blk); 19124236Smckusick else if (write(fcp->wfdes, buf, size) == size) { 19134236Smckusick fcp->mod = 1; 19144236Smckusick return (1); 19154236Smckusick } 19164236Smckusick rwerr("WRITE", blk); 19174236Smckusick return (0); 19184236Smckusick } 19194236Smckusick 19204236Smckusick catch() 19214236Smckusick { 19224236Smckusick 19234236Smckusick ckfini(); 19244236Smckusick exit(12); 19254236Smckusick } 19265325Smckusic 19275325Smckusic /* 19285325Smckusic * block operations 19295325Smckusic */ 19305325Smckusic 19315325Smckusic isblock(fs, cp, h) 19325325Smckusic struct fs *fs; 19335325Smckusic unsigned char *cp; 19345325Smckusic int h; 19355325Smckusic { 19365325Smckusic unsigned char mask; 19375325Smckusic 19385325Smckusic switch (fs->fs_frag) { 19395325Smckusic case 8: 19405325Smckusic return (cp[h] == 0xff); 19415325Smckusic case 4: 19425325Smckusic mask = 0x0f << ((h & 0x1) << 2); 19435325Smckusic return ((cp[h >> 1] & mask) == mask); 19445325Smckusic case 2: 19455325Smckusic mask = 0x03 << ((h & 0x3) << 1); 19465325Smckusic return ((cp[h >> 2] & mask) == mask); 19475325Smckusic case 1: 19485325Smckusic mask = 0x01 << (h & 0x7); 19495325Smckusic return ((cp[h >> 3] & mask) == mask); 19505325Smckusic default: 19515381Smckusic error("isblock bad fs_frag %d\n", fs->fs_frag); 19525381Smckusic return (0); 19535325Smckusic } 19545325Smckusic } 19556489Smckusick 19566489Smckusick /* tables.c 4.1 82/03/25 */ 19576489Smckusick 19586489Smckusick /* merged into kernel: tables.c 2.1 3/25/82 */ 19596489Smckusick 19606489Smckusick /* last monet version: partab.c 4.2 81/03/08 */ 19616489Smckusick 19626489Smckusick /* 19636489Smckusick * bit patterns for identifying fragments in the block map 19646489Smckusick * used as ((map & around) == inside) 19656489Smckusick */ 19666489Smckusick int around[9] = { 19676489Smckusick 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff 19686489Smckusick }; 19696489Smckusick int inside[9] = { 19706489Smckusick 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe 19716489Smckusick }; 19726489Smckusick 19736489Smckusick /* 19746489Smckusick * given a block map bit pattern, the frag tables tell whether a 19756489Smckusick * particular size fragment is available. 19766489Smckusick * 19776489Smckusick * used as: 19786489Smckusick * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] { 19796489Smckusick * at least one fragment of the indicated size is available 19806489Smckusick * } 19816489Smckusick * 19826489Smckusick * These tables are used by the scanc instruction on the VAX to 19836489Smckusick * quickly find an appropriate fragment. 19846489Smckusick */ 19856489Smckusick 19866489Smckusick unsigned char fragtbl124[256] = { 19876489Smckusick 0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e, 19886489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a, 19896489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19906489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19916489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19926489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19936489Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 19946489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 19956489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19966489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19976489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 19986489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 19996489Smckusick 0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e, 20006489Smckusick 0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae, 20016489Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 20026489Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 20036489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 20046489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 20056489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 20066489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 20076489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 20086489Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 20096489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 20106489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 20116489Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 20126489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 20136489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 20146489Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 20156489Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 20166489Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 20176489Smckusick 0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce, 20186489Smckusick 0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a, 20196489Smckusick }; 20206489Smckusick 20216489Smckusick unsigned char fragtbl8[256] = { 20226489Smckusick 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, 20236489Smckusick 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08, 20246489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 20256489Smckusick 0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10, 20266489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 20276489Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 20286489Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 20296489Smckusick 0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20, 20306489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 20316489Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 20326489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 20336489Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 20346489Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 20356489Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 20366489Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 20376489Smckusick 0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40, 20386489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 20396489Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 20406489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 20416489Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 20426489Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 20436489Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 20446489Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 20456489Smckusick 0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21, 20466489Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 20476489Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 20486489Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 20496489Smckusick 0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12, 20506489Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 20516489Smckusick 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c, 20526489Smckusick 0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c, 20536489Smckusick 0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80, 20546489Smckusick }; 20556489Smckusick 20566489Smckusick /* 20576489Smckusick * the actual fragtbl array 20586489Smckusick */ 20596489Smckusick unsigned char *fragtbl[MAXFRAG + 1] = { 20606489Smckusick 0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8, 20616489Smckusick }; 2062