Upgrade mtools to 3.0.37

This version contains a fix for -Wstring-concatenation error.

Test: presubmit
Bug: 175068488
Change-Id: Id4f2ae49da91a481ab2625fdf17668689b640794
diff --git a/minfo.c b/minfo.c
index 05c4e9d..07a1773 100644
--- a/minfo.c
+++ b/minfo.c
@@ -24,13 +24,14 @@
 #include "vfat.h"
 #include "mtools.h"
 #include "nameclash.h"
+#include "fsP.h"
 
 static void usage(int ret) NORETURN;
 static void usage(int ret)
 {
-	fprintf(stderr, 
+	fprintf(stderr,
 		"Mtools version %s, dated %s\n", mversion, mdate);
-	fprintf(stderr, 
+	fprintf(stderr,
 		"Usage: %s [-v] drive\n", progname);
 	exit(ret);
 }
@@ -44,9 +45,9 @@
 		return;
 
 	infosec = (InfoSector_t *) safe_malloc(WORD(secsiz));
-	force_read(Stream, (char *) infosec, 
-			   (mt_off_t) WORD(secsiz) * WORD(ext.fat32.infoSector),
-			   WORD(secsiz));
+	force_pread(Stream, (char *) infosec,
+		    (mt_off_t) WORD(secsiz) * WORD(ext.fat32.infoSector),
+		    WORD(secsiz));
 	printf("\nInfosector:\n");
 	printf("signature=0x%08x\n", _DWORD(infosec->signature1));
 	if(_DWORD(infosec->count) != MAX32)
@@ -55,6 +56,12 @@
 		printf("last allocated cluster=%u\n", _DWORD(infosec->pos));
 }
 
+/*
+ * Number of hidden sector is only a 4 byte quantity if number of sectors is
+ */
+static uint32_t getHidden(union bootsector *boot) {
+	return WORD(psect) ? WORD(nhs) : DWORD(nhs);
+}
 
 static void displayBPB(Stream_t *Stream, union bootsector *boot) {
 	struct label_blk_t *labelBlock;
@@ -66,15 +73,16 @@
 	printf("cluster size: %d sectors\n", boot->boot.clsiz);
 	printf("reserved (boot) sectors: %d\n", WORD(nrsvsect));
 	printf("fats: %d\n", boot->boot.nfat);
-	printf("max available root directory slots: %d\n", 
+	printf("max available root directory slots: %d\n",
 	       WORD(dirents));
 	printf("small size: %d sectors\n", WORD(psect));
 	printf("media descriptor byte: 0x%x\n", boot->boot.descr);
 	printf("sectors per fat: %d\n", WORD(fatlen));
 	printf("sectors per track: %d\n", WORD(nsect));
 	printf("heads: %d\n", WORD(nheads));
-	printf("hidden sectors: %d\n", DWORD(nhs));
-	printf("big size: %d sectors\n", DWORD(bigsect));
+	printf("hidden sectors: %d\n", getHidden(boot));
+	if(!WORD(psect))
+		printf("big size: %u sectors\n", DWORD(bigsect));
 
 	if(WORD(fatlen)) {
 		labelBlock = &boot->boot.ext.old.labelBlock;
@@ -83,20 +91,20 @@
 	}
 
 	if(has_BPB4) {
-		printf("physical drive id: 0x%x\n", 
+		printf("physical drive id: 0x%x\n",
 		       labelBlock->physdrive);
-		printf("reserved=0x%x\n", 
+		printf("reserved=0x%x\n",
 		       labelBlock->reserved);
-		printf("dos4=0x%x\n", 
+		printf("dos4=0x%x\n",
 		       labelBlock->dos4);
-		printf("serial number: %08X\n", 
+		printf("serial number: %08X\n",
 		       _DWORD(labelBlock->serial));
-		printf("disk label=\"%11.11s\"\n", 
+		printf("disk label=\"%11.11s\"\n",
 		       labelBlock->label);
-		printf("disk type=\"%8.8s\"\n", 
+		printf("disk type=\"%8.8s\"\n",
 		       labelBlock->fat_type);
 	}
-		
+
 	if(!WORD(fatlen)){
 		printf("Big fatlen=%u\n",
 		       DWORD(ext.fat32.bigFat));
@@ -116,27 +124,144 @@
 	}
 }
 
+static int try(uint32_t tot_sectors, Fs_t *masterFs, Fs_t *tryFs,
+	       struct device *master_dev, struct device *try_dev,
+	       uint8_t *bootDescr) {
+	*tryFs = *masterFs;
+	*try_dev = *master_dev;
+	return calc_fs_parameters(try_dev, 0, tot_sectors,
+				  tryFs, bootDescr);
+}
+
+static void print_mformat_commandline(const char *imgFile,
+				      char drive,
+				      struct device *dev,
+				      union bootsector *boot,
+				      int media,
+				      int haveBPB) {
+	uint8_t size_code;
+	uint32_t sect_per_track;
+	uint32_t hidden;
+	uint32_t tot_sectors;
+	int tracks_match=0;
+	Fs_t masterFs, tryFs, actual;
+	struct device used_dev;
+	uint8_t tryMedia;
+	int bad;
+
+	sect_per_track = dev->sectors * dev->heads;
+	if(sect_per_track == 0)
+		return;
+
+	tot_sectors = parseFsParams(&actual, boot,
+				    media | (haveBPB ? 0x100:0),
+				    sect_per_track);
+	if(tot_sectors == 0)
+		return;
+
+	printf("mformat command line:\n  mformat ");
+
+	if(haveBPB) {
+		if(media == 0xf0)
+			hidden = getHidden(boot);
+		else
+			hidden = 0;
+		size_code = (uint8_t) actual.sectorShift-7;
+	} else {
+		size_code=2;
+		hidden = 0;
+	}
+
+	if(tot_sectors ==
+	   dev->tracks * sect_per_track - hidden % sect_per_track) {
+		tracks_match=1;
+		printf("-t %d ", dev->tracks);
+	} else {
+		printf("-T %d ", tot_sectors);
+	}
+	printf ("-h %d -s %d ", dev->heads, dev->sectors);
+	if(haveBPB && (hidden || !tracks_match))
+		printf("-H %d ", hidden);
+	used_dev=*dev;
+	if(size_code != 2) {
+		printf("-S %d ",size_code);
+		used_dev.ssize = size_code;
+	}
+
+	initFsForFormat(&masterFs);
+	setFsSectorSize(&masterFs, &used_dev, 0);
+
+	if(actual.num_fat != 2) {
+		masterFs.num_fat = actual.num_fat;
+		printf("-d %d ", actual.num_fat);
+	}
+
+	bad=try(tot_sectors, &masterFs, &tryFs, dev , &used_dev, &tryMedia);
+
+	if(bad || actual.dir_len != tryFs.dir_len) {
+		masterFs.dir_len = actual.dir_len;
+		printf("-r %d ", actual.dir_len);
+		bad = try(tot_sectors,
+			  &masterFs, &tryFs, dev , &used_dev,
+			  &tryMedia);
+	}
+
+	if(bad || actual.cluster_size != tryFs.cluster_size) {
+		masterFs.cluster_size = actual.cluster_size;
+		printf("-c %d ", actual.cluster_size);
+		bad = try(tot_sectors,
+			  &masterFs, &tryFs, dev , &used_dev,
+			  &tryMedia);
+	}
+
+	if(bad || actual.fat_start != tryFs.fat_start) {
+		masterFs.fat_start = actual.fat_start;
+		printf("-R %d ", actual.fat_start);
+		bad = try(tot_sectors,
+			  &masterFs, &tryFs, dev , &used_dev,
+			  &tryMedia);
+	}
+
+	if(bad || actual.fat_len != tryFs.fat_len) {
+		masterFs.fat_len = actual.fat_len;
+		printf("-L %d ", actual.fat_len);
+		bad = try(tot_sectors,
+			  &masterFs, &tryFs, dev , &used_dev,
+			  &tryMedia);
+	}
+#ifdef HAVE_ASSERT_H
+	assert(!bad);
+#endif
+	if((media & 0xff) != (tryMedia & 0xff))
+		printf("-m %d ", (media & 0xff));
+
+	if(actual.fat_bits == 32) {
+		if(actual.backupBoot != tryFs.backupBoot)
+			printf("-K %d ", actual.backupBoot);
+	}
+
+	if(imgFile != NULL)
+		printf("-i \"%s\" ", imgFile);
+	printf("%c:\n", ch_tolower(drive));
+	printf("\n");
+}
+
+
 void minfo(int argc, char **argv, int type UNUSEDP) NORETURN;
 void minfo(int argc, char **argv, int type UNUSEDP)
 {
 	union bootsector boot;
 
 	char name[EXPAND_BUF];
-	int media;
-	int haveBPB;
-	int size_code;
-	int i;
 	struct device dev;
 	char drive;
 	int verbose=0;
 	int c;
 	Stream_t *Stream;
 	int have_drive = 0;
-
-	unsigned long sect_per_track;
-
+	int ex=0;
 	char *imgFile=NULL;
-	
+
 	if(helpFlag(argc, argv))
 		usage(0);
 	while ((c = getopt(argc, argv, "i:vh")) != EOF) {
@@ -156,6 +281,9 @@
 	}
 
 	for(;optind <= argc; optind++) {
+		int media;
+		int haveBPB;
+
 		if(optind == argc) {
 			if(have_drive)
 				break;
@@ -167,13 +295,16 @@
 		}
 		have_drive = 1;
 
-		if(! (Stream = find_device(drive, O_RDONLY, &dev, &boot, 
-					   name, &media, 0, NULL)))
-			exit(1);
+		if(! (Stream = find_device(drive, O_RDONLY, &dev, &boot,
+					   name, &media, 0, NULL))) {
+			fprintf(stderr, "Could not open drive %c:\n", drive);
+			ex=1;
+			continue;
+		}
 
 		haveBPB = media >= 0x100;
 		media = media & 0xff;
-		
+
 		printf("device information:\n");
 		printf("===================\n");
 		printf("filename=\"%s\"\n", name);
@@ -182,78 +313,35 @@
 		printf("cylinders: %d\n\n", dev.tracks);
 		printf("media byte: %02x\n\n", media & 0xff);
 
-		sect_per_track = dev.sectors * dev.heads;
-		if(sect_per_track != 0) {
-			unsigned int hidden;
-			unsigned long tot_sectors;
-			int tracks_match=0;
-			printf("mformat command line: mformat ");
-
-			if(haveBPB) {
-				int sector_size;
-				tot_sectors = DWORD_S(bigsect);
-				SET_INT(tot_sectors, WORD_S(psect));
-				sector_size = WORD_S(secsiz);
-				size_code=2;
-				for(i=0; i<7; i++) {
-					if(sector_size == 128 << i) {
-						size_code = i;
-						break;
-					}
-				}
-				if(media == 0xf0)
-					hidden = DWORD_S(nhs);
-				else
-					hidden = 0;
-			} else {
-				tot_sectors = dev.tracks * sect_per_track;
-				size_code=2;
-				hidden = 0;
-			}
-
-			if(tot_sectors ==
-			   dev.tracks * sect_per_track - hidden % sect_per_track) {
-				tracks_match=1;
-				printf("-t %d ", dev.tracks);
-			} else {
-				printf("-T %ld ", tot_sectors);
-			}
-			printf ("-h %d -s %d ", dev.heads, dev.sectors);
-			if(haveBPB && (hidden || !tracks_match))
-				printf("-H %d ", hidden);
-			if(size_code != 2)
-				printf("-S %d ",size_code);
-			if(imgFile != NULL)
-				printf("-i \"%s\" ", imgFile);
-			printf("%c:\n", ch_tolower(drive));
-			printf("\n");
-		}
+		print_mformat_commandline(imgFile, drive,
+					  &dev, &boot, media, haveBPB);
 
 		if(haveBPB || verbose)
 			displayBPB(Stream, &boot);
 
 		if(verbose) {
-			int size;
+			uint16_t size;
+			ssize_t ssize;
 			unsigned char *buf;
 
 			printf("\n");
 			size = WORD_S(secsiz);
-			
+
 			buf = (unsigned char *) malloc(size);
 			if(!buf) {
 				fprintf(stderr, "Out of memory error\n");
 				exit(1);
 			}
 
-			size = READS(Stream, buf, (mt_off_t) 0, size);
-			if(size < 0) {
+			ssize = PREADS(Stream, buf, 0, size);
+			if(ssize < 0) {
 				perror("read boot sector");
 				exit(1);
 			}
 
-			print_sector("Boot sector hexdump", buf, size);
+			print_sector("Boot sector hexdump", buf, (uint16_t)ssize);
 		}
 	}
 	FREE(&Stream);
-	exit(0);
+	exit(ex);
 }