1*ca38d4f6Saaron /* $OpenBSD: check.c,v 1.7 1999/03/25 01:45:01 aaron Exp $ */ 2b099d67bSprovos /* $NetBSD: check.c,v 1.8 1997/10/17 11:19:29 ws Exp $ */ 39646ab25Sderaadt 49646ab25Sderaadt /* 5b099d67bSprovos * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank 69646ab25Sderaadt * Copyright (c) 1995 Martin Husemann 79646ab25Sderaadt * 89646ab25Sderaadt * Redistribution and use in source and binary forms, with or without 99646ab25Sderaadt * modification, are permitted provided that the following conditions 109646ab25Sderaadt * are met: 119646ab25Sderaadt * 1. Redistributions of source code must retain the above copyright 129646ab25Sderaadt * notice, this list of conditions and the following disclaimer. 139646ab25Sderaadt * 2. Redistributions in binary form must reproduce the above copyright 149646ab25Sderaadt * notice, this list of conditions and the following disclaimer in the 159646ab25Sderaadt * documentation and/or other materials provided with the distribution. 169646ab25Sderaadt * 3. All advertising materials mentioning features or use of this software 179646ab25Sderaadt * must display the following acknowledgement: 189646ab25Sderaadt * This product includes software developed by Martin Husemann 199646ab25Sderaadt * and Wolfgang Solfrank. 209646ab25Sderaadt * 4. Neither the name of the University nor the names of its contributors 219646ab25Sderaadt * may be used to endorse or promote products derived from this software 229646ab25Sderaadt * without specific prior written permission. 239646ab25Sderaadt * 249646ab25Sderaadt * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 259646ab25Sderaadt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 269646ab25Sderaadt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 279646ab25Sderaadt * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 289646ab25Sderaadt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 299646ab25Sderaadt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 309646ab25Sderaadt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 319646ab25Sderaadt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 329646ab25Sderaadt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 339646ab25Sderaadt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 349646ab25Sderaadt */ 359646ab25Sderaadt 369646ab25Sderaadt 379646ab25Sderaadt #ifndef lint 38*ca38d4f6Saaron static char rcsid[] = "$OpenBSD: check.c,v 1.7 1999/03/25 01:45:01 aaron Exp $"; 399646ab25Sderaadt #endif /* not lint */ 409646ab25Sderaadt 419646ab25Sderaadt #include <stdlib.h> 429646ab25Sderaadt #include <string.h> 439646ab25Sderaadt #include <ctype.h> 449646ab25Sderaadt #include <stdio.h> 459646ab25Sderaadt #include <unistd.h> 469646ab25Sderaadt #include <fcntl.h> 479646ab25Sderaadt 489646ab25Sderaadt #include "ext.h" 499646ab25Sderaadt 509646ab25Sderaadt int 519646ab25Sderaadt checkfilesys(fname) 529646ab25Sderaadt const char *fname; 539646ab25Sderaadt { 549646ab25Sderaadt int dosfs; 559646ab25Sderaadt struct bootblock boot; 569646ab25Sderaadt struct fatEntry *fat = NULL; 579646ab25Sderaadt int i; 589646ab25Sderaadt int mod = 0; 599646ab25Sderaadt 609646ab25Sderaadt rdonly = alwaysno; 619646ab25Sderaadt if (!preen) 629646ab25Sderaadt printf("** %s", fname); 639646ab25Sderaadt 649646ab25Sderaadt dosfs = open(fname, rdonly ? O_RDONLY : O_RDWR, 0); 659646ab25Sderaadt if (dosfs < 0 && !rdonly) { 669646ab25Sderaadt dosfs = open(fname, O_RDONLY, 0); 679646ab25Sderaadt if (dosfs >= 0) 689646ab25Sderaadt pwarn(" (NO WRITE)\n"); 699646ab25Sderaadt else if (!preen) 709646ab25Sderaadt printf("\n"); 719646ab25Sderaadt rdonly = 1; 729646ab25Sderaadt } else if (!preen) 739646ab25Sderaadt printf("\n"); 749646ab25Sderaadt 759646ab25Sderaadt if (dosfs < 0) { 769646ab25Sderaadt perror("Can't open"); 77a0dbeb59Smillert return (8); 789646ab25Sderaadt } 799646ab25Sderaadt 809646ab25Sderaadt if (readboot(dosfs, &boot) != FSOK) { 81a0dbeb59Smillert (void)close(dosfs); 82a0dbeb59Smillert return (8); 839646ab25Sderaadt } 849646ab25Sderaadt 859646ab25Sderaadt if (!preen) 86b099d67bSprovos if (boot.ValidFat < 0) 879646ab25Sderaadt printf("** Phase 1 - Read and Compare FATs\n"); 88b099d67bSprovos else 89b099d67bSprovos printf("** Phase 1 - Read FAT\n"); 909646ab25Sderaadt 91b099d67bSprovos mod |= readfat(dosfs, &boot, boot.ValidFat >= 0 ? boot.ValidFat : 0, &fat); 92b099d67bSprovos if (mod & FSFATAL) { 93b099d67bSprovos (void)close(dosfs); 94b099d67bSprovos return 8; 95b099d67bSprovos } 96b099d67bSprovos 97b099d67bSprovos if (boot.ValidFat < 0) 98b099d67bSprovos for (i = 1; i < boot.FATs; i++) { 999646ab25Sderaadt struct fatEntry *currentFat; 1009646ab25Sderaadt mod |= readfat(dosfs, &boot, i, ¤tFat); 1019646ab25Sderaadt 1029646ab25Sderaadt if (mod & FSFATAL) { 1032a4cde9cSderaadt free(fat); 104a0dbeb59Smillert (void)close(dosfs); 105b099d67bSprovos return 8; 1069646ab25Sderaadt } 1079646ab25Sderaadt 108b099d67bSprovos mod |= comparefat(&boot, fat, currentFat, i); 1092a4cde9cSderaadt free(currentFat); 1109646ab25Sderaadt if (mod & FSFATAL) { 1112a4cde9cSderaadt free(fat); 112a0dbeb59Smillert (void)close(dosfs); 113a0dbeb59Smillert return (8); 1149646ab25Sderaadt } 1159646ab25Sderaadt } 1169646ab25Sderaadt 1179646ab25Sderaadt if (!preen) 1189646ab25Sderaadt printf("** Phase 2 - Check Cluster Chains\n"); 1199646ab25Sderaadt 1209646ab25Sderaadt mod |= checkfat(&boot, fat); 1219646ab25Sderaadt if (mod & FSFATAL) { 1222a4cde9cSderaadt free(fat); 123a0dbeb59Smillert (void)close(dosfs); 124a0dbeb59Smillert return (8); 1259646ab25Sderaadt } 1269646ab25Sderaadt 1279646ab25Sderaadt if (mod & FSFATMOD) 1289646ab25Sderaadt mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ 1299646ab25Sderaadt if (mod & FSFATAL) { 1302a4cde9cSderaadt free(fat); 131a0dbeb59Smillert (void)close(dosfs); 132a0dbeb59Smillert return (8); 1339646ab25Sderaadt } 1349646ab25Sderaadt 1359646ab25Sderaadt if (!preen) 136*ca38d4f6Saaron printf("** Phase 3 - Check Directories\n"); 1379646ab25Sderaadt 138b099d67bSprovos mod |= resetDosDirSection(&boot, fat); 139b099d67bSprovos if (mod & FSFATAL) { 140b099d67bSprovos free(fat); 141b099d67bSprovos close(dosfs); 142b099d67bSprovos return 8; 143b099d67bSprovos } 144b099d67bSprovos 145b099d67bSprovos if (mod & FSFATMOD) 146b099d67bSprovos mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ 147b099d67bSprovos if (mod & FSFATAL) { 148b099d67bSprovos finishDosDirSection(); 1492a4cde9cSderaadt free(fat); 150a0dbeb59Smillert (void)close(dosfs); 151a0dbeb59Smillert return (8); 1529646ab25Sderaadt } 1539646ab25Sderaadt 1542a4cde9cSderaadt mod |= handleDirTree(dosfs, &boot, fat); 1559646ab25Sderaadt if (mod & FSFATAL) { 1569646ab25Sderaadt finishDosDirSection(); 1572a4cde9cSderaadt free(fat); 158a0dbeb59Smillert (void)close(dosfs); 159a0dbeb59Smillert return (8); 1602a4cde9cSderaadt } 1619646ab25Sderaadt 1629646ab25Sderaadt if (!preen) 163*ca38d4f6Saaron printf("** Phase 4 - Check for Lost Files\n"); 1649646ab25Sderaadt 1652a4cde9cSderaadt mod |= checklost(dosfs, &boot, fat); 166b099d67bSprovos if (mod & FSFATAL) { 167b099d67bSprovos finishDosDirSection(); 168b099d67bSprovos free(fat); 169b099d67bSprovos (void)close(dosfs); 170b099d67bSprovos return 8; 171b099d67bSprovos } 172b099d67bSprovos 173b099d67bSprovos if (mod & FSFATMOD) 174b099d67bSprovos mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ 1759646ab25Sderaadt 1762a4cde9cSderaadt finishDosDirSection(); 1772a4cde9cSderaadt free(fat); 178a0dbeb59Smillert (void)close(dosfs); 179b099d67bSprovos if (mod & FSFATAL) 180b099d67bSprovos return 8; 1812a4cde9cSderaadt 182c7481c7eSmillert if (boot.NumBad) 183c7481c7eSmillert pwarn("%d files, %d free (%d clusters), %d bad (%d clusters)\n", 184c7481c7eSmillert boot.NumFiles, 185c7481c7eSmillert boot.NumFree * boot.ClusterSize / 1024, boot.NumFree, 186c7481c7eSmillert boot.NumBad * boot.ClusterSize / 1024, boot.NumBad); 187c7481c7eSmillert else 1889646ab25Sderaadt pwarn("%d files, %d free (%d clusters)\n", 189c7481c7eSmillert boot.NumFiles, 190c7481c7eSmillert boot.NumFree * boot.ClusterSize / 1024, boot.NumFree); 191b099d67bSprovos 1929646ab25Sderaadt if (mod & (FSFATAL | FSERROR)) 193a0dbeb59Smillert return (8); 1949646ab25Sderaadt if (mod) { 1959646ab25Sderaadt pwarn("\n***** FILE SYSTEM WAS MODIFIED *****\n"); 196a0dbeb59Smillert return (4); 1979646ab25Sderaadt } 198a0dbeb59Smillert return (0); 1999646ab25Sderaadt } 200