From a72361c15b80c8dbedfab7d4281a74712fdcd14f Mon Sep 17 00:00:00 2001 From: obrien Date: Mon, 9 Jul 2001 10:35:18 +0000 Subject: Add fsck_msdosfs. Obtained from: NetBSD --- sbin/fsck_msdosfs/check.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 sbin/fsck_msdosfs/check.c (limited to 'sbin/fsck_msdosfs/check.c') diff --git a/sbin/fsck_msdosfs/check.c b/sbin/fsck_msdosfs/check.c new file mode 100644 index 0000000..2a7ccc7 --- /dev/null +++ b/sbin/fsck_msdosfs/check.c @@ -0,0 +1,194 @@ +/* + * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank + * Copyright (c) 1995 Martin Husemann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * 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. + */ + + +#include +#ifndef lint +__RCSID("$NetBSD: check.c,v 1.10 2000/04/25 23:02:51 jdolecek Exp $"); +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include + +#include "ext.h" +#include "fsutil.h" + +int +checkfilesys(fname) + const char *fname; +{ + int dosfs; + struct bootblock boot; + struct fatEntry *fat = NULL; + int i, finish_dosdirsection=0; + int mod = 0; + int ret = 8; + + rdonly = alwaysno; + if (!preen) + printf("** %s", fname); + + dosfs = open(fname, rdonly ? O_RDONLY : O_RDWR, 0); + if (dosfs < 0 && !rdonly) { + dosfs = open(fname, O_RDONLY, 0); + if (dosfs >= 0) + pwarn(" (NO WRITE)\n"); + else if (!preen) + printf("\n"); + rdonly = 1; + } else if (!preen) + printf("\n"); + + if (dosfs < 0) { + perror("Can't open"); + return 8; + } + + if (readboot(dosfs, &boot) != FSOK) { + close(dosfs); + printf("\n"); + return 8; + } + + if (!preen) { + if (boot.ValidFat < 0) + printf("** Phase 1 - Read and Compare FATs\n"); + else + printf("** Phase 1 - Read FAT\n"); + } + + mod |= readfat(dosfs, &boot, boot.ValidFat >= 0 ? boot.ValidFat : 0, &fat); + if (mod & FSFATAL) { + close(dosfs); + return 8; + } + + if (boot.ValidFat < 0) + for (i = 1; i < boot.FATs; i++) { + struct fatEntry *currentFat; + + mod |= readfat(dosfs, &boot, i, ¤tFat); + + if (mod & FSFATAL) + goto out; + + mod |= comparefat(&boot, fat, currentFat, i); + free(currentFat); + if (mod & FSFATAL) + goto out; + } + + if (!preen) + printf("** Phase 2 - Check Cluster Chains\n"); + + mod |= checkfat(&boot, fat); + if (mod & FSFATAL) + goto out; + /* delay writing FATs */ + + if (!preen) + printf("** Phase 3 - Checking Directories\n"); + + mod |= resetDosDirSection(&boot, fat); + finish_dosdirsection = 1; + if (mod & FSFATAL) + goto out; + /* delay writing FATs */ + + mod |= handleDirTree(dosfs, &boot, fat); + if (mod & FSFATAL) + goto out; + + if (!preen) + printf("** Phase 4 - Checking for Lost Files\n"); + + mod |= checklost(dosfs, &boot, fat); + if (mod & FSFATAL) + goto out; + + /* now write the FATs */ + if (mod & FSFATMOD) { + if (ask(1, "Update FATs")) { + mod |= writefat(dosfs, &boot, fat, mod & FSFIXFAT); + if (mod & FSFATAL) + goto out; + } else + mod |= FSERROR; + } + + if (boot.NumBad) + pwarn("%d files, %d free (%d clusters), %d bad (%d clusters)\n", + boot.NumFiles, + boot.NumFree * boot.ClusterSize / 1024, boot.NumFree, + boot.NumBad * boot.ClusterSize / 1024, boot.NumBad); + else + pwarn("%d files, %d free (%d clusters)\n", + boot.NumFiles, + boot.NumFree * boot.ClusterSize / 1024, boot.NumFree); + + if (mod && (mod & FSERROR) == 0) { + if (mod & FSDIRTY) { + if (ask(1, "MARK FILE SYSTEM CLEAN") == 0) + mod &= ~FSDIRTY; + + if (mod & FSDIRTY) { + pwarn("MARKING FILE SYSTEM CLEAN\n"); + mod |= writefat(dosfs, &boot, fat, 1); + } else { + pwarn("\n***** FILE SYSTEM IS LEFT MARKED AS DIRTY *****\n"); + mod |= FSERROR; /* file system not clean */ + } + } + } + + if (mod & (FSFATAL | FSERROR)) + goto out; + + ret = 0; + + out: + if (finish_dosdirsection) + finishDosDirSection(); + free(fat); + close(dosfs); + + if (mod & (FSFATMOD|FSDIRMOD)) + pwarn("\n***** FILE SYSTEM WAS MODIFIED *****\n"); + + return ret; +} -- cgit v1.1