msdos utility (sbin) patches

Pedro F. Giffuni pfgshield-freebsd at yahoo.com
Sun Jan 10 01:44:36 PST 2010


Hello;

Here are some updates, mostly taken from NetBSD, to the FAT
utilities. These were made for FreeBSD but this is an area
where dragonfly hasn't changed much so they won't be
difficult to adapt.
enjoy,

Pedro.
diff -ru fsck_msdosfs.orig/boot.c fsck_msdosfs/boot.c
--- fsck_msdosfs.orig/boot.c	2010-01-06 11:07:24.000000000 +0000
+++ fsck_msdosfs/boot.c	2010-01-08 19:53:19.000000000 +0000
@@ -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
@@ -40,7 +33,6 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <unistd.h>
 
@@ -56,8 +48,9 @@
 	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 +154,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 at NetBSD 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 */
 	}
diff -ru fsck_msdosfs.orig/check.c fsck_msdosfs/check.c
--- fsck_msdosfs.orig/check.c	2010-01-06 11:07:24.000000000 +0000
+++ fsck_msdosfs/check.c	2010-01-07 22:09:13.000000000 +0000
@@ -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
@@ -40,7 +33,6 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -54,7 +46,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;
 
diff -ru fsck_msdosfs.orig/dir.c fsck_msdosfs/dir.c
--- fsck_msdosfs.orig/dir.c	2010-01-06 11:07:24.000000000 +0000
+++ fsck_msdosfs/dir.c	2010-01-08 15:30:03.000000000 +0000
@@ -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
@@ -44,7 +37,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include <stdio.h>
 #include <unistd.h>
 #include <time.h>
 
@@ -230,12 +222,24 @@
 	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( b1 > b2 ? b1 : b2)) == NULL) {
+		perror("No space for directory buffer");
 		return FSFATAL;
 	}
+
+	if ((delbuf = malloc(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 +371,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 +390,7 @@
 	/*
 	 * Check size on ordinary files
 	 */
-	int32_t physicalSize;
+	u_int32_t physicalSize;
 
 	if (dir->head == CLUST_FREE)
 		physicalSize = 0;
@@ -644,7 +649,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 +838,10 @@
 			}
 			boot->NumFiles++;
 		}
+
+		if (!(boot->flags & FAT32) && !dir->parent)
+			break;
+
 		if (mod & THISMOD) {
 			last *= 32;
 			if (lseek(f, off, SEEK_SET) != off
@@ -847,6 +857,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 +959,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 +989,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 -ru fsck_msdosfs.orig/dosfs.h fsck_msdosfs/dosfs.h
--- fsck_msdosfs.orig/dosfs.h	2010-01-06 11:07:24.000000000 +0000
+++ fsck_msdosfs/dosfs.h	2010-01-08 19:42:05.000000000 +0000
@@ -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
@@ -55,8 +48,13 @@
 	u_int	FATsmall;		/* number of sectors per FAT */
 	u_int	SecPerTrack;		/* sectors per track */
 	u_int	Heads;			/* number of heads */
-	u_int32_t Sectors;		/* total number of sectors */
 	u_int32_t HiddenSecs;		/* # of hidden sectors */
+	u_int32_t Sectors;		/* total number of sectors */
+#define	FAT32		1		/* this is a FAT32 file system */
+					/*
+					 * Maybe, we should separate out
+					 * various parts of FAT32?	XXX
+					 */
 	u_int32_t HugeSectors;		/* # of sectors if bpbSectors == 0 */
 	u_int	FSInfo;			/* FSInfo sector */
 	u_int	Backup;			/* Backup of Bootblocks */
@@ -66,11 +64,6 @@
 
 	/* and some more calculated values */
 	u_int	flags;			/* some flags: */
-#define	FAT32		1		/* this is a FAT32 file system */
-					/*
-					 * Maybe, we should separate out
-					 * various parts of FAT32?	XXX
-					 */
 	int	ValidFat;		/* valid fat if FAT32 non-mirrored */
 	cl_t	ClustMask;		/* mask for entries in FAT */
 	cl_t	NumClusters;		/* # of entries in a FAT */
diff -ru fsck_msdosfs.orig/ext.h fsck_msdosfs/ext.h
--- fsck_msdosfs.orig/ext.h	2010-01-06 11:07:24.000000000 +0000
+++ fsck_msdosfs/ext.h	2010-01-07 22:09:13.000000000 +0000
@@ -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
@@ -77,12 +70,12 @@
 #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 */
 
 /*
- * read a boot block in a machine independend fashion and translate
+ * read a boot block in a machine independent fashion and translate
  * it into our struct bootblock.
  */
 int readboot(int, struct bootblock *);
@@ -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
diff -ru fsck_msdosfs.orig/fat.c fsck_msdosfs/fat.c
--- fsck_msdosfs.orig/fat.c	2010-01-06 11:07:24.000000000 +0000
+++ fsck_msdosfs/fat.c	2010-01-07 22:13:31.000000000 +0000
@@ -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
@@ -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
@@ -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;
@@ -166,7 +159,7 @@
  * 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;
 
@@ -184,7 +177,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,24 +194,26 @@
  * 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;
 	cl_t cl;
 	int ret = FSOK;
+	size_t len;
 
 	boot->NumFree = boot->NumBad = 0;
 
 	if (!_readfat(fs, boot, no, &buffer))
 		return FSFATAL;
 		
-	fat = calloc(boot->NumClusters, sizeof(struct fatEntry));
+	fat = malloc(len = boot->NumClusters * sizeof(struct fatEntry));
 	if (fat == NULL) {
 		perror("No space for FAT");
 		free(buffer);
 		return FSFATAL;
 	}
+	(void)memset(fat, 0, len);
 
 	if (buffer[0] != boot->Media
 	    || buffer[1] != 0xff || buffer[2] != 0xff
@@ -311,7 +306,11 @@
 	}
 
 	free(buffer);
-	*fp = fat;
+	if (ret & FSFATAL) {
+		free(fat);
+		*fp = NULL;
+	} else
+		*fp = fat;
 	return ret;
 }
 
@@ -331,7 +330,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,13 +345,13 @@
 				}
 				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;
 			}
@@ -360,7 +359,7 @@
 		}
 		pwarn("Cluster %u is marked %s in FAT 0, but continues with cluster %u in FAT %d\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,7 +370,7 @@
 		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;
@@ -383,13 +382,13 @@
 		}
 		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 +400,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;
@@ -542,8 +541,8 @@
 {
 	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;
 
@@ -633,7 +632,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 */
 		}
@@ -683,17 +682,6 @@
 				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 (ask(1, "Fix"))
-				for (head = CLUST_FIRST; head < boot->NumClusters; head++)
-					if (fat[head].next == CLUST_FREE) {
-						boot->FSNext = head;
-						ret = 1;
-						break;
-					}
-		}
 		if (ret)
 			mod |= writefsinfo(dosfs, boot);
 	}
diff -ru fsck_msdosfs.orig/fsck_msdosfs.8 fsck_msdosfs/fsck_msdosfs.8
--- fsck_msdosfs.orig/fsck_msdosfs.8	2010-01-06 11:07:24.000000000 +0000
+++ fsck_msdosfs/fsck_msdosfs.8	2010-01-07 22:09:13.000000000 +0000
@@ -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 -ru fsck_msdosfs.orig/main.c fsck_msdosfs/main.c
--- fsck_msdosfs.orig/main.c	2010-01-06 11:07:24.000000000 +0000
+++ fsck_msdosfs/main.c	2010-01-07 22:09:13.000000000 +0000
@@ -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
@@ -40,7 +33,6 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <errno.h>
diff -ru newfs_msdos.orig/newfs_msdos.8 newfs_msdos/newfs_msdos.8
--- newfs_msdos.orig/newfs_msdos.8	2010-01-06 11:06:02.000000000 +0000
+++ newfs_msdos/newfs_msdos.8	2010-01-09 10:25:12.000000000 +0000
@@ -116,7 +116,7 @@
 .It Fl S Ar sector-size
 Number of bytes per sector.
 Acceptable values are powers of 2
-in the range 128 through 32768.
+in the range 512 through 4096.
 .It Fl a Ar FAT-size
 Number of sectors per FAT.
 .It Fl b Ar block-size
diff -ru newfs_msdos.orig/newfs_msdos.c newfs_msdos/newfs_msdos.c
--- newfs_msdos.orig/newfs_msdos.c	2010-01-06 11:06:02.000000000 +0000
+++ newfs_msdos/newfs_msdos.c	2010-01-10 08:54:15.000000000 +0000
@@ -55,6 +55,7 @@
 #define NPB	  2		/* nibbles per byte */
 
 #define DOSMAGIC  0xaa55	/* DOS magic number */
+#define MAXBPS	  4096		/* maximum bytes per sector */
 #define MINBPS	  512		/* minimum bytes per sector */
 #define MAXSPC	  128		/* maximum sectors per cluster */
 #define MAXNFT	  16		/* maximum number of FATs */
@@ -165,20 +166,23 @@
 
 #define BPBGAP 0, 0, 0, 0, 0, 0
 
+#define INIT(a, b, c, d, e, f, g, h, i, j) \
+    { .bps = a, .spc = b, .res = c, .nft = d, .rde = e, \
+      .sec = f, .mid = g, .spf = h, .spt = i, .hds = j, }
 static struct {
     const char *name;
     struct bpb bpb;
 } const stdfmt[] = {
-    {"160",  {512, 1, 1, 2,  64,  320, 0xfe, 1,  8, 1, BPBGAP}},
-    {"180",  {512, 1, 1, 2,  64,  360, 0xfc, 2,  9, 1, BPBGAP}},
-    {"320",  {512, 2, 1, 2, 112,  640, 0xff, 1,  8, 2, BPBGAP}},
-    {"360",  {512, 2, 1, 2, 112,  720, 0xfd, 2,  9, 2, BPBGAP}},
-    {"640",  {512, 2, 1, 2, 112, 1280, 0xfb, 2,  8, 2, BPBGAP}},    
-    {"720",  {512, 2, 1, 2, 112, 1440, 0xf9, 3,  9, 2, BPBGAP}},
-    {"1200", {512, 1, 1, 2, 224, 2400, 0xf9, 7, 15, 2, BPBGAP}},
-    {"1232", {1024,1, 1, 2, 192, 1232, 0xfe, 2,  8, 2, BPBGAP}},    
-    {"1440", {512, 1, 1, 2, 224, 2880, 0xf0, 9, 18, 2, BPBGAP}},
-    {"2880", {512, 2, 1, 2, 240, 5760, 0xf0, 9, 36, 2, BPBGAP}}
+    {"160",  INIT(512, 1, 1, 2,  64,  320, 0xfe, 1,  8, 1)},
+    {"180",  INIT(512, 1, 1, 2,  64,  360, 0xfc, 2,  9, 1)},
+    {"320",  INIT(512, 2, 1, 2, 112,  640, 0xff, 1,  8, 2)},
+    {"360",  INIT(512, 2, 1, 2, 112,  720, 0xfd, 2,  9, 2)},
+    {"640",  INIT(512, 2, 1, 2, 112, 1280, 0xfb, 2,  8, 2)},    
+    {"720",  INIT(512, 2, 1, 2, 112, 1440, 0xf9, 3,  9, 2)},
+    {"1200", INIT(512, 1, 1, 2, 224, 2400, 0xf9, 7, 15, 2)},
+    {"1232", INIT(1024,1, 1, 2, 192, 1232, 0xfe, 2,  8, 2)},    
+    {"1440", INIT(512, 1, 1, 2, 224, 2880, 0xf0, 9, 18, 2)},
+    {"2880", INIT(512, 2, 1, 2, 240, 5760, 0xf0, 9, 36, 2)}
 };
 
 static const u_int8_t bootcode[] = {
@@ -421,7 +425,9 @@
     }
     if (!powerof2(bpb.bps))
 	errx(1, "bytes/sector (%u) is not a power of 2", bpb.bps);
-    if (bpb.bps < MINBPS)
+    if (bpb.bps > MAXBPS)
+    	printf( "WARNING: bytes/sector (%u) is too big", bpb.bps);
+    else if (bpb.bps < MINBPS)
 	errx(1, "bytes/sector (%u) is too small; minimum is %u",
 	     bpb.bps, MINBPS);
     if (!(fat = opt_F)) {
@@ -533,7 +539,7 @@
     if (!bpb.res)
 	bpb.res = fat == 32 ? MAX(x, MAX(16384 / bpb.bps, 4)) : x;
     else if (bpb.res < x)
-	errx(1, "too few reserved sectors");
+	errx(1, "too few reserved sectors (need %d have %d)", x, bpb.res);
     if (fat != 32 && !bpb.rde)
 	bpb.rde = DEFRDE;
     rds = howmany(bpb.rde, bpb.bps / sizeof(struct de));
@@ -657,8 +663,8 @@
 			 ((u_int)tm->tm_hour << 8 |
 			  (u_int)tm->tm_min));
 		mk4(bsx->volid, x);
-		mklabel(bsx->label, opt_L ? opt_L : "NO NAME");
-		sprintf(buf, "FAT%u", fat);
+		mklabel(bsx->label, opt_L ? opt_L : "NO_NAME");
+		snprintf(buf, sizeof(buf), "FAT%u", fat);
 		setstr(bsx->type, buf, sizeof(bsx->type));
 		if (!opt_B) {
 		    x1 += sizeof(struct bsx);
@@ -666,7 +672,7 @@
 		    mk1(bs->jmp[0], 0xeb);
 		    mk1(bs->jmp[1], x1 - 2);
 		    mk1(bs->jmp[2], 0x90);
-		    setstr(bs->oem, opt_O ? opt_O : "BSD  4.4",
+		    setstr(bs->oem, opt_O ? opt_O : "BSD4.4  ",
 			   sizeof(bs->oem));
 		    memcpy(img + x1, bootcode, sizeof(bootcode));
 		    mk2(img + MINBPS - 2, DOSMAGIC);




More information about the Submit mailing list