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