1*b9fc9a72Sderaadt /* $OpenBSD: check.c,v 1.17 2015/01/16 06:39:58 deraadt 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 * 179646ab25Sderaadt * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 189646ab25Sderaadt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 199646ab25Sderaadt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 209646ab25Sderaadt * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 219646ab25Sderaadt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 229646ab25Sderaadt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239646ab25Sderaadt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249646ab25Sderaadt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259646ab25Sderaadt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 269646ab25Sderaadt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279646ab25Sderaadt */ 289646ab25Sderaadt 29*b9fc9a72Sderaadt #include <sys/types.h> 3098fba8a9Skrw #include <sys/ioctl.h> 3198fba8a9Skrw #include <sys/dkio.h> 3298fba8a9Skrw #include <sys/disklabel.h> 339646ab25Sderaadt #include <stdlib.h> 349646ab25Sderaadt #include <string.h> 359646ab25Sderaadt #include <ctype.h> 369646ab25Sderaadt #include <stdio.h> 379646ab25Sderaadt #include <unistd.h> 38*b9fc9a72Sderaadt #include <limits.h> 399646ab25Sderaadt #include <fcntl.h> 404340e61fSmillert #include <util.h> 419646ab25Sderaadt 429646ab25Sderaadt #include "ext.h" 439646ab25Sderaadt 4498fba8a9Skrw struct disklabel lab; 4598fba8a9Skrw 469646ab25Sderaadt int 474e95fccfSderaadt checkfilesys(const char *fname) 489646ab25Sderaadt { 499646ab25Sderaadt int dosfs; 509646ab25Sderaadt struct bootblock boot; 519646ab25Sderaadt struct fatEntry *fat = NULL; 52549405c0Sjsing char *realdev; 539646ab25Sderaadt int i; 549646ab25Sderaadt int mod = 0; 559646ab25Sderaadt 569646ab25Sderaadt rdonly = alwaysno; 579646ab25Sderaadt 58549405c0Sjsing dosfs = opendev(fname, rdonly ? O_RDONLY : O_RDWR, 0, &realdev); 599646ab25Sderaadt if (dosfs < 0 && !rdonly) { 60549405c0Sjsing dosfs = opendev(fname, O_RDONLY, 0, &realdev); 619646ab25Sderaadt rdonly = 1; 62549405c0Sjsing } 639646ab25Sderaadt if (dosfs < 0) { 64dd133929Sthib xperror("Can't open"); 65a0dbeb59Smillert return (8); 669646ab25Sderaadt } 679646ab25Sderaadt 68549405c0Sjsing if (!preen) { 69549405c0Sjsing printf("** %s", realdev); 70549405c0Sjsing if (strncmp(fname, realdev, PATH_MAX) != 0) 71549405c0Sjsing printf(" (%s)", fname); 72549405c0Sjsing if (rdonly) 73549405c0Sjsing printf(" (NO WRITE)"); 74549405c0Sjsing printf("\n"); 75549405c0Sjsing } 76549405c0Sjsing 7798fba8a9Skrw if (ioctl(dosfs, DIOCGDINFO, (char *)&lab) < 0) 7898fba8a9Skrw pfatal("can't read disk label for %s\n", fname); 7998fba8a9Skrw 809646ab25Sderaadt if (readboot(dosfs, &boot) != FSOK) { 81a0dbeb59Smillert (void)close(dosfs); 82a0dbeb59Smillert return (8); 839646ab25Sderaadt } 849646ab25Sderaadt 85a4df0321Sderaadt 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"); 90a4df0321Sderaadt } 919646ab25Sderaadt 92b099d67bSprovos mod |= readfat(dosfs, &boot, boot.ValidFat >= 0 ? boot.ValidFat : 0, &fat); 93b099d67bSprovos if (mod & FSFATAL) { 94b099d67bSprovos (void)close(dosfs); 95b099d67bSprovos return 8; 96b099d67bSprovos } 97b099d67bSprovos 98b099d67bSprovos if (boot.ValidFat < 0) 99b099d67bSprovos for (i = 1; i < boot.FATs; i++) { 1009646ab25Sderaadt struct fatEntry *currentFat; 1019646ab25Sderaadt mod |= readfat(dosfs, &boot, i, ¤tFat); 1029646ab25Sderaadt 1039646ab25Sderaadt if (mod & FSFATAL) { 1042a4cde9cSderaadt free(fat); 105a0dbeb59Smillert (void)close(dosfs); 106b099d67bSprovos return 8; 1079646ab25Sderaadt } 1089646ab25Sderaadt 109b099d67bSprovos mod |= comparefat(&boot, fat, currentFat, i); 1102a4cde9cSderaadt free(currentFat); 1119646ab25Sderaadt if (mod & FSFATAL) { 1122a4cde9cSderaadt free(fat); 113a0dbeb59Smillert (void)close(dosfs); 114a0dbeb59Smillert return (8); 1159646ab25Sderaadt } 1169646ab25Sderaadt } 1179646ab25Sderaadt 1189646ab25Sderaadt if (!preen) 1199646ab25Sderaadt printf("** Phase 2 - Check Cluster Chains\n"); 1209646ab25Sderaadt 1219646ab25Sderaadt mod |= checkfat(&boot, fat); 1229646ab25Sderaadt if (mod & FSFATAL) { 1232a4cde9cSderaadt free(fat); 124a0dbeb59Smillert (void)close(dosfs); 125a0dbeb59Smillert return (8); 1269646ab25Sderaadt } 1279646ab25Sderaadt 1289646ab25Sderaadt if (mod & FSFATMOD) 1299646ab25Sderaadt mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ 1309646ab25Sderaadt if (mod & FSFATAL) { 1312a4cde9cSderaadt free(fat); 132a0dbeb59Smillert (void)close(dosfs); 133a0dbeb59Smillert return (8); 1349646ab25Sderaadt } 1359646ab25Sderaadt 1369646ab25Sderaadt if (!preen) 137ca38d4f6Saaron printf("** Phase 3 - Check Directories\n"); 1389646ab25Sderaadt 139b099d67bSprovos mod |= resetDosDirSection(&boot, fat); 140b099d67bSprovos if (mod & FSFATAL) { 141b099d67bSprovos free(fat); 142b099d67bSprovos close(dosfs); 143b099d67bSprovos return 8; 144b099d67bSprovos } 145b099d67bSprovos 146b099d67bSprovos if (mod & FSFATMOD) 147b099d67bSprovos mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ 148b099d67bSprovos if (mod & FSFATAL) { 149b099d67bSprovos finishDosDirSection(); 1502a4cde9cSderaadt free(fat); 151a0dbeb59Smillert (void)close(dosfs); 152a0dbeb59Smillert return (8); 1539646ab25Sderaadt } 1549646ab25Sderaadt 1552a4cde9cSderaadt mod |= handleDirTree(dosfs, &boot, fat); 1569646ab25Sderaadt if (mod & FSFATAL) { 1579646ab25Sderaadt finishDosDirSection(); 1582a4cde9cSderaadt free(fat); 159a0dbeb59Smillert (void)close(dosfs); 160a0dbeb59Smillert return (8); 1612a4cde9cSderaadt } 1629646ab25Sderaadt 1639646ab25Sderaadt if (!preen) 164ca38d4f6Saaron printf("** Phase 4 - Check for Lost Files\n"); 1659646ab25Sderaadt 1662a4cde9cSderaadt mod |= checklost(dosfs, &boot, fat); 167b099d67bSprovos if (mod & FSFATAL) { 168b099d67bSprovos finishDosDirSection(); 169b099d67bSprovos free(fat); 170b099d67bSprovos (void)close(dosfs); 171b099d67bSprovos return 8; 172b099d67bSprovos } 173b099d67bSprovos 174b099d67bSprovos if (mod & FSFATMOD) 175b099d67bSprovos mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ 1769646ab25Sderaadt 1772a4cde9cSderaadt finishDosDirSection(); 1782a4cde9cSderaadt free(fat); 179a0dbeb59Smillert (void)close(dosfs); 180b099d67bSprovos if (mod & FSFATAL) 181b099d67bSprovos return 8; 1822a4cde9cSderaadt 183c7481c7eSmillert if (boot.NumBad) 184c7481c7eSmillert pwarn("%d files, %d free (%d clusters), %d bad (%d clusters)\n", 185c7481c7eSmillert boot.NumFiles, 186c7481c7eSmillert boot.NumFree * boot.ClusterSize / 1024, boot.NumFree, 187c7481c7eSmillert boot.NumBad * boot.ClusterSize / 1024, boot.NumBad); 188c7481c7eSmillert else 1899646ab25Sderaadt pwarn("%d files, %d free (%d clusters)\n", 190c7481c7eSmillert boot.NumFiles, 191c7481c7eSmillert boot.NumFree * boot.ClusterSize / 1024, boot.NumFree); 192b099d67bSprovos 1939646ab25Sderaadt if (mod & (FSFATAL | FSERROR)) 194a0dbeb59Smillert return (8); 1959646ab25Sderaadt if (mod) { 1969646ab25Sderaadt pwarn("\n***** FILE SYSTEM WAS MODIFIED *****\n"); 197a0dbeb59Smillert return (4); 1989646ab25Sderaadt } 199a0dbeb59Smillert return (0); 2009646ab25Sderaadt } 201