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