1/*  Copyright 1996-2006,2008,2009 Alain Knaff.
2 *  This file is part of mtools.
3 *
4 *  Mtools is free software: you can redistribute it and/or modify
5 *  it under the terms of the GNU General Public License as published by
6 *  the Free Software Foundation, either version 3 of the License, or
7 *  (at your option) any later version.
8 *
9 *  Mtools is distributed in the hope that it will be useful,
10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 *  GNU General Public License for more details.
13 *
14 *  You should have received a copy of the GNU General Public License
15 *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "sysincludes.h"
19#include "msdos.h"
20#include "stream.h"
21#include "mtools.h"
22#include "fsP.h"
23#include "file_name.h"
24
25#ifdef HAVE_LONG_LONG
26typedef long long fatBitMask;
27#else
28typedef long fatBitMask;
29#endif
30
31typedef struct FatMap_t {
32	unsigned char *data;
33	fatBitMask dirty;
34	fatBitMask valid;
35} FatMap_t;
36
37#define SECT_PER_ENTRY (sizeof(fatBitMask)*8)
38#define ONE ((fatBitMask) 1)
39
40static __inline__ int readSector(Fs_t *This, char *buf, unsigned int off,
41					  size_t size)
42{
43	return READS(This->Next, buf, sectorsToBytes((Stream_t *)This, off),
44				 size << This->sectorShift);
45}
46
47
48static __inline__ int forceReadSector(Fs_t *This, char *buf, unsigned int off,
49				      size_t size)
50{
51	return force_read(This->Next, buf, sectorsToBytes((Stream_t *)This, off),
52					  size << This->sectorShift);
53}
54
55
56static __inline__ int writeSector(Fs_t *This, char *buf, unsigned int off,
57				  size_t size)
58{
59	return WRITES(This->Next, buf, sectorsToBytes((Stream_t*)This, off),
60				  size << This->sectorShift);
61}
62
63static __inline__ int forceWriteSector(Fs_t *This, char *buf, unsigned int off,
64				       size_t size)
65{
66	return force_write(This->Next, buf, sectorsToBytes((Stream_t*)This, off),
67					   size << This->sectorShift);
68}
69
70
71static FatMap_t *GetFatMap(Fs_t *Stream)
72{
73	int nr_entries,i;
74	FatMap_t *map;
75
76	Stream->fat_error = 0;
77	nr_entries = (Stream->fat_len + SECT_PER_ENTRY - 1) / SECT_PER_ENTRY;
78	map = NewArray(nr_entries, FatMap_t);
79	if(!map)
80		return 0;
81
82	for(i=0; i< nr_entries; i++) {
83		map[i].data = 0;
84		map[i].valid = 0;
85		map[i].dirty = 0;
86	}
87
88	return map;
89}
90
91static __inline__ int locate(Fs_t *Stream, size_t offset, int *slot, int *bit)
92{
93	if(offset >= Stream->fat_len)
94		return -1;
95	*slot = offset / SECT_PER_ENTRY;
96	*bit = offset % SECT_PER_ENTRY;
97	return 0;
98}
99
100static __inline__ int fatReadSector(Fs_t *This, int sector, int slot,
101				    int bit, int dupe, fatBitMask bitmap)
102{
103	int fat_start, ret;
104	int nr_sectors;
105
106	dupe = (dupe + This->primaryFat) % This->num_fat;
107	fat_start = This->fat_start + This->fat_len * dupe;
108
109	if(bitmap == 0) {
110	    nr_sectors = SECT_PER_ENTRY - bit%SECT_PER_ENTRY;
111	} else {
112	    nr_sectors = 1;
113	}
114
115	/* first, read as much as the buffer can give us */
116	ret = readSector(This,
117			 (char *)(This->FatMap[slot].data+(bit<<This->sectorShift)),
118			 fat_start+sector,
119			 nr_sectors);
120	if(ret < 0)
121		return 0;
122
123	if((unsigned int) ret < This->sector_size) {
124		/* if we got less than one sector's worth, insist to get at
125		 * least one sector */
126		ret = forceReadSector(This,
127				      (char *) (This->FatMap[slot].data +
128						(bit << This->sectorShift)),
129				      fat_start+sector, 1);
130		if(ret < (int) This->sector_size)
131			return 0;
132		return 1;
133	}
134
135	return ret >> This->sectorShift;
136}
137
138
139static int fatWriteSector(Fs_t *This, int sector, int slot, int bit, int dupe)
140{
141	int fat_start;
142
143	dupe = (dupe + This->primaryFat) % This->num_fat;
144	if(dupe && !This->writeAllFats)
145		return This->sector_size;
146
147	fat_start = This->fat_start + This->fat_len * dupe;
148
149	return forceWriteSector(This,
150				(char *)
151				(This->FatMap[slot].data + bit * This->sector_size),
152				fat_start+sector, 1);
153}
154
155static unsigned char *loadSector(Fs_t *This,
156				 unsigned int sector, fatAccessMode_t mode,
157				 int recurs)
158{
159	int slot, bit, ret;
160
161	if(locate(This,sector, &slot, &bit) < 0)
162		return 0;
163#if 0
164        if (((This->fat_len + SECT_PER_ENTRY - 1) / SECT_PER_ENTRY) <= slot) {
165		fprintf(stderr,"This should not happen\n");
166		fprintf(stderr, "fat_len = %d\n", This->fat_len);
167		fprintf(stderr, "SECT_PER_ENTRY=%d\n", (int)SECT_PER_ENTRY);
168		fprintf(stderr, "sector = %d slot = %d bit=%d\n",
169			sector, slot, bit);
170		fprintf(stderr, "left = %d",(int)
171			((This->fat_len+SECT_PER_ENTRY-1) / SECT_PER_ENTRY));
172                return 0;
173	}
174#endif
175	if(!This->FatMap[slot].data) {
176		/* allocate the storage space */
177		This->FatMap[slot].data =
178			malloc(This->sector_size * SECT_PER_ENTRY);
179		if(!This->FatMap[slot].data)
180			return 0;
181		memset(This->FatMap[slot].data, 0xee,
182		       This->sector_size * SECT_PER_ENTRY);
183	}
184
185	if(! (This->FatMap[slot].valid & (ONE << bit))) {
186		unsigned int i;
187		ret = -1;
188		for(i=0; i< This->num_fat; i++) {
189			/* read the sector */
190			ret = fatReadSector(This, sector, slot, bit, i,
191					    This->FatMap[slot].valid);
192
193			if(ret == 0) {
194				fprintf(stderr,
195					"Error reading fat number %d\n", i);
196				continue;
197			}
198			if(This->FatMap[slot].valid)
199			    /* Set recurs if there have already been
200			     * sectors loaded in this bitmap long
201			     */
202			    recurs = 1;
203			break;
204		}
205
206		/* all copies bad.  Return error */
207		if(ret == 0)
208			return 0;
209
210		for(i=0; (int) i < ret; i++)
211			This->FatMap[slot].valid |= ONE << (bit + i);
212
213		if(!recurs && ret == 1)
214			/* do some prefetching, if we happened to only
215			 * get one sector */
216			loadSector(This, sector+1, mode, 1);
217		if(!recurs && batchmode)
218			for(i=0; i < 1024; i++)
219				loadSector(This, sector+i, mode, 1);
220	}
221
222	if(mode == FAT_ACCESS_WRITE) {
223		This->FatMap[slot].dirty |= ONE << bit;
224		This->fat_dirty = 1;
225	}
226	return This->FatMap[slot].data + (bit << This->sectorShift);
227}
228
229
230static unsigned char *getAddress(Fs_t *Stream,
231				 unsigned int num, fatAccessMode_t mode)
232{
233	unsigned char *ret;
234	int sector;
235	int offset;
236
237	sector = num >> Stream->sectorShift;
238	ret = 0;
239	if(sector == Stream->lastFatSectorNr &&
240	   Stream->lastFatAccessMode >= mode)
241		ret = Stream->lastFatSectorData;
242	if(!ret) {
243		ret = loadSector(Stream, sector, mode, 0);
244		if(!ret)
245			return 0;
246		Stream->lastFatSectorNr = sector;
247		Stream->lastFatSectorData = ret;
248		Stream->lastFatAccessMode = mode;
249	}
250	offset = num & Stream->sectorMask;
251	return ret+offset;
252}
253
254
255static int readByte(Fs_t *Stream, int start)
256{
257	unsigned char *address;
258
259	address = getAddress(Stream, start, FAT_ACCESS_READ);
260	if(!address)
261		return -1;
262	return *address;
263}
264
265
266/*
267 * Fat 12 encoding:
268 *	|    byte n     |   byte n+1    |   byte n+2    |
269 *	|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
270 *	| | | | | | | | | | | | | | | | | | | | | | | | |
271 *	| n+0.0 | n+0.5 | n+1.0 | n+1.5 | n+2.0 | n+2.5 |
272 *	    \_____  \____   \______/________/_____   /
273 *	      ____\______\________/   _____/  ____\_/
274 *	     /     \      \          /       /     \
275 *	| n+1.5 | n+0.0 | n+0.5 | n+2.0 | n+2.5 | n+1.0 |
276 *	|      FAT entry k      |    FAT entry k+1      |
277 */
278
279 /*
280 * Get and decode a FAT (file allocation table) entry.  Returns the cluster
281 * number on success or 1 on failure.
282 */
283
284static unsigned int fat12_decode(Fs_t *Stream, unsigned int num)
285{
286	unsigned int start = num * 3 / 2;
287	int byte0 = readByte(Stream, start);
288	int byte1 = readByte(Stream, start+1);
289
290	if (num < 2 || byte0 < 0 || byte1 < 0 || num > Stream->num_clus+1) {
291		fprintf(stderr,"[1] Bad address %d\n", num);
292		return 1;
293	}
294
295	if (num & 1)
296		return (byte1 << 4) | ((byte0 & 0xf0)>>4);
297	else
298		return ((byte1 & 0xf) << 8) | byte0;
299}
300
301
302/*
303 * Puts a code into the FAT table.  Is the opposite of fat_decode().  No
304 * sanity checking is done on the code.  Returns a 1 on error.
305 */
306static void fat12_encode(Fs_t *Stream, unsigned int num, unsigned int code)
307{
308	int start = num * 3 / 2;
309	unsigned char *address0 = getAddress(Stream, start, FAT_ACCESS_WRITE);
310	unsigned char *address1 = getAddress(Stream, start+1, FAT_ACCESS_WRITE);
311
312	if (num & 1) {
313		/* (odd) not on byte boundary */
314		*address0 = (*address0 & 0x0f) | ((code << 4) & 0xf0);
315		*address1 = (code >> 4) & 0xff;
316	} else {
317		/* (even) on byte boundary */
318		*address0 = code & 0xff;
319		*address1 = (*address1 & 0xf0) | ((code >> 8) & 0x0f);
320	}
321}
322
323
324/*
325 * Fat 16 encoding:
326 *	|    byte n     |   byte n+1    |
327 *	|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
328 *	| | | | | | | | | | | | | | | | |
329 *	|         FAT entry k           |
330 */
331
332static unsigned int fat16_decode(Fs_t *Stream, unsigned int num)
333{
334	unsigned char *address = getAddress(Stream, num << 1, FAT_ACCESS_READ);
335	if(!address)
336		return 1;
337	return _WORD(address);
338}
339
340static void fat16_encode(Fs_t *Stream, unsigned int num, unsigned int code)
341{
342	unsigned char *address = getAddress(Stream, num << 1, FAT_ACCESS_WRITE);
343	set_word(address, code);
344}
345
346
347static unsigned int fast_fat16_decode(Fs_t *Stream, unsigned int num)
348{
349	unsigned short *address =
350		(unsigned short *) getAddress(Stream, num << 1,
351					      FAT_ACCESS_READ);
352	if(!address)
353		return 1;
354	return *address;
355}
356
357static void fast_fat16_encode(Fs_t *Stream, unsigned int num, unsigned int code)
358{
359	unsigned short *address =
360		(unsigned short *) getAddress(Stream, num << 1,
361					      FAT_ACCESS_WRITE);
362	*address = code;
363}
364
365
366
367
368/*
369 * Fat 32 encoding
370 */
371#define FAT32_HIGH 0xf0000000
372#define FAT32_ADDR 0x0fffffff
373
374static unsigned int fat32_decode(Fs_t *Stream, unsigned int num)
375{
376	unsigned char *address = getAddress(Stream, num << 2, FAT_ACCESS_READ);
377	if(!address)
378		return 1;
379	return _DWORD(address) & FAT32_ADDR;
380}
381
382static void fat32_encode(Fs_t *Stream, unsigned int num, unsigned int code)
383{
384	unsigned char *address = getAddress(Stream, num << 2, FAT_ACCESS_WRITE);
385	set_dword(address,(code&FAT32_ADDR) | (_DWORD(address)&FAT32_HIGH));
386}
387
388
389static unsigned int fast_fat32_decode(Fs_t *Stream, unsigned int num)
390{
391	unsigned int *address =
392		(unsigned int *) getAddress(Stream, num << 2,
393					    FAT_ACCESS_READ);
394	if(!address)
395		return 1;
396	return (*address) & FAT32_ADDR;
397}
398
399static void fast_fat32_encode(Fs_t *Stream, unsigned int num, unsigned int code)
400{
401	unsigned int *address =
402		(unsigned int *) getAddress(Stream, num << 2,
403					    FAT_ACCESS_WRITE);
404	*address = (*address & FAT32_HIGH) | (code & FAT32_ADDR);
405}
406
407
408/*
409 * Write the FAT table to the disk.  Up to now the FAT manipulation has
410 * been done in memory.  All errors are fatal.  (Might not be too smart
411 * to wait till the end of the program to write the table.  Oh well...)
412 */
413
414void fat_write(Fs_t *This)
415{
416	unsigned int i, j, dups, bit, slot;
417	int ret;
418	int fat_start;
419
420	/*fprintf(stderr, "Fat write\n");*/
421
422	if (!This->fat_dirty)
423		return;
424
425	dups = This->num_fat;
426	if (This->fat_error)
427		dups = 1;
428
429
430	for(i=0; i<dups; i++){
431		j = 0;
432		fat_start = This->fat_start + i*This->fat_len;
433		for(slot=0;j<This->fat_len;slot++) {
434			if(!This->FatMap[slot].dirty) {
435				j += SECT_PER_ENTRY;
436				continue;
437			}
438			for(bit=0;
439			    bit < SECT_PER_ENTRY && j<This->fat_len;
440			    bit++,j++) {
441				if(!(This->FatMap[slot].dirty & (ONE << bit)))
442					continue;
443				ret = fatWriteSector(This,j,slot, bit, i);
444				if (ret < (int) This->sector_size){
445					if (ret < 0 ){
446						perror("error in fat_write");
447						exit(1);
448					} else {
449						fprintf(stderr,
450							"end of file in fat_write\n");
451						exit(1);
452					}
453				}
454				/* if last dupe, zero it out */
455				if(i==dups-1)
456					This->FatMap[slot].dirty &= ~(ONE<<bit);
457			}
458		}
459	}
460	/* write the info sector, if any */
461	if(This->infoSectorLoc && This->infoSectorLoc != MAX32) {
462		/* initialize info sector */
463		InfoSector_t *infoSector;
464		infoSector = (InfoSector_t *) safe_malloc(This->sector_size);
465		set_dword(infoSector->signature1, INFOSECT_SIGNATURE1);
466		memset(infoSector->filler1, 0, sizeof(infoSector->filler1));
467		memset(infoSector->filler2, 0, sizeof(infoSector->filler2));
468		set_dword(infoSector->signature2, INFOSECT_SIGNATURE2);
469		set_dword(infoSector->pos, This->last);
470		set_dword(infoSector->count, This->freeSpace);
471		set_dword(infoSector->signature3, 0xaa55);
472		if(forceWriteSector(This, (char *)infoSector, This->infoSectorLoc, 1) !=
473		   (signed int) This->sector_size)
474			fprintf(stderr,"Trouble writing the info sector\n");
475		free(infoSector);
476	}
477	This->fat_dirty = 0;
478	This->lastFatAccessMode = FAT_ACCESS_READ;
479}
480
481
482
483/*
484 * Zero-Fat
485 * Used by mformat.
486 */
487int zero_fat(Fs_t *Stream, int media_descriptor)
488{
489	unsigned int i, j;
490	unsigned int fat_start;
491	unsigned char *buf;
492
493	buf = malloc(Stream->sector_size);
494	if(!buf) {
495		perror("alloc fat sector buffer");
496		return -1;
497	}
498	for(i=0; i< Stream->num_fat; i++) {
499		fat_start = Stream->fat_start + i*Stream->fat_len;
500		for(j = 0; j < Stream->fat_len; j++) {
501			if(j <= 1)
502				memset(buf, 0, Stream->sector_size);
503			if(!j) {
504				buf[0] = media_descriptor;
505				buf[2] = buf[1] = 0xff;
506				if(Stream->fat_bits > 12)
507					buf[3] = 0xff;
508				if(Stream->fat_bits > 16) {
509					buf[4] = 0xff;
510					buf[5] = 0xff;
511					buf[6] = 0xff;
512					buf[7] = 0x0f;
513				}
514			}
515
516			if(forceWriteSector(Stream, (char *)buf,
517					    fat_start + j, 1) !=
518			   (signed int) Stream->sector_size) {
519				fprintf(stderr,
520					"Trouble initializing a FAT sector\n");
521				free(buf);
522				return -1;
523			}
524		}
525	}
526
527	free(buf);
528	Stream->FatMap = GetFatMap(Stream);
529	if (Stream->FatMap == NULL) {
530		perror("alloc fat map");
531		return -1;
532	}
533	return 0;
534}
535
536
537void set_fat12(Fs_t *This)
538{
539	This->fat_bits = 12;
540	This->end_fat = 0xfff;
541	This->last_fat = 0xff6;
542	This->fat_decode = fat12_decode;
543	This->fat_encode = fat12_encode;
544}
545
546static char word_endian_test[] = { 0x34, 0x12 };
547
548void set_fat16(Fs_t *This)
549{
550	This->fat_bits = 16;
551	This->end_fat = 0xffff;
552	This->last_fat = 0xfff6;
553
554	if(sizeof(unsigned short) == 2 &&
555	   * (unsigned short *) word_endian_test == 0x1234) {
556		This->fat_decode = fast_fat16_decode;
557		This->fat_encode = fast_fat16_encode;
558	} else {
559		This->fat_decode = fat16_decode;
560		This->fat_encode = fat16_encode;
561	}
562}
563
564static char dword_endian_test[] = { 0x78, 0x56, 0x34, 0x12 };
565
566void set_fat32(Fs_t *This)
567{
568	This->fat_bits = 32;
569	This->end_fat = 0xfffffff;
570	This->last_fat = 0xffffff6;
571
572	if(sizeof(unsigned int) == 4 &&
573	   * (unsigned int *) dword_endian_test == 0x12345678) {
574		This->fat_decode = fast_fat32_decode;
575		This->fat_encode = fast_fat32_encode;
576	} else {
577		This->fat_decode = fat32_decode;
578		This->fat_encode = fat32_encode;
579	}
580}
581
582
583static int check_fat(Fs_t *This)
584{
585	/*
586	 * This is only a sanity check.  For disks with really big FATs,
587	 * there is no point in checking the whole FAT.
588	 */
589
590	unsigned int i, f;
591	unsigned int tocheck;
592	if(mtools_skip_check)
593		return 0;
594
595	/* too few sectors in the FAT */
596	if(This->fat_len < NEEDED_FAT_SIZE(This))
597		return -1;
598	/* we do not warn about too much sectors in FAT, which may
599	 * happen when a partition has been shrunk using FIPS, or on
600	 * other occurrences */
601
602	tocheck = This->num_clus;
603	if (tocheck + 1 >= This->last_fat) {
604		fprintf(stderr, "Too many clusters in FAT\n");
605		return -1;
606	}
607
608	if(tocheck > 4096)
609		tocheck = 4096;
610
611	for ( i= 3 ; i < tocheck; i++){
612		f = This->fat_decode(This,i);
613		if (f == 1 || (f < This->last_fat && f > This->num_clus)){
614			fprintf(stderr,
615				"Cluster # at %d too big(%#x)\n", i,f);
616			fprintf(stderr,"Probably non MS-DOS disk\n");
617			return -1;
618		}
619	}
620	return 0;
621}
622
623
624/*
625 * Read the first sector of FAT table into memory.  Crude error detection on
626 * wrong FAT encoding scheme.
627 */
628static int check_media_type(Fs_t *This, struct bootsector *boot,
629			    unsigned int tot_sectors)
630{
631	unsigned char *address;
632
633	This->num_clus = (tot_sectors - This->clus_start) / This->cluster_size;
634
635	This->FatMap = GetFatMap(This);
636	if (This->FatMap == NULL) {
637		perror("alloc fat map");
638		return -1;
639	}
640
641	address = getAddress(This, 0, FAT_ACCESS_READ);
642	if(!address) {
643		fprintf(stderr,
644			"Could not read first FAT sector\n");
645		return -1;
646	}
647
648	if(mtools_skip_check)
649		return 0;
650
651	if(!address[0] && !address[1] && !address[2])
652		/* Some Atari disks have zeroes where Dos has media descriptor
653		 * and 0xff.  Do not consider this as an error */
654		return 0;
655
656	if((address[0] != boot->descr && boot->descr >= 0xf0 &&
657	    ((address[0] != 0xf9 && address[0] != 0xf7)
658	     || boot->descr != 0xf0)) || address[0] < 0xf0) {
659		fprintf(stderr,
660			"Bad media types %02x/%02x, probably non-MSDOS disk\n",
661				address[0],
662				boot->descr);
663		return -1;
664	}
665
666	if(address[1] != 0xff || address[2] != 0xff){
667		fprintf(stderr,"Initial byte of fat is not 0xff\n");
668		return -1;
669	}
670
671	return 0;
672}
673
674static int fat_32_read(Fs_t *This, struct bootsector *boot,
675		       unsigned int tot_sectors)
676{
677	int size;
678
679	This->fat_len = DWORD(ext.fat32.bigFat);
680	This->writeAllFats = !(boot->ext.fat32.extFlags[0] & 0x80);
681	This->primaryFat = boot->ext.fat32.extFlags[0] & 0xf;
682	This->rootCluster = DWORD(ext.fat32.rootCluster);
683	This->clus_start = This->fat_start + This->num_fat * This->fat_len;
684
685	/* read the info sector */
686	size = This->sector_size;
687	This->infoSectorLoc = WORD(ext.fat32.infoSector);
688	if(This->sector_size >= 512 &&
689	   This->infoSectorLoc && This->infoSectorLoc != MAX32) {
690		InfoSector_t *infoSector;
691		infoSector = (InfoSector_t *) safe_malloc(size);
692		if(forceReadSector(This, (char *)infoSector,
693				   This->infoSectorLoc, 1) ==
694		   (signed int) This->sector_size &&
695		   _DWORD(infoSector->signature1) == INFOSECT_SIGNATURE1 &&
696		   _DWORD(infoSector->signature2) == INFOSECT_SIGNATURE2) {
697			This->freeSpace = _DWORD(infoSector->count);
698			This->last = _DWORD(infoSector->pos);
699		}
700		free(infoSector);
701	}
702
703	set_fat32(This);
704	return(check_media_type(This,boot, tot_sectors) ||
705	       check_fat(This));
706}
707
708
709static int old_fat_read(Fs_t *This, struct bootsector *boot,
710						int config_fat_bits,
711						size_t tot_sectors, int nodups)
712{
713	This->writeAllFats = 1;
714	This->primaryFat = 0;
715	This->dir_start = This->fat_start + This->num_fat * This->fat_len;
716	This->clus_start = This->dir_start + This->dir_len;
717	This->infoSectorLoc = MAX32;
718
719	if(nodups)
720		This->num_fat = 1;
721
722	if(check_media_type(This,boot, tot_sectors))
723		return -1;
724
725	if(This->num_clus >= FAT12) {
726		set_fat16(This);
727		/* third FAT byte must be 0xff */
728		if(!mtools_skip_check && readByte(This, 3) != 0xff)
729			return -1;
730	} else
731		set_fat12(This);
732
733	return check_fat(This);
734}
735
736/*
737 * Read the first sector of the  FAT table into memory and initialize
738 * structures.
739 */
740int fat_read(Fs_t *This, struct bootsector *boot, int fat_bits,
741	   size_t tot_sectors, int nodups)
742{
743	This->fat_error = 0;
744	This->fat_dirty = 0;
745	This->last = MAX32;
746	This->freeSpace = MAX32;
747	This->lastFatSectorNr = 0;
748	This->lastFatSectorData = 0;
749
750	if(This->fat_len)
751		return old_fat_read(This, boot, fat_bits, tot_sectors, nodups);
752	else
753		return fat_32_read(This, boot, tot_sectors);
754}
755
756
757unsigned int fatDecode(Fs_t *This, unsigned int pos)
758{
759	unsigned int ret;
760
761	ret = This->fat_decode(This, pos);
762	if(ret && (ret < 2 || ret > This->num_clus+1) && ret < This->last_fat) {
763		fprintf(stderr, "Bad FAT entry %d at %d\n", ret, pos);
764		This->fat_error++;
765	}
766	return ret;
767}
768
769/* append a new cluster */
770void fatAppend(Fs_t *This, unsigned int pos, unsigned int newpos)
771{
772	This->fat_encode(This, pos, newpos);
773	This->fat_encode(This, newpos, This->end_fat);
774	if(This->freeSpace != MAX32)
775		This->freeSpace--;
776}
777
778/* de-allocates the given cluster */
779void fatDeallocate(Fs_t *This, unsigned int pos)
780{
781	This->fat_encode(This, pos, 0);
782	if(This->freeSpace != MAX32)
783		This->freeSpace++;
784}
785
786/* allocate a new cluster */
787void fatAllocate(Fs_t *This, unsigned int pos, unsigned int value)
788{
789	This->fat_encode(This, pos, value);
790	if(This->freeSpace != MAX32)
791		This->freeSpace--;
792}
793
794void fatEncode(Fs_t *This, unsigned int pos, unsigned int value)
795{
796	unsigned int oldvalue = This->fat_decode(This, pos);
797	This->fat_encode(This, pos, value);
798	if(This->freeSpace != MAX32) {
799		if(oldvalue)
800			This->freeSpace++;
801		if(value)
802			This->freeSpace--;
803	}
804}
805
806unsigned int get_next_free_cluster(Fs_t *This, unsigned int last)
807{
808	unsigned int i;
809
810	if(This->last != MAX32)
811		last = This->last;
812
813	if (last < 2 ||
814	    last >= This->num_clus+1)
815		last = 1;
816
817	for (i=last+1; i< This->num_clus+2; i++) {
818		unsigned int r = fatDecode(This, i);
819		if(r == 1)
820			goto exit_0;
821		if (!r) {
822			This->last = i;
823			return i;
824		}
825	}
826
827	for(i=2; i < last+1; i++) {
828		unsigned int r = fatDecode(This, i);
829		if(r == 1)
830			goto exit_0;
831		if (!r) {
832			This->last = i;
833			return i;
834		}
835	}
836
837
838	fprintf(stderr,"No free cluster %d %d\n", This->preallocatedClusters,
839		This->last);
840	return 1;
841 exit_0:
842	fprintf(stderr, "FAT error\n");
843	return 1;
844}
845
846int fat_error(Stream_t *Dir)
847{
848	Stream_t *Stream = GetFs(Dir);
849	DeclareThis(Fs_t);
850
851	if(This->fat_error)
852		fprintf(stderr,"Fat error detected\n");
853
854	return This->fat_error;
855}
856
857int fat32RootCluster(Stream_t *Dir)
858{
859	Stream_t *Stream = GetFs(Dir);
860	DeclareThis(Fs_t);
861
862	if(This->fat_bits == 32)
863		return This->rootCluster;
864	else
865		return 0;
866}
867
868
869/*
870 * Get the amount of free space on the diskette
871 */
872
873mt_size_t getfree(Stream_t *Dir)
874{
875	Stream_t *Stream = GetFs(Dir);
876	DeclareThis(Fs_t);
877
878	if(This->freeSpace == MAX32 || This->freeSpace == 0) {
879		register unsigned int i;
880		size_t total;
881
882		total = 0L;
883		for (i = 2; i < This->num_clus + 2; i++) {
884			unsigned int r = fatDecode(This,i);
885			if(r == 1) {
886				return -1;
887			}
888			if (!r)
889				total++;
890		}
891		This->freeSpace = total;
892	}
893	return sectorsToBytes((Stream_t*)This,
894						  This->freeSpace * This->cluster_size);
895}
896
897
898/*
899 * Ensure that there is a minimum of total sectors free
900 */
901int getfreeMinClusters(Stream_t *Dir, size_t size)
902{
903	Stream_t *Stream = GetFs(Dir);
904	DeclareThis(Fs_t);
905	register unsigned int i, last;
906	size_t total;
907
908	if(batchmode && This->freeSpace == MAX32)
909		getfree(Stream);
910
911	if(This->freeSpace != MAX32) {
912		if(This->freeSpace >= size)
913			return 1;
914		else {
915			fprintf(stderr, "Disk full\n");
916			got_signal = 1;
917			return 0;
918		}
919	}
920
921	total = 0L;
922
923	/* we start at the same place where we'll start later to actually
924	 * allocate the sectors.  That way, the same sectors of the FAT, which
925	 * are already loaded during getfreeMin will be able to be reused
926	 * during get_next_free_cluster */
927	last = This->last;
928
929	if ( last < 2 || last >= This->num_clus + 2)
930		last = 1;
931	for (i=last+1; i< This->num_clus+2; i++){
932		unsigned int r = fatDecode(This, i);
933		if(r == 1) {
934			goto exit_0;
935		}
936		if (!r)
937			total++;
938		if(total >= size)
939			return 1;
940	}
941	for(i=2; i < last+1; i++){
942		unsigned int r = fatDecode(This, i);
943		if(r == 1) {
944			goto exit_0;
945		}
946		if (!r)
947			total++;
948		if(total >= size)
949			return 1;
950	}
951	fprintf(stderr, "Disk full\n");
952	got_signal = 1;
953	return 0;
954 exit_0:
955	fprintf(stderr, "FAT error\n");
956	return 0;
957}
958
959
960int getfreeMinBytes(Stream_t *Dir, mt_size_t size)
961{
962	Stream_t *Stream = GetFs(Dir);
963	DeclareThis(Fs_t);
964	size_t size2;
965
966	size2 = size  / (This->sector_size * This->cluster_size);
967	if(size % (This->sector_size * This->cluster_size))
968		size2++;
969	return getfreeMinClusters(Dir, size2);
970}
971
972
973unsigned int getStart(Stream_t *Dir, struct directory *dir)
974{
975	Stream_t *Stream = GetFs(Dir);
976	unsigned int first;
977
978	first = START(dir);
979	if(fat32RootCluster(Stream))
980		first |= STARTHI(dir) << 16;
981	return first;
982}
983
984int fs_free(Stream_t *Stream)
985{
986	DeclareThis(Fs_t);
987
988	if(This->FatMap) {
989		int i, nr_entries;
990		nr_entries = (This->fat_len + SECT_PER_ENTRY - 1) /
991			SECT_PER_ENTRY;
992		for(i=0; i< nr_entries; i++)
993			if(This->FatMap[i].data)
994				free(This->FatMap[i].data);
995		free(This->FatMap);
996	}
997	if(This->cp)
998		cp_close(This->cp);
999	return 0;
1000}
1001