Bug 40597 - [patch] add fdisk(8) ability of showing extended partition tables
Summary: [patch] add fdisk(8) ability of showing extended partition tables
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 4.6-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-07-15 15:10 UTC by Artem 'Zazoobr' Ignatjev
Modified: 2017-12-31 22:36 UTC (History)
0 users

See Also:


Attachments
file.diff (4.12 KB, patch)
2002-07-15 15:10 UTC, Artem 'Zazoobr' Ignatjev
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Artem 'Zazoobr' Ignatjev 2002-07-15 15:10:01 UTC
	following patch lets /sbin/fdisk traverse through extended partitions on 
	hdd's of i386 compatible machines, dumping information about partitions it i
	founds.
Comment 1 Artem 'Zazoobr' Ignatjev 2002-07-15 16:43:02 UTC
Ooopss... My previous posting contains wrong patch - I realized that as soon as i've got to host where freebsd slice is adNs9 :-( 
This one works:
==== Begin patch-fdisk ====

--- sbin/i386/fdisk/fdisk.c	Mon Jul 15 13:54:04 2002
+++ sbin/i386/fdisk/fdisk.c	Mon Jul 15 19:35:08 2002
@@ -190,6 +190,7 @@
 
 static void print_s0(int which);
 static void print_part(int i);
+static void dump_part_table(void);
 static void init_sector0(unsigned long start);
 static void init_boot(void);
 static void change_part(int i);
@@ -203,6 +204,7 @@
 static ssize_t write_disk(off_t sector, void *buf);
 static int get_params();
 static int read_s0();
+static int read_sect_into_mboot(u_int32_t sect, struct mboot *mboot);
 static int write_s0();
 static int ok(char *str);
 static int decimal(char *str, int *num, int deflt);
@@ -386,9 +388,11 @@
 	    printf("Media sector size is %d\n", secsize);
 	    printf("Warning: BIOS sector numbering starts with sector 1\n");
 	    printf("Information from DOS bootblock is:\n");
-	    if (partition == -1)
-		for (i = 1; i <= NDOSPART; i++)
-		    change_part(i);
+            if (partition == -1) 
+		if(!i_flag && ! u_flag) dump_part_table();
+	    	else 
+	                for (i = 1; i <= NDOSPART; i++)
+			    change_part(i);
 	    else
 		change_part(partition);
 
@@ -435,8 +439,9 @@
 	print_params();
 	printf("Information from DOS bootblock is:\n");
 	if (which == -1)
-		for (i = 1; i <= NDOSPART; i++)
-			printf("%d: ", i), print_part(i);
+/*		for (i = 1; i <= NDOSPART; i++)
+			printf("%d: ", i), print_part(i);*/
+		dump_part_table();
 	else
 		print_part(which);
 }
@@ -476,6 +481,67 @@
 		,partp->dp_ehd
 		,DPSECT(partp->dp_esect));
 }
+static void
+dump_part_table(void)
+{
+#define MAX_MBR_PARTS 4
+#define MAX_EXT_PARTS 2
+/* Extended partitions are of type 0x0f/0x05 */
+#define is_ext_type(type) (((type)==0x0F) || ((type)== 0x05))
+	struct	  dos_partition *partp;
+	struct    mboot mboot = {{0}, NULL, 0};
+	int 	i;
+	u_int64_t part_mb;
+	u_int64_t first_ext_offs = 0, curr_ext_offs=0;
+/* maximum partitions depends on whether we're in MBR or somewhere in
+ * extended partition. If we're in MBR, then max partitions count is 4,
+ * else 2
+ */
+#define MAX_PARTS_NOW ((first_ext_offs)?MAX_EXT_PARTS:MAX_MBR_PARTS)
+	read_sect_into_mboot(0, &mboot);
+	for(i = 0; i < MAX_PARTS_NOW ; i++) { 
+		partp = ((struct dos_partition *) &mboot.parts) + i;
+	
+		if (!bcmp(partp, &mtpart, sizeof (struct dos_partition))) {
+			printf("<UNUSED>\n");
+			return;
+		}
+		if(is_ext_type(partp->dp_typ))
+			partp->dp_start += first_ext_offs;
+		else
+			partp->dp_start += curr_ext_offs;
+		/*
+		 * Be careful not to overflow.
+		 */
+		part_mb = partp->dp_size;
+		part_mb *= secsize;
+		part_mb /= (1024 * 1024);
+		printf("sysid %d,(%s)\n", partp->dp_typ, get_type(partp->dp_typ));
+		printf("    start %lu, size %lu (%qd Meg), flag %x%s\n",
+			(u_long)partp->dp_start,
+			(u_long)partp->dp_size, 
+			part_mb,
+			partp->dp_flag,
+			partp->dp_flag == ACTIVE ? " (active)" : "");
+		printf("\tbeg: cyl %d/ head %d/ sector %d;\n\tend: cyl %d/ head %d/ sector %d\n"
+			,DPCYL(partp->dp_scyl, partp->dp_ssect)
+			,partp->dp_shd
+			,DPSECT(partp->dp_ssect)
+			,DPCYL(partp->dp_ecyl, partp->dp_esect)
+			,partp->dp_ehd
+			,DPSECT(partp->dp_esect));
+		if(is_ext_type(partp->dp_typ)) {
+			if(first_ext_offs == 0) first_ext_offs = partp->dp_start;
+			curr_ext_offs = partp->dp_start;
+
+			printf("This extended partition at %lu contains:\n", partp->dp_start);
+			if(read_sect_into_mboot(curr_ext_offs, &mboot)) return;
+			i = -1; // Go to the next extended - restart for() cycle
+
+		}
+	}
+}
+
 
 
 static void
@@ -795,6 +861,31 @@
 	memcpy(mboot.parts, &mboot.bootinst[DOSPARTOFF], sizeof(mboot.parts));
 	return 0;
 }
+
+static int
+read_sect_into_mboot(u_int32_t sect, struct mboot * mboot)
+{
+	mboot->bootinst_size = secsize;
+	if (mboot->bootinst != NULL)
+		free(mboot->bootinst);
+	if ((mboot->bootinst = malloc(mboot->bootinst_size)) == NULL) {
+		warnx("unable to allocate buffer to read fdisk "
+		      "partition table");
+		return -1;
+	}
+	if (read_disk(sect , mboot->bootinst) == -1) {
+		warnx("can't read fdisk partition table");
+		return -1;
+	}
+	if (*(uint16_t *)&mboot->bootinst[MBRSIGOFF] != BOOT_MAGIC) {
+		warnx("invalid fdisk partition table found");
+		/* So should we initialize things */
+		return -1;
+	}
+	memcpy(mboot->parts, &mboot->bootinst[DOSPARTOFF], sizeof(mboot->parts));
+	return 0;
+}
+
 
 static int
 write_s0()
==== End patch-fdisk ====
Comment 2 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 08:01:35 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped