summaryrefslogtreecommitdiffstats
path: root/sbin/fsck_msdosfs/fat.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/fsck_msdosfs/fat.c')
-rw-r--r--sbin/fsck_msdosfs/fat.c59
1 files changed, 27 insertions, 32 deletions
diff --git a/sbin/fsck_msdosfs/fat.c b/sbin/fsck_msdosfs/fat.c
index a1123f6..8f4bf4f 100644
--- a/sbin/fsck_msdosfs/fat.c
+++ b/sbin/fsck_msdosfs/fat.c
@@ -40,10 +40,10 @@ static const char rcsid[] =
#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
@@ -128,7 +128,7 @@ err:
* 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;
@@ -159,7 +159,7 @@ checkclnum(struct bootblock *boot, int fat, cl_t cl, cl_t *next)
* 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;
@@ -177,7 +177,7 @@ _readfat(int fs, struct bootblock *boot, int no, u_char **buffer)
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;
@@ -194,24 +194,26 @@ _readfat(int fs, struct bootblock *boot, int no, u_char **buffer)
* 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
@@ -304,7 +306,11 @@ readfat(int fs, struct bootblock *boot, int no, struct fatEntry **fp)
}
free(buffer);
- *fp = fat;
+ if (ret & FSFATAL) {
+ free(fat);
+ *fp = NULL;
+ } else
+ *fp = fat;
return ret;
}
@@ -324,7 +330,7 @@ rsrvdcltype(cl_t cl)
}
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) {
@@ -339,13 +345,13 @@ clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, int fatnum)
}
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;
}
@@ -353,7 +359,7 @@ clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, int fatnum)
}
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;
}
@@ -364,7 +370,7 @@ clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, int fatnum)
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;
@@ -376,13 +382,13 @@ clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, int fatnum)
}
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;
}
@@ -394,8 +400,8 @@ clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, int fatnum)
* 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;
@@ -535,8 +541,8 @@ writefat(int fs, struct bootblock *boot, struct fatEntry *fat, int correct_fat)
{
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;
@@ -626,7 +632,7 @@ writefat(int fs, struct bootblock *boot, struct fatEntry *fat, int correct_fat)
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 */
}
@@ -676,17 +682,6 @@ checklost(int dosfs, struct bootblock *boot, struct fatEntry *fat)
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);
}
OpenPOWER on IntegriCloud