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 --- |