xref: /csrg-svn/sbin/icheck/icheck.c (revision 6490)
1 static	char *sccsid = "@(#)icheck.c	2.1 (Berkeley) 04/08/82";
2 
3 /*
4  * icheck
5  */
6 #define	NB	500
7 #define	MAXFN	500
8 #define	MAXNINDIR	(MAXBSIZE / sizeof (daddr_t))
9 
10 #ifndef STANDALONE
11 #include <stdio.h>
12 #endif
13 #ifndef SIMFS
14 #include <sys/param.h>
15 #include <sys/inode.h>
16 #include <sys/fs.h>
17 #else
18 #include "../h/param.h"
19 #include "../h/inode.h"
20 #include "../h/fs.h"
21 #endif
22 
23 union {
24 	struct	fs sb;
25 	char pad[MAXBSIZE];
26 } sbun;
27 #define	sblock sbun.sb
28 
29 union {
30 	struct	cg cg;
31 	char pad[MAXBSIZE];
32 } cgun;
33 #define	cgrp cgun.cg
34 
35 struct	dinode	itab[MAXIPG];
36 daddr_t	blist[NB];
37 char	*bmap;
38 
39 int	mflg;
40 int	sflg;
41 int	dflg;
42 int	fi;
43 ino_t	ino;
44 int	cginit;
45 
46 ino_t	nrfile;
47 ino_t	ndfile;
48 ino_t	nbfile;
49 ino_t	ncfile;
50 ino_t	nlfile;
51 
52 daddr_t	nblock;
53 daddr_t	nfrag;
54 daddr_t	nindir;
55 daddr_t	niindir;
56 
57 daddr_t	nffree;
58 daddr_t	nbfree;
59 
60 daddr_t	ndup;
61 
62 int	nerror;
63 
64 extern int inside[], around[];
65 extern unsigned char *fragtbl[];
66 
67 long	atol();
68 #ifndef STANDALONE
69 char	*malloc();
70 char	*calloc();
71 #endif
72 
73 main(argc, argv)
74 	int argc;
75 	char *argv[];
76 {
77 	register i;
78 	long n;
79 
80 	blist[0] = -1;
81 #ifndef STANDALONE
82 	while (--argc) {
83 		argv++;
84 		if (**argv=='-')
85 		switch ((*argv)[1]) {
86 		case 'd':
87 			dflg++;
88 			continue;
89 
90 		case 'm':
91 			mflg++;
92 			continue;
93 
94 		case 's':
95 			sflg++;
96 			continue;
97 
98 		case 'b':
99 			for(i=0; i<NB; i++) {
100 				n = atol(argv[1]);
101 				if(n == 0)
102 					break;
103 				blist[i] = n;
104 				argv++;
105 				argc--;
106 			}
107 			blist[i] = -1;
108 			continue;
109 
110 		default:
111 			printf("Bad flag\n");
112 		}
113 		check(*argv);
114 	}
115 #else
116 	{
117 		static char fname[128];
118 
119 		printf("File: ");
120 		gets(fname);
121 		check(fname);
122 	}
123 #endif
124 	return(nerror);
125 }
126 
127 check(file)
128 	char *file;
129 {
130 	register i, j, c;
131 	daddr_t d, cgd, cbase, b;
132 	long n;
133 
134 	fi = open(file, sflg ? 2 : 0);
135 	if (fi < 0) {
136 		perror(file);
137 		nerror |= 04;
138 		return;
139 	}
140 	printf("%s:\n", file);
141 	nrfile = 0;
142 	ndfile = 0;
143 	ncfile = 0;
144 	nbfile = 0;
145 	nlfile = 0;
146 
147 	nblock = 0;
148 	nfrag = 0;
149 	nindir = 0;
150 	niindir = 0;
151 
152 	ndup = 0;
153 #ifndef STANDALONE
154 	sync();
155 #endif
156 	getsb(&sblock, file);
157 	if (nerror)
158 		return;
159 	ino = 0;
160 	n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short));
161 #ifdef STANDALONE
162 	bmap = NULL;
163 #else
164 	bmap = malloc((unsigned)n);
165 #endif
166 	if (bmap==NULL) {
167 		printf("Not enough core; duplicates unchecked\n");
168 		dflg++;
169 		if (sflg) {
170 			printf("No Updates\n");
171 			sflg = 0;
172 		}
173 	}
174 	ino = 0;
175 	cginit = 1;
176 	if(!dflg) {
177 		for (i=0; i<(unsigned)n; i++)
178 			bmap[i] = 0;
179 		for (c=0; c < sblock.fs_ncg; c++) {
180 			cgd = cgtod(&sblock, c);
181 			for (d = cgbase(&sblock, c); d < cgd; d += sblock.fs_frag)
182 				chk(d, "badcg", sblock.fs_bsize);
183 			d = cgimin(&sblock, c);
184 			while (cgd < d) {
185 				chk(cgd, "cg", sblock.fs_bsize);
186 				cgd += sblock.fs_frag;
187 			}
188 			d = cgdmin(&sblock, c);
189 			for (; cgd < d; cgd += sblock.fs_frag)
190 				chk(cgd, "inode", sblock.fs_bsize);
191 			if (c == 0) {
192 				d += howmany(sblock.fs_cssize, sblock.fs_bsize)
193 				    * sblock.fs_frag;
194 				for (; cgd < d; cgd += sblock.fs_frag)
195 					chk(cgd, "csum", sblock.fs_bsize);
196 			}
197 		}
198 	}
199 	cginit = 0;
200 	for (c = 0; c < sblock.fs_ncg; c++) {
201 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
202 		    sblock.fs_ipg * sizeof (struct dinode));
203 		for (j=0; j < sblock.fs_ipg; j++) {
204 			pass1(&itab[j]);
205 			ino++;
206 		}
207 	}
208 	ino = 0;
209 #ifndef STANDALONE
210 	sync();
211 #endif
212 	if (sflg) {
213 		makecg();
214 		close(fi);
215 #ifndef STANDALONE
216 		if (bmap)
217 			free(bmap);
218 #endif
219 		return;
220 	}
221 	nffree = 0;
222 	nbfree = 0;
223 	for (c = 0; c < sblock.fs_ncg; c++) {
224 		cbase = cgbase(&sblock, c);
225 		bread(fsbtodb(&sblock, cgtod(&sblock, c)), (char *)&cgrp,
226 			sblock.fs_cgsize);
227 		for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) {
228 			if (isblock(&sblock, cgrp.cg_free,
229 			    b / sblock.fs_frag)) {
230 				nbfree++;
231 				chk(cbase+b, "block", sblock.fs_bsize);
232 			} else {
233 				for (d = 0; d < sblock.fs_frag; d++)
234 					if (isset(cgrp.cg_free, b+d)) {
235 						chk(cbase+b+d, "frag", sblock.fs_fsize);
236 						nffree++;
237 					}
238 			}
239 		}
240 	}
241 	close(fi);
242 #ifndef STANDALONE
243 	if (bmap)
244 		free(bmap);
245 #endif
246 
247 	i = nrfile + ndfile + ncfile + nbfile + nlfile;
248 #ifndef STANDALONE
249 	printf("files %6u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n",
250 		i, nrfile, ndfile, nbfile, ncfile, nlfile);
251 #else
252 	printf("files %u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n",
253 		i, nrfile, ndfile, nbfile, ncfile, nlfile);
254 #endif
255 	n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag;
256 #ifdef STANDALONE
257 	printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
258 		n, nindir, niindir, nblock, nfrag);
259 	printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
260 	    nbfree, nffree);
261 #else
262 	printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
263 		n, nindir, niindir, nblock, nfrag);
264 	printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
265 	    nbfree, nffree);
266 #endif
267 	if(!dflg) {
268 		n = 0;
269 		for (d = 0; d < sblock.fs_size; d++)
270 			if(!duped(d, sblock.fs_fsize)) {
271 				if(mflg)
272 					printf("%ld missing\n", d);
273 				n++;
274 			}
275 		printf("missing%5ld\n", n);
276 	}
277 }
278 
279 pass1(ip)
280 	register struct dinode *ip;
281 {
282 	daddr_t ind1[MAXNINDIR];
283 	daddr_t ind2[MAXNINDIR];
284 	daddr_t db, ib;
285 	register int i, j, k, siz;
286 
287 	i = ip->di_mode & IFMT;
288 	if(i == 0)
289 		return;
290 	switch (i) {
291 	case IFCHR:
292 		ncfile++;
293 		return;
294 	case IFBLK:
295 		nbfile++;
296 		return;
297 	case IFDIR:
298 		ndfile++;
299 		break;
300 	case IFREG:
301 		nrfile++;
302 		break;
303 	case IFLNK:
304 		nlfile++;
305 		break;
306 	default:
307 		printf("bad mode %u\n", ino);
308 		return;
309 	}
310 	for (i = 0; i < NDADDR; i++) {
311 		db = ip->di_db[i];
312 		if (db == 0)
313 			continue;
314 		siz = dblksize(&sblock, ip, i);
315 		chk(db, "data (block)", siz);
316 		if (siz == sblock.fs_bsize)
317 			nblock++;
318 		else
319 			nfrag += howmany(siz, sblock.fs_fsize);
320 	}
321 	for(i = 0; i < NIADDR; i++) {
322 		ib = ip->di_ib[i];
323 		if(ib == 0)
324 			continue;
325 		if (chk(ib, "1st indirect", sblock.fs_bsize))
326 			continue;
327 		bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize);
328 		nindir++;
329 		for (j = 0; j < NINDIR(&sblock); j++) {
330 			ib = ind1[j];
331 			if (ib == 0)
332 				continue;
333 			if (i == 0) {
334 				siz = dblksize(&sblock, ip, NDADDR + j);
335 				chk(ib, "data (large)", siz);
336 				if (siz == sblock.fs_bsize)
337 					nblock++;
338 				else
339 					nfrag += howmany(siz, sblock.fs_fsize);
340 				continue;
341 			}
342 			if (chk(ib, "2nd indirect", sblock.fs_bsize))
343 				continue;
344 			bread(fsbtodb(&sblock, ib), (char *)ind2,
345 				sblock.fs_bsize);
346 			niindir++;
347 			for (k = 0; k < NINDIR(&sblock); k++) {
348 				ib = ind2[k];
349 				if (ib == 0)
350 					continue;
351 				siz = dblksize(&sblock, ip,
352 				    NDADDR + NINDIR(&sblock) * (i + j) + k);
353 				chk(ib, "data (huge)", siz);
354 				if (siz == sblock.fs_bsize)
355 					nblock++;
356 				else
357 					nfrag += howmany(siz, sblock.fs_fsize);
358 			}
359 		}
360 	}
361 }
362 
363 chk(bno, s, size)
364 	daddr_t bno;
365 	char *s;
366 	int size;
367 {
368 	register n, cg;
369 	int frags;
370 
371 	cg = dtog(&sblock, bno);
372 	if (cginit==0 &&
373 	    bno<cgdmin(&sblock, cg) || bno >= sblock.fs_frag * sblock.fs_size) {
374 		printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
375 		return(1);
376 	}
377 	if (size == sblock.fs_bsize) {
378 		if (duped(bno, size)) {
379 			printf("%ld dup block; inode=%u, class=%s\n",
380 			    bno, ino, s);
381 			ndup += sblock.fs_frag;
382 		}
383 	} else {
384 		frags = numfrags(&sblock, size);
385 		for (n = 0; n < frags; n++) {
386 			if (duped(bno + n, sblock.fs_fsize)) {
387 				printf("%ld dup frag; inode=%u, class=%s\n",
388 				    bno, ino, s);
389 				ndup++;
390 			}
391 		}
392 	}
393 	for (n=0; blist[n] != -1; n++)
394 		if (bno == blist[n])
395 			printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
396 	return(0);
397 }
398 
399 duped(bno, size)
400 	daddr_t bno;
401 	int size;
402 {
403 	if(dflg)
404 		return(0);
405 	if (size != sblock.fs_fsize && size != sblock.fs_bsize)
406 		printf("bad size %d to duped\n", size);
407 	if (size == sblock.fs_fsize) {
408 		if (isset(bmap, bno))
409 			return(1);
410 		setbit(bmap, bno);
411 		return (0);
412 	}
413 	if (bno % sblock.fs_frag != 0)
414 		printf("bad bno %d to duped\n", bno);
415 	if (isblock(&sblock, bmap, bno/sblock.fs_frag))
416 		return (1);
417 	setblock(&sblock, bmap, bno/sblock.fs_frag);
418 	return(0);
419 }
420 
421 makecg()
422 {
423 	int c, blk;
424 	daddr_t dbase, d, dmin, dmax;
425 	long i, j, s;
426 	register struct csum *cs;
427 	register struct dinode *dp;
428 
429 	sblock.fs_cstotal.cs_nbfree = 0;
430 	sblock.fs_cstotal.cs_nffree = 0;
431 	sblock.fs_cstotal.cs_nifree = 0;
432 	sblock.fs_cstotal.cs_ndir = 0;
433 	for (c = 0; c < sblock.fs_ncg; c++) {
434 		dbase = cgbase(&sblock, c);
435 		dmax = dbase + sblock.fs_fpg;
436 		if (dmax > sblock.fs_size) {
437 			for ( ; dmax >= sblock.fs_size; dmax--)
438 				clrbit(cgrp.cg_free, dmax - dbase);
439 			dmax++;
440 		}
441 		dmin = sblock.fs_dblkno;
442 		cs = &sblock.fs_cs(&sblock, c);
443 		cgrp.cg_time = time(0);
444 		cgrp.cg_magic = CG_MAGIC;
445 		cgrp.cg_cgx = c;
446 		cgrp.cg_ncyl = sblock.fs_cpg;
447 		cgrp.cg_niblk = sblock.fs_ipg;
448 		cgrp.cg_ndblk = dmax - dbase;
449 		cgrp.cg_cs.cs_ndir = 0;
450 		cgrp.cg_cs.cs_nffree = 0;
451 		cgrp.cg_cs.cs_nbfree = 0;
452 		cgrp.cg_cs.cs_nifree = 0;
453 		cgrp.cg_rotor = dmin;
454 		cgrp.cg_frotor = dmin;
455 		cgrp.cg_irotor = 0;
456 		for (i = 0; i < sblock.fs_frag; i++)
457 			cgrp.cg_frsum[i] = 0;
458 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
459 		      sblock.fs_ipg * sizeof(struct dinode));
460 		for (i = 0; i < sblock.fs_ipg; i++) {
461 			cgrp.cg_cs.cs_nifree++;
462 			clrbit(cgrp.cg_iused, i);
463 			dp = &itab[i];
464 			if ((dp->di_mode & IFMT) != 0) {
465 				if ((dp->di_mode & IFMT) == IFDIR)
466 					cgrp.cg_cs.cs_ndir++;
467 				cgrp.cg_cs.cs_nifree--;
468 				setbit(cgrp.cg_iused, i);
469 				continue;
470 			}
471 		}
472 		while (i < MAXIPG) {
473 			clrbit(cgrp.cg_iused, i);
474 			i++;
475 		}
476 		if (c == 0)
477 			for (i = 0; i < ROOTINO; i++) {
478 				setbit(cgrp.cg_iused, i);
479 				cgrp.cg_cs.cs_nifree--;
480 			}
481 		for (s = 0; s < MAXCPG; s++) {
482 			cgrp.cg_btot[s] = 0;
483 			for (i = 0; i < NRPOS; i++)
484 				cgrp.cg_b[s][i] = 0;
485 		}
486 		if (c == 0) {
487 			dmin += howmany(sblock.fs_cssize, sblock.fs_bsize) *
488 			    sblock.fs_frag;
489 		}
490 		for (d = 0; d < dmin; d++)
491 			clrbit(cgrp.cg_free, d);
492 		for (; (d + sblock.fs_frag) <= dmax - dbase; d += sblock.fs_frag) {
493 			j = 0;
494 			for (i = 0; i < sblock.fs_frag; i++) {
495 				if (!isset(bmap, dbase+d+i)) {
496 					setbit(cgrp.cg_free, d+i);
497 					j++;
498 				} else
499 					clrbit(cgrp.cg_free, d+i);
500 			}
501 			if (j == sblock.fs_frag) {
502 				cgrp.cg_cs.cs_nbfree++;
503 				cgrp.cg_btot[cbtocylno(&sblock, d)]++;
504 				cgrp.cg_b[cbtocylno(&sblock, d)]
505 				    [cbtorpos(&sblock, d)]++;
506 			} else if (j > 0) {
507 				cgrp.cg_cs.cs_nffree += j;
508 				blk = ((cgrp.cg_free[d / NBBY] >> (d % NBBY)) &
509 				       (0xff >> (NBBY - sblock.fs_frag)));
510 				fragacct(&sblock, blk, cgrp.cg_frsum, 1);
511 			}
512 		}
513 		for (j = d; d < dmax - dbase; d++) {
514 			if (!isset(bmap, dbase+d)) {
515 				setbit(cgrp.cg_free, d);
516 				cgrp.cg_cs.cs_nffree++;
517 			} else
518 				clrbit(cgrp.cg_free, d);
519 		}
520 		if (j != d) {
521 			blk = ((cgrp.cg_free[j / NBBY] >> (j % NBBY)) &
522 			       (0xff >> (NBBY - sblock.fs_frag)));
523 			fragacct(&sblock, blk, cgrp.cg_frsum, 1);
524 		}
525 		for (; d < MAXBPG(&sblock); d++)
526 			clrbit(cgrp.cg_free, d);
527 		sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree;
528 		sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree;
529 		sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree;
530 		sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir;
531 		*cs = cgrp.cg_cs;
532 		bwrite(fsbtodb(&sblock, cgtod(&sblock, c)), &cgrp,
533 			sblock.fs_cgsize);
534 	}
535 	for (i = 0; i < howmany(sblock.fs_cssize, sblock.fs_bsize); i++) {
536 		bwrite(fsbtodb(&sblock,
537 		    sblock.fs_csaddr + (i * sblock.fs_frag)),
538 		    (char *)sblock.fs_csp[i], sblock.fs_bsize);
539 	}
540 	sblock.fs_ronly = 0;
541 	sblock.fs_fmod = 0;
542 	bwrite(SBLOCK, (char *)&sblock, SBSIZE);
543 }
544 
545 /*
546  * update the frsum fields to reflect addition or deletion
547  * of some frags
548  */
549 fragacct(fs, fragmap, fraglist, cnt)
550 	struct fs *fs;
551 	int fragmap;
552 	long fraglist[];
553 	int cnt;
554 {
555 	int inblk;
556 	register int field, subfield;
557 	register int siz, pos;
558 
559 	inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1);
560 	fragmap <<= 1;
561 	for (siz = 1; siz < fs->fs_frag; siz++) {
562 		if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
563 			continue;
564 		field = around[siz];
565 		subfield = inside[siz];
566 		for (pos = siz; pos <= fs->fs_frag; pos++) {
567 			if ((fragmap & field) == subfield) {
568 				fraglist[siz] += cnt;
569 				pos += siz;
570 				field <<= siz;
571 				subfield <<= siz;
572 			}
573 			field <<= 1;
574 			subfield <<= 1;
575 		}
576 	}
577 }
578 
579 getsb(fs, file)
580 	register struct fs *fs;
581 	char *file;
582 {
583 	int i;
584 
585 	if (bread(SBLOCK, fs, SBSIZE)) {
586 		printf("bad super block");
587 		perror(file);
588 		nerror |= 04;
589 		return;
590 	}
591 	if (fs->fs_magic != FS_MAGIC) {
592 		printf("%s: bad magic number\n", file);
593 		nerror |= 04;
594 		return;
595 	}
596 	for (i = 0; i < howmany(fs->fs_cssize, fs->fs_bsize); i++) {
597 		fs->fs_csp[i] = (struct csum *)calloc(1, fs->fs_bsize);
598 		bread(fsbtodb(fs, fs->fs_csaddr + (i * fs->fs_frag)),
599 		      (char *)fs->fs_csp[i], fs->fs_bsize);
600 	}
601 }
602 
603 bwrite(blk, buf, size)
604 	char *buf;
605 	daddr_t blk;
606 	register size;
607 {
608 	if (lseek(fi, blk * DEV_BSIZE, 0) < 0) {
609 		perror("FS SEEK");
610 		return(1);
611 	}
612 	if (write(fi, buf, size) != size) {
613 		perror("FS WRITE");
614 		return(1);
615 	}
616 	return (0);
617 }
618 
619 bread(bno, buf, cnt)
620 	daddr_t bno;
621 	char *buf;
622 {
623 	register i;
624 
625 	lseek(fi, bno * DEV_BSIZE, 0);
626 	if ((i = read(fi, buf, cnt)) != cnt) {
627 		if (sflg) {
628 			printf("No Update\n");
629 			sflg = 0;
630 		}
631 		for(i=0; i<sblock.fs_bsize; i++)
632 			buf[i] = 0;
633 		return (1);
634 	}
635 	return (0);
636 }
637 
638 /*
639  * block operations
640  */
641 
642 isblock(fs, cp, h)
643 	struct fs *fs;
644 	unsigned char *cp;
645 	int h;
646 {
647 	unsigned char mask;
648 
649 	switch (fs->fs_frag) {
650 	case 8:
651 		return (cp[h] == 0xff);
652 	case 4:
653 		mask = 0x0f << ((h & 0x1) << 2);
654 		return ((cp[h >> 1] & mask) == mask);
655 	case 2:
656 		mask = 0x03 << ((h & 0x3) << 1);
657 		return ((cp[h >> 2] & mask) == mask);
658 	case 1:
659 		mask = 0x01 << (h & 0x7);
660 		return ((cp[h >> 3] & mask) == mask);
661 	default:
662 		fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
663 		return;
664 	}
665 }
666 
667 setblock(fs, cp, h)
668 	struct fs *fs;
669 	unsigned char *cp;
670 	int h;
671 {
672 	switch (fs->fs_frag) {
673 	case 8:
674 		cp[h] = 0xff;
675 		return;
676 	case 4:
677 		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
678 		return;
679 	case 2:
680 		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
681 		return;
682 	case 1:
683 		cp[h >> 3] |= (0x01 << (h & 0x7));
684 		return;
685 	default:
686 		fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag);
687 		return;
688 	}
689 }
690 
691 /*	tables.c	4.1	82/03/25	*/
692 
693 /* merged into kernel:	tables.c 2.1 3/25/82 */
694 
695 /* last monet version:	partab.c	4.2	81/03/08	*/
696 
697 /*
698  * bit patterns for identifying fragments in the block map
699  * used as ((map & around) == inside)
700  */
701 int around[9] = {
702 	0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff
703 };
704 int inside[9] = {
705 	0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe
706 };
707 
708 /*
709  * given a block map bit pattern, the frag tables tell whether a
710  * particular size fragment is available.
711  *
712  * used as:
713  * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] {
714  *	at least one fragment of the indicated size is available
715  * }
716  *
717  * These tables are used by the scanc instruction on the VAX to
718  * quickly find an appropriate fragment.
719  */
720 
721 unsigned char fragtbl124[256] = {
722 	0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e,
723 	0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a,
724 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
725 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
726 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
727 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
728 	0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e,
729 	0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa,
730 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
731 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
732 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
733 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
734 	0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e,
735 	0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae,
736 	0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e,
737 	0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce,
738 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
739 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
740 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
741 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
742 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
743 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
744 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e,
745 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe,
746 	0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e,
747 	0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa,
748 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e,
749 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe,
750 	0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e,
751 	0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce,
752 	0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce,
753 	0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a,
754 };
755 
756 unsigned char fragtbl8[256] = {
757 	0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04,
758 	0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08,
759 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
760 	0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10,
761 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
762 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
763 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
764 	0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20,
765 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
766 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
767 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
768 	0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
769 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
770 	0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a,
771 	0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04,
772 	0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40,
773 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
774 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
775 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
776 	0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
777 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
778 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
779 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
780 	0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21,
781 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
782 	0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a,
783 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
784 	0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12,
785 	0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04,
786 	0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c,
787 	0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c,
788 	0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80,
789 };
790 
791 /*
792  * the actual fragtbl array
793  */
794 unsigned char *fragtbl[MAXFRAG + 1] = {
795 	0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8,
796 };
797