/*  Copyright 1986-1992 Emmet P. Gray.
 *  Copyright 1994,1996-2009 Alain Knaff.
 *  This file is part of mtools.
 *
 *  Mtools is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Mtools is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
 *
 * mformat.c
 */

#define DONT_NEED_WAIT

#include "sysincludes.h"
#include "msdos.h"
#include "mtools.h"
#include "mainloop.h"
#include "fsP.h"
#include "file.h"
#include "plain_io.h"
#include "floppyd_io.h"
#include "nameclash.h"
#include "buffer.h"
#ifdef HAVE_ASSERT_H
#include <assert.h>
#endif
#ifdef USE_XDF
#include "xdf_io.h"
#endif
#include "partition.h"
#include "file_name.h"

#ifndef abs
#define abs(x) ((x)>0?(x):-(x))
#endif

#ifdef OS_linux
#include "linux/hdreg.h"

#define _LINUX_STRING_H_
#define kdev_t int
#include "linux/fs.h"
#undef _LINUX_STRING_H_

#endif


static int init_geometry_boot(union bootsector *boot, struct device *dev,
			      uint8_t sectors0,
			      uint8_t rate_0, uint8_t rate_any,
			      unsigned long *tot_sectors, int keepBoot)
{
	int nb_renum;
	int sector2;
	int sum;

	set_word(boot->boot.nsect, dev->sectors);
	set_word(boot->boot.nheads, dev->heads);

#ifdef HAVE_ASSERT_H
	assert(*tot_sectors != 0);
#endif

	if (*tot_sectors <= UINT16_MAX){
		set_word(boot->boot.psect, (uint16_t) *tot_sectors);
		set_dword(boot->boot.bigsect, 0);
	} else if(*tot_sectors <= UINT32_MAX){
		set_word(boot->boot.psect, 0);
		set_dword(boot->boot.bigsect, (uint32_t) *tot_sectors);
	} else {
		fprintf(stderr, "Too many sectors %ld\n", *tot_sectors);
		exit(1);
	}

	if (dev->use_2m & 0x7f){
		int bootOffset;
		uint8_t j;
		uint8_t size2;
		uint16_t i;
		strncpy(boot->boot.banner, "2M-STV04", 8);
		boot->boot.ext.old.res_2m = 0;
		boot->boot.ext.old.fmt_2mf = 6;
		if ( dev->sectors % ( ((1 << dev->ssize) + 3) >> 2 ))
			boot->boot.ext.old.wt = 1;
		else
			boot->boot.ext.old.wt = 0;
		boot->boot.ext.old.rate_0= rate_0;
		boot->boot.ext.old.rate_any= rate_any;
		if (boot->boot.ext.old.rate_any== 2 )
			boot->boot.ext.old.rate_any= 1;
		i=76;

		/* Infp0 */
		set_word(boot->boot.ext.old.Infp0, i);
		boot->bytes[i++] = sectors0;
		boot->bytes[i++] = 108;
		for(j=1; j<= sectors0; j++)
			boot->bytes[i++] = j;

		set_word(boot->boot.ext.old.InfpX, i);

		boot->bytes[i++] = 64;
		boot->bytes[i++] = 3;
		nb_renum = i++;
		sector2 = dev->sectors;
		size2 = dev->ssize;
		j=1;
		while( sector2 ){
			while ( sector2 < (1 << size2) >> 2 )
				size2--;
			boot->bytes[i++] = 128 + j;
			boot->bytes[i++] = j++;
			boot->bytes[i++] = size2;
			sector2 -= (1 << size2) >> 2;
		}
		boot->bytes[nb_renum] = ( i - nb_renum - 1 ) / 3;

		set_word(boot->boot.ext.old.InfTm, i);

		sector2 = dev->sectors;
		size2= dev->ssize;
		while(sector2){
			while ( sector2 < 1 << ( size2 - 2) )
				size2--;
			boot->bytes[i++] = size2;
			sector2 -= 1 << (size2 - 2 );
		}

		set_word(boot->boot.ext.old.BootP,i);
		bootOffset = i;

		/* checksum */
		for (sum=0, j=64; j<i; j++)
			sum += boot->bytes[j];/* checksum */
		boot->boot.ext.old.CheckSum=-sum;
		return bootOffset;
	} else {
		if(!keepBoot) {
			boot->boot.jump[0] = 0xeb;
			boot->boot.jump[1] = 0;
			boot->boot.jump[2] = 0x90;
			strncpy(boot->boot.banner, mformat_banner, 8);
			/* It looks like some versions of DOS are
			 * rather picky about this, and assume default
			 * parameters without this, ignoring any
			 * indication about cluster size et al. */
		}
		return 0;
	}
}


static int comp_fat_bits(Fs_t *Fs, int estimate,
			 unsigned long tot_sectors, int fat32)
{
	int needed_fat_bits;

	needed_fat_bits = 12;

#define MAX_DISK_SIZE(bits,clusters) \
	TOTAL_DISK_SIZE((bits), Fs->sector_size, (clusters), \
			Fs->num_fat, MAX_BYTES_PER_CLUSTER/Fs->sector_size)

	if(tot_sectors > MAX_DISK_SIZE(12, FAT12-1))
		needed_fat_bits = 16;
	if(fat32 || tot_sectors > MAX_DISK_SIZE(16, FAT16-1))
		needed_fat_bits = 32;

#undef MAX_DISK_SIZE

	if(abs(estimate) && abs(estimate) < needed_fat_bits) {
		if(fat32) {
			fprintf(stderr,
				"Contradiction between FAT size on command line and FAT size in conf file\n");
			exit(1);
		}
		fprintf(stderr,
			"Device too big for a %d bit FAT\n",
			estimate);
		exit(1);
	}

	if(!estimate) {
		unsigned int min_fat16_size;

		if(needed_fat_bits > 12)
			return needed_fat_bits;
		min_fat16_size = DISK_SIZE(16, Fs->sector_size, FAT12,
					   Fs->num_fat, 1);
		if(tot_sectors < min_fat16_size)
			return 12;
 		else if(Fs->cluster_size == 0 &&
			tot_sectors >= 2* min_fat16_size)
 			return 16; /* heuristics */
 	}

 	return estimate;
}


/*
 * According to Microsoft "Hardware White Paper", "Microsoft
 * Extensible Formware Initiative", "FAT32 File System Specification",
 * Version 1.03, December 6, 2000:
 * If (CountofClusters < 4085) { // 0x0ff5
 *  // Volume is FAT12
 * } else if (CountofClusters < 65525) { // 0xfff5
 *  // Volume is FAT16
 * } else {
 *  //Volume is FAT32
 * }
 *
 * This document can be found at the following URL:
 * https://staff.washington.edu/dittrich/misc/fatgen103.pdf
 * The relevant passus is on page 15.
 *
 * Actually, experimentations with Windows NT 4 show that the
 * cutoff is 4087 rather than 4085... This is Microsoft after all.
 * Not sure what the other Microsoft OS'es do though...
 */
static void calc_fat_bits2(Fs_t *Fs, unsigned long tot_sectors, int fat_bits,
			   int may_change_cluster_size,
			   int may_change_root_size)
{
	unsigned long rem_sect;

	/*
	 * the "remaining sectors" after directory and boot
	 * hasve been accounted for.
	 */
	rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start;
	switch(abs(fat_bits)) {
		case 0:

#define MY_DISK_SIZE(bits,clusters) \
			DISK_SIZE( (bits), Fs->sector_size, (clusters), \
				   Fs->num_fat, Fs->cluster_size)

			if(rem_sect >= MY_DISK_SIZE(16, FAT12+2))
				/* big enough for FAT16
				 * We take a margin of 2, because NT4
				 * misbehaves, and starts considering a disk
				 * as FAT16 only if it is larger than 4086
				 * sectors, rather than 4084 as it should
				 */
				set_fat16(Fs);
			else if(rem_sect <= MY_DISK_SIZE(12, FAT12-1))
				 /* small enough for FAT12 */
				 set_fat12(Fs);
			else {
				/* "between two chairs",
				 * augment cluster size, and
				 * settle it */
				if(may_change_cluster_size &&
				   Fs->cluster_size * Fs->sector_size * 2
				   <= MAX_BYTES_PER_CLUSTER)
					Fs->cluster_size <<= 1;
				else if(may_change_root_size) {
					Fs->dir_len +=
						rem_sect - MY_DISK_SIZE(12, FAT12-1);
				}
				set_fat12(Fs);
			}
			break;
#undef MY_DISK_SIZE

		case 12:
			set_fat12(Fs);
			break;
		case 16:
			set_fat16(Fs);
			break;
		case 32:
			set_fat32(Fs);
			break;
	}
}

static __inline__ void format_root(Fs_t *Fs, char *label, union bootsector *boot)
{
	Stream_t *RootDir;
	char *buf;
	unsigned int i;
	struct ClashHandling_t ch;
	unsigned int dirlen;

	init_clash_handling(&ch);
	ch.name_converter = label_name_uc;
	ch.ignore_entry = -2;

	buf = safe_malloc(Fs->sector_size);
	RootDir = OpenRoot((Stream_t *)Fs);
	if(!RootDir){
		fprintf(stderr,"Could not open root directory\n");
		exit(1);
	}

	memset(buf, '\0', Fs->sector_size);

	if(Fs->fat_bits == 32) {
		/* on a FAT32 system, we only write one sector,
		 * as the directory can be extended at will...*/
		dirlen = Fs->cluster_size;
		fatAllocate(Fs, Fs->rootCluster, Fs->end_fat);
	} else
		dirlen = Fs->dir_len;
	for (i = 0; i < dirlen; i++)
		WRITES(RootDir, buf, sectorsToBytes((Stream_t*)Fs, i),
			   Fs->sector_size);

	ch.ignore_entry = 1;
	if(label[0])
		mwrite_one(RootDir,label, 0, labelit, NULL,&ch);

	FREE(&RootDir);
	if(Fs->fat_bits == 32)
		set_word(boot->boot.dirents, 0);
	else
		set_word(boot->boot.dirents, Fs->dir_len * (Fs->sector_size / 32));
	free(buf);
}


#ifdef USE_XDF
static void xdf_calc_fat_size(Fs_t *Fs, unsigned long tot_sectors,
			      int fat_bits)
{
	unsigned int rem_sect;

	rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start - 2 * Fs->fat_len;

	if(Fs->fat_len) {
		/* an XDF disk, we know the fat_size and have to find
		 * out the rest. We start with a cluster size of 1 and
		 * keep doubling until everything fits into the
		 * FAT. This will occur eventually, as our FAT has a
		 * minimal size of 1 */
		for(Fs->cluster_size = 1; 1 ; Fs->cluster_size <<= 1) {
			Fs->num_clus = rem_sect / Fs->cluster_size;
			if(abs(fat_bits) == 16 || Fs->num_clus >= FAT12)
				set_fat16(Fs);
			else
				set_fat12(Fs);
			if (Fs->fat_len >= NEEDED_FAT_SIZE(Fs))
				return;
		}
	}
	fprintf(stderr,"Internal error while calculating Xdf fat size\n");
	exit(1);
}
#endif

static void calc_fat_size(Fs_t *Fs, unsigned long tot_sectors)
{
	unsigned long rem_sect;
	unsigned long real_rem_sect;
	unsigned long numerator;
	unsigned long denominator;
	unsigned int fat_nybbles;
	unsigned int slack;
	int printGrowMsg=1; /* Should we print "growing FAT" messages ?*/

#ifdef DEBUG
	fprintf(stderr, "Fat start=%d\n", Fs->fat_start);
	fprintf(stderr, "tot_sectors=%lu\n", tot_sectors);
	fprintf(stderr, "dir_len=%d\n", Fs->dir_len);
#endif
	real_rem_sect = rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start;

	/* Cheat a little bit to address the _really_ common case of
	   odd number of remaining sectors while both nfat and cluster size
	   are even... */
	if(rem_sect         %2 == 1 &&
	   Fs->num_fat      %2 == 0 &&
	   Fs->cluster_size %2 == 0)
		rem_sect--;

#ifdef DEBUG
	fprintf(stderr, "Rem sect=%lu\n", rem_sect);
#endif

	if(Fs->fat_bits == 0) {
		fprintf(stderr, "Weird, fat bits = 0\n");
		exit(1);
	}


	/* See fat_size_calculation.tex or
	   (http://ftp.gnu.org/software/mtools/manual/fat_size_calculation.pdf)
	   for an explantation about why the stuff below works...
	*/

	fat_nybbles = Fs->fat_bits / 4;
	numerator   = rem_sect+2*Fs->cluster_size;
	denominator =
	  Fs->cluster_size * Fs->sector_size * 2 +
	  Fs->num_fat * fat_nybbles;

	if(fat_nybbles == 3)
		numerator *= fat_nybbles;
	else
		/* Avoid numerical overflows, divide the denominator
		 * rather than multiplying the numerator */
		denominator = denominator / fat_nybbles;

#ifdef DEBUG
	fprintf(stderr, "Numerator=%lu denominator=%lu\n",
		numerator, denominator);
#endif

	Fs->fat_len = (numerator-1)/denominator+1;
	Fs->num_clus = (rem_sect-(Fs->fat_len*Fs->num_fat))/Fs->cluster_size;

	/* Apply upper bounds for FAT bits */
	if(Fs->fat_bits == 16 && Fs->num_clus >= FAT16)
		Fs->num_clus = FAT16-1;
	if(Fs->fat_bits == 12 && Fs->num_clus >= FAT12)
		Fs->num_clus = FAT12-1;

	/* A safety, if above math is correct, this should not be happen...*/
	if(Fs->num_clus > (Fs->fat_len * Fs->sector_size * 2 /
			   fat_nybbles - 2)) {
		fprintf(stderr,
			"Fat size miscalculation, shrinking num_clus from %d ",
			Fs->num_clus);
		Fs->num_clus = (Fs->fat_len * Fs->sector_size * 2 /
				fat_nybbles - 2);
		fprintf(stderr, " to %d\n", Fs->num_clus);
	}
#ifdef DEBUG
	fprintf(stderr, "Num_clus=%d fat_len=%d nybbles=%d\n",
		Fs->num_clus, Fs->fat_len, fat_nybbles);
#endif

	if ( Fs->num_clus < FAT16 && Fs->fat_bits > 16 ){
		fprintf(stderr,"Too few clusters for this fat size."
			" Please choose a 16-bit fat in your /etc/mtools.conf"
			" or .mtoolsrc file\n");
		exit(1);
	}

	/* As the number of clusters is specified nowhere in the boot sector,
	 * it will be calculated by removing everything else from total number
	 * of sectors. This means that if we reduced the number of clusters
	 * above, we will have to grow the FAT in order to take up any excess
	 * sectors... */
#ifdef HAVE_ASSERT_H
	assert(rem_sect >= Fs->num_clus * Fs->cluster_size +
	       Fs->fat_len * Fs->num_fat);
#endif
	slack = rem_sect -
		Fs->num_clus * Fs->cluster_size -
		Fs->fat_len * Fs->num_fat;
	if(slack >= Fs->cluster_size) {
		/* This can happen under two circumstances:
		   1. We had to reduce num_clus because we reached maximum
		   number of cluster for FAT12 or FAT16
		*/
		if(printGrowMsg) {
			fprintf(stderr, "Slack=%d\n", slack);
			fprintf(stderr, "Growing fat size from %d",
				Fs->fat_len);
		}
		Fs->fat_len +=
			(slack - Fs->cluster_size) / Fs->num_fat + 1;
		if(printGrowMsg) {
			fprintf(stderr,
				" to %d in order to take up excess cluster area\n",
				Fs->fat_len);
		}
		Fs->num_clus = (rem_sect-(Fs->fat_len*Fs->num_fat))/
			Fs->cluster_size;

	}

#ifdef HAVE_ASSERT_H
	/* Fat must be big enough for all clusters */
	assert( ((Fs->num_clus+2) * fat_nybbles) <=
		(Fs->fat_len*Fs->sector_size*2));

	/* num_clus must be big enough to cover rest of disk, or else further
	 * users of the filesystem will assume a bigger num_clus, which might
	 * be too big for fat_len */
	assert(Fs->num_clus ==
	       (real_rem_sect - Fs->num_fat * Fs->fat_len) / Fs->cluster_size);
#endif
}


static unsigned char bootprog[]=
{0xfa, 0x31, 0xc0, 0x8e, 0xd8, 0x8e, 0xc0, 0xfc, 0xb9, 0x00, 0x01,
 0xbe, 0x00, 0x7c, 0xbf, 0x00, 0x80, 0xf3, 0xa5, 0xea, 0x00, 0x00,
 0x00, 0x08, 0xb8, 0x01, 0x02, 0xbb, 0x00, 0x7c, 0xba, 0x80, 0x00,
 0xb9, 0x01, 0x00, 0xcd, 0x13, 0x72, 0x05, 0xea, 0x00, 0x7c, 0x00,
 0x00, 0xcd, 0x19};

static __inline__ void inst_boot_prg(union bootsector *boot, int offset)
{
	memcpy((char *) boot->boot.jump + offset,
	       (char *) bootprog, sizeof(bootprog) /sizeof(bootprog[0]));
	if(offset - 2 < 0x80) {
	  /* short jump */
	  boot->boot.jump[0] = 0xeb;
	  boot->boot.jump[1] = offset -2;
	  boot->boot.jump[2] = 0x90;
	} else {
	  /* long jump, if offset is too large */
	  boot->boot.jump[0] = 0xe9;
	  boot->boot.jump[1] = offset -3;
	  boot->boot.jump[2] = 0x00;
	}
	set_word(boot->boot.jump + offset + 20, offset + 24);
}

static void calc_cluster_size(struct Fs_t *Fs, unsigned long tot_sectors,
			      int fat_bits)

{
	unsigned int max_clusters; /* maximal possible number of sectors for
				   * this FAT entry length (12/16/32) */
	unsigned int max_fat_size; /* maximal size of the FAT for this FAT
				    * entry length (12/16/32) */
	unsigned int rem_sect; /* remaining sectors after we accounted for
				* the root directory and boot sector(s) */

	switch(abs(fat_bits)) {
		case 12:
			max_clusters = FAT12-1;
			max_fat_size = Fs->num_fat *
				FAT_SIZE(12, Fs->sector_size, max_clusters);
			break;
		case 16:
		case 0: /* still hesititating between 12 and 16 */
			max_clusters = FAT16-1;
			max_fat_size = Fs->num_fat *
				FAT_SIZE(16, Fs->sector_size, max_clusters);
			break;
		case 32:
			/*
			   FAT32 cluster sizes for disks with 512 block size
			   according to Microsoft specification fatgen103.doc:
			
			   32.5 MB - 260 MB   cluster_size =  1
			    260 MB -   8 GB   cluster_size =  8
			      8 GB -  16 GB   cluster_size = 16
			     16 GB -  32 GB   cluster_size = 32
			     32 GB -   2 TB   cluster_size = 64
			
			   Below calculation is generalized and does not depend
			   on 512 block size.
			 */
			Fs->cluster_size = tot_sectors > 32*1024*1024*2 ? 64 :
			                   tot_sectors > 16*1024*1024*2 ? 32 :
			                   tot_sectors >  8*1024*1024*2 ? 16 :
			                   tot_sectors >     260*1024*2 ? 8 : 1;
			return;
		default:
			fprintf(stderr,"Bad fat size\n");
			exit(1);
	}

	if(tot_sectors <= Fs->fat_start + Fs->num_fat + Fs->dir_len) {
		/* we need at least enough sectors to fit boot, fat and root
		 * dir */
		fprintf(stderr, "Not enough sectors\n");
		exit(1);
	}

	rem_sect = tot_sectors - Fs->dir_len - Fs->fat_start;

	/* double the cluster size until we can fill up the disk with
	 * the maximal number of sectors of this size */
	while(Fs->cluster_size * max_clusters  + max_fat_size < rem_sect) {
		if(Fs->cluster_size > 64) {
			/* bigger than 64. Should fit */
			fprintf(stderr,
				"Internal error while calculating cluster size\n");
			exit(1);
		}
		Fs->cluster_size <<= 1;
	}
}


static int old_dos_size_to_geom(size_t size,
				unsigned int *cyls,
				unsigned short *heads,
				unsigned short *sects)
{
	struct OldDos_t *params = getOldDosBySize(size);
	if(params != NULL) {
		*cyls = params->tracks;
		*heads = params->heads;
		*sects = params->sectors;
		return 0;
	} else
		return 1;
}


static void calc_fs_parameters(struct device *dev, unsigned long tot_sectors,
			       struct Fs_t *Fs, union bootsector *boot)
{
	struct OldDos_t *params=NULL;
	if(dev->fat_bits == 0 || abs(dev->fat_bits) == 12)
		params = getOldDosByParams(dev->tracks,dev->heads,dev->sectors,
					   Fs->dir_len, Fs->cluster_size);
	if(params != NULL) {
		boot->boot.descr = params->media;
		Fs->cluster_size = params->cluster_size;
		Fs->dir_len = params->dir_len;
		Fs->fat_len = params->fat_len;
		Fs->fat_bits = 12;
	} else {
		int may_change_cluster_size = (Fs->cluster_size == 0);
		int may_change_root_size = (Fs->dir_len == 0);

		/* a non-standard format */
		if(DWORD(nhs) || tot_sectors % (dev->sectors * dev->heads))
			boot->boot.descr = 0xf8;
		else
			boot->boot.descr = 0xf0;


		if(!Fs->cluster_size) {
			if (dev->heads == 1)
				Fs->cluster_size = 1;
			else {
				Fs->cluster_size = (tot_sectors > 2000 ) ? 1:2;
				if (dev->use_2m & 0x7f)
					Fs->cluster_size = 1;
			}
		}

		if(!Fs->dir_len) {
			if (dev->heads == 1)
				Fs->dir_len = 4;
			else
				Fs->dir_len = (tot_sectors > 2000) ? 32 : 7;
		}

		calc_cluster_size(Fs, tot_sectors, dev->fat_bits);
#ifdef USE_XDF
		if(Fs->fat_len)
			xdf_calc_fat_size(Fs, tot_sectors, dev->fat_bits);
		else
#endif
		{
			calc_fat_bits2(Fs, tot_sectors, dev->fat_bits,
				       may_change_cluster_size,
				       may_change_root_size);
			calc_fat_size(Fs, tot_sectors);
		}
	}

	set_word(boot->boot.fatlen, Fs->fat_len);
}



static void calc_fs_parameters_32(unsigned long tot_sectors,
				  struct Fs_t *Fs, union bootsector *boot)
{
	unsigned long num_clus;
	if(DWORD(nhs))
		boot->boot.descr = 0xf8;
	else
		boot->boot.descr = 0xf0;

	if(!Fs->cluster_size)
		calc_cluster_size(Fs, tot_sectors, 32);
	Fs->dir_len = 0;
	num_clus = tot_sectors / Fs->cluster_size;
	/* Maximal number of clusters on FAT32 is 0xffffff6 */
	if (num_clus > 0xffffff6) {
		fprintf(stderr, "Too many clusters\n");
		exit(1);
	}
	Fs->num_clus = (unsigned int) num_clus;
	set_fat32(Fs);
	calc_fat_size(Fs, tot_sectors);
	set_word(boot->boot.fatlen, 0);
	set_dword(boot->boot.ext.fat32.bigFat, Fs->fat_len);
}




static void usage(int ret) NORETURN;
static void usage(int ret)
{
	fprintf(stderr,
		"Mtools version %s, dated %s\n", mversion, mdate);
	fprintf(stderr,
		"Usage: %s [-V] [-t tracks] [-h heads] [-n sectors] "
		"[-v label] [-1] [-4] [-8] [-f size] "
		"[-N serialnumber] "
		"[-k] [-B bootsector] [-r root_dir_len] [-L fat_len] "
		"[-F] [-I fsVersion] [-C] [-c cluster_size] "
		"[-H hidden_sectors] "
#ifdef USE_XDF
		"[-X] "
#endif
		"[-S hardsectorsize] [-M softsectorsize] [-3] "
		"[-2 track0sectors] [-0 rate0] [-A rateany] [-a]"
		"device\n", progname);
	exit(ret);
}

#ifdef OS_linux
static int get_sector_size(int fd, char *errmsg) {
	int sec_size;
	if (ioctl(fd, BLKSSZGET, &sec_size) != 0 || sec_size <= 0) {
		sprintf(errmsg, "Could not get sector size of device (%s)",
			strerror(errno));
		return -1;
	}

	/* Cap sector size at 4096 */
	if(sec_size > 4096)
		sec_size = 4096;
	return sec_size;
}

static int get_block_geom(int fd, struct device *dev, char *errmsg) {
	struct hd_geometry geom;
	int sec_size;
	long size;
	uint16_t heads=dev->heads;
	uint16_t sectors=dev->sectors;
	unsigned int sect_per_track;

	if (ioctl(fd, HDIO_GETGEO, &geom) < 0) {
		sprintf(errmsg, "Could not get geometry of device (%s)",
			strerror(errno));
		return -1;
	}

	if (ioctl(fd, BLKGETSIZE, &size) < 0) {
		sprintf(errmsg, "Could not get size of device (%s)",
			strerror(errno));
		return -1;
	}

	sec_size = get_sector_size(fd, errmsg);
	if(sec_size < 0)
		return -1;
	
	dev->ssize = 0;
	while (dev->ssize < 0x7F && (128 << dev->ssize) < sec_size)
		dev->ssize++;

	if(!heads)
		heads = geom.heads;
	if(!sectors)
		sectors = geom.sectors;

	sect_per_track = heads * sectors;
	if(!dev->hidden) {
		unsigned long hidden;
		hidden = geom.start % sect_per_track;
		if(hidden && hidden != sectors) {
			sprintf(errmsg,
				"Hidden (%ld) does not match sectors (%d)\n",
				hidden, sectors);
			return -1;
		}
		dev->hidden = hidden;
	}
	dev->heads = heads;
	dev->sectors = sectors;
	if(!dev->tracks)
		dev->tracks = (size + dev->hidden % sect_per_track) / sect_per_track;
	return 0;
}
#endif

static int get_lba_geom(Stream_t *Direct, unsigned long tot_sectors, struct device *dev, char *errmsg) {
	int sect_per_track;
	unsigned long tracks;

	/* if one value is already specified we do not want to overwrite it */
	if (dev->heads || dev->sectors || dev->tracks) {
		sprintf(errmsg, "Number of heads or sectors or tracks was already specified");
		return -1;
	}

	if (!tot_sectors) {
#ifdef OS_linux
		int fd;
		int sec_size;
		long size;
		struct MT_STAT stbuf;

		fd = get_fd(Direct);
		if (MT_FSTAT(fd, &stbuf) < 0) {
			sprintf(errmsg, "Could not stat file (%s)", strerror(errno));
			return -1;
		}

		if (S_ISBLK(stbuf.st_mode)) {
			if (ioctl(fd, BLKGETSIZE, &size) != 0) {
				sprintf(errmsg, "Could not get size of device (%s)",
					strerror(errno));
				return -1;
			}
			sec_size = get_sector_size(fd, errmsg);
			if(sec_size < 0)
				return -1;

			if (!(dev->ssize & 0x80)) {
				dev->ssize = 0;
				while (dev->ssize < 0x7F && (128 << dev->ssize) < sec_size)
				dev->ssize++;
			}
			if ((dev->ssize & 0x7f) > 2)
				tot_sectors = size >> ((dev->ssize & 0x7f) - 2);
			else
				tot_sectors = size << (2 - (dev->ssize & 0x7f));
		} else if (S_ISREG(stbuf.st_mode)) {
			tot_sectors = stbuf.st_size >> ((dev->ssize & 0x7f) + 7);
		} else {
			sprintf(errmsg, "Could not get size of device (%s)",
				"No method available");
			return -1;
		}
#else
		mt_size_t size;
		GET_DATA(Direct, 0, &size, 0, 0);
		if (size == 0) {
			sprintf(errmsg, "Could not get size of device (%s)",
				"No method available");
			return -1;
		}
		tot_sectors = size >> ((dev->ssize & 0x7f) + 7);
#endif
	}

	dev->sectors = 63;

	if (tot_sectors < 16*63*1024)
		dev->heads = 16;
	else if (tot_sectors < 32*63*1024)
		dev->heads = 32;
	else if (tot_sectors < 64*63*1024)
		dev->heads = 64;
	else if (tot_sectors < 128*63*1024)
		dev->heads = 128;
	else
		dev->heads = 255;

	sect_per_track = dev->heads * dev->sectors;
	tracks = (tot_sectors + dev->hidden % sect_per_track) / sect_per_track;
	if (tracks > 0xFFFFFFFF) {
		sprintf(errmsg, "Device is too big, it has too many tracks");
		return -1;
	}

	dev->tracks = (uint32_t) tracks;

	return 0;
}

void mformat(int argc, char **argv, int dummy UNUSEDP) NORETURN;
void mformat(int argc, char **argv, int dummy UNUSEDP)
{
	int r; /* generic return value */
	Fs_t Fs;
	unsigned int hs;
	int hs_set;
	unsigned int arguse_2m = 0;
	uint8_t sectors0=18; /* number of sectors on track 0 */
	int create = 0;
	uint8_t rate_0, rate_any;
	int mangled;
	uint8_t argssize=0; /* sector size */
	int msize=0;
	int fat32 = 0;
	struct label_blk_t *labelBlock;
	int bootOffset;

#ifdef USE_XDF
	unsigned int i;
	int format_xdf = 0;
	struct xdf_info info;
#endif
	union bootsector boot;
	char *bootSector=0;
	int c;
	int keepBoot = 0;
	struct device used_dev;
	unsigned int argtracks;
	uint16_t argheads, argsectors;
	unsigned long tot_sectors=0;
	int blocksize;

	char drive, name[EXPAND_BUF];

	char label[VBUFSIZE];

	dos_name_t shortlabel;
	struct device *dev;
	char errmsg[2100];

	uint32_t serial;
 	int serial_set;
	int fsVersion;
	int mediaDesc=-1;

	mt_size_t maxSize;

	int Atari = 0; /* should we add an Atari-style serial number ? */

	unsigned int backupBoot = 6;
	int backupBootSet = 0;

	unsigned int resvSects = 0;
	
	char *endptr;

	hs = hs_set = 0;
	argtracks = 0;
	argheads = 0;
	argsectors = 0;
	arguse_2m = 0;
	argssize = 0x2;
	label[0] = '\0';
	serial_set = 0;
	serial = 0;
	fsVersion = 0;

	Fs.cluster_size = 0;
	Fs.refs = 1;
	Fs.dir_len = 0;
	if(getenv("MTOOLS_DIR_LEN")) {
	  Fs.dir_len = atoui(getenv("MTOOLS_DIR_LEN"));
	  if(Fs.dir_len <= 0)
	    Fs.dir_len=0;
	}
	Fs.fat_len = 0;
	Fs.num_fat = 2;
	if(getenv("MTOOLS_NFATS")) {
	  Fs.num_fat = atoui(getenv("MTOOLS_NFATS"));
	  if(Fs.num_fat <= 0)
	    Fs.num_fat=2;
	}
	Fs.Class = &FsClass;
	rate_0 = mtools_rate_0;
	rate_any = mtools_rate_any;

	/* get command line options */
	if(helpFlag(argc, argv))
		usage(0);
	while ((c = getopt(argc,argv,
			   "i:148f:t:n:v:qub"
			   "kK:R:B:r:L:I:FCc:Xh:s:T:l:N:H:M:S:2:30:Aad:m:"))!= EOF) {
		errno = 0;
		endptr = NULL;
		switch (c) {
			case 'i':
				set_cmd_line_image(optarg);
				break;

			/* standard DOS flags */
			case '1':
				argheads = 1;
				break;
			case '4':
				argsectors = 9;
				argtracks = 40;
				break;
			case '8':
				argsectors = 8;
				argtracks = 40;
				break;
			case 'f':
				r=old_dos_size_to_geom(atoul(optarg),
						       &argtracks, &argheads,
						       &argsectors);
				if(r) {
					fprintf(stderr,
						"Bad size %s\n", optarg);
					exit(1);
				}
				break;
			case 't':
				argtracks = atou16(optarg);
				break;

			case 'T':
				tot_sectors = atoui(optarg);
				break;

			case 'n': /*non-standard*/
			case 's':
				argsectors = atou16(optarg);
				break;

			case 'l': /* non-standard */
			case 'v':
				strncpy(label, optarg, VBUFSIZE-1);
				label[VBUFSIZE-1] = '\0';
				break;

			/* flags supported by Dos but not mtools */
			case 'q':
			case 'u':
			case 'b':
			/*case 's': leave this for compatibility */
				fprintf(stderr,
					"Flag %c not supported by mtools\n",c);
				exit(1);



			/* flags added by mtools */
			case 'F':
				fat32 = 1;
				break;


			case 'S':
				argssize = atou8(optarg) | 0x80;
				if(argssize < 0x80)
					usage(1);
				if(argssize >= 0x87) {
					fprintf(stderr, "argssize must be less than 6\n");
					usage(1);
				}
				break;

#ifdef USE_XDF
			case 'X':
				format_xdf = 1;
				break;
#endif

			case '2':
				arguse_2m = 0xff;
				sectors0 = atou8(optarg);
				break;
			case '3':
				arguse_2m = 0x80;
				break;

			case '0': /* rate on track 0 */
				rate_0 = atou8(optarg);
				break;
			case 'A': /* rate on other tracks */
				rate_any = atou8(optarg);
				break;

			case 'M':
				msize = atoi(optarg);
				if(msize != 512 &&
				   msize != 1024 &&
				   msize != 2048 &&
				   msize != 4096) {
				  fprintf(stderr, "Only sector sizes of 512, 1024, 2048 or 4096 bytes are allowed\n");
				  usage(1);
				}
				break;

			case 'N':
 				serial = strtou32(optarg,&endptr,16);
 				serial_set = 1;
 				break;
			case 'a': /* Atari style serial number */
				Atari = 1;
				break;

			case 'C':
				create = O_CREAT | O_TRUNC;
				break;

			case 'H':
				hs = atoui(optarg);
				hs_set = 1;
				break;

			case 'I':
				fsVersion = strtoi(optarg,&endptr,0);
				break;

			case 'c':
				Fs.cluster_size = atoui(optarg);
				break;

			case 'r':
				Fs.dir_len = strtoui(optarg,&endptr,0);
				break;
			case 'L':
				Fs.fat_len = strtoui(optarg,&endptr,0);
				break;


			case 'B':
				bootSector = optarg;
				break;
			case 'k':
				keepBoot = 1;
				break;
			case 'K':
				backupBoot = atoui(optarg);
				backupBootSet=1;
				if(backupBoot < 2) {
				  fprintf(stderr, "Backupboot must be greater than 2\n");
				  exit(1);
				}
				break;
			case 'R':
				resvSects = atoui(optarg);
				break;
			case 'h':
				argheads = atou16(optarg);
				break;
			case 'd':
				Fs.num_fat = atoui(optarg);
				break;
			case 'm':
				mediaDesc = strtoi(optarg,&endptr,0);
				if(*endptr)
					mediaDesc = strtoi(optarg,&endptr,16);
				break;
			default:
				usage(1);
		}
		check_number_parse_errno(c, optarg, endptr);
	}

	if (argc - optind > 1)
		usage(1);
	if(argc - optind == 1) {
	    if(!argv[optind][0] || argv[optind][1] != ':')
		usage(1);
	    drive = ch_toupper(argv[argc -1][0]);
	} else {
	    drive = get_default_drive();
	    if(drive != ':') {
	      /* Use default drive only if it is ":" (image file), as else
		 it would be too dangerous... */
	      fprintf(stderr, "Drive letter missing\n");
	      exit(1);
	    }
	}

	if(argtracks && tot_sectors) {
		fprintf(stderr, "Only one of -t or -T may be specified\n");
		usage(1);
	}

#ifdef USE_XDF
	if(create && format_xdf) {
		fprintf(stderr,"Create and XDF can't be used together\n");
		exit(1);
	}
#endif

	/* check out a drive whose letter and parameters match */
	sprintf(errmsg, "Drive '%c:' not supported", drive);
	Fs.Direct = NULL;
	blocksize = 0;
	for(dev=devices;dev->drive;dev++) {
		FREE(&(Fs.Direct));
		/* drive letter */
		if (dev->drive != drive)
			continue;
		used_dev = *dev;

		SET_INT(used_dev.tracks, argtracks);
		SET_INT(used_dev.heads, argheads);
		SET_INT(used_dev.sectors, argsectors);
		SET_INT(used_dev.use_2m, arguse_2m);
		SET_INT(used_dev.ssize, argssize);
		if(hs_set)
			used_dev.hidden = hs;

		expand(dev->name, name);
#ifdef USING_NEW_VOLD
		strcpy(name, getVoldName(dev, name));
#endif

#ifdef USE_XDF
		if(!format_xdf) {
#endif
			Fs.Direct = 0;
#ifdef USE_FLOPPYD
			Fs.Direct = FloppydOpen(&used_dev, name,
						O_RDWR | create,
						errmsg, &maxSize);
#endif
			if(!Fs.Direct) {
				Fs.Direct = SimpleFileOpen(&used_dev, dev, name,
							   O_RDWR | create,
							   errmsg, 0, 1,
							   &maxSize);
			}
#ifdef USE_XDF
		} else {
			used_dev.misc_flags |= USE_XDF_FLAG;
			Fs.Direct = XdfOpen(&used_dev, name, O_RDWR,
					    errmsg, &info);
			if(Fs.Direct && !Fs.fat_len)
				Fs.fat_len = info.FatSize;
			if(Fs.Direct && !Fs.dir_len)
				Fs.dir_len = info.RootDirSize;
		}
#endif

		if (!Fs.Direct)
			continue;

#ifdef OS_linux
		if ((!used_dev.tracks || !used_dev.heads || !used_dev.sectors) &&
			(!IS_SCSI(dev))) {
			int fd= get_fd(Fs.Direct);
			struct MT_STAT stbuf;

			if (MT_FSTAT(fd, &stbuf) < 0) {
				sprintf(errmsg, "Could not stat file (%s)", strerror(errno));
				continue;
			}

			if (S_ISBLK(stbuf.st_mode))
			    /* If the following get_block_geom fails, do not 
			     * continue to next drive description, but allow
			     * get_lba_geom to kick in
			     */
			    get_block_geom(fd, &used_dev, errmsg);
		}
#endif

		if ((!used_dev.tracks && !tot_sectors) ||
		     !used_dev.heads || !used_dev.sectors){
			if (get_lba_geom(Fs.Direct, tot_sectors, &used_dev,
					 errmsg) < 0) {
				sprintf(errmsg, "%s: "
					"Complete geometry of the disk "
					"was not specified, \n"
					"neither in /etc/mtools.conf nor "
					"on the command line. \n"
					"LBA Assist Translation for "
					"calculating CHS geometry "
					"of the disk failed.\n", argv[0]);
				continue;
			}
		}

#if 0
		/* set parameters, if needed */
		if(SET_GEOM(Fs.Direct, &used_dev, 0xf0, boot)){
			sprintf(errmsg,"Can't set disk parameters: %s",
				strerror(errno));
			continue;
		}
#endif
		Fs.sector_size = 512;
		if( !(used_dev.use_2m & 0x7f)) {
			Fs.sector_size = 128 << (used_dev.ssize & 0x7f);
		}

		SET_INT(Fs.sector_size, msize);
		{
		    unsigned int j;
		    for(j = 0; j < 31; j++) {
			if (Fs.sector_size == (unsigned int) (1 << j)) {
			    Fs.sectorShift = j;
			    break;
			}
		    }
		    Fs.sectorMask = Fs.sector_size - 1;
		}

		if(!used_dev.blocksize || used_dev.blocksize < Fs.sector_size)
			blocksize = Fs.sector_size;
		else
			blocksize = used_dev.blocksize;

		if(blocksize > MAX_SECTOR)
			blocksize = MAX_SECTOR;

		/* do a "test" read */
		if (!create &&
		    READS(Fs.Direct, &boot.characters, 0, Fs.sector_size) !=
		    (signed int) Fs.sector_size) {
#ifdef HAVE_SNPRINTF
			snprintf(errmsg, sizeof(errmsg)-1,
				 "Error reading from '%s', wrong parameters?",
				 name);
#else
			sprintf(errmsg,
				"Error reading from '%s', wrong parameters?",
				name);
#endif
			continue;
		}
		break;
	}


	/* print error msg if needed */
	if ( dev->drive == 0 ){
		FREE(&Fs.Direct);
		fprintf(stderr,"%s: %s\n", argv[0],errmsg);
		exit(1);
	}

	/* calculate the total number of sectors */
	if(tot_sectors == 0) {
		unsigned long sect_per_track = used_dev.heads*used_dev.sectors;
		tot_sectors = used_dev.tracks*sect_per_track - used_dev.hidden%sect_per_track;
		/* Number of sectors must fit into 32bit value */
		if (tot_sectors > 0xFFFFFFFF) {
			fprintf(stderr, "Too many sectors\n");
			exit(1);
		}
	}

	/* create the image file if needed */
	if (create) {
		WRITES(Fs.Direct, &boot.characters,
		       sectorsToBytes((Stream_t*)&Fs, tot_sectors-1),
		       Fs.sector_size);
	}

	/* the boot sector */
	if(bootSector) {
		int fd;

		fd = open(bootSector, O_RDONLY | O_BINARY | O_LARGEFILE);
		if(fd < 0) {
			perror("open boot sector");
			exit(1);
		}
		if(read(fd, &boot.bytes, blocksize) < blocksize) {
			perror("short read on boot sector");
			exit(1);
		}
		keepBoot = 1;
		close(fd);
	}
	if(!keepBoot && !(used_dev.use_2m & 0x7f))
		memset(boot.characters, '\0', Fs.sector_size);
	set_dword(boot.boot.nhs, used_dev.hidden);

	Fs.Next = buf_init(Fs.Direct,
			   blocksize * used_dev.heads * used_dev.sectors,
			   blocksize * used_dev.heads * used_dev.sectors,
			   blocksize);
	Fs.Buffer = 0;

	boot.boot.nfat = Fs.num_fat;
	if(!keepBoot)
		set_word(&boot.bytes[510], 0xaa55);

	/* Initialize the remaining parameters */
	set_word(boot.boot.nsect, used_dev.sectors);
	set_word(boot.boot.nheads, used_dev.heads);

	used_dev.fat_bits = comp_fat_bits(&Fs,used_dev.fat_bits, tot_sectors, fat32);

	if(!keepBoot && !(used_dev.use_2m & 0x7f)) {
		if(!used_dev.partition) {
			/* install fake partition table pointing to itself */
			struct partition *partTable=(struct partition *)
				(&boot.bytes[0x1ae]);
			setBeginEnd(&partTable[1], 0,
				    used_dev.heads * used_dev.sectors *
				    used_dev.tracks,
				    used_dev.heads, used_dev.sectors, 1, 0,
				    used_dev.fat_bits);
		}
	}

	if(used_dev.fat_bits == 32) {
		Fs.primaryFat = 0;
		Fs.writeAllFats = 1;
		if(resvSects) {
			if(resvSects < 3) {
				fprintf(stderr,
					"For FAT 32, reserved sectors need to be at least 3\n");
				resvSects = 32;
			}

			if(resvSects <= backupBoot && !backupBootSet)
				backupBoot = resvSects - 1;
			Fs.fat_start = resvSects;
		} else 
			Fs.fat_start = 32;

		if(Fs.fat_start <= backupBoot) {
			fprintf(stderr,
				"Reserved sectors (%d) must be more than backupBoot (%d)\n", Fs.fat_start, backupBoot);
			backupBoot = 6;
			Fs.fat_start = 32;
		}

		calc_fs_parameters_32(tot_sectors, &Fs, &boot);

		Fs.clus_start = Fs.num_fat * Fs.fat_len + Fs.fat_start;

		/* extension flags: mirror fats, and use #0 as primary */
		set_word(boot.boot.ext.fat32.extFlags,0);

		/* fs version.  What should go here? */
		set_word(boot.boot.ext.fat32.fsVersion,fsVersion);

		/* root directory */
		set_dword(boot.boot.ext.fat32.rootCluster, Fs.rootCluster = 2);

		/* info sector */
		set_word(boot.boot.ext.fat32.infoSector, Fs.infoSectorLoc = 1);
		Fs.infoSectorLoc = 1;

		/* no backup boot sector */
		set_word(boot.boot.ext.fat32.backupBoot, backupBoot);

		labelBlock = & boot.boot.ext.fat32.labelBlock;
	} else {
		Fs.infoSectorLoc = 0;
		if(resvSects) {
			if(resvSects < 1) {
				fprintf(stderr,
					"Reserved sectors need to be at least 1\n");
				resvSects = 1;
			}
			Fs.fat_start = resvSects;
		} else 
			Fs.fat_start = 1;
		calc_fs_parameters(&used_dev, tot_sectors, &Fs, &boot);
		Fs.dir_start = Fs.num_fat * Fs.fat_len + Fs.fat_start;
		Fs.clus_start = Fs.dir_start + Fs.dir_len;
		labelBlock = & boot.boot.ext.old.labelBlock;

	}

	/* Set the codepage */
	Fs.cp = cp_open(used_dev.codepage);
	if(Fs.cp == NULL)
		exit(1);

	if (!keepBoot)
		/* only zero out physdrive if we don't have a template
		 * bootsector */
		labelBlock->physdrive = 0x00;
	labelBlock->reserved = 0;
	labelBlock->dos4 = 0x29;

	if (!serial_set || Atari)
		init_random();
	if (!serial_set)
		serial=(uint32_t) random();
	set_dword(labelBlock->serial, serial);
	label_name_pc(GET_DOSCONVERT((Stream_t *)&Fs),
		      label[0] ? label : "NO NAME    ", 0,
		      &mangled, &shortlabel);
	strncpy(labelBlock->label, shortlabel.base, 8);
	strncpy(labelBlock->label+8, shortlabel.ext, 3);
	sprintf(labelBlock->fat_type, "FAT%2.2d  ", Fs.fat_bits);
	labelBlock->fat_type[7] = ' ';

	set_word(boot.boot.secsiz, Fs.sector_size);
	boot.boot.clsiz = (unsigned char) Fs.cluster_size;
	set_word(boot.boot.nrsvsect, Fs.fat_start);

	bootOffset = init_geometry_boot(&boot, &used_dev, sectors0,
					rate_0, rate_any,
					&tot_sectors, keepBoot);
	if(!bootOffset) {
		bootOffset = ((unsigned char *) labelBlock) - boot.bytes +
			sizeof(struct label_blk_t);
	}
	if(Atari) {
		boot.boot.banner[4] = 0;
		boot.boot.banner[5] = (char) random();
		boot.boot.banner[6] = (char) random();
		boot.boot.banner[7] = (char) random();
	}

	if(!keepBoot)
		inst_boot_prg(&boot, bootOffset);
	/* Mimic 3.8 behavior, else 2m disk do not work (???)
	 * luferbu@fluidsignal.com (Luis Bustamante), Fri, 14 Jun 2002
	 */
	if(used_dev.use_2m & 0x7f) {
	  boot.boot.jump[0] = 0xeb;
	  boot.boot.jump[1] = 0x80;
	  boot.boot.jump[2] = 0x90;
	}
	if(used_dev.use_2m & 0x7f)
		Fs.num_fat = 1;
	if(mediaDesc != -1)
		boot.boot.descr=mediaDesc;
	Fs.lastFatSectorNr = 0;
	Fs.lastFatSectorData = 0;
	zero_fat(&Fs, boot.boot.descr);
	Fs.freeSpace = Fs.num_clus;
	Fs.last = 2;

#ifdef USE_XDF
	if(format_xdf)
		for(i=0;
		    i < (info.BadSectors+Fs.cluster_size-1)/Fs.cluster_size;
		    i++)
			fatEncode(&Fs, i+2, 0xfff7);
#endif

	format_root(&Fs, label, &boot);
	WRITES((Stream_t *)&Fs, boot.characters,
	       (mt_off_t) 0, Fs.sector_size);

	if(used_dev.fat_bits == 32) {
	  WRITES((Stream_t *)&Fs, boot.characters,
		 (mt_off_t) backupBoot * Fs.sector_size, Fs.sector_size);
	}

	if(Fs.fat_bits == 32 && WORD_S(ext.fat32.backupBoot) != MAX16) {
		WRITES((Stream_t *)&Fs, boot.characters,
		       sectorsToBytes((Stream_t*)&Fs,
				      WORD_S(ext.fat32.backupBoot)),
		       Fs.sector_size);
	}
	FLUSH((Stream_t *)&Fs); /* flushes Fs.
				 * This triggers the writing of the FAT */
	FREE(&Fs.Next);
	Fs.Class->freeFunc((Stream_t *)&Fs);
#ifdef USE_XDF
	if(format_xdf && isatty(0) && !getenv("MTOOLS_USE_XDF"))
		fprintf(stderr,
			"Note:\n"
			"Remember to set the \"MTOOLS_USE_XDF\" environmental\n"
			"variable before accessing this disk\n\n"
			"Bourne shell syntax (sh, ash, bash, ksh, zsh etc):\n"
			" export MTOOLS_USE_XDF=1\n\n"
			"C shell syntax (csh and tcsh):\n"
			" setenv MTOOLS_USE_XDF 1\n" );
#endif
	exit(0);
}
