xref: /openbsd/sbin/fsck_msdos/check.c (revision ca38d4f6)
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, &currentFat);
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