1 /* $OpenBSD: check.c,v 1.14 2010/12/17 19:36:03 millert Exp $ */ 2 /* $NetBSD: check.c,v 1.8 1997/10/17 11:19:29 ws Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank 6 * Copyright (c) 1995 Martin Husemann 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Martin Husemann 19 * and Wolfgang Solfrank. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #include <sys/param.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <ctype.h> 40 #include <stdio.h> 41 #include <unistd.h> 42 #include <fcntl.h> 43 #include <util.h> 44 45 #include "ext.h" 46 47 int 48 checkfilesys(const char *fname) 49 { 50 int dosfs; 51 struct bootblock boot; 52 struct fatEntry *fat = NULL; 53 char *realdev; 54 int i; 55 int mod = 0; 56 57 rdonly = alwaysno; 58 59 dosfs = opendev(fname, rdonly ? O_RDONLY : O_RDWR, 0, &realdev); 60 if (dosfs < 0 && !rdonly) { 61 dosfs = opendev(fname, O_RDONLY, 0, &realdev); 62 rdonly = 1; 63 } 64 if (dosfs < 0) { 65 xperror("Can't open"); 66 return (8); 67 } 68 69 if (!preen) { 70 printf("** %s", realdev); 71 if (strncmp(fname, realdev, PATH_MAX) != 0) 72 printf(" (%s)", fname); 73 if (rdonly) 74 printf(" (NO WRITE)"); 75 printf("\n"); 76 } 77 78 if (readboot(dosfs, &boot) != FSOK) { 79 (void)close(dosfs); 80 return (8); 81 } 82 83 if (!preen) { 84 if (boot.ValidFat < 0) 85 printf("** Phase 1 - Read and Compare FATs\n"); 86 else 87 printf("** Phase 1 - Read FAT\n"); 88 } 89 90 mod |= readfat(dosfs, &boot, boot.ValidFat >= 0 ? boot.ValidFat : 0, &fat); 91 if (mod & FSFATAL) { 92 (void)close(dosfs); 93 return 8; 94 } 95 96 if (boot.ValidFat < 0) 97 for (i = 1; i < boot.FATs; i++) { 98 struct fatEntry *currentFat; 99 mod |= readfat(dosfs, &boot, i, ¤tFat); 100 101 if (mod & FSFATAL) { 102 free(fat); 103 (void)close(dosfs); 104 return 8; 105 } 106 107 mod |= comparefat(&boot, fat, currentFat, i); 108 free(currentFat); 109 if (mod & FSFATAL) { 110 free(fat); 111 (void)close(dosfs); 112 return (8); 113 } 114 } 115 116 if (!preen) 117 printf("** Phase 2 - Check Cluster Chains\n"); 118 119 mod |= checkfat(&boot, fat); 120 if (mod & FSFATAL) { 121 free(fat); 122 (void)close(dosfs); 123 return (8); 124 } 125 126 if (mod & FSFATMOD) 127 mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ 128 if (mod & FSFATAL) { 129 free(fat); 130 (void)close(dosfs); 131 return (8); 132 } 133 134 if (!preen) 135 printf("** Phase 3 - Check Directories\n"); 136 137 mod |= resetDosDirSection(&boot, fat); 138 if (mod & FSFATAL) { 139 free(fat); 140 close(dosfs); 141 return 8; 142 } 143 144 if (mod & FSFATMOD) 145 mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ 146 if (mod & FSFATAL) { 147 finishDosDirSection(); 148 free(fat); 149 (void)close(dosfs); 150 return (8); 151 } 152 153 mod |= handleDirTree(dosfs, &boot, fat); 154 if (mod & FSFATAL) { 155 finishDosDirSection(); 156 free(fat); 157 (void)close(dosfs); 158 return (8); 159 } 160 161 if (!preen) 162 printf("** Phase 4 - Check for Lost Files\n"); 163 164 mod |= checklost(dosfs, &boot, fat); 165 if (mod & FSFATAL) { 166 finishDosDirSection(); 167 free(fat); 168 (void)close(dosfs); 169 return 8; 170 } 171 172 if (mod & FSFATMOD) 173 mod |= writefat(dosfs, &boot, fat); /* delay writing fats? XXX */ 174 175 finishDosDirSection(); 176 free(fat); 177 (void)close(dosfs); 178 if (mod & FSFATAL) 179 return 8; 180 181 if (boot.NumBad) 182 pwarn("%d files, %d free (%d clusters), %d bad (%d clusters)\n", 183 boot.NumFiles, 184 boot.NumFree * boot.ClusterSize / 1024, boot.NumFree, 185 boot.NumBad * boot.ClusterSize / 1024, boot.NumBad); 186 else 187 pwarn("%d files, %d free (%d clusters)\n", 188 boot.NumFiles, 189 boot.NumFree * boot.ClusterSize / 1024, boot.NumFree); 190 191 if (mod & (FSFATAL | FSERROR)) 192 return (8); 193 if (mod) { 194 pwarn("\n***** FILE SYSTEM WAS MODIFIED *****\n"); 195 return (4); 196 } 197 return (0); 198 } 199