Deleted Added
full compact
fat.c (79455) fat.c (92839)
1/*
2 * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
3 * Copyright (c) 1995 Martin Husemann
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 21 unchanged lines hidden (view full) ---

30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33
34#include <sys/cdefs.h>
35#ifndef lint
36__RCSID("$NetBSD: fat.c,v 1.12 2000/10/10 20:24:52 is Exp $");
37static const char rcsid[] =
1/*
2 * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
3 * Copyright (c) 1995 Martin Husemann
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 21 unchanged lines hidden (view full) ---

30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33
34#include <sys/cdefs.h>
35#ifndef lint
36__RCSID("$NetBSD: fat.c,v 1.12 2000/10/10 20:24:52 is Exp $");
37static const char rcsid[] =
38 "$FreeBSD: head/sbin/fsck_msdosfs/fat.c 79455 2001-07-09 10:35:18Z obrien $";
38 "$FreeBSD: head/sbin/fsck_msdosfs/fat.c 92839 2002-03-20 22:57:10Z imp $";
39#endif /* not lint */
40
41#include <stdlib.h>
42#include <string.h>
43#include <ctype.h>
44#include <stdio.h>
45#include <unistd.h>
46
47#include "ext.h"
48#include "fsutil.h"
49
39#endif /* not lint */
40
41#include <stdlib.h>
42#include <string.h>
43#include <ctype.h>
44#include <stdio.h>
45#include <unistd.h>
46
47#include "ext.h"
48#include "fsutil.h"
49
50static int checkclnum __P((struct bootblock *, int, cl_t, cl_t *));
51static int clustdiffer __P((cl_t, cl_t *, cl_t *, int));
52static int tryclear __P((struct bootblock *, struct fatEntry *, cl_t, cl_t *));
53static int _readfat __P((int, struct bootblock *, int, u_char **));
50static int checkclnum(struct bootblock *, int, cl_t, cl_t *);
51static int clustdiffer(cl_t, cl_t *, cl_t *, int);
52static int tryclear(struct bootblock *, struct fatEntry *, cl_t, cl_t *);
53static int _readfat(int, struct bootblock *, int, u_char **);
54
55/*
56 * Check a cluster number for valid value
57 */
58static int
54
55/*
56 * Check a cluster number for valid value
57 */
58static int
59checkclnum(boot, fat, cl, next)
60 struct bootblock *boot;
61 int fat;
62 cl_t cl;
63 cl_t *next;
59checkclnum(struct bootblock *boot, int fat, cl_t cl, cl_t *next)
64{
65 if (*next >= (CLUST_RSRVD&boot->ClustMask))
66 *next |= ~boot->ClustMask;
67 if (*next == CLUST_FREE) {
68 boot->NumFree++;
69 return FSOK;
70 }
71 if (*next == CLUST_BAD) {

--- 14 unchanged lines hidden (view full) ---

86 }
87 return FSOK;
88}
89
90/*
91 * Read a FAT from disk. Returns 1 if successful, 0 otherwise.
92 */
93static int
60{
61 if (*next >= (CLUST_RSRVD&boot->ClustMask))
62 *next |= ~boot->ClustMask;
63 if (*next == CLUST_FREE) {
64 boot->NumFree++;
65 return FSOK;
66 }
67 if (*next == CLUST_BAD) {

--- 14 unchanged lines hidden (view full) ---

82 }
83 return FSOK;
84}
85
86/*
87 * Read a FAT from disk. Returns 1 if successful, 0 otherwise.
88 */
89static int
94_readfat(fs, boot, no, buffer)
95 int fs;
96 struct bootblock *boot;
97 int no;
98 u_char **buffer;
90_readfat(int fs, struct bootblock *boot, int no, u_char **buffer)
99{
100 off_t off;
101
102 *buffer = malloc(boot->FATsecs * boot->BytesPerSec);
103 if (*buffer == NULL) {
104 perror("No space for FAT");
105 return 0;
106 }

--- 18 unchanged lines hidden (view full) ---

125 free(*buffer);
126 return 0;
127}
128
129/*
130 * Read a FAT and decode it into internal format
131 */
132int
91{
92 off_t off;
93
94 *buffer = malloc(boot->FATsecs * boot->BytesPerSec);
95 if (*buffer == NULL) {
96 perror("No space for FAT");
97 return 0;
98 }

--- 18 unchanged lines hidden (view full) ---

117 free(*buffer);
118 return 0;
119}
120
121/*
122 * Read a FAT and decode it into internal format
123 */
124int
133readfat(fs, boot, no, fp)
134 int fs;
135 struct bootblock *boot;
136 int no;
137 struct fatEntry **fp;
125readfat(int fs, struct bootblock *boot, int no, struct fatEntry **fp)
138{
139 struct fatEntry *fat;
140 u_char *buffer, *p;
141 cl_t cl;
142 int ret = FSOK;
143
144 boot->NumFree = boot->NumBad = 0;
145

--- 101 unchanged lines hidden (view full) ---

247 *fp = fat;
248 return ret;
249}
250
251/*
252 * Get type of reserved cluster
253 */
254char *
126{
127 struct fatEntry *fat;
128 u_char *buffer, *p;
129 cl_t cl;
130 int ret = FSOK;
131
132 boot->NumFree = boot->NumBad = 0;
133

--- 101 unchanged lines hidden (view full) ---

235 *fp = fat;
236 return ret;
237}
238
239/*
240 * Get type of reserved cluster
241 */
242char *
255rsrvdcltype(cl)
256 cl_t cl;
243rsrvdcltype(cl_t cl)
257{
258 if (cl == CLUST_FREE)
259 return "free";
260 if (cl < CLUST_BAD)
261 return "reserved";
262 if (cl > CLUST_BAD)
263 return "as EOF";
264 return "bad";
265}
266
267static int
244{
245 if (cl == CLUST_FREE)
246 return "free";
247 if (cl < CLUST_BAD)
248 return "reserved";
249 if (cl > CLUST_BAD)
250 return "as EOF";
251 return "bad";
252}
253
254static int
268clustdiffer(cl, cp1, cp2, fatnum)
269 cl_t cl;
270 cl_t *cp1;
271 cl_t *cp2;
272 int fatnum;
255clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, int fatnum)
273{
274 if (*cp1 == CLUST_FREE || *cp1 >= CLUST_RSRVD) {
275 if (*cp2 == CLUST_FREE || *cp2 >= CLUST_RSRVD) {
276 if ((*cp1 != CLUST_FREE && *cp1 < CLUST_BAD
277 && *cp2 != CLUST_FREE && *cp2 < CLUST_BAD)
278 || (*cp1 > CLUST_BAD && *cp2 > CLUST_BAD)) {
279 pwarn("Cluster %u is marked %s with different indicators, ",
280 cl, rsrvdcltype(*cp1));

--- 53 unchanged lines hidden (view full) ---

334 return FSERROR;
335}
336
337/*
338 * Compare two FAT copies in memory. Resolve any conflicts and merge them
339 * into the first one.
340 */
341int
256{
257 if (*cp1 == CLUST_FREE || *cp1 >= CLUST_RSRVD) {
258 if (*cp2 == CLUST_FREE || *cp2 >= CLUST_RSRVD) {
259 if ((*cp1 != CLUST_FREE && *cp1 < CLUST_BAD
260 && *cp2 != CLUST_FREE && *cp2 < CLUST_BAD)
261 || (*cp1 > CLUST_BAD && *cp2 > CLUST_BAD)) {
262 pwarn("Cluster %u is marked %s with different indicators, ",
263 cl, rsrvdcltype(*cp1));

--- 53 unchanged lines hidden (view full) ---

317 return FSERROR;
318}
319
320/*
321 * Compare two FAT copies in memory. Resolve any conflicts and merge them
322 * into the first one.
323 */
324int
342comparefat(boot, first, second, fatnum)
343 struct bootblock *boot;
344 struct fatEntry *first;
345 struct fatEntry *second;
346 int fatnum;
325comparefat(struct bootblock *boot, struct fatEntry *first,
326 struct fatEntry *second, int fatnum)
347{
348 cl_t cl;
349 int ret = FSOK;
350
351 for (cl = CLUST_FIRST; cl < boot->NumClusters; cl++)
352 if (first[cl].next != second[cl].next)
353 ret |= clustdiffer(cl, &first[cl].next, &second[cl].next, fatnum);
354 return ret;
355}
356
357void
327{
328 cl_t cl;
329 int ret = FSOK;
330
331 for (cl = CLUST_FIRST; cl < boot->NumClusters; cl++)
332 if (first[cl].next != second[cl].next)
333 ret |= clustdiffer(cl, &first[cl].next, &second[cl].next, fatnum);
334 return ret;
335}
336
337void
358clearchain(boot, fat, head)
359 struct bootblock *boot;
360 struct fatEntry *fat;
361 cl_t head;
338clearchain(struct bootblock *boot, struct fatEntry *fat, cl_t head)
362{
363 cl_t p, q;
364
365 for (p = head; p >= CLUST_FIRST && p < boot->NumClusters; p = q) {
366 if (fat[p].head != head)
367 break;
368 q = fat[p].next;
369 fat[p].next = fat[p].head = CLUST_FREE;
370 fat[p].length = 0;
371 }
372}
373
374int
339{
340 cl_t p, q;
341
342 for (p = head; p >= CLUST_FIRST && p < boot->NumClusters; p = q) {
343 if (fat[p].head != head)
344 break;
345 q = fat[p].next;
346 fat[p].next = fat[p].head = CLUST_FREE;
347 fat[p].length = 0;
348 }
349}
350
351int
375tryclear(boot, fat, head, trunc)
376 struct bootblock *boot;
377 struct fatEntry *fat;
378 cl_t head;
379 cl_t *trunc;
352tryclear(struct bootblock *boot, struct fatEntry *fat, cl_t head, cl_t *trunc)
380{
381 if (ask(0, "Clear chain starting at %u", head)) {
382 clearchain(boot, fat, head);
383 return FSFATMOD;
384 } else if (ask(0, "Truncate")) {
385 *trunc = CLUST_EOF;
386 return FSFATMOD;
387 } else
388 return FSERROR;
389}
390
391/*
392 * Check a complete FAT in-memory for crosslinks
393 */
394int
353{
354 if (ask(0, "Clear chain starting at %u", head)) {
355 clearchain(boot, fat, head);
356 return FSFATMOD;
357 } else if (ask(0, "Truncate")) {
358 *trunc = CLUST_EOF;
359 return FSFATMOD;
360 } else
361 return FSERROR;
362}
363
364/*
365 * Check a complete FAT in-memory for crosslinks
366 */
367int
395checkfat(boot, fat)
396 struct bootblock *boot;
397 struct fatEntry *fat;
368checkfat(struct bootblock *boot, struct fatEntry *fat)
398{
399 cl_t head, p, h, n;
400 u_int len;
401 int ret = 0;
402 int conf;
403
404 /*
405 * pass 1: figure out the cluster chains.

--- 77 unchanged lines hidden (view full) ---

483
484 return ret;
485}
486
487/*
488 * Write out FATs encoding them from the internal format
489 */
490int
369{
370 cl_t head, p, h, n;
371 u_int len;
372 int ret = 0;
373 int conf;
374
375 /*
376 * pass 1: figure out the cluster chains.

--- 77 unchanged lines hidden (view full) ---

454
455 return ret;
456}
457
458/*
459 * Write out FATs encoding them from the internal format
460 */
461int
491writefat(fs, boot, fat, correct_fat)
492 int fs;
493 struct bootblock *boot;
494 struct fatEntry *fat;
495 int correct_fat;
462writefat(int fs, struct bootblock *boot, struct fatEntry *fat, int correct_fat)
496{
497 u_char *buffer, *p;
498 cl_t cl;
499 int i;
500 u_int32_t fatsz;
501 off_t off;
502 int ret = FSOK;
503

--- 91 unchanged lines hidden (view full) ---

595 free(buffer);
596 return ret;
597}
598
599/*
600 * Check a complete in-memory FAT for lost cluster chains
601 */
602int
463{
464 u_char *buffer, *p;
465 cl_t cl;
466 int i;
467 u_int32_t fatsz;
468 off_t off;
469 int ret = FSOK;
470

--- 91 unchanged lines hidden (view full) ---

562 free(buffer);
563 return ret;
564}
565
566/*
567 * Check a complete in-memory FAT for lost cluster chains
568 */
569int
603checklost(dosfs, boot, fat)
604 int dosfs;
605 struct bootblock *boot;
606 struct fatEntry *fat;
570checklost(int dosfs, struct bootblock *boot, struct fatEntry *fat)
607{
608 cl_t head;
609 int mod = FSOK;
610 int ret;
611
612 for (head = CLUST_FIRST; head < boot->NumClusters; head++) {
613 /* find next untravelled chain */
614 if (fat[head].head != head

--- 45 unchanged lines hidden ---
571{
572 cl_t head;
573 int mod = FSOK;
574 int ret;
575
576 for (head = CLUST_FIRST; head < boot->NumClusters; head++) {
577 /* find next untravelled chain */
578 if (fat[head].head != head

--- 45 unchanged lines hidden ---