summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJose M. Guisado <jguisado@soleta.eu>2022-12-14 17:24:11 +0100
committerJose M. Guisado <jguisado@soleta.eu>2022-12-15 17:37:07 +0100
commit5eba6d4d65fb5a633f7d0c67a308410a97b6a3ad (patch)
tree087415f858c2106414f25cf1364bf5bb0340a4df
parent7271bc99db8dcb349464eabd50da3f41942f6822 (diff)
parttype: add parttype class and functions
Parttype is a container for partition types in libfdisk. In python-libfdisk, the only way to create parttype instances is using the corresponding label-specific function: get_parttype_from_{code,string} This function wraps libfdisk's label_get_parttype_from_code (lookup DOS label parttype by hex code) and label_get_parttype_from_string (lookup GPT parttype by type uuid) For example, to get the parttype instance of 'EFI System' partition type of a GPT label, with type uuid 'c12a7328-f81f-11d2-ba4b-00a0c93ec93b': >>> import fdisk >>> cxt = fdisk.Context('./disk.bin', readonly=False) >>> cxt.create_disklabel('gpt') >>> efitype = cxt.label.get_parttype_from_string("c12a7328-f81f-11d2-ba4b-00a0c93ec93b") >>> efitype <libfdisk.PartType object at 0x7f503e4a5270, name=EFI System> See: https://cdn.kernel.org/pub/linux/utils/util-linux/v2.34/libfdisk-docs/libfdisk-Partition-types.html https://cdn.kernel.org/pub/linux/utils/util-linux/v2.34/libfdisk-docs/libfdisk-Label.html#fdisk-label-get-parttype-from-code https://cdn.kernel.org/pub/linux/utils/util-linux/v2.34/libfdisk-docs/libfdisk-Label.html#fdisk-label-get-parttype-from-string
-rw-r--r--fdisk.c1
-rw-r--r--fdisk.h8
-rw-r--r--label.c41
-rw-r--r--parttype.c86
-rw-r--r--setup.py3
5 files changed, 138 insertions, 1 deletions
diff --git a/fdisk.c b/fdisk.c
index c44b2f1..909d95c 100644
--- a/fdisk.c
+++ b/fdisk.c
@@ -66,6 +66,7 @@ PyInit_fdisk(void)
Context_AddModuleObject(m);
Label_AddModuleObject(m);
Partition_AddModuleObject(m);
+ PartType_AddModuleObject(m);
return m;
diff --git a/fdisk.h b/fdisk.h
index 496b6f7..39b4c95 100644
--- a/fdisk.h
+++ b/fdisk.h
@@ -39,15 +39,23 @@ typedef struct {
struct fdisk_partition *pa;
} PartitionObject;
+typedef struct {
+ PyObject_HEAD
+ struct fdisk_parttype *type;
+} PartTypeObject;
+
extern PyTypeObject ContextType;
extern PyTypeObject PartitionType;
+extern PyTypeObject PartTypeType;
extern void Context_AddModuleObject(PyObject *mod);
extern void Label_AddModuleObject(PyObject *mod);
extern void Partition_AddModuleObject(PyObject *mod);
+extern void PartType_AddModuleObject(PyObject *mod);
extern PyObject *PyObjectResultStr(const char *s);
extern PyObject *PyObjectResultLabel(struct fdisk_label *lb);
extern PyObject *PyObjectResultPartition(struct fdisk_partition *pa);
+extern PyObject *PyObjectResultPartType(struct fdisk_parttype *t);
#endif
diff --git a/label.c b/label.c
index 626ca5f..a4bd265 100644
--- a/label.c
+++ b/label.c
@@ -60,8 +60,49 @@ static int Label_init(LabelObject *self, PyObject *args, PyObject *kwds)
return 0;
}
+#define Label_get_parttype_from_code_HELP "get_parttype_from_code(code)\n\n" \
+ "Search for partition type in label-specific table."
+static PyObject *Label_get_parttype_from_code(LabelObject *self, PyObject *args, PyObject *kwds)
+{
+ struct fdisk_parttype *ptype;
+ unsigned int ptype_code;
+
+ if (!PyArg_ParseTuple(args, "I", &ptype_code)) {
+ PyErr_SetString(PyExc_TypeError, ARG_ERR);
+ return NULL;
+ }
+ ptype = fdisk_label_get_parttype_from_code(self->lb, ptype_code);
+ if (!ptype) {
+ PyErr_Format(PyExc_RuntimeError, "No match for parttype with code: %d", ptype_code);
+ return NULL;
+ }
+
+ return PyObjectResultPartType(ptype);
+}
+#define Label_get_parttype_from_string_HELP "get_parttype_from_string(uuid)\n\n" \
+ "Search by string for partition type in label-specific table."
+static PyObject *Label_get_parttype_from_string(LabelObject *self, PyObject *args, PyObject *kwds)
+{
+ struct fdisk_parttype *ptype = NULL;
+ char *str;
+
+ if (!PyArg_ParseTuple(args, "s", &str)) {
+ PyErr_SetString(PyExc_TypeError, ARG_ERR);
+ return NULL;
+ }
+
+ ptype = fdisk_label_get_parttype_from_string(self->lb, str);
+ if (!ptype) {
+ PyErr_Format(PyExc_RuntimeError, "No match for parttype with string: %s", str);
+ return NULL;
+ }
+
+ return PyObjectResultPartType(ptype);
+}
static PyMethodDef Label_methods[] = {
+ {"get_parttype_from_code", (PyCFunction)Label_get_parttype_from_code, METH_VARARGS, Label_get_parttype_from_code_HELP},
+ {"get_parttype_from_string", (PyCFunction)Label_get_parttype_from_string, METH_VARARGS, Label_get_parttype_from_string_HELP},
{NULL}
};
diff --git a/parttype.c b/parttype.c
new file mode 100644
index 0000000..e3c6238
--- /dev/null
+++ b/parttype.c
@@ -0,0 +1,86 @@
+/*
+ * (C) 2022 Soleta Consulting S.L. <info@soleta.eu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Author: Jose M. Guisado <jguisado@soleta.eu>
+ */
+
+#include "fdisk.h"
+
+static PyMemberDef PartType_members[] = {
+ { NULL }
+};
+
+static void PartType_dealloc(PartTypeObject *self)
+{
+ Py_TYPE(self)->tp_free((PyObject *) self);
+}
+
+static PyMethodDef PartType_methods[] = {
+ {NULL}
+};
+
+static PyObject *PartType_get_name(PartTypeObject *self)
+{
+ return PyObjectResultStr(fdisk_parttype_get_name(self->type));
+}
+static PyObject *PartType_get_code(PartTypeObject *self)
+{
+ return PyLong_FromUnsignedLong(fdisk_parttype_get_code(self->type));
+}
+static PyGetSetDef PartType_getseters[] = {
+ {"name", (getter)PartType_get_name, NULL, "parttype human readable name", NULL},
+ {"code", (getter)PartType_get_code, NULL, "parttype DOS code", NULL},
+ {NULL}
+};
+
+static PyObject *PartType_repr(PartTypeObject *self)
+{
+ return PyUnicode_FromFormat("<libfdisk.PartType object at %p, name=%s>",
+ self, fdisk_parttype_get_name(self->type));
+}
+
+PyTypeObject PartTypeType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "libfdisk.PartType",
+ .tp_basicsize = sizeof(PartTypeObject),
+ .tp_dealloc = (destructor)PartType_dealloc,
+ .tp_repr = (reprfunc) PartType_repr,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /* TODO: .tp_doc = PartType_HELP, */
+ .tp_methods = PartType_methods,
+ .tp_members = PartType_members,
+ .tp_getset = PartType_getseters,
+};
+
+PyObject *PyObjectResultPartType(struct fdisk_parttype *t)
+{
+ PartTypeObject *result;
+
+ if (!t) {
+ PyErr_SetString(PyExc_AssertionError, "lb assert failed");
+ return NULL;
+ }
+
+ result = PyObject_New(PartTypeObject, &PartTypeType);
+ if (!result) {
+ PyErr_SetString(PyExc_MemoryError, "Couldn't allocate PartType object");
+ return NULL;
+ }
+
+ result->type = t;
+ return (PyObject *) result;
+}
+
+void PartType_AddModuleObject(PyObject *mod)
+{
+ if (PyType_Ready(&PartTypeType) < 0)
+ return;
+
+ Py_INCREF(&PartTypeType);
+ PyModule_AddObject(mod, "PartType", (PyObject *)&PartTypeType);
+}
diff --git a/setup.py b/setup.py
index aed3664..d360edf 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,8 @@ from setuptools import setup, Extension
libfdisk = Extension('fdisk',
libraries = ['fdisk'],
- sources = ['fdisk.c', 'context.c', 'label.c', 'partition.c'])
+ sources = ['fdisk.c', 'context.c', 'label.c',
+ 'partition.c', 'parttype.c'])
setup (name = 'libfdisk',
version = '1.0',