summaryrefslogtreecommitdiffstats
path: root/balkan/dos.c
diff options
context:
space:
mode:
authorErik Troan <ewt@redhat.com>1999-04-25 21:11:14 +0000
committerErik Troan <ewt@redhat.com>1999-04-25 21:11:14 +0000
commit352ffc99c02f93ac3788dff095ba8ac8c89f5e5a (patch)
treed2f9b623f9b1a85f662a2e4373a99c8514882138 /balkan/dos.c
parent3a44d1f8ea178f88e2e9f540de6cfdcfcbaba001 (diff)
downloadanaconda-352ffc99c02f93ac3788dff095ba8ac8c89f5e5a.tar.gz
anaconda-352ffc99c02f93ac3788dff095ba8ac8c89f5e5a.tar.xz
anaconda-352ffc99c02f93ac3788dff095ba8ac8c89f5e5a.zip
*** empty log message ***
Diffstat (limited to 'balkan/dos.c')
-rw-r--r--balkan/dos.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/balkan/dos.c b/balkan/dos.c
new file mode 100644
index 000000000..e37a53f69
--- /dev/null
+++ b/balkan/dos.c
@@ -0,0 +1,138 @@
+/* DOS style partitioning */
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "balkan.h"
+
+struct singlePartition {
+ unsigned char active;
+ unsigned char startHead;
+ unsigned char startSector;
+ unsigned char startCyl;
+ unsigned char type;
+ unsigned char endHead;
+ unsigned char endSector;
+ unsigned char endCyl;
+ unsigned int start; /* in sectors */
+ unsigned int size; /* in sectors */
+};
+
+struct singlePartitionTable {
+ struct singlePartition parts[4];
+};
+
+/* Location of partition table in MBR */
+#define TABLE_OFFSET 446
+#define MBR_MAGIC 0x55aa
+#define MBR_MAGIC_OFFSET 510
+#define SECTOR_SIZE 512
+
+#define DOSP_TYPE_EXTENDED 5
+
+long long llseek(int fd, long long offset, int whence);
+
+static int readSingleTable(int fd, struct singlePartitionTable * table,
+ long long partSector) {
+ unsigned char sector[SECTOR_SIZE];
+ unsigned short magic;
+
+ if (llseek(fd, ((long long) SECTOR_SIZE * (long long) partSector),
+ SEEK_SET) < 0)
+ return BALKAN_ERROR_ERRNO;
+
+ if (read(fd, sector, sizeof(sector)) != sizeof(sector))
+ return BALKAN_ERROR_ERRNO;
+
+ magic = (sector[MBR_MAGIC_OFFSET] << 8) + sector[MBR_MAGIC_OFFSET + 1];
+ if (magic != MBR_MAGIC)
+ return BALKAN_ERROR_BADMAGIC;
+
+ memcpy(table, sector + TABLE_OFFSET, sizeof(struct singlePartitionTable));
+
+ return 0;
+}
+
+static int readNextTable(int fd, struct partitionTable * table, int nextNum,
+ long long partSector, long long sectorOffset) {
+ struct singlePartitionTable singleTable;
+ int rc;
+ int i;
+ int gotExtended = 0;
+
+ if ((rc = readSingleTable(fd, &singleTable, partSector + sectorOffset)))
+ return rc;
+
+ if (nextNum > 4) {
+ /* This is an extended table */
+ if (singleTable.parts[2].size || singleTable.parts[3].size)
+ return BALKAN_ERROR_BADTABLE;
+ }
+
+ for (i = 0; i < 4; i++) {
+ if (!singleTable.parts[i].size) continue;
+ if (singleTable.parts[i].type == DOSP_TYPE_EXTENDED &&
+ nextNum >= 5) continue;
+
+ table->parts[nextNum].startSector = singleTable.parts[i].start +
+ sectorOffset;
+ table->parts[nextNum].size = singleTable.parts[i].size;
+ table->parts[nextNum].type = singleTable.parts[i].type;
+
+ nextNum++;
+ }
+
+ /* look for extended partitions */
+ for (i = 0; i < 4; i++) {
+ if (!singleTable.parts[i].size) continue;
+
+ if (singleTable.parts[i].type == DOSP_TYPE_EXTENDED) {
+ if (gotExtended) return BALKAN_ERROR_BADTABLE;
+ gotExtended = 1;
+
+ if (sectorOffset)
+ rc = readNextTable(fd, table, nextNum > 5 ? nextNum : 5,
+ singleTable.parts[i].start, sectorOffset);
+ else
+ rc = readNextTable(fd, table, nextNum > 5 ? nextNum : 5,
+ 0, singleTable.parts[i].start);
+
+ if (rc) return rc;
+ }
+ }
+
+ return 0;
+}
+
+int dospReadTable(int fd, struct partitionTable * table) {
+ int i;
+
+ table->maxNumPartitions = 16;
+
+ for (i = 0; i < table->maxNumPartitions; i++)
+ table->parts[i].type = -1;
+
+ table->sectorSize = SECTOR_SIZE;
+
+ return readNextTable(fd, table, 0, 0, 0);
+}
+
+#ifdef STANDALONE_TEST
+
+void main() {
+ int fd;
+ int i;
+ struct partitionTable table;
+
+ fd = open("/dev/hda", O_RDONLY);
+
+ printf("rc= %d\n", dospReadTable(fd, &table));
+
+ for (i = 0; i < table.maxNumPartitions; i++) {
+ if (table.parts[i].type == -1) continue;
+
+ printf("%d: %x %d\n", i, table.parts[i].type, table.parts[i].size);
+ }
+}
+
+#endif