xref: /csrg-svn/sbin/fsck/utilities.c (revision 39975)
122055Sdist /*
222055Sdist  * Copyright (c) 1980 Regents of the University of California.
322055Sdist  * All rights reserved.  The Berkeley software License Agreement
422055Sdist  * specifies the terms and conditions for redistribution.
522055Sdist  */
622055Sdist 
716269Smckusick #ifndef lint
8*39975Smckusick static char sccsid[] = "@(#)utilities.c	5.20 (Berkeley) 02/01/90";
922055Sdist #endif not lint
1016269Smckusick 
1116269Smckusick #include <sys/param.h>
1239383Smckusick #include <ufs/dinode.h>
1338337Smckusick #include <ufs/fs.h>
1438337Smckusick #include <ufs/dir.h>
1539165Sbostic #include <stdio.h>
1639165Sbostic #include <ctype.h>
1716269Smckusick #include "fsck.h"
1816269Smckusick 
1934225Smckusick long	diskreads, totalreads;	/* Disk cache statistics */
2016269Smckusick long	lseek();
2138377Smckusick char	*malloc();
2216269Smckusick 
2316269Smckusick ftypeok(dp)
2439973Smckusick 	struct dinode *dp;
2516269Smckusick {
2616269Smckusick 	switch (dp->di_mode & IFMT) {
2716269Smckusick 
2816269Smckusick 	case IFDIR:
2916269Smckusick 	case IFREG:
3016269Smckusick 	case IFBLK:
3116269Smckusick 	case IFCHR:
3216269Smckusick 	case IFLNK:
3316269Smckusick 	case IFSOCK:
3416269Smckusick 		return (1);
3516269Smckusick 
3616269Smckusick 	default:
3716269Smckusick 		if (debug)
3816269Smckusick 			printf("bad file type 0%o\n", dp->di_mode);
3916269Smckusick 		return (0);
4016269Smckusick 	}
4116269Smckusick }
4216269Smckusick 
43*39975Smckusick reply(question)
44*39975Smckusick 	char *question;
4516269Smckusick {
46*39975Smckusick 	int persevere;
47*39975Smckusick 	char c;
4816269Smckusick 
4916269Smckusick 	if (preen)
5016269Smckusick 		pfatal("INTERNAL ERROR: GOT TO reply()");
51*39975Smckusick 	persevere = !strcmp(question, "CONTINUE");
52*39975Smckusick 	printf("\n");
53*39975Smckusick 	if (!persevere && (nflag || fswritefd < 0)) {
54*39975Smckusick 		printf("%s? no\n\n", question);
5516269Smckusick 		return (0);
5616269Smckusick 	}
57*39975Smckusick 	if (yflag || (persevere && nflag)) {
58*39975Smckusick 		printf("%s? yes\n\n", question);
5916269Smckusick 		return (1);
6016269Smckusick 	}
61*39975Smckusick 	do	{
62*39975Smckusick 		printf("%s? [yn] ", question);
63*39975Smckusick 		(void) fflush(stdout);
64*39975Smckusick 		c = getc(stdin);
65*39975Smckusick 		while (c != '\n' && getc(stdin) != '\n')
66*39975Smckusick 			if (feof(stdin))
67*39975Smckusick 				return (0);
68*39975Smckusick 	} while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
6916269Smckusick 	printf("\n");
70*39975Smckusick 	if (c == 'y' || c == 'Y')
7116269Smckusick 		return (1);
72*39975Smckusick 	return (0);
7316269Smckusick }
7416269Smckusick 
7534225Smckusick /*
7634225Smckusick  * Malloc buffers and set up cache.
7734225Smckusick  */
7834225Smckusick bufinit()
7934225Smckusick {
8039973Smckusick 	register struct bufarea *bp;
8134225Smckusick 	long bufcnt, i;
8234225Smckusick 	char *bufp;
8334225Smckusick 
8439973Smckusick 	bufp = malloc((unsigned int)sblock.fs_bsize);
8534225Smckusick 	if (bufp == 0)
8634225Smckusick 		errexit("cannot allocate buffer pool\n");
8734225Smckusick 	cgblk.b_un.b_buf = bufp;
8834225Smckusick 	initbarea(&cgblk);
8934225Smckusick 	bufhead.b_next = bufhead.b_prev = &bufhead;
9034225Smckusick 	bufcnt = MAXBUFSPACE / sblock.fs_bsize;
9134225Smckusick 	if (bufcnt < MINBUFS)
9234225Smckusick 		bufcnt = MINBUFS;
9334225Smckusick 	for (i = 0; i < bufcnt; i++) {
9439973Smckusick 		bp = (struct bufarea *)malloc(sizeof(struct bufarea));
9539973Smckusick 		bufp = malloc((unsigned int)sblock.fs_bsize);
9638377Smckusick 		if (bp == NULL || bufp == NULL) {
9734225Smckusick 			if (i >= MINBUFS)
9834225Smckusick 				break;
9934225Smckusick 			errexit("cannot allocate buffer pool\n");
10034225Smckusick 		}
10134225Smckusick 		bp->b_un.b_buf = bufp;
10234225Smckusick 		bp->b_prev = &bufhead;
10334225Smckusick 		bp->b_next = bufhead.b_next;
10434225Smckusick 		bufhead.b_next->b_prev = bp;
10534225Smckusick 		bufhead.b_next = bp;
10634225Smckusick 		initbarea(bp);
10734225Smckusick 	}
10834482Smckusick 	bufhead.b_size = i;	/* save number of buffers */
10934225Smckusick }
11034225Smckusick 
11134225Smckusick /*
11234225Smckusick  * Manage a cache of directory blocks.
11334225Smckusick  */
11439973Smckusick struct bufarea *
11534225Smckusick getdatablk(blkno, size)
11634225Smckusick 	daddr_t blkno;
11734225Smckusick 	long size;
11834225Smckusick {
11939973Smckusick 	register struct bufarea *bp;
12034225Smckusick 
12134225Smckusick 	for (bp = bufhead.b_next; bp != &bufhead; bp = bp->b_next)
12234671Smckusick 		if (bp->b_bno == fsbtodb(&sblock, blkno))
12334225Smckusick 			goto foundit;
12434225Smckusick 	for (bp = bufhead.b_prev; bp != &bufhead; bp = bp->b_prev)
12534225Smckusick 		if ((bp->b_flags & B_INUSE) == 0)
12634225Smckusick 			break;
12734225Smckusick 	if (bp == &bufhead)
12834225Smckusick 		errexit("deadlocked buffer pool\n");
12934225Smckusick 	getblk(bp, blkno, size);
13034225Smckusick 	/* fall through */
13134225Smckusick foundit:
13234225Smckusick 	totalreads++;
13334225Smckusick 	bp->b_prev->b_next = bp->b_next;
13434225Smckusick 	bp->b_next->b_prev = bp->b_prev;
13534225Smckusick 	bp->b_prev = &bufhead;
13634225Smckusick 	bp->b_next = bufhead.b_next;
13734225Smckusick 	bufhead.b_next->b_prev = bp;
13834225Smckusick 	bufhead.b_next = bp;
13934225Smckusick 	bp->b_flags |= B_INUSE;
14034225Smckusick 	return (bp);
14134225Smckusick }
14234225Smckusick 
14339973Smckusick struct bufarea *
14416269Smckusick getblk(bp, blk, size)
14539973Smckusick 	register struct bufarea *bp;
14616269Smckusick 	daddr_t blk;
14716269Smckusick 	long size;
14816269Smckusick {
14916269Smckusick 	daddr_t dblk;
15016269Smckusick 
15134671Smckusick 	dblk = fsbtodb(&sblock, blk);
15234671Smckusick 	if (bp->b_bno == dblk)
15316269Smckusick 		return (bp);
15439973Smckusick 	flush(fswritefd, bp);
15534225Smckusick 	diskreads++;
15639973Smckusick 	bp->b_errs = bread(fsreadfd, bp->b_un.b_buf, dblk, size);
15734671Smckusick 	bp->b_bno = dblk;
15821540Smckusick 	bp->b_size = size;
15921540Smckusick 	return (bp);
16016269Smckusick }
16116269Smckusick 
16239973Smckusick flush(fd, bp)
16339973Smckusick 	int fd;
16439973Smckusick 	register struct bufarea *bp;
16516269Smckusick {
16617931Smckusick 	register int i, j;
16716269Smckusick 
16817931Smckusick 	if (!bp->b_dirty)
16917931Smckusick 		return;
17021540Smckusick 	if (bp->b_errs != 0)
17130609Skarels 		pfatal("WRITING %sZERO'ED BLOCK %d TO DISK\n",
17230609Skarels 		    (bp->b_errs == bp->b_size / dev_bsize) ? "" : "PARTIALLY ",
17330609Skarels 		    bp->b_bno);
17416269Smckusick 	bp->b_dirty = 0;
17521540Smckusick 	bp->b_errs = 0;
17639973Smckusick 	bwrite(fd, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size);
17717931Smckusick 	if (bp != &sblk)
17817931Smckusick 		return;
17917931Smckusick 	for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
18039973Smckusick 		bwrite(fswritefd, (char *)sblock.fs_csp[j],
18117931Smckusick 		    fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
18217931Smckusick 		    sblock.fs_cssize - i < sblock.fs_bsize ?
18317931Smckusick 		    sblock.fs_cssize - i : sblock.fs_bsize);
18417931Smckusick 	}
18516269Smckusick }
18616269Smckusick 
18739973Smckusick rwerror(mesg, blk)
18839973Smckusick 	char *mesg;
18916269Smckusick 	daddr_t blk;
19016269Smckusick {
19116269Smckusick 
19216269Smckusick 	if (preen == 0)
19316269Smckusick 		printf("\n");
19439973Smckusick 	pfatal("CANNOT %s: BLK %ld", mesg, blk);
19516269Smckusick 	if (reply("CONTINUE") == 0)
19616269Smckusick 		errexit("Program terminated\n");
19716269Smckusick }
19816269Smckusick 
19916269Smckusick ckfini()
20016269Smckusick {
20139973Smckusick 	register struct bufarea *bp, *nbp;
20234482Smckusick 	int cnt = 0;
20316269Smckusick 
20439973Smckusick 	flush(fswritefd, &sblk);
20530859Skarels 	if (havesb && sblk.b_bno != SBOFF / dev_bsize &&
20630518Smckusick 	    !preen && reply("UPDATE STANDARD SUPERBLOCK")) {
20730556Smckusick 		sblk.b_bno = SBOFF / dev_bsize;
20816269Smckusick 		sbdirty();
20939973Smckusick 		flush(fswritefd, &sblk);
21016269Smckusick 	}
21139973Smckusick 	flush(fswritefd, &cgblk);
21238342Smckusick 	free(cgblk.b_un.b_buf);
21338342Smckusick 	for (bp = bufhead.b_prev; bp != &bufhead; bp = nbp) {
21434482Smckusick 		cnt++;
21539973Smckusick 		flush(fswritefd, bp);
21638342Smckusick 		nbp = bp->b_prev;
21738342Smckusick 		free(bp->b_un.b_buf);
21838342Smckusick 		free((char *)bp);
21934482Smckusick 	}
22034482Smckusick 	if (bufhead.b_size != cnt)
22134482Smckusick 		errexit("Panic: lost %d buffers\n", bufhead.b_size - cnt);
22234225Smckusick 	if (debug)
22334482Smckusick 		printf("cache missed %d of %d (%d%%)\n", diskreads,
22434482Smckusick 		    totalreads, diskreads * 100 / totalreads);
22539973Smckusick 	(void)close(fsreadfd);
22639973Smckusick 	(void)close(fswritefd);
22716269Smckusick }
22816269Smckusick 
22939973Smckusick bread(fd, buf, blk, size)
23039973Smckusick 	int fd;
23116269Smckusick 	char *buf;
23216269Smckusick 	daddr_t blk;
23316269Smckusick 	long size;
23416269Smckusick {
23521540Smckusick 	char *cp;
23621540Smckusick 	int i, errs;
23721540Smckusick 
23839973Smckusick 	if (lseek(fd, blk * dev_bsize, 0) < 0)
23939973Smckusick 		rwerror("SEEK", blk);
24039973Smckusick 	else if (read(fd, buf, (int)size) == size)
24121540Smckusick 		return (0);
24239973Smckusick 	rwerror("READ", blk);
24339973Smckusick 	if (lseek(fd, blk * dev_bsize, 0) < 0)
24439973Smckusick 		rwerror("SEEK", blk);
24521540Smckusick 	errs = 0;
24639973Smckusick 	bzero(buf, (int)size);
24730609Skarels 	printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:");
24830609Skarels 	for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) {
24939973Smckusick 		if (read(fd, cp, (int)secsize) < 0) {
25039973Smckusick 			lseek(fd, blk * dev_bsize + i + secsize, 0);
25130859Skarels 			if (secsize != dev_bsize && dev_bsize != 1)
25230609Skarels 				printf(" %d (%d),",
25330609Skarels 				    (blk * dev_bsize + i) / secsize,
25430609Skarels 				    blk + i / dev_bsize);
25530609Skarels 			else
25630609Skarels 				printf(" %d,", blk + i / dev_bsize);
25721540Smckusick 			errs++;
25821540Smckusick 		}
25921540Smckusick 	}
26021758Smckusick 	printf("\n");
26121540Smckusick 	return (errs);
26216269Smckusick }
26316269Smckusick 
26439973Smckusick bwrite(fd, buf, blk, size)
26539973Smckusick 	int fd;
26616269Smckusick 	char *buf;
26716269Smckusick 	daddr_t blk;
26816269Smckusick 	long size;
26916269Smckusick {
27021758Smckusick 	int i;
27121758Smckusick 	char *cp;
27216269Smckusick 
27339973Smckusick 	if (fd < 0)
27421758Smckusick 		return;
27539973Smckusick 	if (lseek(fd, blk * dev_bsize, 0) < 0)
27639973Smckusick 		rwerror("SEEK", blk);
27739973Smckusick 	else if (write(fd, buf, (int)size) == size) {
27839973Smckusick 		fsmodified = 1;
27921758Smckusick 		return;
28016269Smckusick 	}
28139973Smckusick 	rwerror("WRITE", blk);
28239973Smckusick 	if (lseek(fd, blk * dev_bsize, 0) < 0)
28339973Smckusick 		rwerror("SEEK", blk);
28430609Skarels 	printf("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:");
28530518Smckusick 	for (cp = buf, i = 0; i < size; i += dev_bsize, cp += dev_bsize)
28639973Smckusick 		if (write(fd, cp, (int)dev_bsize) < 0) {
28739973Smckusick 			lseek(fd, blk * dev_bsize + i + dev_bsize, 0);
28830518Smckusick 			printf(" %d,", blk + i / dev_bsize);
28930395Smckusick 		}
29021758Smckusick 	printf("\n");
29121758Smckusick 	return;
29216269Smckusick }
29316269Smckusick 
29417944Smckusick /*
29517944Smckusick  * allocate a data block with the specified number of fragments
29617944Smckusick  */
29717944Smckusick allocblk(frags)
29839973Smckusick 	long frags;
29917944Smckusick {
30017944Smckusick 	register int i, j, k;
30117944Smckusick 
30217944Smckusick 	if (frags <= 0 || frags > sblock.fs_frag)
30317944Smckusick 		return (0);
30439973Smckusick 	for (i = 0; i < maxfsblock - sblock.fs_frag; i += sblock.fs_frag) {
30517944Smckusick 		for (j = 0; j <= sblock.fs_frag - frags; j++) {
30639973Smckusick 			if (testbmap(i + j))
30717944Smckusick 				continue;
30817944Smckusick 			for (k = 1; k < frags; k++)
30939973Smckusick 				if (testbmap(i + j + k))
31017944Smckusick 					break;
31117944Smckusick 			if (k < frags) {
31217944Smckusick 				j += k;
31317944Smckusick 				continue;
31417944Smckusick 			}
31517944Smckusick 			for (k = 0; k < frags; k++)
31617944Smckusick 				setbmap(i + j + k);
31717944Smckusick 			n_blks += frags;
31817944Smckusick 			return (i + j);
31917944Smckusick 		}
32017944Smckusick 	}
32117944Smckusick 	return (0);
32217944Smckusick }
32317944Smckusick 
32417944Smckusick /*
32517944Smckusick  * Free a previously allocated block
32617944Smckusick  */
32717944Smckusick freeblk(blkno, frags)
32817944Smckusick 	daddr_t blkno;
32939973Smckusick 	long frags;
33017944Smckusick {
33117944Smckusick 	struct inodesc idesc;
33217944Smckusick 
33317944Smckusick 	idesc.id_blkno = blkno;
33417944Smckusick 	idesc.id_numfrags = frags;
33517944Smckusick 	pass4check(&idesc);
33617944Smckusick }
33717944Smckusick 
33817991Smckusick /*
33917991Smckusick  * Find a pathname
34017991Smckusick  */
34117991Smckusick getpathname(namebuf, curdir, ino)
34217991Smckusick 	char *namebuf;
34317991Smckusick 	ino_t curdir, ino;
34417991Smckusick {
34517991Smckusick 	int len;
34617991Smckusick 	register char *cp;
34717991Smckusick 	struct inodesc idesc;
34817991Smckusick 	extern int findname();
34917991Smckusick 
35017991Smckusick 	if (statemap[ino] != DSTATE && statemap[ino] != DFOUND) {
35117991Smckusick 		strcpy(namebuf, "?");
35217991Smckusick 		return;
35317991Smckusick 	}
35439973Smckusick 	bzero((char *)&idesc, sizeof(struct inodesc));
35517991Smckusick 	idesc.id_type = DATA;
35617991Smckusick 	cp = &namebuf[BUFSIZ - 1];
35730354Smckusick 	*cp = '\0';
35817991Smckusick 	if (curdir != ino) {
35917991Smckusick 		idesc.id_parent = curdir;
36017991Smckusick 		goto namelookup;
36117991Smckusick 	}
36217991Smckusick 	while (ino != ROOTINO) {
36317991Smckusick 		idesc.id_number = ino;
36417991Smckusick 		idesc.id_func = findino;
36517991Smckusick 		idesc.id_name = "..";
36630354Smckusick 		if ((ckinode(ginode(ino), &idesc) & FOUND) == 0)
36717991Smckusick 			break;
36817991Smckusick 	namelookup:
36917991Smckusick 		idesc.id_number = idesc.id_parent;
37017991Smckusick 		idesc.id_parent = ino;
37117991Smckusick 		idesc.id_func = findname;
37217991Smckusick 		idesc.id_name = namebuf;
37330354Smckusick 		if ((ckinode(ginode(idesc.id_number), &idesc) & FOUND) == 0)
37417991Smckusick 			break;
37517991Smckusick 		len = strlen(namebuf);
37617991Smckusick 		cp -= len;
37717991Smckusick 		if (cp < &namebuf[MAXNAMLEN])
37817991Smckusick 			break;
37917991Smckusick 		bcopy(namebuf, cp, len);
38017991Smckusick 		*--cp = '/';
38117991Smckusick 		ino = idesc.id_number;
38217991Smckusick 	}
38317991Smckusick 	if (ino != ROOTINO) {
38417991Smckusick 		strcpy(namebuf, "?");
38517991Smckusick 		return;
38617991Smckusick 	}
38717991Smckusick 	bcopy(cp, namebuf, &namebuf[BUFSIZ] - cp);
38817991Smckusick }
38917991Smckusick 
39039165Sbostic void
39116269Smckusick catch()
39216269Smckusick {
39316269Smckusick 	ckfini();
39416269Smckusick 	exit(12);
39516269Smckusick }
39616269Smckusick 
39716269Smckusick /*
39824680Skarels  * When preening, allow a single quit to signal
39924680Skarels  * a special exit after filesystem checks complete
40024680Skarels  * so that reboot sequence may be interrupted.
40124680Skarels  */
40239165Sbostic void
40324680Skarels catchquit()
40424680Skarels {
40524680Skarels 	extern returntosingle;
40624680Skarels 
40724680Skarels 	printf("returning to single-user after filesystem check\n");
40824680Skarels 	returntosingle = 1;
40924680Skarels 	(void)signal(SIGQUIT, SIG_DFL);
41024680Skarels }
41124680Skarels 
41224680Skarels /*
41324680Skarels  * Ignore a single quit signal; wait and flush just in case.
41424680Skarels  * Used by child processes in preen.
41524680Skarels  */
41639165Sbostic void
41724680Skarels voidquit()
41824680Skarels {
41924680Skarels 
42024680Skarels 	sleep(1);
42124680Skarels 	(void)signal(SIGQUIT, SIG_IGN);
42224680Skarels 	(void)signal(SIGQUIT, SIG_DFL);
42324680Skarels }
42424680Skarels 
42524680Skarels /*
42616269Smckusick  * determine whether an inode should be fixed.
42716269Smckusick  */
42817931Smckusick dofix(idesc, msg)
42916269Smckusick 	register struct inodesc *idesc;
43017931Smckusick 	char *msg;
43116269Smckusick {
43216269Smckusick 
43316269Smckusick 	switch (idesc->id_fix) {
43416269Smckusick 
43516269Smckusick 	case DONTKNOW:
43617931Smckusick 		if (idesc->id_type == DATA)
43739973Smckusick 			direrror(idesc->id_number, msg);
43817931Smckusick 		else
43917931Smckusick 			pwarn(msg);
44017931Smckusick 		if (preen) {
44117931Smckusick 			printf(" (SALVAGED)\n");
44217931Smckusick 			idesc->id_fix = FIX;
44317931Smckusick 			return (ALTERED);
44417931Smckusick 		}
44516269Smckusick 		if (reply("SALVAGE") == 0) {
44616269Smckusick 			idesc->id_fix = NOFIX;
44716269Smckusick 			return (0);
44816269Smckusick 		}
44916269Smckusick 		idesc->id_fix = FIX;
45016269Smckusick 		return (ALTERED);
45116269Smckusick 
45216269Smckusick 	case FIX:
45316269Smckusick 		return (ALTERED);
45416269Smckusick 
45516269Smckusick 	case NOFIX:
45616269Smckusick 		return (0);
45716269Smckusick 
45816269Smckusick 	default:
45916269Smckusick 		errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix);
46016269Smckusick 	}
46116269Smckusick 	/* NOTREACHED */
46216269Smckusick }
46316269Smckusick 
46416269Smckusick /* VARARGS1 */
46517931Smckusick errexit(s1, s2, s3, s4)
46616269Smckusick 	char *s1;
46716269Smckusick {
46816269Smckusick 	printf(s1, s2, s3, s4);
46916269Smckusick 	exit(8);
47016269Smckusick }
47116269Smckusick 
47216269Smckusick /*
47339973Smckusick  * An unexpected inconsistency occured.
47439973Smckusick  * Die if preening, otherwise just print message and continue.
47516269Smckusick  */
47616269Smckusick /* VARARGS1 */
47716269Smckusick pfatal(s, a1, a2, a3)
47816269Smckusick 	char *s;
47916269Smckusick {
48016269Smckusick 
48116269Smckusick 	if (preen) {
48216269Smckusick 		printf("%s: ", devname);
48316269Smckusick 		printf(s, a1, a2, a3);
48416269Smckusick 		printf("\n");
48517931Smckusick 		printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n",
48617931Smckusick 			devname);
48717931Smckusick 		exit(8);
48816269Smckusick 	}
48916269Smckusick 	printf(s, a1, a2, a3);
49016269Smckusick }
49116269Smckusick 
49216269Smckusick /*
49339973Smckusick  * Pwarn just prints a message when not preening,
49416269Smckusick  * or a warning (preceded by filename) when preening.
49516269Smckusick  */
49616269Smckusick /* VARARGS1 */
49716269Smckusick pwarn(s, a1, a2, a3, a4, a5, a6)
49816269Smckusick 	char *s;
49916269Smckusick {
50016269Smckusick 
50116269Smckusick 	if (preen)
50216269Smckusick 		printf("%s: ", devname);
50316269Smckusick 	printf(s, a1, a2, a3, a4, a5, a6);
50416269Smckusick }
50516269Smckusick 
50616269Smckusick #ifndef lint
50716269Smckusick /*
50816269Smckusick  * Stub for routines from kernel.
50916269Smckusick  */
51016269Smckusick panic(s)
51116269Smckusick 	char *s;
51216269Smckusick {
51316269Smckusick 
51417931Smckusick 	pfatal("INTERNAL INCONSISTENCY:");
51517931Smckusick 	errexit(s);
51616269Smckusick }
51716269Smckusick #endif
518