summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/fsck_msdos/check.c82
-rw-r--r--sbin/fsck_msdos/dir.c360
-rw-r--r--sbin/fsck_msdos/dosfs.h6
-rw-r--r--sbin/fsck_msdos/ext.h26
-rw-r--r--sbin/fsck_msdos/fat.c27
-rw-r--r--sbin/fsck_msdos/main.c24
6 files changed, 318 insertions, 207 deletions
diff --git a/sbin/fsck_msdos/check.c b/sbin/fsck_msdos/check.c
index adf41300c79..940157a0bd7 100644
--- a/sbin/fsck_msdos/check.c
+++ b/sbin/fsck_msdos/check.c
@@ -1,4 +1,4 @@
-/* $NetBSD: check.c,v 1.1 1996/05/14 17:39:29 ws Exp $ */
+/* $NetBSD: check.c,v 1.1.4.1 1996/05/31 18:41:33 jtc Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank
@@ -34,7 +34,7 @@
#ifndef lint
-static char rcsid[] = "$NetBSD: check.c,v 1.1 1996/05/14 17:39:29 ws Exp $";
+static char rcsid[] = "$NetBSD: check.c,v 1.1.4.1 1996/05/31 18:41:33 jtc Exp $";
#endif /* not lint */
#include <stdlib.h>
@@ -51,7 +51,6 @@ checkfilesys(fname)
const char *fname;
{
int dosfs;
- struct dosDirEntry *rootDir;
struct bootblock boot;
struct fatEntry * fat = NULL;
int i;
@@ -90,7 +89,9 @@ checkfilesys(fname)
mod |= readfat(dosfs, &boot, i, &currentFat);
- if (mod&FSFATAL) {
+ if (mod & FSFATAL) {
+ if (fat)
+ free(fat);
close(dosfs);
return 8;
}
@@ -99,7 +100,9 @@ checkfilesys(fname)
fat = currentFat;
else {
mod |= comparefat(&boot, fat, currentFat, i + 1);
- if (mod&FSFATAL) {
+ free(currentFat);
+ if (mod & FSFATAL) {
+ free(fat);
close(dosfs);
return 8;
}
@@ -110,83 +113,50 @@ checkfilesys(fname)
printf("** Phase 2 - Check Cluster Chains\n");
mod |= checkfat(&boot, fat);
- if (mod&FSFATAL) {
+ if (mod & FSFATAL) {
+ free(fat);
close(dosfs);
return 8;
}
- if (mod&FSFATMOD)
+ if (mod & FSFATMOD)
mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */
- if (mod&FSFATAL) {
+ if (mod & FSFATAL) {
+ free(fat);
close(dosfs);
return 8;
}
if (!preen)
printf("** Phase 3 - Checking Directories\n");
-
- rootDir = malloc(sizeof(struct dosDirEntry));
- memset(rootDir, 0, sizeof(struct dosDirEntry));
- rootDir->fullpath = strdup("/");
- if (resetDosDirSection(&boot)&FSFATAL) {
- close(dosfs);
- return 8;
- }
-
- mod = readDosDirSection(dosfs, &boot, fat, rootDir);
- if (mod&FSFATAL) {
+
+ if (resetDosDirSection(&boot) & FSFATAL) {
+ free(fat);
close(dosfs);
return 8;
}
-
- if (mod&FSFATMOD)
- mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */
- if (mod&FSFATAL) {
+
+ mod |= handleDirTree(dosfs, &boot, fat);
+ if (mod & FSFATAL) {
+ finishDosDirSection();
+ free(fat);
close(dosfs);
return 8;
}
- /*
- * process the directory todo list
- */
- while (pendingDirectories) {
- struct dosDirEntry *dir = pendingDirectories->dir;
- struct dirTodoNode *n = pendingDirectories->next;
-
- /*
- * remove TODO entry now, the list might change during
- * directory reads
- */
- free(pendingDirectories);
- pendingDirectories = n;
-
- /*
- * handle subdirectory
- */
- mod |= readDosDirSection(dosfs, &boot, fat, dir);
- if (mod&FSFATAL) {
- close(dosfs);
- return 8;
- }
- if (mod&FSFATMOD)
- mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */
- if (mod&FSFATAL) {
- close(dosfs);
- return 8;
- }
- }
- finishDosDirSection();
-
if (!preen)
printf("** Phase 4 - Checking for Lost Files\n");
- mod |= checklost(dosfs, &boot, fat, rootDir);
+ mod |= checklost(dosfs, &boot, fat);
+ finishDosDirSection();
+ free(fat);
close(dosfs);
+
pwarn("%d files, %d free (%d clusters)\n",
boot.NumFiles, boot.NumFree * boot.ClusterSize / 1024,
boot.NumFree);
- if (mod&(FSFATAL|FSERROR))
+ if (mod & (FSFATAL | FSERROR))
return 8;
if (mod) {
pwarn("\n***** FILE SYSTEM WAS MODIFIED *****\n");
diff --git a/sbin/fsck_msdos/dir.c b/sbin/fsck_msdos/dir.c
index d0b205cf98f..6b06737747b 100644
--- a/sbin/fsck_msdos/dir.c
+++ b/sbin/fsck_msdos/dir.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dir.c,v 1.1 1996/05/14 17:39:30 ws Exp $ */
+/* $NetBSD: dir.c,v 1.1.4.1 1996/05/31 18:41:38 jtc Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank
@@ -36,7 +36,7 @@
#ifndef lint
-static char rcsid[] = "$NetBSD: dir.c,v 1.1 1996/05/14 17:39:30 ws Exp $";
+static char rcsid[] = "$NetBSD: dir.c,v 1.1.4.1 1996/05/31 18:41:38 jtc Exp $";
#endif /* not lint */
#include <stdio.h>
@@ -47,6 +47,8 @@ static char rcsid[] = "$NetBSD: dir.c,v 1.1 1996/05/14 17:39:30 ws Exp $";
#include <unistd.h>
#include <time.h>
+#include <sys/param.h>
+
#include "ext.h"
#define SLOT_EMPTY 0x00 /* slot has never been used */
@@ -88,6 +90,89 @@ static char rcsid[] = "$NetBSD: dir.c,v 1.1 1996/05/14 17:39:30 ws Exp $";
#define DD_YEAR_SHIFT 9
/*
+ * Manage free dosDirEntry structures.
+ */
+static struct dosDirEntry *freede;
+
+static struct dosDirEntry *
+newDosDirEntry()
+{
+ struct dosDirEntry *de;
+
+ if (!(de = freede)) {
+ if (!(de = (struct dosDirEntry *)malloc(sizeof *de)))
+ return 0;
+ } else
+ freede = de->next;
+ return de;
+}
+
+static void
+freeDosDirEntry(de)
+ struct dosDirEntry *de;
+{
+ de->next = freede;
+ freede = de;
+}
+
+/*
+ * The same for dirTodoNode structures.
+ */
+static struct dirTodoNode *freedt;
+
+static struct dirTodoNode *
+newDirTodo()
+{
+ struct dirTodoNode *dt;
+
+ if (!(dt = freedt)) {
+ if (!(dt = (struct dirTodoNode *)malloc(sizeof *dt)))
+ return 0;
+ } else
+ freedt = dt->next;
+ return dt;
+}
+
+static void
+freeDirTodo(dt)
+ struct dirTodoNode *dt;
+{
+ dt->next = freedt;
+ freedt = dt;
+}
+
+/*
+ * The stack of unread directories
+ */
+struct dirTodoNode *pendingDirectories = NULL;
+
+/*
+ * Return the full pathname for a directory entry.
+ */
+static char *
+fullpath(dir)
+ struct dosDirEntry *dir;
+{
+ static char namebuf[MAXPATHLEN + 1];
+ char *cp, *np;
+ int nl;
+
+ cp = namebuf + sizeof namebuf - 1;
+ *cp = '\0';
+ do {
+ np = dir->lname[0] ? dir->lname : dir->name;
+ nl = strlen(np);
+ if ((cp -= nl) <= namebuf + 1)
+ break;
+ memcpy(cp, np, nl);
+ *--cp = '/';
+ } while (dir = dir->parent);
+ if (dir->parent)
+ *--cp = '?';
+ return cp;
+}
+
+/*
* Calculate a checksum over an 8.3 alias name
*/
static u_char
@@ -112,6 +197,9 @@ static char longName[DOSLONGNAMELEN] = "";
static u_char *buffer = NULL;
static u_char *delbuf = NULL;
+struct dosDirEntry *rootDir;
+static struct dosDirEntry *lostDir;
+
/*
* Init internal state for a new directory scan.
*/
@@ -125,10 +213,12 @@ resetDosDirSection(boot)
b2 = boot->SecPerClust * boot->BytesPerSec;
if (!(buffer = malloc(b1 > b2 ? b1 : b2))
- || !(delbuf = malloc(b2))) {
+ || !(delbuf = malloc(b2))
+ || !(rootDir = newDosDirEntry())) {
perror("No space for directory");
return FSFATAL;
}
+ memset(rootDir, 0, sizeof *rootDir);
return FSOK;
}
@@ -138,6 +228,24 @@ resetDosDirSection(boot)
void
finishDosDirSection()
{
+ struct dirTodoNode *p, *np;
+ struct dosDirEntry *d, *nd;
+
+ for (p = pendingDirectories; p; p = np) {
+ np = p->next;
+ freeDirTodo(p);
+ }
+ pendingDirectories = 0;
+ for (d = rootDir; d; d = nd) {
+ if (nd = d->child) {
+ d->child = 0;
+ continue;
+ }
+ if (!(nd = d->next))
+ nd = d->parent;
+ freeDosDirEntry(d);
+ }
+ rootDir = lostDir = NULL;
free(buffer);
free(delbuf);
buffer = NULL;
@@ -195,7 +303,7 @@ delete(f, boot, fat, startcl, startoff, endcl, endoff, notlast)
}
static int
-removede(f, boot, fat, start, end, startcl, endcl, curcl, path, eof)
+removede(f, boot, fat, start, end, startcl, endcl, curcl, path, type)
int f;
struct bootblock *boot;
struct fatEntry *fat;
@@ -205,12 +313,19 @@ removede(f, boot, fat, start, end, startcl, endcl, curcl, path, eof)
cl_t endcl;
cl_t curcl;
char *path;
- int eof;
+ int type;
{
- if (!eof)
+ switch (type) {
+ case 0:
pwarn("Invalid long filename entry for %s\n", path);
- else
+ break;
+ case 1:
pwarn("Invalid long filename entry at end of directory %s\n", path);
+ break;
+ case 2:
+ pwarn("Invalid long filename entry for volume label\n");
+ break;
+ }
if (ask(0, "Remove")) {
if (startcl != curcl) {
if (delete(f, boot, fat,
@@ -241,14 +356,18 @@ checksize(boot, fat, p, dir)
/*
* Check size on ordinary files
*/
- u_int32_t physicalSize;
+ int32_t physicalSize;
- if (dir->head < CLUST_FIRST || dir->head >= boot->NumClusters)
- return FSERROR;
- physicalSize = fat[dir->head].length * boot->ClusterSize;
+ if (dir->head == CLUST_FREE)
+ physicalSize = 0;
+ else {
+ if (dir->head < CLUST_FIRST || dir->head >= boot->NumClusters)
+ return FSERROR;
+ physicalSize = fat[dir->head].length * boot->ClusterSize;
+ }
if (physicalSize < dir->size) {
pwarn("size of %s is %lu, should at most be %lu\n",
- dir->fullpath, dir->size, physicalSize);
+ fullpath(dir), dir->size, physicalSize);
if (ask(1, "Truncate")) {
dir->size = physicalSize;
p[28] = (u_char)physicalSize;
@@ -260,7 +379,7 @@ checksize(boot, fat, p, dir)
return FSERROR;
} else if (physicalSize - dir->size >= boot->ClusterSize) {
pwarn("%s has too many clusters allocated\n",
- dir->fullpath);
+ fullpath(dir));
if (ask(1, "Drop superfluous clusters")) {
cl_t cl;
u_int32_t sz = 0;
@@ -277,17 +396,12 @@ checksize(boot, fat, p, dir)
}
/*
- * The stack of unread directories
- */
-struct dirTodoNode *pendingDirectories = NULL;
-
-/*
* Read a directory and
* - resolve long name records
* - enter file and directory records into the parent's list
* - push directories onto the todo-stack
*/
-int
+static int
readDosDirSection(f, boot, fat, dir)
int f;
struct bootblock *boot;
@@ -306,7 +420,7 @@ readDosDirSection(f, boot, fat, dir)
#define THISMOD 0x8000 /* Only used within this routine */
cl = dir->head;
- if (dir->fullpath[1] && (cl < CLUST_FIRST || cl >= boot->NumClusters)) {
+ if (dir->parent && (cl < CLUST_FIRST || cl >= boot->NumClusters)) {
/*
* Already handled somewhere else.
*/
@@ -315,7 +429,7 @@ readDosDirSection(f, boot, fat, dir)
shortSum = -1;
vallfn = invlfn = empty = NULL;
do {
- if (!dir->fullpath[1]) {
+ if (!dir->parent) {
last = boot->RootDirEnts * 32;
off = boot->ResSectors + boot->FATs * boot->FATsecs;
} else {
@@ -351,7 +465,7 @@ readDosDirSection(f, boot, fat, dir)
if (dir->fsckflags & DIREMPTY) {
if (!(dir->fsckflags & DIREMPWARN)) {
pwarn("%s has entries after end of directory\n",
- dir->fullpath);
+ fullpath(dir));
if (ask(1, "Extend")) {
dir->fsckflags &= ~DIREMPTY;
if (delete(f, boot, fat,
@@ -465,10 +579,20 @@ readDosDirSection(f, boot, fat, dir)
k++;
if (dirent.name[0] == SLOT_E5)
dirent.name[0] = 0xe5;
- /*
- * What about volume names with extensions? XXX
- */
- if ((dirent.flags & ATTR_VOLUME) == 0 && p[8] != ' ')
+
+ if (dirent.flags & ATTR_VOLUME) {
+ if (vallfn || invlfn) {
+ mod |= removede(f, boot, fat,
+ invlfn ? invlfn : vallfn, p,
+ invlfn ? invcl : valcl, -1, 0,
+ fullpath(dir), 2);
+ vallfn = NULL;
+ invlfn = NULL;
+ }
+ continue;
+ }
+
+ if (p[8] != ' ')
dirent.name[k++] = '.';
for (j = 0; j < 3; j++)
dirent.name[k++] = p[j+8];
@@ -490,20 +614,12 @@ readDosDirSection(f, boot, fat, dir)
longName[0] = '\0';
shortSum = -1;
}
-
- k = strlen(dirent.lname[0] ? dirent.lname : dirent.name);
- k += strlen(dir->fullpath) + 2;
- dirent.fullpath = malloc(k);
- strcpy(dirent.fullpath, dir->fullpath);
- if (dir->fullpath[1])
- strcat(dirent.fullpath, "/");
- strcat(dirent.fullpath,
- dirent.lname[0] ? dirent.lname : dirent.name);
+
if (invlfn) {
mod |= k = removede(f, boot, fat,
invlfn, vallfn ? vallfn : p,
invcl, vallfn ? valcl : cl, cl,
- dirent.fullpath, 0);
+ fullpath(&dirent), 0);
if (mod & FSFATAL)
return FSFATAL;
if (vallfn
@@ -518,7 +634,7 @@ readDosDirSection(f, boot, fat, dir)
if (dirent.size == 0 && !(dirent.flags & ATTR_DIRECTORY)) {
if (dirent.head != 0) {
pwarn("%s has clusters, but size 0\n",
- dirent.fullpath);
+ fullpath(&dirent));
if (ask(1, "Drop allocated clusters")) {
p[26] = p[27] = 0;
clearchain(boot, fat, dirent.head);
@@ -529,7 +645,8 @@ readDosDirSection(f, boot, fat, dir)
}
} else if (dirent.head == 0
&& !strcmp(dirent.name, "..")
- && !strcmp(dir->parent->fullpath, "/")) {
+ && dir->parent /* XXX */
+ && !dir->parent->parent) {
/*
* Do nothing, the parent is the root
*/
@@ -541,22 +658,22 @@ readDosDirSection(f, boot, fat, dir)
|| fat[dirent.head].head != dirent.head) {
if (dirent.head == 0)
pwarn("%s has no clusters\n",
- dirent.fullpath);
+ fullpath(&dirent));
else if (dirent.head < CLUST_FIRST
|| dirent.head >= boot->NumClusters)
pwarn("%s starts with cluster out of range(%d)\n",
- dirent.fullpath,
+ fullpath(&dirent),
dirent.head);
else if (fat[dirent.head].next == CLUST_FREE)
pwarn("%s starts with free cluster\n",
- dirent.fullpath);
+ fullpath(&dirent));
else if (fat[dirent.head].next >= CLUST_RSRVD)
pwarn("%s starts with %s cluster\n",
- dirent.fullpath,
+ fullpath(&dirent),
rsrvdcltype(fat[dirent.head].next));
else
pwarn("%s doesn't start a cluster chain\n",
- dirent.fullpath);
+ fullpath(&dirent));
if (dirent.flags & ATTR_DIRECTORY) {
if (ask(0, "Remove")) {
*p = SLOT_DELETED;
@@ -574,28 +691,23 @@ readDosDirSection(f, boot, fat, dir)
}
}
- /* create directory tree node */
- d = malloc(sizeof(struct dosDirEntry));
- memcpy(d, &dirent, sizeof(struct dosDirEntry));
- /* link it into the directory tree */
- d->parent = dir;
- d->next = dir->child;
- dir->child = d;
- if (d->head >= CLUST_FIRST && d->head < boot->NumClusters)
- fat[d->head].dirp = d;
+ dirent.parent = dir;
+ dirent.next = dir->child;
+ if (dirent.head >= CLUST_FIRST && dirent.head < boot->NumClusters)
+ fat[dirent.head].flags |= FAT_USED;
- if (d->flags & ATTR_DIRECTORY) {
+ if (dirent.flags & ATTR_DIRECTORY) {
/*
* gather more info for directories
*/
struct dirTodoNode * n;
- if (d->size) {
+ if (dirent.size) {
pwarn("Directory %s has size != 0\n",
- d->fullpath);
+ fullpath(&dirent));
if (ask(1, "Correct")) {
p[28] = p[29] = p[30] = p[31] = 0;
- d->size = 0;
+ dirent.size = 0;
mod |= THISMOD|FSDIRMOD;
} else
mod |= FSERROR;
@@ -603,28 +715,29 @@ readDosDirSection(f, boot, fat, dir)
/*
* handle `.' and `..' specially
*/
- if (strcmp(d->name, ".") == 0) {
- if (d->head != dir->head) {
+ if (strcmp(dirent.name, ".") == 0) {
+ if (dirent.head != dir->head) {
pwarn("`.' entry in %s has incorrect start cluster\n",
- dir->fullpath);
+ fullpath(dir));
if (ask(1, "Correct")) {
- d->head = dir->head;
- p[26] = (u_char)d->head;
- p[27] = (u_char)(d->head >> 8);
+ dirent.head = dir->head;
+ p[26] = (u_char)dirent.head;
+ p[27] = (u_char)(dirent.head >> 8);
mod |= THISMOD|FSDIRMOD;
} else
mod |= FSERROR;
}
continue;
}
- if (strcmp(d->name, "..") == 0) {
- if (d->head != dir->parent->head) {
+ if (strcmp(dirent.name, "..") == 0) {
+ if (dir->parent /* XXX */
+ && dirent.head != dir->parent->head) {
pwarn("`..' entry in %s has incorrect start cluster\n",
- dir->fullpath);
+ fullpath(dir));
if (ask(1, "Correct")) {
- d->head = dir->parent->head;
- p[26] = (u_char)d->head;
- p[27] = (u_char)(d->head >> 8);
+ dirent.head = dir->parent->head;
+ p[26] = (u_char)dirent.head;
+ p[27] = (u_char)(dirent.head >> 8);
mod |= THISMOD|FSDIRMOD;
} else
mod |= FSERROR;
@@ -633,13 +746,27 @@ readDosDirSection(f, boot, fat, dir)
}
boot->NumFiles++;
+
+ /* create directory tree node */
+ if (!(d = newDosDirEntry())) {
+ perror("No space for directory");
+ return FSFATAL;
+ }
+
+ memcpy(d, &dirent, sizeof(struct dosDirEntry));
+ /* link it into the tree */
+ dir->child = d;
+
/* Enter this directory into the todo list */
- n = malloc(sizeof(struct dirTodoNode));
+ if (!(n = newDirTodo())) {
+ perror("No space for todo list");
+ return FSFATAL;
+ }
n->next = pendingDirectories;
n->dir = d;
pendingDirectories = n;
} else {
- mod |= k = checksize(boot, fat, p, d);
+ mod |= k = checksize(boot, fat, p, &dirent);
if (k & FSDIRMOD)
mod |= THISMOD;
boot->NumFiles++;
@@ -659,10 +786,60 @@ readDosDirSection(f, boot, fat, dir)
mod |= removede(f, boot, fat,
invlfn ? invlfn : vallfn, p,
invlfn ? invcl : valcl, -1, 0,
- dir->fullpath, 1);
+ fullpath(dir), 1);
return mod & ~THISMOD;
}
+int
+handleDirTree(dosfs, boot, fat)
+ int dosfs;
+ struct bootblock *boot;
+ struct fatEntry *fat;
+{
+ int mod;
+
+ mod = readDosDirSection(dosfs, boot, fat, rootDir);
+ if (mod & FSFATAL)
+ return FSFATAL;
+
+ if (mod & FSFATMOD) {
+ mod &= ~FSFATMOD;
+ mod |= writefat(dosfs, boot, fat); /* delay writing fats? XXX */
+ }
+
+ if (mod & FSFATAL)
+ return FSFATAL;
+
+ /*
+ * process the directory todo list
+ */
+ while (pendingDirectories) {
+ struct dosDirEntry *dir = pendingDirectories->dir;
+ struct dirTodoNode *n = pendingDirectories->next;
+
+ /*
+ * remove TODO entry now, the list might change during
+ * directory reads
+ */
+ freeDirTodo(pendingDirectories);
+ pendingDirectories = n;
+
+ /*
+ * handle subdirectory
+ */
+ mod |= readDosDirSection(dosfs, boot, fat, dir);
+ if (mod & FSFATAL)
+ return FSFATAL;
+ if (mod & FSFATMOD) {
+ mod &= ~FSFATMOD;
+ mod |= writefat(dosfs, boot, fat); /* delay writing fats? XXX */
+ }
+ if (mod & FSFATAL)
+ return FSFATAL;
+ }
+ return mod;
+}
+
/*
* Try to reconnect a FAT chain into dir
*/
@@ -671,18 +848,25 @@ static cl_t lfcl;
static off_t lfoff;
int
-reconnect(dosfs, boot, fat, head, dir)
+reconnect(dosfs, boot, fat, head)
int dosfs;
struct bootblock *boot;
struct fatEntry *fat;
cl_t head;
- struct dosDirEntry *dir;
{
struct dosDirEntry d;
u_char *p;
- if (!dir) /* Create lfdir? XXX */
- return FSERROR;
+ if (!lostDir) {
+ for (lostDir = rootDir->child; lostDir; lostDir = lostDir->next) {
+ if (!strcmp(lostDir->name, LOSTDIR))
+ break;
+ }
+ if (!lostDir) { /* Create LOSTDIR? XXX */
+ pwarn("No %s directory\n", LOSTDIR);
+ return FSERROR;
+ }
+ }
if (!lfbuf) {
lfbuf = malloc(boot->ClusterSize);
if (!lfbuf) {
@@ -700,9 +884,9 @@ reconnect(dosfs, boot, fat, head, dir)
break;
if (p && p < lfbuf + boot->ClusterSize)
break;
- lfcl = p ? fat[lfcl].next : dir->head;
+ lfcl = p ? fat[lfcl].next : lostDir->head;
if (lfcl < CLUST_FIRST || lfcl >= boot->NumClusters) {
- /* Extend lfdir? XXX */
+ /* Extend LOSTDIR? XXX */
pwarn("No space in %s\n", LOSTDIR);
return FSERROR;
}
@@ -723,26 +907,20 @@ reconnect(dosfs, boot, fat, head, dir)
/* Ensure uniqueness of entry here! XXX */
memset(&d, 0, sizeof d);
sprintf(d.name, "%d", head);
- d.fullpath = malloc(strlen(dir->fullpath) + strlen(d.name) + 2);
- sprintf(d.fullpath, "%s/%s", dir->fullpath, d.name);
d.flags = 0;
d.head = head;
d.size = fat[head].length * boot->ClusterSize;
- d.parent = dir;
- d.next = dir->child;
- dir->child = malloc(sizeof(struct dosDirEntry));
- memcpy(dir->child, &d, sizeof(struct dosDirEntry));
memset(p, 0, 32);
memset(p, ' ', 11);
- memcpy(p, dir->name, strlen(dir->name));
- p[26] = (u_char)dir->head;
- p[27] = (u_char)(dir->head >> 8);
- p[28] = (u_char)dir->size;
- p[29] = (u_char)(dir->size >> 8);
- p[30] = (u_char)(dir->size >> 16);
- p[31] = (u_char)(dir->size >> 24);
- fat[head].dirp = dir;
+ memcpy(p, d.name, strlen(d.name));
+ p[26] = (u_char)d.head;
+ p[27] = (u_char)(d.head >> 8);
+ p[28] = (u_char)d.size;
+ p[29] = (u_char)(d.size >> 8);
+ p[30] = (u_char)(d.size >> 16);
+ p[31] = (u_char)(d.size >> 24);
+ fat[head].flags |= FAT_USED;
if (lseek(dosfs, lfoff, SEEK_SET) != lfoff
|| write(dosfs, buffer, boot->ClusterSize) != boot->ClusterSize) {
perror("could not write LOST.DIR");
diff --git a/sbin/fsck_msdos/dosfs.h b/sbin/fsck_msdos/dosfs.h
index c0295bc7b10..e94bb8b0a60 100644
--- a/sbin/fsck_msdos/dosfs.h
+++ b/sbin/fsck_msdos/dosfs.h
@@ -1,3 +1,4 @@
+/* $NetBSD: dosfs.h,v 1.1.4.1 1996/05/31 18:41:42 jtc Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank
@@ -77,7 +78,7 @@ struct fatEntry {
cl_t next; /* pointer to next cluster */
cl_t head; /* pointer to start of chain */
u_int32_t length; /* number of clusters on chain */
- struct dosDirEntry *dirp; /* corresponding file name */
+ int flags; /* see below */
};
#define CLUST_FREE 0 /* 0 means cluster is free */
@@ -87,6 +88,8 @@ struct fatEntry {
#define CLUST_EOFS 0xfff8 /* start of EOF indicators */
#define CLUST_EOF 0xffff /* standard value for last cluster */
+#define FAT_USED 1 /* This fat chain is used in a file */
+
#define DOSLONGNAMELEN 256 /* long name maximal length */
#define LRFIRST 0x40 /* first long name record */
#define LRNOMASK 0x1f /* mask to extract long record
@@ -100,7 +103,6 @@ struct dosDirEntry {
*parent, /* previous tree level */
*next, /* next brother */
*child; /* if this is a directory */
- char *fullpath; /* path name from root to this directory */
char name[8+1+3+1]; /* alias name first part */
char lname[DOSLONGNAMELEN]; /* real name */
uint flags; /* attributes */
diff --git a/sbin/fsck_msdos/ext.h b/sbin/fsck_msdos/ext.h
index 63615e8e195..ae019457ed4 100644
--- a/sbin/fsck_msdos/ext.h
+++ b/sbin/fsck_msdos/ext.h
@@ -1,3 +1,5 @@
+/* $NetBSD: ext.h,v 1.1.4.1 1996/05/31 18:41:45 jtc Exp $ */
+
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank
* Copyright (c) 1995 Martin Husemann
@@ -35,17 +37,6 @@
#include <sys/types.h>
-#if sun
-#define __P(a) a
-
-typedef char int8_t;
-typedef unsigned char u_int8_t;
-typedef short int16_t;
-typedef unsigned short u_int16_t;
-typedef long int32_t;
-typedef unsigned long u_int32_t;
-#endif
-
#include "dosfs.h"
#define LOSTDIR "LOST.DIR"
@@ -60,6 +51,8 @@ extern int rdonly; /* device is opened read only (supersedes above) */
extern char *fname; /* filesystem currently checked */
+extern struct dosDirEntry *rootDir;
+
/*
* function declarations
*/
@@ -117,12 +110,7 @@ int writefat __P((int, struct bootblock *, struct fatEntry *));
*/
int resetDosDirSection __P((struct bootblock *));
void finishDosDirSection __P((void));
-int readDosDirSection __P((int, struct bootblock *, struct fatEntry *, struct dosDirEntry *));
-
-/*
- * A stack of directories which should be examined later
- */
-extern struct dirTodoNode *pendingDirectories;
+int handleDirTree __P((int, struct bootblock *, struct fatEntry *));
/*
* Cross-check routines run after everything is completely in memory
@@ -130,11 +118,11 @@ extern struct dirTodoNode *pendingDirectories;
/*
* Check for lost cluster chains
*/
-int checklost __P((int, struct bootblock *, struct fatEntry *, struct dosDirEntry *));
+int checklost __P((int, struct bootblock *, struct fatEntry *));
/*
* Try to reconnect a lost cluster chain
*/
-int reconnect __P((int, struct bootblock *, struct fatEntry *, cl_t, struct dosDirEntry *));
+int reconnect __P((int, struct bootblock *, struct fatEntry *, cl_t));
void finishlf __P((void));
/*
diff --git a/sbin/fsck_msdos/fat.c b/sbin/fsck_msdos/fat.c
index 6ebb99e529d..830f5d44d48 100644
--- a/sbin/fsck_msdos/fat.c
+++ b/sbin/fsck_msdos/fat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fat.c,v 1.1 1996/05/14 17:39:34 ws Exp $ */
+/* $NetBSD: fat.c,v 1.1.4.1 1996/05/31 18:41:50 jtc Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank
@@ -34,7 +34,7 @@
#ifndef lint
-static char rcsid[] = "$NetBSD: fat.c,v 1.1 1996/05/14 17:39:34 ws Exp $";
+static char rcsid[] = "$NetBSD: fat.c,v 1.1.4.1 1996/05/31 18:41:50 jtc Exp $";
#endif /* not lint */
#include <stdlib.h>
@@ -478,35 +478,28 @@ writefat(fs, boot, fat)
* Check a complete in-memory FAT for lost cluster chains
*/
int
-checklost(dosfs, boot, fat, rootDir)
+checklost(dosfs, boot, fat)
int dosfs;
struct bootblock *boot;
struct fatEntry *fat;
- struct dosDirEntry *rootDir;
{
cl_t head;
- struct dosDirEntry *lfdir;
int mod = FSOK;
- for (lfdir = rootDir->child; lfdir; lfdir = lfdir->next) {
- if (!strcmp(lfdir->name, LOSTDIR))
- break;
- }
for (head = CLUST_FIRST; head < boot->NumClusters; head++) {
/* find next untraveled chain */
if (fat[head].head != head
|| fat[head].next == CLUST_FREE
|| (fat[head].next >= CLUST_RSRVD
- && fat[head].next < CLUST_EOFS))
+ && fat[head].next < CLUST_EOFS)
+ || (fat[head].flags & FAT_USED))
continue;
- if (fat[head].dirp == NULL) {
- pwarn("Lost cluster chain at cluster 0x%04x\n%d Cluster(s) lost\n",
- head, fat[head].length);
- mod |= reconnect(dosfs, boot, fat, head, lfdir);
- if (mod&FSFATAL)
- break;
- }
+ pwarn("Lost cluster chain at cluster 0x%04x\n%d Cluster(s) lost\n",
+ head, fat[head].length);
+ mod |= reconnect(dosfs, boot, fat, head);
+ if (mod & FSFATAL)
+ break;
}
finishlf();
diff --git a/sbin/fsck_msdos/main.c b/sbin/fsck_msdos/main.c
index 67634aa278f..e786a9d76a3 100644
--- a/sbin/fsck_msdos/main.c
+++ b/sbin/fsck_msdos/main.c
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.1 1996/05/14 17:39:36 ws Exp $ */
+/* $NetBSD: main.c,v 1.1.4.1 1996/05/31 18:41:54 jtc Exp $ */
/*
* Copyright (C) 1995 Wolfgang Solfrank
@@ -34,7 +34,7 @@
#ifndef lint
-static char rcsid[] = "$NetBSD: main.c,v 1.1 1996/05/14 17:39:36 ws Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.1.4.1 1996/05/31 18:41:54 jtc Exp $";
#endif /* not lint */
#include <stdlib.h>
@@ -179,22 +179,6 @@ pwarn(fmt, va_alist)
va_end(ap);
}
-#if sun
-char *
-strerror(n)
- int n;
-{
- extern int sys_nerr;
- extern char *sys_errlist[];
- static char alt[80];
-
- if (n < sys_nerr)
- return sys_errlist[n];
- sprintf(alt, "Unknown error %d", n);
- return alt;
-}
-#endif
-
void
perror(s)
const char *s;
@@ -231,11 +215,7 @@ ask(def, fmt, va_alist)
#else
va_start(ap);
#endif
-#if sun
- vsprintf(prompt, fmt, ap);
-#else
vsnprintf(prompt, sizeof(prompt), fmt, ap);
-#endif
if (alwaysyes || rdonly) {
printf("%s? %s\n", prompt, rdonly ? "no" : "yes");
return !rdonly;