summaryrefslogtreecommitdiffstats
path: root/balkan
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
parent3a44d1f8ea178f88e2e9f540de6cfdcfcbaba001 (diff)
downloadanaconda-352ffc99c02f93ac3788dff095ba8ac8c89f5e5a.tar.gz
anaconda-352ffc99c02f93ac3788dff095ba8ac8c89f5e5a.tar.xz
anaconda-352ffc99c02f93ac3788dff095ba8ac8c89f5e5a.zip
*** empty log message ***
Diffstat (limited to 'balkan')
-rw-r--r--balkan/Makefile19
-rw-r--r--balkan/_balkanmodule.c105
-rw-r--r--balkan/balkan.h23
-rw-r--r--balkan/dos.c138
-rw-r--r--balkan/dos.h6
-rw-r--r--balkan/rw.c6
-rwxr-xr-xbalkan/testit10
7 files changed, 307 insertions, 0 deletions
diff --git a/balkan/Makefile b/balkan/Makefile
new file mode 100644
index 000000000..37f85a592
--- /dev/null
+++ b/balkan/Makefile
@@ -0,0 +1,19 @@
+
+OBJECTS = rw.o dos.o
+
+TARGET = libbalkan.a
+
+all: $(TARGET) _balkanmodule.so
+
+_balkanmodule.so: _balkanmodule.o libbalkan.a
+ gcc -shared -o $@ _balkanmodule.o libbalkan.a
+
+_balkanmodule.o: _balkanmodule.c balkan.h
+ gcc $(CFLAGS) -I/usr/include/python1.5 -c -fPIC -o $@ $<
+
+libbalkan.a: libbalkan.a($(OBJECTS))
+
+clean:
+ rm -f *.o $(TARGET)
+
+dos.o: dos.h
diff --git a/balkan/_balkanmodule.c b/balkan/_balkanmodule.c
new file mode 100644
index 000000000..0cdda8c4b
--- /dev/null
+++ b/balkan/_balkanmodule.c
@@ -0,0 +1,105 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "Python.h"
+#include "balkan.h"
+
+typedef struct pythonPartTable_s {
+ PyObject_HEAD;
+ struct partitionTable table;
+} pythonPartTable;
+
+static void emptyDestructor(PyObject * s);
+static pythonPartTable * readTable(PyObject * s, PyObject * args);
+static PyObject * tableGetAttr(PyObject * s, char * name);
+static int tableLength(PyObject * o);
+PyObject * tableItem(PyObject * o, int n);
+
+static PySequenceMethods pythonPartTableAsSequence = {
+ tableLength, /* length */
+ 0, /* concat */
+ 0, /* repeat */
+ tableItem, /* item */
+ 0, /* slice */
+ 0, /* assign item */
+ 0, /* assign slice */
+};
+
+static PyTypeObject pythonPartTableType = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /* ob_size */
+ "parttable", /* tp_name */
+ sizeof(pythonPartTable), /* tp_size */
+ 0, /* tp_itemsize */
+ emptyDestructor, /* tp_dealloc */
+ 0, /* tp_print */
+ tableGetAttr, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ &pythonPartTableAsSequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+};
+
+static PyMethodDef balkanModuleMethods[] = {
+ { "readTable", (PyCFunction) readTable, METH_VARARGS, NULL },
+ { NULL }
+} ;
+
+static pythonPartTable * readTable(PyObject * s, PyObject * args) {
+ char * device;
+ pythonPartTable * table;
+ int fd;
+
+ if (!PyArg_ParseTuple(args, "s", &device)) return NULL;
+
+ table = PyObject_NEW(pythonPartTable, &pythonPartTableType);
+
+ fd = open(device, O_RDONLY | O_RDONLY);
+ balkanReadTable(fd, &table->table);
+ close(fd);
+
+ return table;
+}
+
+static int tableLength(PyObject * o) {
+ pythonPartTable * t = (void *) o;
+
+ return t->table.maxNumPartitions;
+}
+
+PyObject * tableItem(PyObject * o, int n) {
+ pythonPartTable * t = (void *) o;
+
+ if (n > t->table.maxNumPartitions) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return NULL;
+ }
+
+ return Py_BuildValue("(iii)", t->table.parts[n].type,
+ t->table.parts[n].startSector,
+ t->table.parts[n].size);
+}
+
+static PyObject * tableGetAttr(PyObject * o, char * name) {
+ pythonPartTable * t = (void *) o;
+
+ if (!strcmp(name, "allocationUnit")) {
+ return Py_BuildValue("i", t->table.allocationUnit);
+ } else if (!strcmp(name, "sectorSize")) {
+ return Py_BuildValue("i", t->table.sectorSize);
+ }
+
+ return NULL;
+}
+
+void init_balkan(void) {
+ Py_InitModule("_balkan", balkanModuleMethods);
+}
+
+static void emptyDestructor(PyObject * s) {
+}
diff --git a/balkan/balkan.h b/balkan/balkan.h
new file mode 100644
index 000000000..905047c9d
--- /dev/null
+++ b/balkan/balkan.h
@@ -0,0 +1,23 @@
+#ifndef H_BALKAN
+#define H_BALKAN 1
+
+#define BALKAN_ERROR_ERRNO 1
+#define BALKAN_ERROR_BADMAGIC 2
+#define BALKAN_ERROR_BADTABLE 3
+
+struct partition {
+ long startSector;
+ long size; /* in sectors */
+ int type; /* -1 for "not used" */
+};
+
+struct partitionTable {
+ int allocationUnit; /* in sectors */
+ int maxNumPartitions;
+ int sectorSize;
+ struct partition parts[50];
+};
+
+int balkanReadTable(int fd, struct partitionTable * table);
+
+#endif
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
diff --git a/balkan/dos.h b/balkan/dos.h
new file mode 100644
index 000000000..753fc4193
--- /dev/null
+++ b/balkan/dos.h
@@ -0,0 +1,6 @@
+#ifndef H_DOS
+#define H_DOS 1
+
+int dospReadTable(int fd, struct partitionTable * table);
+
+#endif;
diff --git a/balkan/rw.c b/balkan/rw.c
new file mode 100644
index 000000000..f715952e3
--- /dev/null
+++ b/balkan/rw.c
@@ -0,0 +1,6 @@
+#include "balkan.h"
+#include "dos.h"
+
+int balkanReadTable(int fd, struct partitionTable * table) {
+ return dospReadTable(fd, table);
+}
diff --git a/balkan/testit b/balkan/testit
new file mode 100755
index 000000000..bd1bb0c39
--- /dev/null
+++ b/balkan/testit
@@ -0,0 +1,10 @@
+#!/usr/bin/python
+
+import _balkan
+
+p = _balkan.readTable('/dev/hda')
+
+for i in range(0, len(p) - 1):
+ (type, start, size) = p[i]
+ if (type != -1):
+ print "i:", i, p[i]