#include #include #include #include #include #include "Python.h" #include "fsedit.h" #ifdef GNOME #include "pygtk.h" #endif typedef struct fseditObject_t fseditObject; static PyObject * libfdiskError; #ifdef GNOME static PyObject * doGetWindow(fseditObject * s, PyObject * args); static PyObject * doGetConfirm (fseditObject * o, PyObject * args); static PyObject * doSetCallback (fseditObject * o, PyObject * args); static PyObject * doBack (fseditObject * o, PyObject * args); static PyObject * doNext (fseditObject * o, PyObject * args); #endif static PyObject * doEdit(fseditObject * s, PyObject * args); static PyObject * doSave(fseditObject * s, PyObject * args); static PyObject * doGetFstab(fseditObject * s, PyObject * args); static PyObject * doGetPartitions(fseditObject * s, PyObject * args); static PyObject * doAttempt (fseditObject * o, PyObject * args); static PyMethodDef fseditObjectMethods[] = { #ifdef GNOME { "getWindow", (PyCFunction) doGetWindow, METH_VARARGS, NULL }, { "getConfirm", (PyCFunction) doGetConfirm, METH_VARARGS, NULL }, { "setCallback", (PyCFunction) doSetCallback, METH_VARARGS, NULL }, { "next", (PyCFunction) doNext, METH_VARARGS, NULL }, { "back", (PyCFunction) doBack, METH_VARARGS, NULL }, #endif { "edit", (PyCFunction) doEdit, METH_VARARGS, NULL }, { "save", (PyCFunction) doSave, METH_VARARGS, NULL }, { "attempt", (PyCFunction) doAttempt, METH_VARARGS, NULL }, { "getFstab", (PyCFunction) doGetFstab, METH_VARARGS, NULL }, { "partitionList", (PyCFunction) doGetPartitions, METH_VARARGS, NULL }, { NULL }, }; static fseditObject * newFseditObject (PyObject * s, PyObject * args); static PyMethodDef fseditModuleMethods[] = { { "fsedit", (PyCFunction) newFseditObject, METH_VARARGS, NULL }, { NULL }, }; typedef void (* simpleCallback)(void); struct fseditObject_t { PyObject_HEAD; int testing; void * state; char ** deviceList; FseditContext *context; #ifdef GNOME PyObject *enableForward; #endif } ; static PyObject * fseditGetAttr(fseditObject * o, char * name); static void fseditDealloc (fseditObject * o); static PyTypeObject fseditType = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ "fsedit", /* tp_name */ sizeof(fseditObject), /* tp_size */ 0, /* tp_itemsize */ (destructor) fseditDealloc, /* tp_dealloc */ 0, /* tp_print */ (getattrfunc) fseditGetAttr, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ }; static PyObject * fseditGetAttr(fseditObject * o, char * name) { return Py_FindMethod(fseditObjectMethods, (PyObject * ) o, name); } static void fseditDealloc (fseditObject * o) { PyObject * function, * data; function = (PyObject *) o->context->cbi.function; data = (PyObject *) o->context->cbi.data; Py_XDECREF (function); Py_XDECREF (data); free (o->deviceList); delFseditContext (o->context); } #ifdef GNOME GtkWidget * create_main_window (void); GtkWidget * create_confirm_window (void); typedef void (* enableCallback)(PyObject *cb, int disable); void fsedit_enable_next (void *function, void *data, int enable) { PyObject *args, *result; PyObject * enableFunction = function; PyGtk_BlockThreads (); if (!PyCallable_Check(enableFunction)) { PyGtk_UnblockThreads (); return; } args = Py_BuildValue("(i)", enable); result = PyEval_CallObject(enableFunction, args); if (!result) { PyErr_Print(); PyErr_Clear(); } Py_DECREF (args); Py_XDECREF (result); PyGtk_UnblockThreads (); } void next_cb (void); void back_cb (void); static PyObject * doBack (fseditObject * o, PyObject * args) { back_cb (); Py_INCREF(Py_None); return Py_None; } static PyObject * doNext (fseditObject * o, PyObject * args) { next_cb (); Py_INCREF(Py_None); return Py_None; } static PyObject * doSetCallback (fseditObject * o, PyObject * args) { PyObject *function = NULL, *data = NULL; if (!PyArg_ParseTuple(args, "O|O", &function, &data)) return NULL; o->context->cbi.function = function; o->context->cbi.data = data; Py_INCREF (function); Py_XINCREF (data); Py_INCREF(Py_None); return Py_None; } static PyObject * doGetWindow (fseditObject * o, PyObject * args) { return PyGtk_New((GtkObject *) create_main_window ()); } static PyObject * doGetConfirm (fseditObject * o, PyObject * args) { GtkObject *window; window = (GtkObject *) create_confirm_window (); if (window) return PyGtk_New(window); else { Py_INCREF(Py_None); return Py_None; } } #endif struct repartitionInfo { HardDrive ** hdarr; int numDrives; }; static PyObject * doSave (fseditObject * o, PyObject * args) { int rc; if (o->context->repartInfo) { if ((rc = FSWritePartitions(o->deviceList, o->context->repartInfo))) { char error[256]; struct repartitionInfo * rpi = o->context->repartInfo; snprintf (error, sizeof (error) - 1, "Error partitioning drive %s: %s", rpi->hdarr[rc - 1]->name, strerror (errno)); PyErr_SetString(PyExc_SystemError, error); return NULL; } } Py_INCREF(Py_None); return Py_None; } static PyObject * doAttempt (fseditObject * o, PyObject * args) { PyObject *tuple, *list; struct attemptedPartition * attempt; int i, size, type, grow, start, flags, rc; char *mount, *name; if (!PyArg_ParseTuple(args, "Osi", &list, &name, &flags)) return NULL; if (!PyList_Check(list)) { PyErr_SetString(PyExc_TypeError, "list argument expected"); return NULL; } attempt = alloca (sizeof (struct attemptedPartition) * PyList_Size(list) + 1); for (i = 0; i < PyList_Size(list); i++) { tuple = PyList_GetItem(list, i); if (!PyArg_ParseTuple(tuple, "siiii", &mount, &size, &type, &grow, &start)) return NULL; attempt[i].mount = strdup (mount); attempt[i].size = size; attempt[i].type = type; attempt[i].grow = grow; attempt[i].start = start; } attempt[i].mount = NULL; rc = guessAtPartitioning (o->context, flags, name, attempt, 0); for (i = 0; i < PyList_Size(list); i++) { free (attempt[i].mount); } if (rc) { PyErr_SetString(libfdiskError, "autopartitioning failed\n"); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * doGetPartitions(fseditObject * o, PyObject * args) { PyObject * list; PyObject * raidList; PyObject * deviceList; partitionList * result; int i, j; char * raidType; result = FSPartitionList(o->context); list = PyList_New(0); for (i = 0; result[i].device; i++) { PyList_Append(list, Py_BuildValue("(ssi)", result[i].device, result[i].name, result[i].type)); } if (o->context->raid) { raidList = PyList_New(0); i = 0; while (o->context->raid[i].mntpt) { deviceList = PyList_New(0); j = 0; while (o->context->raid[i].devices[j]) { PyList_Append(deviceList, PyString_FromString(o->context->raid[i].devices[j])); j++; } if (o->context->raid[i].parttype == LINUX_SWAP_PARTITION) raidType = "swap"; else raidType = "ext2"; PyList_Append(raidList, Py_BuildValue("(sssiO)", o->context->raid[i].mntpt, o->context->raid[i].device, raidType, o->context->raid[i].type, deviceList)); i++; } } else { raidList = Py_None; Py_INCREF(raidList); } for (i = 0; result[i].device; i++) { free(result[i].device); free(result[i].name); } free(result); return Py_BuildValue("(OO)", list, raidList); } static PyObject * doGetFstab (fseditObject * o, PyObject * args) { PyObject *list; int i; char *fsystem; list = PyList_New(o->context->fstab.numEntries); for (i = 0; i < o->context->fstab.numEntries; i++) { switch (o->context->fstab.entries[i].type) { case PART_EXT2: fsystem = "ext2"; break; case PART_SWAP: fsystem = "swap"; break; case PART_DOS: case PART_FAT32: fsystem = "vfat"; break; default: fsystem = "auto"; break; } PyList_SetItem(list, i, Py_BuildValue("(sssi)", o->context->fstab.entries[i].device, o->context->fstab.entries[i].mntpoint, fsystem, o->context->fstab.entries[i].size)); } return list; } static PyObject * doEdit(fseditObject * o, PyObject * args) { int dir; dir = FSEditPartitions(o->context); return Py_BuildValue("i", dir); } static fseditObject * newFseditObject (PyObject * s, PyObject * args) { int i, rc; PyObject * devList, * oneObject, * fstab; int testing; fseditObject * o; struct fstab fs; struct fstabEntry entry; int clearMbr = 0; int readOnly = 0; if (!PyArg_ParseTuple(args, "iOO|ii", &testing, &devList, &fstab, &clearMbr, &readOnly)) return NULL; if (!PyList_Check(devList) || !PyList_Check(fstab)) { PyErr_SetString(PyExc_TypeError, "list argument expected"); return NULL; } o = PyObject_NEW(fseditObject, &fseditType); o->testing = testing; o->deviceList = malloc((PyList_Size(devList) + 1) * sizeof(char *)); #ifdef GNOME o->enableForward = NULL; #endif for (i = 0; i < PyList_Size(devList); i++) { oneObject = PyList_GetItem(devList, i); if (!PyString_Check(oneObject)) { PyErr_SetString(PyExc_TypeError, "list of strings"); return NULL; } o->deviceList[i] = strdup (PyString_AsString(oneObject)); } o->deviceList[i] = NULL; memset(&fs, 0, sizeof(fs)); for (i = 0; i < PyList_Size(fstab); i++) { oneObject = PyList_GetItem(fstab, i); memset(&entry, 0, sizeof(entry)); if (!PyArg_ParseTuple(oneObject, "ss|i", &entry.device, &entry.mntpoint, &entry.size)) return NULL; entry.device = strdup(entry.device); entry.mntpoint = strdup(entry.mntpoint); addFstabEntry(&fs, entry); } if ((rc = newFseditContext (o->deviceList, &fs, (o->testing ? FSEDIT_TESTING : 0) | (readOnly ? FSEDIT_READONLY : 0) | (clearMbr ? FSEDIT_AUTOCLEARMBR : 0), &o->context))) { PyErr_SetString(PyExc_TypeError, "list of strings"); return NULL; } FSEditInitialize(o->context); return o; } void INITFN(void) { PyObject * m, * d; m = Py_InitModule(NAME, fseditModuleMethods); d = PyModule_GetDict(m); libfdiskError = PyString_FromString("libfdisk.error"); PyDict_SetItemString(d, "error", libfdiskError); PyDict_SetItemString(d, "CLEARALL", PyInt_FromLong(FSEDIT_CLEARALL)); PyDict_SetItemString(d, "CLEARLINUX", PyInt_FromLong(FSEDIT_CLEARLINUX)); #ifdef GNOME init_pygtk(); #endif }