Subject: Re: fsck problems
To: Juergen Keil <jk@tools.de>
From: Alan Barrett <barrett@daisy.ee.und.ac.za>
List: current-users
Date: 07/28/1994 00:23:32
Juergen Keil wrote:
> 1. On a filesystem using the old inode format, fsck always
>    generates new directory entries (i.e. in lost+found) in the
>    new directory record format!

I thought the byte-swapping code looked error prone.  I haven't examined
the code closely enough to tell how well this would work out in
practice, but I wondered why the BYTE_ORDER tests were not put in the
definition of struct direct in <ufs/ufs/direct.h>, rather than scattered
around the kernel and various utilities.

> I suggest the following patch, which should fix both problems.

Thanks!  I rearranged your patch slightly and integrated it into my test
version of fsck.  It cleaned up my disk almost perfectly, leaving only
one bad directory entry in lost+found, which I was able to zap with
clri.  I think that the one entry that the new fsck couldn't fix
was one that had been created in a corrupted state by the bad fsck.

I append my patch, which incorporates everything from Juergen (in a slightly
rearranged form), as well as my fixes to reduce the number of compiler
warnings.

--apb (Alan Barrett)

diff -r -u3 fsck/Makefile TEST-fsck/Makefile
--- fsck/Makefile	Thu Jun 30 12:31:26 1994
+++ TEST-fsck/Makefile	Wed Jul 27 09:21:44 1994
@@ -1,6 +1,7 @@
 #	from: @(#)Makefile	8.1 (Berkeley) 6/5/93
 #	$Id: Makefile,v 1.8 1994/06/30 05:33:33 cgd Exp $
 
+CFLAGS=	-g -ansi -pedantic -Wall -Wtraditional -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wconversion -Wredundant-decls
 PROG=	fsck
 MAN8=	fsck.0
 SRCS=	dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
diff -r -u3 fsck/dir.c TEST-fsck/dir.c
--- fsck/dir.c	Thu Jun  9 12:10:22 1994
+++ TEST-fsck/dir.c	Wed Jul 27 23:49:20 1994
@@ -41,6 +41,7 @@
 #include <ufs/ufs/dinode.h>
 #include <ufs/ufs/dir.h>
 #include <ufs/ffs/fs.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "fsck.h"
@@ -63,6 +64,7 @@
 /*
  * Propagate connected state through the tree.
  */
+void
 propagate()
 {
 	register struct inoinfo **inpp, *inp;
@@ -88,6 +90,7 @@
 /*
  * Scan each entry in a directory block.
  */
+int
 dirscan(idesc)
 	register struct inodesc *idesc;
 {
@@ -110,6 +113,9 @@
 	idesc->id_loc = 0;
 	for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
 		dsize = dp->d_reclen;
+		/* XXX there is a problem here if (dsize > DIRBLKSIZE)
+		 * but we should be able to rely on fsck_readdir() having
+		 * sanitised it already. */
 		bcopy((char *)dp, dbuf, (size_t)dsize);
 #		if (BYTE_ORDER == LITTLE_ENDIAN)
 			if (!newinofmt) {
@@ -156,6 +162,7 @@
 	register struct direct *dp, *ndp;
 	register struct bufarea *bp;
 	long size, blksiz, fix, dploc;
+	long old_reclen;
 
 	blksiz = idesc->id_numfrags * sblock.fs_fsize;
 	bp = getdirblk(idesc->id_blkno, blksiz);
@@ -193,10 +200,11 @@
 		size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
 		idesc->id_loc += size;
 		idesc->id_filesize -= size;
+		old_reclen = dp->d_reclen; /* dofix() might change d_reclen */
 		fix = dofix(idesc, "DIRECTORY CORRUPTED");
 		bp = getdirblk(idesc->id_blkno, blksiz);
 		dp = (struct direct *)(bp->b_un.b_buf + dploc);
-		dp->d_reclen += size;
+		dp->d_reclen = old_reclen + size;
 		if (fix)
 			dirty(bp);
 	}
@@ -207,6 +215,7 @@
  * Verify that a directory entry is valid.
  * This is a superset of the checks made in the kernel.
  */
+int
 dircheck(idesc, dp)
 	struct inodesc *idesc;
 	register struct direct *dp;
@@ -249,6 +258,7 @@
 	return (0);
 }
 
+void
 direrror(ino, errmesg)
 	ino_t ino;
 	char *errmesg;
@@ -257,6 +267,7 @@
 	fileerror(ino, ino, errmesg);
 }
 
+void
 fileerror(cwd, ino, errmesg)
 	ino_t cwd, ino;
 	char *errmesg;
@@ -280,6 +291,7 @@
 		pfatal("NAME=%s\n", pathbuf);
 }
 
+void
 adjust(idesc, lcnt)
 	register struct inodesc *idesc;
 	short lcnt;
@@ -310,6 +322,7 @@
 	}
 }
 
+int
 mkentry(idesc)
 	struct inodesc *idesc;
 {
@@ -336,15 +349,29 @@
 	dirp->d_reclen = newent.d_reclen;
 	dirp->d_namlen = newent.d_namlen;
 	bcopy(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
+	/* 
+	 * 'dirscan' will eventually swap the original dirp back to the
+	 * old inode format.  Handle the new dirent here.
+	 */
+#	if (BYTE_ORDER == LITTLE_ENDIAN)
+		if (!newinofmt) {
+			u_char tmp;
+
+			tmp = dirp->d_namlen;
+			dirp->d_namlen = dirp->d_type;
+			dirp->d_type = tmp;
+		}
+#	endif
 	return (ALTERED|STOP);
 }
 
+int
 chgino(idesc)
 	struct inodesc *idesc;
 {
 	register struct direct *dirp = idesc->id_dirp;
 
-	if (bcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1))
+	if (bcmp(dirp->d_name, idesc->id_name, (size_t)dirp->d_namlen + 1))
 		return (KEEPON);
 	dirp->d_ino = idesc->id_parent;
 	if (newinofmt)
@@ -354,6 +381,7 @@
 	return (ALTERED|STOP);
 }
 
+int
 linkup(orphan, parentdir)
 	ino_t orphan;
 	ino_t parentdir;
@@ -461,6 +489,7 @@
 /*
  * fix an entry in a directory.
  */
+int
 changeino(dir, name, newnum)
 	ino_t dir;
 	char *name;
@@ -481,6 +510,7 @@
 /*
  * make an entry in a directory
  */
+int
 makeentry(parent, ino, name)
 	ino_t parent, ino;
 	char *name;
@@ -516,6 +546,7 @@
 /*
  * Attempt to expand the size of a directory
  */
+int
 expanddir(dp, name)
 	register struct dinode *dp;
 	char *name;
@@ -572,6 +603,7 @@
 /*
  * allocate a new directory
  */
+int
 allocdir(parent, request, mode)
 	ino_t parent, request;
 	int mode;
@@ -627,6 +659,7 @@
 /*
  * free a directory inode
  */
+void
 freedir(ino, parent)
 	ino_t ino, parent;
 {
@@ -643,6 +676,7 @@
 /*
  * generate a temporary name for the lost+found directory.
  */
+int
 lftempname(bufp, ino)
 	char *bufp;
 	ino_t ino;
diff -r -u3 fsck/fsck.h TEST-fsck/fsck.h
--- fsck/fsck.h	Thu Jun  9 12:10:23 1994
+++ TEST-fsck/fsck.h	Thu Jul 28 00:06:44 1994
@@ -214,3 +214,68 @@
 void getblk();
 ino_t allocino();
 int findino();
+
+void addpart();
+void adjust();
+int allocblk();
+int allocdir();
+int argtoi();
+void badsb();
+void blkerror();
+int bread();
+void bufinit();
+void bwrite();
+void cacheino();
+int calcsb();
+int changeino();
+int checkfstab();
+void checkinode();
+int chkrange();
+void ckfini();
+int ckinode();
+void clri();
+int dircheck();
+void direrror();
+int dirscan();
+int dofix();
+int expanddir();
+int ffs_fragacct();
+void fileerror();
+void flush();
+void freeblk();
+void freedir();
+void freeino();
+void freeinodebuf();
+int ftypeok();
+void getpathname();
+int iblock();
+void inocleanup();
+void inodirty();
+int lftempname();
+int linkup();
+int makeentry();
+void panic();
+void pass1();
+void pass1b();
+void pass2();
+void pass3();
+void pass4();
+int pass4check();
+void pass5();
+void pinode();
+void propagate();
+int readsb();
+int reply();
+void resetinodebuf();
+int setup();
+int startdisk();
+
+#if __STDC__
+void errexit(const char*, ...);
+void pfatal(const char*, ...);
+void pwarn(const char*, ...);
+#else
+void errexit();
+void pfatal();
+void pwarn();
+#endif
diff -r -u3 fsck/inode.c TEST-fsck/inode.c
--- fsck/inode.c	Wed Jun 15 12:21:35 1994
+++ TEST-fsck/inode.c	Mon Jul 25 18:16:42 1994
@@ -44,12 +44,14 @@
 #ifndef SMALL
 #include <pwd.h>
 #endif
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "fsck.h"
 
 static ino_t startinum;
 
+int
 ckinode(dp, idesc)
 	struct dinode *dp;
 	register struct inodesc *idesc;
@@ -103,6 +105,7 @@
 	return (KEEPON);
 }
 
+int
 iblock(idesc, ilevel, isize)
 	struct inodesc *idesc;
 	long ilevel;
@@ -168,6 +171,7 @@
  * Check that a block in a legal block number.
  * Return 0 if in range, 1 if out of range.
  */
+int
 chkrange(blk, cnt)
 	daddr_t blk;
 	int cnt;
@@ -257,6 +261,7 @@
 	return (dp++);
 }
 
+void
 resetinodebuf()
 {
 
@@ -282,6 +287,7 @@
 		(void)getnextinode(nextino);
 }
 
+void
 freeinodebuf()
 {
 
@@ -297,6 +303,7 @@
  *
  * Enter inodes into the cache.
  */
+void
 cacheino(dp, inumber)
 	register struct dinode *dp;
 	ino_t inumber;
@@ -353,6 +360,7 @@
 /*
  * Clean up all the inode cache structure.
  */
+void
 inocleanup()
 {
 	register struct inoinfo **inpp;
@@ -366,12 +374,14 @@
 	inphead = inpsort = NULL;
 }
 	
+void
 inodirty()
 {
 	
 	dirty(pbp);
 }
 
+void
 clri(idesc, type, flag)
 	register struct inodesc *idesc;
 	char *type;
@@ -396,6 +406,7 @@
 	}
 }
 
+int
 findname(idesc)
 	struct inodesc *idesc;
 {
@@ -407,6 +418,7 @@
 	return (STOP|FOUND);
 }
 
+int
 findino(idesc)
 	struct inodesc *idesc;
 {
@@ -422,6 +434,7 @@
 	return (KEEPON);
 }
 
+void
 pinode(ino)
 	ino_t ino;
 {
@@ -436,7 +449,7 @@
 	dp = ginode(ino);
 	printf(" OWNER=");
 #ifndef SMALL
-	if ((pw = getpwuid((int)dp->di_uid)) != 0)
+	if ((pw = getpwuid((uid_t)dp->di_uid)) != 0)
 		printf("%s ", pw->pw_name);
 	else
 #endif
@@ -449,6 +462,7 @@
 	printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
 }
 
+void
 blkerror(ino, type, blk)
 	ino_t ino;
 	char *type;
@@ -529,6 +543,7 @@
 /*
  * deallocate an inode
  */
+void
 freeino(ino)
 	ino_t ino;
 {
diff -r -u3 fsck/main.c TEST-fsck/main.c
--- fsck/main.c	Thu Jun  9 12:10:24 1994
+++ TEST-fsck/main.c	Mon Jul 25 17:19:01 1994
@@ -57,6 +57,7 @@
 void	catch(), catchquit(), voidquit();
 int	returntosingle;
 
+int
 main(argc, argv)
 	int	argc;
 	char	*argv[];
@@ -131,6 +132,7 @@
 	exit(ret);
 }
 
+int
 argtoi(flag, req, str, base)
 	int flag;
 	char *req, *str;
@@ -148,6 +150,7 @@
 /*
  * Determine whether a filesystem should be checked.
  */
+int
 docheck(fsp)
 	register struct fstab *fsp;
 {
@@ -164,9 +167,11 @@
  * Check the specified filesystem.
  */
 /* ARGSUSED */
+int
 checkfilesys(filesys, mntpt, auxdata, child)
 	char *filesys, *mntpt;
 	long auxdata;
+	int child;
 {
 	daddr_t n_ffree, n_bfree;
 	struct dups *dp;
diff -r -u3 fsck/pass1.c TEST-fsck/pass1.c
--- fsck/pass1.c	Thu Jun 30 12:31:26 1994
+++ TEST-fsck/pass1.c	Mon Jul 25 17:29:07 1994
@@ -41,6 +41,7 @@
 #include <ufs/ufs/dinode.h>
 #include <ufs/ufs/dir.h>
 #include <ufs/ffs/fs.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "fsck.h"
@@ -50,6 +51,7 @@
 int pass1check();
 struct dinode *getnextinode();
 
+void
 pass1()
 {
 	ino_t inumber;
@@ -88,6 +90,7 @@
 	freeinodebuf();
 }
 
+void
 checkinode(inumber, idesc)
 	ino_t inumber;
 	register struct inodesc *idesc;
@@ -149,7 +152,7 @@
 		if (doinglevel2 &&
 		    dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN &&
 		    dp->di_blocks != 0) {
-			symbuf = alloca(secsize);
+			symbuf = alloca((size_t)secsize);
 			if (bread(fsreadfd, symbuf,
 			    fsbtodb(&sblock, dp->di_db[0]),
 			    (long)secsize) != 0)
@@ -161,7 +164,7 @@
 			}
 			dp = ginode(inumber);
 			bcopy(symbuf, (caddr_t)dp->di_shortlink,
-			    (long)dp->di_size);
+			    (size_t)dp->di_size);
 			dp->di_blocks = 0;
 			inodirty();
 		}
@@ -256,6 +259,7 @@
 	}
 }
 
+int
 pass1check(idesc)
 	register struct inodesc *idesc;
 {
diff -r -u3 fsck/pass1b.c TEST-fsck/pass1b.c
--- fsck/pass1b.c	Thu Jun  9 12:10:24 1994
+++ TEST-fsck/pass1b.c	Mon Jul 25 17:04:58 1994
@@ -46,6 +46,7 @@
 int	pass1bcheck();
 static  struct dups *duphead;
 
+void
 pass1b()
 {
 	register int c, i;
@@ -73,6 +74,7 @@
 	}
 }
 
+int
 pass1bcheck(idesc)
 	register struct inodesc *idesc;
 {
diff -r -u3 fsck/pass2.c TEST-fsck/pass2.c
--- fsck/pass2.c	Thu Jun  9 12:10:25 1994
+++ TEST-fsck/pass2.c	Mon Jul 25 17:29:50 1994
@@ -41,6 +41,7 @@
 #include <ufs/ufs/dinode.h>
 #include <ufs/ufs/dir.h>
 #include <ufs/ffs/fs.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "fsck.h"
@@ -49,6 +50,7 @@
 
 int	pass2check(), blksort();
 
+void
 pass2()
 {
 	register struct dinode *dp;
@@ -190,6 +192,7 @@
 	propagate();
 }
 
+int
 pass2check(idesc)
 	struct inodesc *idesc;
 {
@@ -423,6 +426,7 @@
 /*
  * Routine to sort disk blocks.
  */
+int
 blksort(inpp1, inpp2)
 	struct inoinfo **inpp1, **inpp2;
 {
diff -r -u3 fsck/pass3.c TEST-fsck/pass3.c
--- fsck/pass3.c	Thu Jun  9 12:10:25 1994
+++ TEST-fsck/pass3.c	Mon Jul 25 17:05:38 1994
@@ -42,6 +42,7 @@
 #include <ufs/ffs/fs.h>
 #include "fsck.h"
 
+void
 pass3()
 {
 	register struct inoinfo **inpp, *inp;
diff -r -u3 fsck/pass4.c TEST-fsck/pass4.c
--- fsck/pass4.c	Thu Jun  9 12:10:25 1994
+++ TEST-fsck/pass4.c	Mon Jul 25 17:05:50 1994
@@ -46,6 +46,7 @@
 
 int	pass4check();
 
+void
 pass4()
 {
 	register ino_t inumber;
@@ -104,6 +105,7 @@
 	}
 }
 
+int
 pass4check(idesc)
 	register struct inodesc *idesc;
 {
diff -r -u3 fsck/pass5.c TEST-fsck/pass5.c
--- fsck/pass5.c	Thu Jun  9 12:10:26 1994
+++ TEST-fsck/pass5.c	Mon Jul 25 17:32:17 1994
@@ -43,6 +43,7 @@
 #include <string.h>
 #include "fsck.h"
 
+void
 pass5()
 {
 	int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
@@ -292,15 +293,15 @@
 			continue;
 		}
 		if (bcmp(cg_inosused(newcg),
-			 cg_inosused(cg), mapsize) != 0 &&
+			 cg_inosused(cg), (size_t)mapsize) != 0 &&
 		    dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
 			bcopy(cg_inosused(newcg), cg_inosused(cg),
 			      (size_t)mapsize);
 			cgdirty();
 		}
-		if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 ||
+		if ((bcmp((char *)newcg, (char *)cg, (size_t)basesize) != 0 ||
 		     bcmp((char *)&cg_blktot(newcg)[0],
-			  (char *)&cg_blktot(cg)[0], sumsize) != 0) &&
+			  (char *)&cg_blktot(cg)[0], (size_t)sumsize) != 0) &&
 		    dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
 			bcopy((char *)newcg, (char *)cg, (size_t)basesize);
 			bcopy((char *)&cg_blktot(newcg)[0],
diff -r -u3 fsck/preen.c TEST-fsck/preen.c
--- fsck/preen.c	Thu Jun  9 12:10:26 1994
+++ TEST-fsck/preen.c	Mon Jul 25 18:13:21 1994
@@ -39,13 +39,17 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
+#include <sys/types.h>
 #include <fstab.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <ctype.h>
 
 char	*rawname(), *unrawname(), *blockcheck();
+void	addpart();
+int	checkfstab(), startdisk();
 
 struct part {
 	struct	part *next;		/* forward link of partitions on disk */
@@ -64,8 +68,9 @@
 int	nrun, ndisks;
 char	hotroot;
 
-checkfstab(preen, maxrun, docheck, chkit)
-	int preen, maxrun;
+int
+checkfstab(dopreen, maxrun, docheck, chkit)
+	int dopreen, maxrun;
 	int (*docheck)(), (*chkit)();
 {
 	register struct fstab *fsp;
@@ -85,12 +90,12 @@
 		while ((fsp = getfsent()) != 0) {
 			if ((auxdata = (*docheck)(fsp)) == 0)
 				continue;
-			if (preen == 0 || passno == 1 && fsp->fs_passno == 1) {
+			if (dopreen == 0 || passno == 1 && fsp->fs_passno == 1) {
 				if (name = blockcheck(fsp->fs_spec)) {
 					if (sumstatus = (*chkit)(name,
 					    fsp->fs_file, auxdata, 0))
 						return (sumstatus);
-				} else if (preen)
+				} else if (dopreen)
 					return (8);
 			} else if (passno == 2 && fsp->fs_passno > 1) {
 				if ((name = blockcheck(fsp->fs_spec)) == NULL) {
@@ -102,10 +107,10 @@
 				addpart(name, fsp->fs_file, auxdata);
 			}
 		}
-		if (preen == 0)
+		if (dopreen == 0)
 			return (0);
 	}
-	if (preen) {
+	if (dopreen) {
 		if (maxrun == 0)
 			maxrun = ndisks;
 		if (maxrun > ndisks)
@@ -226,6 +231,7 @@
 	return (dk);
 }
 
+void
 addpart(name, fsname, auxdata)
 	char *name, *fsname;
 	long auxdata;
@@ -257,6 +263,7 @@
 	pt->auxdata = auxdata;
 }
 
+int
 startdisk(dk, checkit)
 	register struct disk *dk;
 	int (*checkit)();
diff -r -u3 fsck/setup.c TEST-fsck/setup.c
--- fsck/setup.c	Thu Jun 30 12:31:27 1994
+++ TEST-fsck/setup.c	Mon Jul 25 17:38:10 1994
@@ -46,6 +46,7 @@
 #include <sys/disklabel.h>
 #include <sys/file.h>
 #include <errno.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
@@ -57,6 +58,7 @@
 
 struct	disklabel *getdisklabel();
 
+int
 setup(dev)
 	char *dev;
 {
@@ -296,6 +298,7 @@
 /*
  * Read in the super block and its summary info.
  */
+int
 readsb(listerr)
 	int listerr;
 {
@@ -370,7 +373,7 @@
 	altsblock.fs_qfmask = sblock.fs_qfmask;
 	altsblock.fs_state = sblock.fs_state;
 	altsblock.fs_maxfilesize = sblock.fs_maxfilesize;
-	if (bcmp((char *)&sblock, (char *)&altsblock, (int)sblock.fs_sbsize)) {
+	if (bcmp((char *)&sblock, (char *)&altsblock, (size_t)sblock.fs_sbsize)) {
 		badsb(listerr,
 		"VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
 		return (0);
@@ -379,6 +382,7 @@
 	return (1);
 }
 
+void
 badsb(listerr, s)
 	int listerr;
 	char *s;
@@ -397,6 +401,7 @@
  * can be used. Do NOT attempt to use other macros without verifying that
  * their needed information is available!
  */
+int
 calcsb(dev, devfd, fs)
 	char *dev;
 	int devfd;
diff -r -u3 fsck/utilities.c TEST-fsck/utilities.c
--- fsck/utilities.c	Thu Jun  9 12:10:28 1994
+++ TEST-fsck/utilities.c	Thu Jul 28 00:02:49 1994
@@ -47,8 +47,15 @@
 #include <ctype.h>
 #include "fsck.h"
 
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
 long	diskreads, totalreads;	/* Disk cache statistics */
 
+int
 ftypeok(dp)
 	struct dinode *dp;
 {
@@ -70,6 +77,7 @@
 	}
 }
 
+int
 reply(question)
 	char *question;
 {
@@ -105,6 +113,7 @@
 /*
  * Malloc buffers and set up cache.
  */
+void
 bufinit()
 {
 	register struct bufarea *bp;
@@ -189,6 +198,7 @@
 	}
 }
 
+void
 flush(fd, bp)
 	int fd;
 	register struct bufarea *bp;
@@ -214,6 +224,7 @@
 	}
 }
 
+void
 rwerror(mesg, blk)
 	char *mesg;
 	daddr_t blk;
@@ -226,6 +237,7 @@
 		errexit("Program terminated\n");
 }
 
+void
 ckfini()
 {
 	register struct bufarea *bp, *nbp;
@@ -261,6 +273,7 @@
 	(void)close(fswritefd);
 }
 
+int
 bread(fd, buf, blk, size)
 	int fd;
 	char *buf;
@@ -299,6 +312,7 @@
 	return (errs);
 }
 
+void
 bwrite(fd, buf, blk, size)
 	int fd;
 	char *buf;
@@ -335,6 +349,7 @@
 /*
  * allocate a data block with the specified number of fragments
  */
+int
 allocblk(frags)
 	long frags;
 {
@@ -365,6 +380,7 @@
 /*
  * Free a previously allocated block
  */
+void
 freeblk(blkno, frags)
 	daddr_t blkno;
 	long frags;
@@ -379,6 +395,7 @@
 /*
  * Find a pathname
  */
+void
 getpathname(namebuf, curdir, ino)
 	char *namebuf;
 	ino_t curdir, ino;
@@ -474,6 +491,7 @@
 /*
  * determine whether an inode should be fixed.
  */
+int
 dofix(idesc, msg)
 	register struct inodesc *idesc;
 	char *msg;
@@ -512,10 +530,24 @@
 }
 
 /* VARARGS1 */
-errexit(s1, s2, s3, s4)
-	char *s1;
-{
-	printf(s1, s2, s3, s4);
+void
+#if __STDC__
+errexit(const char *fmt, ...)
+#else
+errexit(fmt, va_alist)
+	char *fmt;
+	va_dcl
+#endif
+{
+	va_list ap;
+
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	vprintf(fmt, ap);
+	va_end(ap);
 	exit(8);
 }
 
@@ -524,19 +556,34 @@
  * Die if preening, otherwise just print message and continue.
  */
 /* VARARGS1 */
-pfatal(s, a1, a2, a3)
-	char *s;
-{
+void
+#if __STDC__
+pfatal(const char *fmt, ...)
+#else
+pfatal(fmt, va_alist)
+	char *fmt;
+	va_dcl
+#endif
+{
+	va_list ap;
+
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
 
 	if (preen) {
 		printf("%s: ", cdevname);
-		printf(s, a1, a2, a3);
+		vprintf(fmt, ap);
 		printf("\n");
 		printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n",
 			cdevname);
+		va_end(ap);
 		exit(8);
 	}
-	printf(s, a1, a2, a3);
+	vprintf(fmt, ap);
+	va_end(ap);
 }
 
 /*
@@ -544,19 +591,34 @@
  * or a warning (preceded by filename) when preening.
  */
 /* VARARGS1 */
-pwarn(s, a1, a2, a3, a4, a5, a6)
-	char *s;
-{
+void
+#if __STDC__
+pwarn(const char *fmt, ...)
+#else
+pwarn(fmt, va_alist)
+	char *fmt;
+	va_dcl
+#endif
+{
+	va_list ap;
+
+#if __STDC__
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
 
 	if (preen)
 		printf("%s: ", cdevname);
-	printf(s, a1, a2, a3, a4, a5, a6);
+	vprintf(fmt, ap);
+	va_end(ap);
 }
 
 #ifndef lint
 /*
  * Stub for routines from kernel.
  */
+void
 panic(s)
 	char *s;
 {

------------------------------------------------------------------------------