diff miscprog/grokdsn.c @ 192:5d84f63eff72

grokdsn: able to follow the FAT chain for the directory
author Michael Spacefalcon <falcon@ivan.Harhan.ORG>
date Wed, 07 Jan 2015 07:12:51 +0000
parents 0c631396b8ce
children 37f78f986a0a
line wrap: on
line diff
--- a/miscprog/grokdsn.c	Wed Jan 07 06:55:33 2015 +0000
+++ b/miscprog/grokdsn.c	Wed Jan 07 07:12:51 2015 +0000
@@ -50,7 +50,7 @@
 char *dsnfilename;
 u_char *filemapping;
 struct cdf_header *cdf_header;
-unsigned total_sectors;
+unsigned total_sectors, fat_nsectors;
 
 open_and_mmap_file()
 {
@@ -108,6 +108,73 @@
 	return(0);
 }
 
+u_char *
+get_sector_ptr(secid)
+	unsigned secid;
+{
+	if (secid > total_sectors) {
+		fprintf(stderr,
+		"error: request for sector #%u; we only have %u in total\n",
+			secid, total_sectors);
+		exit(1);
+	}
+	return filemapping + (secid + 1) * 512;
+}
+
+init_fat_access()
+{
+	fat_nsectors = le32toh(cdf_header->fat_sectors);
+	if (fat_nsectors > HEADER_MFAT_ENTRIES) {
+		fprintf(stderr, "error: large FAT not supported\n");
+		exit(1);
+	}
+	return(0);
+}
+
+u_char *
+get_fat_sector(fat_sec_no)
+	unsigned fat_sec_no;
+{
+	unsigned secid;
+
+	if (fat_sec_no > fat_nsectors) {
+		fprintf(stderr,
+		"error: request for FAT sector #%u; we only have %u in total\n",
+			fat_sec_no, fat_nsectors);
+		exit(1);
+	}
+	secid = le32toh(cdf_header->fat_secids[fat_sec_no]);
+	return get_sector_ptr(secid);
+}
+
+int32_t
+get_fat_entry(entry_no)
+	unsigned entry_no;
+{
+	unsigned fat_sec_no, entry_in_sec;
+	uint32_t *fat_sector;
+
+	fat_sec_no = entry_no / 128;
+	entry_in_sec = entry_no % 128;
+	fat_sector = (uint32_t *) get_fat_sector(fat_sec_no);
+	return le32toh(fat_sector[entry_in_sec]);
+}
+
+dump_fat_chain(sarg)
+	char *sarg;
+{
+	int i, n;
+
+	init_fat_access();
+	i = atoi(sarg);
+	while (i >= 0) {
+		n = get_fat_entry(i);
+		printf("FAT[%d] = %d\n", i, n);
+		i = n;
+	}
+	return(0);
+}
+
 main(argc, argv)
 	char **argv;
 {
@@ -115,14 +182,16 @@
 		fprintf(stderr, "error: struct cdf_header is misdefined\n");
 		exit(1);
 	}
-	if (argc != 3) {
-		fprintf(stderr, "usage: %s binfile.dsn <operation>\n", argv[0]);
+	if (argc < 3) {
+		fprintf(stderr, "usage: %s binfile.dsn <op> [args]\n", argv[0]);
 		exit(1);
 	}
 	dsnfilename = argv[1];
 	open_and_mmap_file();
 	if (!strcmp(argv[2], "hdr"))
 		return dump_cdf_header();
+	if (!strcmp(argv[2], "fatchain"))
+		return dump_fat_chain(argv[3]);
 	fprintf(stderr, "error: \"%s\" is not a recognized command\n", argv[2]);
 	exit(1);
 }