bin/139802: sbin/fsck_msdosfs: sync with NetBSD sources, increasing WARNS

Ulrich Spoerlein uqs at spoerlein.net
Tue Oct 20 19:10:02 UTC 2009


>Number:         139802
>Category:       bin
>Synopsis:       sbin/fsck_msdosfs: sync with NetBSD sources, increasing WARNS
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 20 19:10:01 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     Ulrich Spoerlein
>Release:        FreeBSD 7.2-STABLE i386
>Organization:
>Environment:
	
>Description:
NetBSD managed to squash some compiler warnings, so we can increase WARNS to
3 after this sync. They also changed to a 2-clause BSD license. Not sure if
we can follow, but I would strongly encourage this.

If we had perr() in fsutil.h, better error output could be brought
over from NetBSD as well ...

>How-To-Repeat:
	
>Fix:
	

--- fsck_msdosfs.diff begins here ---

diff -r 41230069d22f -r 6a5580020f7b sbin/fsck_msdosfs/Makefile
--- a/sbin/fsck_msdosfs/Makefile	Mon Oct 19 17:27:04 2009 +0200
+++ b/sbin/fsck_msdosfs/Makefile	Mon Oct 19 18:30:28 2009 +0200
@@ -8,7 +8,7 @@
 MAN=	fsck_msdosfs.8
 SRCS=	main.c check.c boot.c fat.c dir.c fsutil.c
 
+WARNS?=	3
 CFLAGS+= -I${FSCK}
-WARNS?=	0
 
 .include <bsd.prog.mk>
diff -r 41230069d22f -r 6a5580020f7b sbin/fsck_msdosfs/boot.c
--- a/sbin/fsck_msdosfs/boot.c	Mon Oct 19 17:27:04 2009 +0200
+++ b/sbin/fsck_msdosfs/boot.c	Mon Oct 19 18:30:28 2009 +0200
@@ -10,13 +10,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by Martin Husemann
- *	and Wolfgang Solfrank.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -33,7 +26,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: boot.c,v 1.9 2003/07/24 19:25:46 ws Exp $");
+__RCSID("$NetBSD: boot.c,v 1.15 2009/04/11 07:14:50 lukem Exp $");
 static const char rcsid[] =
   "$FreeBSD$";
 #endif /* not lint */
@@ -48,16 +41,15 @@
 #include "fsutil.h"
 
 int
-readboot(dosfs, boot)
-	int dosfs;
-	struct bootblock *boot;
+readboot(int dosfs, struct bootblock *boot)
 {
 	u_char block[DOSBOOTBLOCKSIZE];
 	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
 	u_char backup[DOSBOOTBLOCKSIZE];
 	int ret = FSOK;
+	int i;
 	
-	if (read(dosfs, block, sizeof block) < sizeof block) {
+	if ((size_t)read(dosfs, block, sizeof block) != sizeof block) {
 		perror("could not read boot block");
 		return FSFATAL;
 	}
@@ -161,12 +153,22 @@
 		}
 		backup[65] = block[65];				/* XXX */
 		if (memcmp(block + 11, backup + 11, 79)) {
-			/* Correct?					XXX */
-			pfatal("backup doesn't compare to primary bootblock");
-			if (alwaysno)
-				pfatal("\n");
-			else
-				return FSFATAL;
+			/*
+			 * XXX We require a reference that explains
+			 * that these bytes need to match, or should
+			 * drop the check.  gdt@ has observed
+			 * filesystems that work fine under Windows XP
+			 * and NetBSD that do not match, so the
+			 * requirement is suspect.  For now, just
+			 * print out useful information and continue.
+			 */
+			pfatal("backup (block %d) mismatch with primary bootblock:\n",
+			        boot->Backup);
+			for (i = 11; i < 11 + 90; i++) {
+				if (block[i] != backup[i])
+					pfatal("\ti=%d\tprimary 0x%02x\tbackup 0x%02x\n",
+					       i, block[i], backup[i]);
+			}
 		}
 		/* Check backup FSInfo?					XXX */
 	}
@@ -230,9 +232,7 @@
 }
 
 int
-writefsinfo(dosfs, boot)
-	int dosfs;
-	struct bootblock *boot;
+writefsinfo(int dosfs, struct bootblock *boot)
 {
 	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
 
diff -r 41230069d22f -r 6a5580020f7b sbin/fsck_msdosfs/check.c
--- a/sbin/fsck_msdosfs/check.c	Mon Oct 19 17:27:04 2009 +0200
+++ b/sbin/fsck_msdosfs/check.c	Mon Oct 19 18:30:28 2009 +0200
@@ -10,13 +10,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by Martin Husemann
- *	and Wolfgang Solfrank.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -33,7 +26,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: check.c,v 1.10 2000/04/25 23:02:51 jdolecek Exp $");
+__RCSID("$NetBSD: check.c,v 1.18 2009/04/11 07:14:50 lukem Exp $");
 static const char rcsid[] =
   "$FreeBSD$";
 #endif /* not lint */
@@ -54,7 +47,8 @@
 	int dosfs;
 	struct bootblock boot;
 	struct fatEntry *fat = NULL;
-	int i, finish_dosdirsection=0;
+	int finish_dosdirsection=0;
+	u_int i;
 	int mod = 0;
 	int ret = 8;
 
@@ -105,7 +99,7 @@
 	}
 
 	if (boot.ValidFat < 0)
-		for (i = 1; i < (int)boot.FATs; i++) {
+		for (i = 1; i < boot.FATs; i++) {
 			struct fatEntry *currentFat;
 
 			mod |= readfat(dosfs, &boot, i, &currentFat);
diff -r 41230069d22f -r 6a5580020f7b sbin/fsck_msdosfs/dir.c
--- a/sbin/fsck_msdosfs/dir.c	Mon Oct 19 17:27:04 2009 +0200
+++ b/sbin/fsck_msdosfs/dir.c	Mon Oct 19 18:30:28 2009 +0200
@@ -12,13 +12,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by Martin Husemann
- *	and Wolfgang Solfrank.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -35,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: dir.c,v 1.14 1998/08/25 19:18:15 ross Exp $");
+__RCSID("$NetBSD: dir.c,v 1.23 2009/04/11 07:14:50 lukem Exp $");
 static const char rcsid[] =
   "$FreeBSD$";
 #endif /* not lint */
@@ -46,6 +39,7 @@
 #include <ctype.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <assert.h>
 #include <time.h>
 
 #include <sys/param.h>
@@ -226,16 +220,29 @@
 	int b1, b2;
 	cl_t cl;
 	int ret = FSOK;
+	size_t len;
 
 	b1 = boot->RootDirEnts * 32;
 	b2 = boot->SecPerClust * boot->BytesPerSec;
 
-	if (!(buffer = malloc(b1 > b2 ? b1 : b2))
-	    || !(delbuf = malloc(b2))
-	    || !(rootDir = newDosDirEntry())) {
-		perror("No space for directory");
+	if ((buffer = malloc(len = b1 > b2 ? b1 : b2)) == NULL) {
+		perror("No space for directory buffer");
 		return FSFATAL;
 	}
+
+	if ((delbuf = malloc(len = b2)) == NULL) {
+		free(buffer);
+		perror("No space for directory delbuf");
+		return FSFATAL;
+	}
+
+	if ((rootDir = newDosDirEntry()) == NULL) {
+		free(buffer);
+		free(delbuf);
+		perror("No space for directory entry");
+		return FSFATAL;
+	}
+
 	memset(rootDir, 0, sizeof *rootDir);
 	if (boot->flags & FAT32) {
 		if (boot->RootCl < CLUST_FIRST || boot->RootCl >= boot->NumClusters) {
@@ -367,7 +374,8 @@
 				return FSFATAL;
 			start = buffer;
 		}
-		if (endcl == curcl)
+		/* startcl is < CLUST_FIRST for !fat32 root */
+		if ((endcl == curcl) || (startcl < CLUST_FIRST))
 			for (; start < end; start += 32)
 				*start = SLOT_DELETED;
 		return FSDIRMOD;
@@ -385,7 +393,7 @@
 	/*
 	 * Check size on ordinary files
 	 */
-	int32_t physicalSize;
+	u_int32_t physicalSize;
 
 	if (dir->head == CLUST_FREE)
 		physicalSize = 0;
@@ -501,6 +509,7 @@
 							   cl, p - buffer, 1) == FSFATAL)
 							return FSFATAL;
 						q = empcl == cl ? empty : buffer;
+						assert(q != NULL);
 						for (; q < p; q += 32)
 							*q = SLOT_DELETED;
 						mod |= THISMOD|FSDIRMOD;
@@ -644,7 +653,8 @@
 				dirent.head |= (p[20] << 16) | (p[21] << 24);
 			dirent.size = p[28] | (p[29] << 8) | (p[30] << 16) | (p[31] << 24);
 			if (vallfn) {
-				strcpy(dirent.lname, longName);
+				strlcpy(dirent.lname, longName,
+				    sizeof(dirent.lname));
 				longName[0] = '\0';
 				shortSum = -1;
 			}
@@ -832,6 +842,10 @@
 			}
 			boot->NumFiles++;
 		}
+
+		if (!(boot->flags & FAT32) && !dir->parent)
+			break;
+
 		if (mod & THISMOD) {
 			last *= 32;
 			if (lseek(f, off, SEEK_SET) != off
@@ -847,6 +861,19 @@
 				invlfn ? invlfn : vallfn, p,
 				invlfn ? invcl : valcl, -1, 0,
 				fullpath(dir), 1);
+
+	/* The root directory of non fat32 filesystems is in a special
+	 * area and may have been modified above without being written out.
+	 */
+	if ((mod & FSDIRMOD) && !(boot->flags & FAT32) && !dir->parent) {
+		last *= 32;
+		if (lseek(f, off, SEEK_SET) != off
+		    || write(f, buffer, last) != last) {
+			perror("Unable to write directory");
+			return FSFATAL;
+		}
+		mod &= ~THISMOD;
+	}
 	return mod & ~THISMOD;
 }
 
@@ -936,7 +963,7 @@
 		lfoff = lfcl * boot->ClusterSize
 		    + boot->ClusterOffset * boot->BytesPerSec;
 		if (lseek(dosfs, lfoff, SEEK_SET) != lfoff
-		    || read(dosfs, lfbuf, boot->ClusterSize) != boot->ClusterSize) {
+		    || (size_t)read(dosfs, lfbuf, boot->ClusterSize) != boot->ClusterSize) {
 			perror("could not read LOST.DIR");
 			return FSFATAL;
 		}
@@ -966,7 +993,7 @@
 	p[31] = (u_char)(d.size >> 24);
 	fat[head].flags |= FAT_USED;
 	if (lseek(dosfs, lfoff, SEEK_SET) != lfoff
-	    || write(dosfs, lfbuf, boot->ClusterSize) != boot->ClusterSize) {
+	    || (size_t)write(dosfs, lfbuf, boot->ClusterSize) != boot->ClusterSize) {
 		perror("could not write LOST.DIR");
 		return FSFATAL;
 	}
diff -r 41230069d22f -r 6a5580020f7b sbin/fsck_msdosfs/dosfs.h
--- a/sbin/fsck_msdosfs/dosfs.h	Mon Oct 19 17:27:04 2009 +0200
+++ b/sbin/fsck_msdosfs/dosfs.h	Mon Oct 19 18:30:28 2009 +0200
@@ -2,7 +2,7 @@
  * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
  * Copyright (c) 1995 Martin Husemann
  * Some structure declaration borrowed from Paul Popelka
- * (paulp at uts.amdahl.com), see /sys/msdosfs/ for reference.
+ * (paulp at uts.amdahl.com), see sys/fs/msdosfs/ for reference.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -12,13 +12,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by Martin Husemann
- *	and Wolfgang Solfrank.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -30,7 +23,7 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *	$NetBSD: dosfs.h,v 1.4 1997/01/03 14:32:48 ws Exp $
+ *	$NetBSD: dosfs.h,v 1.6 2008/06/13 20:46:09 martin Exp $
  * $FreeBSD$
  */
 
diff -r 41230069d22f -r 6a5580020f7b sbin/fsck_msdosfs/ext.h
--- a/sbin/fsck_msdosfs/ext.h	Mon Oct 19 17:27:04 2009 +0200
+++ b/sbin/fsck_msdosfs/ext.h	Mon Oct 19 18:30:28 2009 +0200
@@ -10,13 +10,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by Martin Husemann
- *	and Wolfgang Solfrank.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -28,7 +21,7 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *	$NetBSD: ext.h,v 1.6 2000/04/25 23:02:51 jdolecek Exp $
+ *	$NetBSD: ext.h,v 1.13 2009/04/11 07:14:50 lukem Exp $
  * $FreeBSD$
  */
 
@@ -77,7 +70,7 @@
 #define	FSDIRMOD	2		/* Some directory was modified */
 #define	FSFATMOD	4		/* The FAT was modified */
 #define	FSERROR		8		/* Some unrecovered error remains */
-#define	FSFATAL		16		/* Some unrecoverable error occured */
+#define	FSFATAL		16		/* Some unrecoverable error occurred */
 #define FSDIRTY		32		/* File system is dirty */
 #define FSFIXFAT	64		/* Fix file system FAT */
 
@@ -96,13 +89,13 @@
  * Read one of the FAT copies and return a pointer to the new
  * allocated array holding our description of it.
  */
-int readfat(int, struct bootblock *, int, struct fatEntry **);
+int readfat(int, struct bootblock *, u_int, struct fatEntry **);
 
 /*
  * Check two FAT copies for consistency and merge changes into the
- * first if neccessary.
+ * first if necessary.
  */
-int comparefat(struct bootblock *, struct fatEntry *, struct fatEntry *, int);
+int comparefat(struct bootblock *, struct fatEntry *, struct fatEntry *, u_int);
 
 /*
  * Check a FAT
@@ -140,7 +133,7 @@
 /*
  * Return the type of a reserved cluster as text
  */
-char *rsrvdcltype(cl_t);
+const char *rsrvdcltype(cl_t);
 
 /*
  * Clear a cluster chain in a FAT
diff -r 41230069d22f -r 6a5580020f7b sbin/fsck_msdosfs/fat.c
--- a/sbin/fsck_msdosfs/fat.c	Mon Oct 19 17:27:04 2009 +0200
+++ b/sbin/fsck_msdosfs/fat.c	Mon Oct 19 18:30:28 2009 +0200
@@ -10,13 +10,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by Martin Husemann
- *	and Wolfgang Solfrank.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -33,7 +26,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: fat.c,v 1.12 2000/10/10 20:24:52 is Exp $");
+__RCSID("$NetBSD: fat.c,v 1.22 2009/04/11 07:14:50 lukem Exp $");
 static const char rcsid[] =
   "$FreeBSD$";
 #endif /* not lint */
@@ -47,10 +40,10 @@
 #include "ext.h"
 #include "fsutil.h"
 
-static int checkclnum(struct bootblock *, int, cl_t, cl_t *);
-static int clustdiffer(cl_t, cl_t *, cl_t *, int);
+static int checkclnum(struct bootblock *, u_int, cl_t, cl_t *);
+static int clustdiffer(cl_t, cl_t *, cl_t *, u_int);
 static int tryclear(struct bootblock *, struct fatEntry *, cl_t, cl_t *);
-static int _readfat(int, struct bootblock *, int, u_char **);
+static int _readfat(int, struct bootblock *, u_int, u_char **);
 
 /*-
  * The first 2 FAT entries contain pseudo-cluster numbers with the following
@@ -94,7 +87,7 @@
 		goto err;
 	}
 
-	if (read(fs, buffer, boot->BytesPerSec) != boot->BytesPerSec) {
+	if ((size_t)read(fs, buffer, boot->BytesPerSec) != boot->BytesPerSec) {
 		perror("Unable to read FAT");
 		goto err;
 	}
@@ -135,7 +128,7 @@
  * Check a cluster number for valid value
  */
 static int
-checkclnum(struct bootblock *boot, int fat, cl_t cl, cl_t *next)
+checkclnum(struct bootblock *boot, u_int fat, cl_t cl, cl_t *next)
 {
 	if (*next >= (CLUST_RSRVD&boot->ClustMask))
 		*next |= ~boot->ClustMask;
@@ -149,7 +142,7 @@
 	}
 	if (*next < CLUST_FIRST
 	    || (*next >= boot->NumClusters && *next < CLUST_EOFS)) {
-		pwarn("Cluster %u in FAT %d continues with %s cluster number %u\n",
+		pwarn("Cluster %u in FAT %u continues with %s cluster number %u\n",
 		      cl, fat,
 		      *next < CLUST_RSRVD ? "out of range" : "reserved",
 		      *next&boot->ClustMask);
@@ -166,13 +159,14 @@
  * Read a FAT from disk. Returns 1 if successful, 0 otherwise.
  */
 static int
-_readfat(int fs, struct bootblock *boot, int no, u_char **buffer)
+_readfat(int fs, struct bootblock *boot, u_int no, u_char **buffer)
 {
 	off_t off;
+	size_t len;
 
-	*buffer = malloc(boot->FATsecs * boot->BytesPerSec);
+	*buffer = malloc(len = boot->FATsecs * boot->BytesPerSec);
 	if (*buffer == NULL) {
-		perror("No space for FAT");
+		perror("No space for FAT sectors");
 		return 0;
 	}
 
@@ -184,7 +178,7 @@
 		goto err;
 	}
 
-	if (read(fs, *buffer, boot->FATsecs * boot->BytesPerSec)
+	if ((size_t)read(fs, *buffer, boot->FATsecs * boot->BytesPerSec)
 	    != boot->FATsecs * boot->BytesPerSec) {
 		perror("Unable to read FAT");
 		goto err;
@@ -201,7 +195,7 @@
  * Read a FAT and decode it into internal format
  */
 int
-readfat(int fs, struct bootblock *boot, int no, struct fatEntry **fp)
+readfat(int fs, struct bootblock *boot, u_int no, struct fatEntry **fp)
 {
 	struct fatEntry *fat;
 	u_char *buffer, *p;
@@ -212,10 +206,10 @@
 
 	if (!_readfat(fs, boot, no, &buffer))
 		return FSFATAL;
-		
+
 	fat = calloc(boot->NumClusters, sizeof(struct fatEntry));
 	if (fat == NULL) {
-		perror("No space for FAT");
+		perror("No space for FAT clusters");
 		free(buffer);
 		return FSFATAL;
 	}
@@ -244,7 +238,7 @@
 			ret |= FSDIRTY;
 		else {
 			/* just some odd byte sequence in FAT */
-				
+
 			switch (boot->ClustMask) {
 			case CLUST32_MASK:
 				pwarn("%s (%02x%02x%02x%02x%02x%02x%02x%02x)\n",
@@ -264,7 +258,7 @@
 				break;
 			}
 
-	
+
 			if (ask(1, "Correct"))
 				ret |= FSFIXFAT;
 		}
@@ -311,14 +305,18 @@
 	}
 
 	free(buffer);
-	*fp = fat;
+	if (ret & FSFATAL) {
+		free(fat);
+		*fp = NULL;
+	} else
+		*fp = fat;
 	return ret;
 }
 
 /*
  * Get type of reserved cluster
  */
-char *
+const char *
 rsrvdcltype(cl_t cl)
 {
 	if (cl == CLUST_FREE)
@@ -331,7 +329,7 @@
 }
 
 static int
-clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, int fatnum)
+clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, u_int fatnum)
 {
 	if (*cp1 == CLUST_FREE || *cp1 >= CLUST_RSRVD) {
 		if (*cp2 == CLUST_FREE || *cp2 >= CLUST_RSRVD) {
@@ -346,21 +344,21 @@
 				}
 				return FSFATAL;
 			}
-			pwarn("Cluster %u is marked %s in FAT 0, %s in FAT %d\n",
+			pwarn("Cluster %u is marked %s in FAT 0, %s in FAT %u\n",
 			      cl, rsrvdcltype(*cp1), rsrvdcltype(*cp2), fatnum);
 			if (ask(0, "Use FAT 0's entry")) {
 				*cp2 = *cp1;
 				return FSFATMOD;
 			}
-			if (ask(0, "Use FAT %d's entry", fatnum)) {
+			if (ask(0, "Use FAT %u's entry", fatnum)) {
 				*cp1 = *cp2;
 				return FSFATMOD;
 			}
 			return FSFATAL;
 		}
-		pwarn("Cluster %u is marked %s in FAT 0, but continues with cluster %u in FAT %d\n",
+		pwarn("Cluster %u is marked %s in FAT 0, but continues with cluster %u in FAT %u\n",
 		      cl, rsrvdcltype(*cp1), *cp2, fatnum);
-		if (ask(0, "Use continuation from FAT %d", fatnum)) {
+		if (ask(0, "Use continuation from FAT %u", fatnum)) {
 			*cp1 = *cp2;
 			return FSFATMOD;
 		}
@@ -371,25 +369,25 @@
 		return FSFATAL;
 	}
 	if (*cp2 == CLUST_FREE || *cp2 >= CLUST_RSRVD) {
-		pwarn("Cluster %u continues with cluster %u in FAT 0, but is marked %s in FAT %d\n",
+		pwarn("Cluster %u continues with cluster %u in FAT 0, but is marked %s in FAT %u\n",
 		      cl, *cp1, rsrvdcltype(*cp2), fatnum);
 		if (ask(0, "Use continuation from FAT 0")) {
 			*cp2 = *cp1;
 			return FSFATMOD;
 		}
-		if (ask(0, "Use mark from FAT %d", fatnum)) {
+		if (ask(0, "Use mark from FAT %u", fatnum)) {
 			*cp1 = *cp2;
 			return FSFATMOD;
 		}
 		return FSERROR;
 	}
-	pwarn("Cluster %u continues with cluster %u in FAT 0, but with cluster %u in FAT %d\n",
+	pwarn("Cluster %u continues with cluster %u in FAT 0, but with cluster %u in FAT %u\n",
 	      cl, *cp1, *cp2, fatnum);
 	if (ask(0, "Use continuation from FAT 0")) {
 		*cp2 = *cp1;
 		return FSFATMOD;
 	}
-	if (ask(0, "Use continuation from FAT %d", fatnum)) {
+	if (ask(0, "Use continuation from FAT %u", fatnum)) {
 		*cp1 = *cp2;
 		return FSFATMOD;
 	}
@@ -401,8 +399,8 @@
  * into the first one.
  */
 int
-comparefat(struct bootblock *boot, struct fatEntry *first, 
-    struct fatEntry *second, int fatnum)
+comparefat(struct bootblock *boot, struct fatEntry *first,
+    struct fatEntry *second, u_int fatnum)
 {
 	cl_t cl;
 	int ret = FSOK;
@@ -428,13 +426,13 @@
 }
 
 int
-tryclear(struct bootblock *boot, struct fatEntry *fat, cl_t head, cl_t *trunc)
+tryclear(struct bootblock *boot, struct fatEntry *fat, cl_t head, cl_t *truncp)
 {
 	if (ask(0, "Clear chain starting at %u", head)) {
 		clearchain(boot, fat, head);
 		return FSFATMOD;
 	} else if (ask(0, "Truncate")) {
-		*trunc = CLUST_EOF;
+		*truncp = CLUST_EOF;
 		return FSFATMOD;
 	} else
 		return FSERROR;
@@ -542,14 +540,14 @@
 {
 	u_char *buffer, *p;
 	cl_t cl;
-	int i;
-	u_int32_t fatsz;
+	u_int i;
+	size_t fatsz;
 	off_t off;
 	int ret = FSOK;
 
 	buffer = malloc(fatsz = boot->FATsecs * boot->BytesPerSec);
 	if (buffer == NULL) {
-		perror("No space for FAT");
+		perror("No space for FAT sectors");
 		return FSFATAL;
 	}
 	memset(buffer, 0, fatsz);
@@ -598,7 +596,7 @@
 		free(old_fat);
 		p += count;
 	}
-			
+
 	for (cl = CLUST_FIRST; cl < boot->NumClusters; cl++) {
 		switch (boot->ClustMask) {
 		case CLUST32_MASK:
@@ -633,7 +631,7 @@
 		off = boot->ResSectors + i * boot->FATsecs;
 		off *= boot->BytesPerSec;
 		if (lseek(fs, off, SEEK_SET) != off
-		    || write(fs, buffer, fatsz) != fatsz) {
+		    || (size_t)write(fs, buffer, fatsz) != fatsz) {
 			perror("Unable to write FAT");
 			ret = FSFATAL; /* Return immediately?		XXX */
 		}
@@ -651,7 +649,7 @@
 	cl_t head;
 	int mod = FSOK;
 	int ret;
-	
+
 	for (head = CLUST_FIRST; head < boot->NumClusters; head++) {
 		/* find next untravelled chain */
 		if (fat[head].head != head
@@ -683,9 +681,10 @@
 				ret = 1;
 			}
 		}
-		if (boot->NumFree && fat[boot->FSNext].next != CLUST_FREE) {
-			pwarn("Next free cluster in FSInfo block (%u) not free\n",
-			      boot->FSNext);
+		if (boot->FSNext >= boot->NumClusters || (boot->NumFree && fat[boot->FSNext].next != CLUST_FREE)) {
+			pwarn("Next free cluster in FSInfo block (%u) %s\n",
+			      boot->FSNext,
+			      (boot->FSNext >= boot->NumClusters) ? "invalid" : "not free");
 			if (ask(1, "Fix"))
 				for (head = CLUST_FIRST; head < boot->NumClusters; head++)
 					if (fat[head].next == CLUST_FREE) {
diff -r 41230069d22f -r 6a5580020f7b sbin/fsck_msdosfs/fsck_msdosfs.8
--- a/sbin/fsck_msdosfs/fsck_msdosfs.8	Mon Oct 19 17:27:04 2009 +0200
+++ b/sbin/fsck_msdosfs/fsck_msdosfs.8	Mon Oct 19 18:30:28 2009 +0200
@@ -1,4 +1,4 @@
-.\"	$NetBSD: fsck_msdos.8,v 1.9 1997/10/17 11:19:58 ws Exp $
+.\"	$NetBSD: fsck_msdos.8,v 1.15 2008/06/13 20:46:09 martin Exp $
 .\"
 .\" Copyright (C) 1995 Wolfgang Solfrank
 .\" Copyright (c) 1995 Martin Husemann
@@ -11,13 +11,6 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\"    must display the following acknowledgement:
-.\"	This product includes software developed by Martin Husemann
-.\"	and Wolfgang Solfrank.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\"    may be used to endorse or promote products derived from this software
-.\"    without specific prior written permission.
 .\"
 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
diff -r 41230069d22f -r 6a5580020f7b sbin/fsck_msdosfs/main.c
--- a/sbin/fsck_msdosfs/main.c	Mon Oct 19 17:27:04 2009 +0200
+++ b/sbin/fsck_msdosfs/main.c	Mon Oct 19 18:30:28 2009 +0200
@@ -10,13 +10,6 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by Martin Husemann
- *	and Wolfgang Solfrank.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -33,7 +26,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: main.c,v 1.10 1997/10/01 02:18:14 enami Exp $");
+__RCSID("$NetBSD: main.c,v 1.21 2008/06/13 20:46:09 martin Exp $");
 static const char rcsid[] =
   "$FreeBSD$";
 #endif /* not lint */
@@ -146,6 +139,7 @@
 
 	va_start(ap, fmt);
 	vsnprintf(prompt, sizeof(prompt), fmt, ap);
+	va_end(ap);
 	if (alwaysyes || rdonly) {
 		printf("%s? %s\n", prompt, rdonly ? "no" : "yes");
 		return !rdonly;
--- fsck_msdosfs.diff ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list