/* * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include typedef struct fsimage_fs { PyObject_HEAD fsi_t *fs; } fsimage_fs_t; typedef struct fsimage_file { PyObject_HEAD fsimage_fs_t *fs; fsi_file_t *file; } fsimage_file_t; static PyObject * fsimage_file_read(fsimage_file_t *file, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "size", "offset", NULL }; int bufsize; int size = 0; uint64_t offset = 0; ssize_t bytesread = 0; PyObject * buffer; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iL", kwlist, &size, &offset)) return (NULL); bufsize = size ? size : 4096; buffer = #if PY_MAJOR_VERSION < 3 PyString_FromStringAndSize(NULL, bufsize); #else PyBytes_FromStringAndSize(NULL, bufsize); #endif if (buffer == NULL) return (NULL); while (1) { int err; void *buf = #if PY_MAJOR_VERSION < 3 PyString_AS_STRING(buffer) + bytesread; #else PyBytes_AS_STRING(buffer) + bytesread; #endif err = fsi_pread_file(file->file, buf, bufsize, bytesread + offset); if (err == -1) { Py_DECREF(buffer); PyErr_SetFromErrno(PyExc_IOError); return (NULL); } else if (err == 0) { break; } bytesread += err; if (size != 0) { bufsize -= bytesread; if (bufsize == 0) break; } else { #if PY_MAJOR_VERSION < 3 if (_PyString_Resize(&buffer, bytesread + bufsize) < 0) #else if (_PyBytes_Resize(&buffer, bytesread + bufsize) < 0) #endif return (NULL); } } #if PY_MAJOR_VERSION < 3 _PyString_Resize(&buffer, bytesread); #else _PyBytes_Resize(&buffer, bytesread); #endif return (buffer); } PyDoc_STRVAR(fsimage_file_read__doc__, "read(file, [size=size, offset=off])\n" "\n" "Read size bytes (or all bytes if not set) from the given " "file. If offset is specified as well, read from the given " "offset.\n"); static struct PyMethodDef fsimage_file_methods[] = { { "read", (PyCFunction) fsimage_file_read, METH_VARARGS|METH_KEYWORDS, fsimage_file_read__doc__ }, { NULL, NULL, 0, NULL } }; #if PY_MAJOR_VERSION < 3 static PyObject * fsimage_file_getattr(fsimage_file_t *file, char *name) { return (Py_FindMethod(fsimage_file_methods, (PyObject *)file, name)); } #endif static void fsimage_file_dealloc(fsimage_file_t *file) { if (file->file != NULL) fsi_close_file(file->file); Py_XDECREF(file->fs); PyObject_DEL(file); } static char fsimage_file_type__doc__[] = "Filesystem image file"; PyTypeObject fsimage_file_type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "xenfsimage.file", .tp_basicsize = sizeof(fsimage_file_t), .tp_dealloc = (destructor) fsimage_file_dealloc, #if PY_MAJOR_VERSION < 3 .tp_getattr = (getattrfunc) fsimage_file_getattr, #endif .tp_flags = Py_TPFLAGS_DEFAULT, .tp_doc = fsimage_file_type__doc__, #if PY_MAJOR_VERSION >= 3 .tp_methods = fsimage_file_methods, #endif }; static PyObject * fsimage_fs_open_file(fsimage_fs_t *fs, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "name", NULL }; fsimage_file_t *file; char *name; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name)) return (NULL); file = (fsimage_file_t *)PyObject_NEW(fsimage_file_t, &fsimage_file_type); if (file == NULL) return (NULL); file->fs = fs; Py_INCREF(file->fs); if ((file->file = fsi_open_file(fs->fs, name)) == NULL) { Py_DECREF(file->fs); file->fs = NULL; PyErr_SetFromErrno(PyExc_IOError); return (NULL); } return ((PyObject *)file); } static PyObject * fsimage_fs_file_exists(fsimage_fs_t *fs, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "name", NULL }; char *name; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name)) return (NULL); if (fsi_file_exists(fs->fs, name)) { Py_INCREF(Py_True); return (Py_True); } Py_INCREF(Py_False); return (Py_False); } PyDoc_STRVAR(fsimage_fs_open_file__doc__, "open_file(fs, filename) - lookup name in the given fs and return the file"); PyDoc_STRVAR(fsimage_fs_file_exists__doc__, "file_exists(fs, name) - lookup name in the given fs and return " "True if it exists"); static struct PyMethodDef fsimage_fs_methods[] = { { "open_file", (PyCFunction) fsimage_fs_open_file, METH_VARARGS|METH_KEYWORDS, fsimage_fs_open_file__doc__ }, { "file_exists", (PyCFunction) fsimage_fs_file_exists, METH_VARARGS|METH_KEYWORDS, fsimage_fs_file_exists__doc__ }, { NULL, NULL, 0, NULL } }; #if PY_MAJOR_VERSION < 3 static PyObject * fsimage_fs_getattr(fsimage_fs_t *fs, char *name) { return (Py_FindMethod(fsimage_fs_methods, (PyObject *)fs, name)); } #endif static void fsimage_fs_dealloc (fsimage_fs_t *fs) { if (fs->fs != NULL) fsi_close_fsimage(fs->fs); PyObject_DEL(fs); } PyDoc_STRVAR(fsimage_fs_type__doc__, "Filesystem image"); PyTypeObject fsimage_fs_type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) .tp_name = "xenfsimage.fs", .tp_basicsize = sizeof(fsimage_fs_t), .tp_dealloc = (destructor) fsimage_fs_dealloc, #if PY_MAJOR_VERSION < 3 .tp_getattr = (getattrfunc) fsimage_fs_getattr, #endif .tp_flags = Py_TPFLAGS_DEFAULT, .tp_doc = fsimage_fs_type__doc__, #if PY_MAJOR_VERSION >= 3 .tp_methods = fsimage_fs_methods, #endif }; static PyObject * fsimage_open(PyObject *o, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "name", "offset", "options", NULL }; char *name; char *options = NULL; uint64_t offset = 0; fsimage_fs_t *fs; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Ls", kwlist, &name, &offset, &options)) return (NULL); if ((fs = PyObject_NEW(fsimage_fs_t, &fsimage_fs_type)) == NULL) return (NULL); if ((fs->fs = fsi_open_fsimage(name, offset, options)) == NULL) { PyErr_SetFromErrno(PyExc_IOError); return (NULL); } return (PyObject *)fs; } static PyObject * fsimage_getbootstring(PyObject *o, PyObject *args) { PyObject *fs; char *bootstring; fsi_t *fsi; if (!PyArg_ParseTuple(args, "O", &fs)) return (NULL); fsi = ((fsimage_fs_t *)fs)->fs; bootstring = fsi_fs_bootstring(fsi); return Py_BuildValue("s", bootstring); } static PyObject * fsimage_init(PyObject *o, PyObject *args) { if (!PyArg_ParseTuple(args, "")) return (NULL); return Py_BuildValue("i", fsi_init()); } PyDoc_STRVAR(fsimage_open__doc__, "open(name, [offset=off]) - Open the given file as a filesystem image.\n" "\n" "name - name of file to open.\n" "offset - offset of file system within file image.\n" "options - mount options string.\n"); PyDoc_STRVAR(fsimage_getbootstring__doc__, "getbootstring(fs) - Return the boot string needed for this file system " "or NULL if none is needed.\n"); PyDoc_STRVAR(fsimage_init__doc__, "init() - Loads every dynamic library contained in xenfsimage " "into memory so that it can be used in chrooted environments.\n"); static struct PyMethodDef fsimage_module_methods[] = { { "init", (PyCFunction)fsimage_init, METH_VARARGS, fsimage_init__doc__ }, { "open", (PyCFunction)fsimage_open, METH_VARARGS|METH_KEYWORDS, fsimage_open__doc__ }, { "getbootstring", (PyCFunction)fsimage_getbootstring, METH_VARARGS, fsimage_getbootstring__doc__ }, { NULL, NULL, 0, NULL } }; #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef fsimage_module_def = { PyModuleDef_HEAD_INIT, .m_name = "xenfsimage", .m_size = -1, .m_methods = fsimage_module_methods, }; #endif PyMODINIT_FUNC #if PY_MAJOR_VERSION >= 3 PyInit_xenfsimage(void) #else initxenfsimage(void) #endif { #if PY_MAJOR_VERSION < 3 Py_InitModule("xenfsimage", fsimage_module_methods); #else if (PyType_Ready(&fsimage_fs_type) < 0 || PyType_Ready(&fsimage_file_type) < 0) return NULL; return PyModule_Create(&fsimage_module_def); #endif }