diff --git a/dosfstools/src/check.c b/dosfstools/src/check.c
new file mode 100644
index 0000000..3f175b0
--- /dev/null
+++ b/dosfstools/src/check.c
@@ -0,0 +1,1051 @@
+/* check.c - Check and repair a PC/MS-DOS file system
+
+   Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
+   Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+   On Debian systems, the complete text of the GNU General Public License
+   can be found in /usr/share/common-licenses/GPL-3 file.
+*/
+
+/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
+ * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <time.h>
+
+#include "common.h"
+#include "dosfsck.h"
+#include "io.h"
+#include "fat.h"
+#include "file.h"
+#include "lfn.h"
+#include "check.h"
+
+static DOS_FILE *root;
+
+/* get start field of a dir entry */
+#define FSTART(p,fs) \
+  ((unsigned long)CF_LE_W(p->dir_ent.start) | \
+   (fs->fat_bits == 32 ? CF_LE_W(p->dir_ent.starthi) << 16 : 0))
+
+#define MODIFY(p,i,v)					\
+  do {							\
+    if (p->offset) {					\
+	p->dir_ent.i = v;				\
+	fs_write(p->offset+offsetof(DIR_ENT,i),		\
+		 sizeof(p->dir_ent.i),&p->dir_ent.i);	\
+    }							\
+  } while(0)
+
+#define MODIFY_START(p,v,fs)						\
+  do {									\
+    unsigned long __v = (v);						\
+    if (!p->offset) {							\
+	/* writing to fake entry for FAT32 root dir */			\
+	if (!__v) die("Oops, deleting FAT32 root dir!");		\
+	fs->root_cluster = __v;						\
+	p->dir_ent.start = CT_LE_W(__v&0xffff);				\
+	p->dir_ent.starthi = CT_LE_W(__v>>16);				\
+	__v = CT_LE_L(__v);						\
+	fs_write((loff_t)offsetof(struct boot_sector,root_cluster),	\
+	         sizeof(((struct boot_sector *)0)->root_cluster),	\
+		 &__v);							\
+    }									\
+    else {								\
+	MODIFY(p,start,CT_LE_W((__v)&0xffff));				\
+	if (fs->fat_bits == 32)						\
+	    MODIFY(p,starthi,CT_LE_W((__v)>>16));			\
+    }									\
+  } while(0)
+
+loff_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern)
+{
+    static int curr_num = 0;
+    loff_t offset;
+
+    if (fs->root_cluster) {
+	DIR_ENT d2;
+	int i = 0, got = 0;
+	unsigned long clu_num, prev = 0;
+	loff_t offset2;
+
+	clu_num = fs->root_cluster;
+	offset = cluster_start(fs, clu_num);
+	while (clu_num > 0 && clu_num != -1) {
+	    fs_read(offset, sizeof(DIR_ENT), &d2);
+	    if (IS_FREE(d2.name) && d2.attr != VFAT_LN_ATTR) {
+		got = 1;
+		break;
+	    }
+	    i += sizeof(DIR_ENT);
+	    offset += sizeof(DIR_ENT);
+	    if ((i % fs->cluster_size) == 0) {
+		prev = clu_num;
+		if ((clu_num = next_cluster(fs, clu_num)) == 0 || clu_num == -1)
+		    break;
+		offset = cluster_start(fs, clu_num);
+	    }
+	}
+	if (!got) {
+	    /* no free slot, need to extend root dir: alloc next free cluster
+	     * after previous one */
+	    if (!prev)
+		die("Root directory has no cluster allocated!");
+	    for (clu_num = prev + 1; clu_num != prev; clu_num++) {
+		FAT_ENTRY entry;
+
+		if (clu_num >= fs->clusters + 2)
+		    clu_num = 2;
+		get_fat(&entry, fs->fat, clu_num, fs);
+		if (!entry.value)
+		    break;
+	    }
+	    if (clu_num == prev)
+		die("Root directory full and no free cluster");
+	    set_fat(fs, prev, clu_num);
+	    set_fat(fs, clu_num, -1);
+	    set_owner(fs, clu_num, get_owner(fs, fs->root_cluster));
+	    /* clear new cluster */
+	    memset(&d2, 0, sizeof(d2));
+	    offset = cluster_start(fs, clu_num);
+	    for (i = 0; i < fs->cluster_size; i += sizeof(DIR_ENT))
+		fs_write(offset + i, sizeof(d2), &d2);
+	}
+	memset(de, 0, sizeof(DIR_ENT));
+	while (1) {
+	    char expanded[12];
+	    sprintf(expanded, pattern, curr_num);
+	    memcpy(de->name + 4, expanded, 4);
+	    memcpy(de->ext, expanded + 4, 3);
+	    clu_num = fs->root_cluster;
+	    i = 0;
+	    offset2 = cluster_start(fs, clu_num);
+	    while (clu_num > 0 && clu_num != -1) {
+		fs_read(offset2, sizeof(DIR_ENT), &d2);
+		if (offset2 != offset &&
+		    !strncmp((const char *)d2.name, (const char *)de->name,
+			     MSDOS_NAME))
+		    break;
+		i += sizeof(DIR_ENT);
+		offset2 += sizeof(DIR_ENT);
+		if ((i % fs->cluster_size) == 0) {
+		    if ((clu_num = next_cluster(fs, clu_num)) == 0 ||
+			clu_num == -1)
+			break;
+		    offset2 = cluster_start(fs, clu_num);
+		}
+	    }
+	    if (clu_num == 0 || clu_num == -1)
+		break;
+	    if (++curr_num >= 10000)
+		die("Unable to create unique name");
+	}
+    } else {
+	DIR_ENT *root;
+	int next_free = 0, scan;
+
+	root = alloc(fs->root_entries * sizeof(DIR_ENT));
+	fs_read(fs->root_start, fs->root_entries * sizeof(DIR_ENT), root);
+
+	while (next_free < fs->root_entries)
+	    if (IS_FREE(root[next_free].name) &&
+		root[next_free].attr != VFAT_LN_ATTR)
+		break;
+	    else
+		next_free++;
+	if (next_free == fs->root_entries)
+	    die("Root directory is full.");
+	offset = fs->root_start + next_free * sizeof(DIR_ENT);
+	memset(de, 0, sizeof(DIR_ENT));
+	while (1) {
+	    sprintf((char *)de->name, pattern, curr_num);
+	    for (scan = 0; scan < fs->root_entries; scan++)
+		if (scan != next_free &&
+		    !strncmp((const char *)root[scan].name,
+			     (const char *)de->name, MSDOS_NAME))
+		    break;
+	    if (scan == fs->root_entries)
+		break;
+	    if (++curr_num >= 10000)
+		die("Unable to create unique name");
+	}
+	free(root);
+    }
+    ++n_files;
+    return offset;
+}
+
+/**
+ * Construct a full path (starting with '/') for the specified dentry,
+ * relative to the partition. All components are "long" names where possible.
+ *
+ * @param[in]   file    Information about dentry (file or directory) of interest
+ *
+ * return       Pointer to static string containing file's full path
+ */
+static char *path_name(DOS_FILE * file)
+{
+    static char path[PATH_MAX * 2];
+
+    if (!file)
+	*path = 0;		/* Reached the root directory */
+    else {
+	if (strlen(path_name(file->parent)) > PATH_MAX)
+	    die("Path name too long.");
+	if (strcmp(path, "/") != 0)
+	    strcat(path, "/");
+
+	/* Append the long name to the path,
+	 * or the short name if there isn't a long one
+	 */
+	strcpy(strrchr(path, 0),
+	       file->lfn ? file->lfn : file_name(file->dir_ent.name));
+    }
+    return path;
+}
+
+static int day_n[] =
+    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0 };
+		  /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
+
+/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
+
+time_t date_dos2unix(unsigned short time, unsigned short date)
+{
+    int month, year;
+    time_t secs;
+
+    month = ((date >> 5) & 15) - 1;
+    year = date >> 9;
+    secs =
+	(time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 +
+	86400 * ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 -
+		 ((year & 3) == 0 && month < 2 ? 1 : 0) + 3653);
+    /* days since 1.1.70 plus 80's leap day */
+    return secs;
+}
+
+static char *file_stat(DOS_FILE * file)
+{
+    static char temp[100];
+    struct tm *tm;
+    char tmp[100];
+    time_t date;
+
+    date =
+	date_dos2unix(CF_LE_W(file->dir_ent.time), CF_LE_W(file->dir_ent.date));
+    tm = localtime(&date);
+    strftime(tmp, 99, "%H:%M:%S %b %d %Y", tm);
+    sprintf(temp, "  Size %u bytes, date %s", CF_LE_L(file->dir_ent.size), tmp);
+    return temp;
+}
+
+static int bad_name(DOS_FILE * file)
+{
+    int i, spc, suspicious = 0;
+    char *bad_chars = atari_format ? "*?\\/:" : "*?<>|\"\\/:";
+    unsigned char *name = file->dir_ent.name;
+
+    /* Do not complain about (and auto-correct) the extended attribute files
+     * of OS/2. */
+    if (strncmp((const char *)name, "EA DATA  SF", 11) == 0 ||
+	strncmp((const char *)name, "WP ROOT  SF", 11) == 0)
+	return 0;
+
+    /* don't complain about the dummy 11 bytes used by patched Linux
+       kernels */
+    if (file->dir_ent.lcase & FAT_NO_83NAME)
+	return 0;
+
+    for (i = 0; i < 8; i++) {
+	if (name[i] < ' ' || name[i] == 0x7f)
+	    return 1;
+	if (name[i] > 0x7f)
+	    ++suspicious;
+	if (strchr(bad_chars, name[i]))
+	    return 1;
+    }
+
+    for (i = 8; i < 11; i++) {
+	if (name[i] < ' ' || name[i] == 0x7f)
+	    return 1;
+	if (name[i] > 0x7f)
+	    ++suspicious;
+	if (strchr(bad_chars, name[i]))
+	    return 1;
+    }
+
+    spc = 0;
+    for (i = 0; i < 8; i++) {
+	if (name[i] == ' ')
+	    spc = 1;
+	else if (spc)
+	    /* non-space after a space not allowed, space terminates the name
+	     * part */
+	    return 1;
+    }
+
+    spc = 0;
+    for (i = 8; i < 11; i++) {
+	if (name[i] == ' ')
+	    spc = 1;
+	else if (spc)
+	    /* non-space after a space not allowed, space terminates the name
+	     * part */
+	    return 1;
+    }
+
+    /* Under GEMDOS, chars >= 128 are never allowed. */
+    if (atari_format && suspicious)
+	return 1;
+
+    /* Under MS-DOS and Windows, chars >= 128 in short names are valid
+     * (but these characters can be visualised differently depending on
+     * local codepage: CP437, CP866, etc). The chars are all basically ok,
+     * so we shouldn't auto-correct such names. */
+    return 0;
+}
+
+static void lfn_remove(loff_t from, loff_t to)
+{
+    DIR_ENT empty;
+
+    /* New dir entry is zeroed except first byte, which is set to 0xe5.
+     * This is to avoid that some FAT-reading OSes (not Linux! ;) stop reading
+     * a directory at the first zero entry...
+     */
+    memset(&empty, 0, sizeof(empty));
+    empty.name[0] = DELETED_FLAG;
+
+    for (; from < to; from += sizeof(empty)) {
+	fs_write(from, sizeof(DIR_ENT), &empty);
+    }
+}
+
+static void drop_file(DOS_FS * fs, DOS_FILE * file)
+{
+    unsigned long cluster;
+
+    MODIFY(file, name[0], DELETED_FLAG);
+    if (file->lfn)
+	lfn_remove(file->lfn_offset, file->offset);
+    for (cluster = FSTART(file, fs); cluster > 0 && cluster <
+	 fs->clusters + 2; cluster = next_cluster(fs, cluster))
+	set_owner(fs, cluster, NULL);
+    --n_files;
+}
+
+static void truncate_file(DOS_FS * fs, DOS_FILE * file, unsigned long clusters)
+{
+    int deleting;
+    unsigned long walk, next, prev;
+
+    walk = FSTART(file, fs);
+    prev = 0;
+    if ((deleting = !clusters))
+	MODIFY_START(file, 0, fs);
+    while (walk > 0 && walk != -1) {
+	next = next_cluster(fs, walk);
+	if (deleting)
+	    set_fat(fs, walk, 0);
+	else if ((deleting = !--clusters))
+	    set_fat(fs, walk, -1);
+	prev = walk;
+	walk = next;
+    }
+}
+
+static void auto_rename(DOS_FILE * file)
+{
+    DOS_FILE *first, *walk;
+    unsigned long int number;
+
+    if (!file->offset)
+	return;			/* cannot rename FAT32 root dir */
+    first = file->parent ? file->parent->first : root;
+    number = 0;
+    while (1) {
+	char num[8];
+	sprintf(num, "%07lu", number);
+	memcpy(file->dir_ent.name, "FSCK", 4);
+	memcpy(file->dir_ent.name + 4, num, 4);
+	memcpy(file->dir_ent.ext, num + 4, 3);
+	for (walk = first; walk; walk = walk->next)
+	    if (walk != file
+		&& !strncmp((const char *)walk->dir_ent.name,
+			    (const char *)file->dir_ent.name, MSDOS_NAME))
+		break;
+	if (!walk) {
+	    fs_write(file->offset, MSDOS_NAME, file->dir_ent.name);
+	    if (file->lfn)
+		lfn_fix_checksum(file->lfn_offset, file->offset,
+				 (const char *)file->dir_ent.name);
+	    return;
+	}
+	number++;
+	if (number > 9999999) {
+	    die("Too many files need repair.");
+	}
+    }
+    die("Can't generate a unique name.");
+}
+
+static void rename_file(DOS_FILE * file)
+{
+    unsigned char name[46];
+    unsigned char *walk, *here;
+
+    if (!file->offset) {
+	printf("Cannot rename FAT32 root dir\n");
+	return;			/* cannot rename FAT32 root dir */
+    }
+    while (1) {
+	printf("New name: ");
+	fflush(stdout);
+	if (fgets((char *)name, 45, stdin)) {
+	    if ((here = (unsigned char *)strchr((const char *)name, '\n')))
+		*here = 0;
+	    for (walk = (unsigned char *)strrchr((const char *)name, 0);
+		 walk >= name && (*walk == ' ' || *walk == '\t'); walk--) ;
+	    walk[1] = 0;
+	    for (walk = name; *walk == ' ' || *walk == '\t'; walk++) ;
+	    if (file_cvt(walk, file->dir_ent.name)) {
+		fs_write(file->offset, MSDOS_NAME, file->dir_ent.name);
+		if (file->lfn)
+		    lfn_fix_checksum(file->lfn_offset, file->offset,
+				     (const char *)file->dir_ent.name);
+		return;
+	    }
+	}
+    }
+}
+
+static int handle_dot(DOS_FS * fs, DOS_FILE * file, int dots)
+{
+    char *name;
+
+    name =
+	strncmp((const char *)file->dir_ent.name, MSDOS_DOT,
+		MSDOS_NAME) ? ".." : ".";
+    if (!(file->dir_ent.attr & ATTR_DIR)) {
+	printf("%s\n  Is a non-directory.\n", path_name(file));
+	if (interactive)
+	    printf("1) Drop it\n2) Auto-rename\n3) Rename\n"
+		   "4) Convert to directory\n");
+	else
+	    printf("  Auto-renaming it.\n");
+	switch (interactive ? get_key("1234", "?") : '2') {
+	case '1':
+	    drop_file(fs, file);
+	    return 1;
+	case '2':
+	    auto_rename(file);
+	    printf("  Renamed to %s\n", file_name(file->dir_ent.name));
+	    return 0;
+	case '3':
+	    rename_file(file);
+	    return 0;
+	case '4':
+	    MODIFY(file, size, CT_LE_L(0));
+	    MODIFY(file, attr, file->dir_ent.attr | ATTR_DIR);
+	    break;
+	}
+    }
+    if (!dots) {
+	printf("Root contains directory \"%s\". Dropping it.\n", name);
+	drop_file(fs, file);
+	return 1;
+    }
+    return 0;
+}
+
+static int check_file(DOS_FS * fs, DOS_FILE * file)
+{
+    DOS_FILE *owner;
+    int restart;
+    unsigned long expect, curr, this, clusters, prev, walk, clusters2;
+
+    if (file->dir_ent.attr & ATTR_DIR) {
+	if (CF_LE_L(file->dir_ent.size)) {
+	    printf("%s\n  Directory has non-zero size. Fixing it.\n",
+		   path_name(file));
+	    MODIFY(file, size, CT_LE_L(0));
+	}
+	if (file->parent
+	    && !strncmp((const char *)file->dir_ent.name, MSDOS_DOT,
+			MSDOS_NAME)) {
+	    expect = FSTART(file->parent, fs);
+	    if (FSTART(file, fs) != expect) {
+		printf("%s\n  Start (%ld) does not point to parent (%ld)\n",
+		       path_name(file), FSTART(file, fs), expect);
+		MODIFY_START(file, expect, fs);
+	    }
+	    return 0;
+	}
+	if (file->parent
+	    && !strncmp((const char *)file->dir_ent.name, MSDOS_DOTDOT,
+			MSDOS_NAME)) {
+	    expect =
+		file->parent->parent ? FSTART(file->parent->parent, fs) : 0;
+	    if (fs->root_cluster && expect == fs->root_cluster)
+		expect = 0;
+	    if (FSTART(file, fs) != expect) {
+		printf("%s\n  Start (%lu) does not point to .. (%lu)\n",
+		       path_name(file), FSTART(file, fs), expect);
+		MODIFY_START(file, expect, fs);
+	    }
+	    return 0;
+	}
+	if (FSTART(file, fs) == 0) {
+	    printf("%s\n Start does point to root directory. Deleting dir. \n",
+		   path_name(file));
+	    MODIFY(file, name[0], DELETED_FLAG);
+	    return 0;
+	}
+    }
+    if (FSTART(file, fs) >= fs->clusters + 2) {
+	printf
+	    ("%s\n  Start cluster beyond limit (%lu > %lu). Truncating file.\n",
+	     path_name(file), FSTART(file, fs), fs->clusters + 1);
+	if (!file->offset)
+	    die("Bad FAT32 root directory! (bad start cluster)\n");
+	MODIFY_START(file, 0, fs);
+    }
+    clusters = prev = 0;
+    for (curr = FSTART(file, fs) ? FSTART(file, fs) :
+	 -1; curr != -1; curr = next_cluster(fs, curr)) {
+	FAT_ENTRY curEntry;
+	get_fat(&curEntry, fs->fat, curr, fs);
+
+	if (!curEntry.value || bad_cluster(fs, curr)) {
+	    printf("%s\n  Contains a %s cluster (%lu). Assuming EOF.\n",
+		   path_name(file), curEntry.value ? "bad" : "free", curr);
+	    if (prev)
+		set_fat(fs, prev, -1);
+	    else if (!file->offset)
+		die("FAT32 root dir starts with a bad cluster!");
+	    else
+		MODIFY_START(file, 0, fs);
+	    break;
+	}
+	if (!(file->dir_ent.attr & ATTR_DIR) && CF_LE_L(file->dir_ent.size) <=
+	    (unsigned long long)clusters * fs->cluster_size) {
+	    printf
+		("%s\n  File size is %u bytes, cluster chain length is > %llu "
+		 "bytes.\n  Truncating file to %u bytes.\n", path_name(file),
+		 CF_LE_L(file->dir_ent.size),
+		 (unsigned long long)clusters * fs->cluster_size,
+		 CF_LE_L(file->dir_ent.size));
+	    truncate_file(fs, file, clusters);
+	    break;
+	}
+	if ((owner = get_owner(fs, curr))) {
+	    int do_trunc = 0;
+	    printf("%s  and\n", path_name(owner));
+	    printf("%s\n  share clusters.\n", path_name(file));
+	    clusters2 = 0;
+	    for (walk = FSTART(owner, fs); walk > 0 && walk != -1; walk =
+		 next_cluster(fs, walk))
+		if (walk == curr)
+		    break;
+		else
+		    clusters2++;
+	    restart = file->dir_ent.attr & ATTR_DIR;
+	    if (!owner->offset) {
+		printf("  Truncating second to %llu bytes because first "
+		       "is FAT32 root dir.\n",
+		       (unsigned long long)clusters2 * fs->cluster_size);
+		do_trunc = 2;
+	    } else if (!file->offset) {
+		printf("  Truncating first to %llu bytes because second "
+		       "is FAT32 root dir.\n",
+		       (unsigned long long)clusters * fs->cluster_size);
+		do_trunc = 1;
+	    } else if (interactive)
+		printf("1) Truncate first to %llu bytes%s\n"
+		       "2) Truncate second to %llu bytes\n",
+		       (unsigned long long)clusters * fs->cluster_size,
+		       restart ? " and restart" : "",
+		       (unsigned long long)clusters2 * fs->cluster_size);
+	    else
+		printf("  Truncating second to %llu bytes.\n",
+		       (unsigned long long)clusters2 * fs->cluster_size);
+	    if (do_trunc != 2
+		&& (do_trunc == 1
+		    || (interactive && get_key("12", "?") == '1'))) {
+		prev = 0;
+		clusters = 0;
+		for (this = FSTART(owner, fs); this > 0 && this != -1; this =
+		     next_cluster(fs, this)) {
+		    if (this == curr) {
+			if (prev)
+			    set_fat(fs, prev, -1);
+			else
+			    MODIFY_START(owner, 0, fs);
+			MODIFY(owner, size,
+			       CT_LE_L((unsigned long long)clusters *
+				       fs->cluster_size));
+			if (restart)
+			    return 1;
+			while (this > 0 && this != -1) {
+			    set_owner(fs, this, NULL);
+			    this = next_cluster(fs, this);
+			}
+			this = curr;
+			break;
+		    }
+		    clusters++;
+		    prev = this;
+		}
+		if (this != curr)
+		    die("Internal error: didn't find cluster %d in chain"
+			" starting at %d", curr, FSTART(owner, fs));
+	    } else {
+		if (prev)
+		    set_fat(fs, prev, -1);
+		else
+		    MODIFY_START(file, 0, fs);
+		break;
+	    }
+	}
+	set_owner(fs, curr, file);
+	clusters++;
+	prev = curr;
+    }
+    if (!(file->dir_ent.attr & ATTR_DIR) && CF_LE_L(file->dir_ent.size) >
+	(unsigned long long)clusters * fs->cluster_size) {
+	printf
+	    ("%s\n  File size is %u bytes, cluster chain length is %llu bytes."
+	     "\n  Truncating file to %llu bytes.\n", path_name(file),
+	     CF_LE_L(file->dir_ent.size),
+	     (unsigned long long)clusters * fs->cluster_size,
+	     (unsigned long long)clusters * fs->cluster_size);
+	MODIFY(file, size,
+	       CT_LE_L((unsigned long long)clusters * fs->cluster_size));
+    }
+    return 0;
+}
+
+static int check_files(DOS_FS * fs, DOS_FILE * start)
+{
+    while (start) {
+	if (check_file(fs, start))
+	    return 1;
+	start = start->next;
+    }
+    return 0;
+}
+
+static int check_dir(DOS_FS * fs, DOS_FILE ** root, int dots)
+{
+    DOS_FILE *parent, **walk, **scan;
+    int dot, dotdot, skip, redo;
+    int good, bad;
+
+    if (!*root)
+	return 0;
+    parent = (*root)->parent;
+    good = bad = 0;
+    for (walk = root; *walk; walk = &(*walk)->next)
+	if (bad_name(*walk))
+	    bad++;
+	else
+	    good++;
+    if (*root && parent && good + bad > 4 && bad > good / 2) {
+	printf("%s\n  Has a large number of bad entries. (%d/%d)\n",
+	       path_name(parent), bad, good + bad);
+	if (!dots)
+	    printf("  Not dropping root directory.\n");
+	else if (!interactive)
+	    printf("  Not dropping it in auto-mode.\n");
+	else if (get_key("yn", "Drop directory ? (y/n)") == 'y') {
+	    truncate_file(fs, parent, 0);
+	    MODIFY(parent, name[0], DELETED_FLAG);
+	    /* buglet: deleted directory stays in the list. */
+	    return 1;
+	}
+    }
+    dot = dotdot = redo = 0;
+    walk = root;
+    while (*walk) {
+	if (!strncmp
+	    ((const char *)((*walk)->dir_ent.name), MSDOS_DOT, MSDOS_NAME)
+	    || !strncmp((const char *)((*walk)->dir_ent.name), MSDOS_DOTDOT,
+			MSDOS_NAME)) {
+	    if (handle_dot(fs, *walk, dots)) {
+		*walk = (*walk)->next;
+		continue;
+	    }
+	    if (!strncmp
+		((const char *)((*walk)->dir_ent.name), MSDOS_DOT, MSDOS_NAME))
+		dot++;
+	    else
+		dotdot++;
+	}
+	if (!((*walk)->dir_ent.attr & ATTR_VOLUME) && bad_name(*walk)) {
+	    puts(path_name(*walk));
+	    printf("  Bad short file name (%s).\n",
+		   file_name((*walk)->dir_ent.name));
+	    if (interactive)
+		printf("1) Drop file\n2) Rename file\n3) Auto-rename\n"
+		       "4) Keep it\n");
+	    else
+		printf("  Auto-renaming it.\n");
+	    switch (interactive ? get_key("1234", "?") : '3') {
+	    case '1':
+		drop_file(fs, *walk);
+		walk = &(*walk)->next;
+		continue;
+	    case '2':
+		rename_file(*walk);
+		redo = 1;
+		break;
+	    case '3':
+		auto_rename(*walk);
+		printf("  Renamed to %s\n", file_name((*walk)->dir_ent.name));
+		break;
+	    case '4':
+		break;
+	    }
+	}
+	/* don't check for duplicates of the volume label */
+	if (!((*walk)->dir_ent.attr & ATTR_VOLUME)) {
+	    scan = &(*walk)->next;
+	    skip = 0;
+	    while (*scan && !skip) {
+		if (!((*scan)->dir_ent.attr & ATTR_VOLUME) &&
+		    !memcmp((*walk)->dir_ent.name, (*scan)->dir_ent.name,
+			    MSDOS_NAME)) {
+		    printf("%s\n  Duplicate directory entry.\n  First  %s\n",
+			   path_name(*walk), file_stat(*walk));
+		    printf("  Second %s\n", file_stat(*scan));
+		    if (interactive)
+			printf
+			    ("1) Drop first\n2) Drop second\n3) Rename first\n"
+			     "4) Rename second\n5) Auto-rename first\n"
+			     "6) Auto-rename second\n");
+		    else
+			printf("  Auto-renaming second.\n");
+		    switch (interactive ? get_key("123456", "?") : '6') {
+		    case '1':
+			drop_file(fs, *walk);
+			*walk = (*walk)->next;
+			skip = 1;
+			break;
+		    case '2':
+			drop_file(fs, *scan);
+			*scan = (*scan)->next;
+			continue;
+		    case '3':
+			rename_file(*walk);
+			printf("  Renamed to %s\n", path_name(*walk));
+			redo = 1;
+			break;
+		    case '4':
+			rename_file(*scan);
+			printf("  Renamed to %s\n", path_name(*walk));
+			redo = 1;
+			break;
+		    case '5':
+			auto_rename(*walk);
+			printf("  Renamed to %s\n",
+			       file_name((*walk)->dir_ent.name));
+			break;
+		    case '6':
+			auto_rename(*scan);
+			printf("  Renamed to %s\n",
+			       file_name((*scan)->dir_ent.name));
+			break;
+		    }
+		}
+		scan = &(*scan)->next;
+	    }
+	    if (skip)
+		continue;
+	}
+	if (!redo)
+	    walk = &(*walk)->next;
+	else {
+	    walk = root;
+	    dot = dotdot = redo = 0;
+	}
+    }
+    if (dots && !dot)
+	printf("%s\n  \".\" is missing. Can't fix this yet.\n",
+	       path_name(parent));
+    if (dots && !dotdot)
+	printf("%s\n  \"..\" is missing. Can't fix this yet.\n",
+	       path_name(parent));
+    return 0;
+}
+
+/**
+ * Check a dentry's cluster chain for bad clusters.
+ * If requested, we verify readability and mark unreadable clusters as bad.
+ *
+ * @param[inout]    fs          Information about the filesystem
+ * @param[in]       file        dentry to check
+ * @param[in]       read_test   Nonzero == verify that dentry's clusters can
+ *                              be read
+ */
+static void test_file(DOS_FS * fs, DOS_FILE * file, int read_test)
+{
+    DOS_FILE *owner;
+    unsigned long walk, prev, clusters, next_clu;
+
+    prev = clusters = 0;
+    for (walk = FSTART(file, fs); walk > 0 && walk < fs->clusters + 2;
+	 walk = next_clu) {
+	next_clu = next_cluster(fs, walk);
+
+	/* In this stage we are checking only for a loop within our own
+	 * cluster chain.
+	 * Cross-linking of clusters is handled in check_file()
+	 */
+	if ((owner = get_owner(fs, walk))) {
+	    if (owner == file) {
+		printf("%s\n  Circular cluster chain. Truncating to %lu "
+		       "cluster%s.\n", path_name(file), clusters,
+		       clusters == 1 ? "" : "s");
+		if (prev)
+		    set_fat(fs, prev, -1);
+		else if (!file->offset)
+		    die("Bad FAT32 root directory! (bad start cluster)\n");
+		else
+		    MODIFY_START(file, 0, fs);
+	    }
+	    break;
+	}
+	if (bad_cluster(fs, walk))
+	    break;
+	if (read_test) {
+	    if (fs_test(cluster_start(fs, walk), fs->cluster_size)) {
+		prev = walk;
+		clusters++;
+	    } else {
+		printf("%s\n  Cluster %lu (%lu) is unreadable. Skipping it.\n",
+		       path_name(file), clusters, walk);
+		if (prev)
+		    set_fat(fs, prev, next_cluster(fs, walk));
+		else
+		    MODIFY_START(file, next_cluster(fs, walk), fs);
+		set_fat(fs, walk, -2);
+	    }
+	}
+	set_owner(fs, walk, file);
+    }
+    /* Revert ownership (for now) */
+    for (walk = FSTART(file, fs); walk > 0 && walk < fs->clusters + 2;
+	 walk = next_cluster(fs, walk))
+	if (bad_cluster(fs, walk))
+	    break;
+	else if (get_owner(fs, walk) == file)
+	    set_owner(fs, walk, NULL);
+	else
+	    break;
+}
+
+static void undelete(DOS_FS * fs, DOS_FILE * file)
+{
+    unsigned long clusters, left, prev, walk;
+
+    clusters = left = (CF_LE_L(file->dir_ent.size) + fs->cluster_size - 1) /
+	fs->cluster_size;
+    prev = 0;
+
+    walk = FSTART(file, fs);
+
+    while (left && (walk >= 2) && (walk < fs->clusters + 2)) {
+
+	FAT_ENTRY curEntry;
+	get_fat(&curEntry, fs->fat, walk, fs);
+
+	if (!curEntry.value)
+	    break;
+
+	left--;
+	if (prev)
+	    set_fat(fs, prev, walk);
+	prev = walk;
+	walk++;
+    }
+    if (prev)
+	set_fat(fs, prev, -1);
+    else
+	MODIFY_START(file, 0, fs);
+    if (left)
+	printf("Warning: Did only undelete %lu of %lu cluster%s.\n",
+	       clusters - left, clusters, clusters == 1 ? "" : "s");
+
+}
+
+static void new_dir(void)
+{
+    lfn_reset();
+}
+
+/**
+ * Create a description for a referenced dentry and insert it in our dentry
+ * tree. Then, go check the dentry's cluster chain for bad clusters and
+ * cluster loops.
+ *
+ * @param[inout]    fs      Information about the filesystem
+ * @param[out]      chain
+ * @param[in]       parent  Information about parent directory of this file
+ *                          NULL == no parent ('file' is root directory)
+ * @param[in]       offset  Partition-relative byte offset of directory entry of interest
+ *                          0 == Root directory
+ * @param           cp
+ */
+static void add_file(DOS_FS * fs, DOS_FILE *** chain, DOS_FILE * parent,
+		     loff_t offset, FDSC ** cp)
+{
+    DOS_FILE *new;
+    DIR_ENT de;
+    FD_TYPE type;
+
+    if (offset)
+	fs_read(offset, sizeof(DIR_ENT), &de);
+    else {
+	/* Construct a DIR_ENT for the root directory */
+	memcpy(de.name, "           ", MSDOS_NAME);
+	de.attr = ATTR_DIR;
+	de.size = de.time = de.date = 0;
+	de.start = CT_LE_W(fs->root_cluster & 0xffff);
+	de.starthi = CT_LE_W((fs->root_cluster >> 16) & 0xffff);
+    }
+    if ((type = file_type(cp, (char *)de.name)) != fdt_none) {
+	if (type == fdt_undelete && (de.attr & ATTR_DIR))
+	    die("Can't undelete directories.");
+	file_modify(cp, (char *)de.name);
+	fs_write(offset, 1, &de);
+    }
+    if (IS_FREE(de.name)) {
+	lfn_check_orphaned();
+	return;
+    }
+    if (de.attr == VFAT_LN_ATTR) {
+	lfn_add_slot(&de, offset);
+	return;
+    }
+    new = qalloc(&mem_queue, sizeof(DOS_FILE));
+    new->lfn = lfn_get(&de, &new->lfn_offset);
+    new->offset = offset;
+    memcpy(&new->dir_ent, &de, sizeof(de));
+    new->next = new->first = NULL;
+    new->parent = parent;
+    if (type == fdt_undelete)
+	undelete(fs, new);
+    **chain = new;
+    *chain = &new->next;
+    if (list) {
+	printf("Checking file %s", path_name(new));
+	if (new->lfn)
+	    printf(" (%s)", file_name(new->dir_ent.name));	/* (8.3) */
+	printf("\n");
+    }
+    /* Don't include root directory, '.', or '..' in the total file count */
+    if (offset &&
+	strncmp((const char *)de.name, MSDOS_DOT, MSDOS_NAME) != 0 &&
+	strncmp((const char *)de.name, MSDOS_DOTDOT, MSDOS_NAME) != 0)
+	++n_files;
+    test_file(fs, new, test);	/* Bad cluster check */
+}
+
+static int subdirs(DOS_FS * fs, DOS_FILE * parent, FDSC ** cp);
+
+static int scan_dir(DOS_FS * fs, DOS_FILE * this, FDSC ** cp)
+{
+    DOS_FILE **chain;
+    int i;
+    unsigned long clu_num;
+
+    chain = &this->first;
+    i = 0;
+    clu_num = FSTART(this, fs);
+    new_dir();
+    while (clu_num > 0 && clu_num != -1) {
+	add_file(fs, &chain, this,
+		 cluster_start(fs, clu_num) + (i % fs->cluster_size), cp);
+	i += sizeof(DIR_ENT);
+	if (!(i % fs->cluster_size))
+	    if ((clu_num = next_cluster(fs, clu_num)) == 0 || clu_num == -1)
+		break;
+    }
+    lfn_check_orphaned();
+    if (check_dir(fs, &this->first, this->offset))
+	return 0;
+    if (check_files(fs, this->first))
+	return 1;
+    return subdirs(fs, this, cp);
+}
+
+/**
+ * Recursively scan subdirectories of the specified parent directory.
+ *
+ * @param[inout]    fs      Information about the filesystem
+ * @param[in]       parent  Identifies the directory to scan
+ * @param[in]       cp
+ *
+ * @return  0   Success
+ * @return  1   Error
+ */
+static int subdirs(DOS_FS * fs, DOS_FILE * parent, FDSC ** cp)
+{
+    DOS_FILE *walk;
+
+    for (walk = parent ? parent->first : root; walk; walk = walk->next)
+	if (walk->dir_ent.attr & ATTR_DIR)
+	    if (strncmp((const char *)walk->dir_ent.name, MSDOS_DOT, MSDOS_NAME)
+		&& strncmp((const char *)walk->dir_ent.name, MSDOS_DOTDOT,
+			   MSDOS_NAME))
+		if (scan_dir(fs, walk, file_cd(cp, (char *)walk->dir_ent.name)))
+		    return 1;
+    return 0;
+}
+
+/**
+ * Scan all directory and file information for errors.
+ *
+ * @param[inout]    fs      Information about the filesystem
+ *
+ * @return  0   Success
+ * @return  1   Error
+ */
+int scan_root(DOS_FS * fs)
+{
+    DOS_FILE **chain;
+    int i;
+
+    root = NULL;
+    chain = &root;
+    new_dir();
+    if (fs->root_cluster) {
+	add_file(fs, &chain, NULL, 0, &fp_root);
+    } else {
+	for (i = 0; i < fs->root_entries; i++)
+	    add_file(fs, &chain, NULL, fs->root_start + i * sizeof(DIR_ENT),
+		     &fp_root);
+    }
+    lfn_check_orphaned();
+    (void)check_dir(fs, &root, 0);
+    if (check_files(fs, root))
+	return 1;
+    return subdirs(fs, NULL, &fp_root);
+}
