summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorChristos Zoulas <christos@zoulas.com>2003-10-15 02:22:59 +0000
committerChristos Zoulas <christos@zoulas.com>2003-10-15 02:22:59 +0000
commitff3bfb82017cd80732b72e66d8c420fd650f129f (patch)
treef9c5d17cbc0dcef4263ad0b4848dfddcc16407f5 /python
parent97fb3b38b917b4ccb0ff1bd08e37b82b308b0060 (diff)
downloadfile-git-ff3bfb82017cd80732b72e66d8c420fd650f129f.tar.gz
add python bindings
Diffstat (limited to 'python')
-rw-r--r--python/README24
-rw-r--r--python/py_magic.c331
-rw-r--r--python/py_magic.h29
-rw-r--r--python/setup.py24
4 files changed, 408 insertions, 0 deletions
diff --git a/python/README b/python/README
new file mode 100644
index 00000000..880dfa50
--- /dev/null
+++ b/python/README
@@ -0,0 +1,24 @@
+
+This directory contains Python bindings to allow you to access the
+libmagic api. At the moment their status is "experimental" and
+they are not built by default.
+
+In order to be able to compile magic-python you need to have python
+and the python-dev packages installed.
+
+Python libraries are always built for a particular version of Python
+(2.2, 2.3, etc), and libraries built for one version will not be seen
+by another.
+
+To build:
+
+$ python setup.py build
+
+Now, you can install the modules:
+
+$ cp build/lib.*/magic.so /usr/lib/python2.3/lib-dynload/
+
+(the directory /usr/lib/python2.3 may vary, depending on your installation)
+
+magic-python should work now!
+
diff --git a/python/py_magic.c b/python/py_magic.c
new file mode 100644
index 00000000..48700c25
--- /dev/null
+++ b/python/py_magic.c
@@ -0,0 +1,331 @@
+/*
+ Python wrappers for magic functions.
+
+ Copyright (C) Brett Funderburg, Deepfile Corp. Austin, TX, US 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <Python.h>
+#include <magic.h>
+#include "py_magic.h"
+
+/* Exceptions raised by this module */
+
+PyObject* magic_error_obj;
+
+/* Create a new magic_cookie_hnd object */
+PyObject* new_magic_cookie_handle(magic_t cookie)
+{
+ magic_cookie_hnd* mch;
+
+ mch = PyObject_New(magic_cookie_hnd, &magic_cookie_type);
+
+ mch->cookie = cookie;
+
+ return (PyObject*)mch;
+}
+
+static char _magic_open__doc__[] =
+"Returns a magic cookie on success and None on failure.\n";
+static PyObject* py_magic_open(PyObject* self, PyObject* args)
+{
+ int flags = 0;
+ magic_t cookie;
+
+ if(!PyArg_ParseTuple(args, "i", &flags))
+ return NULL;
+
+ if(!(cookie = magic_open(flags))) {
+ PyErr_SetString(magic_error_obj, "failure initializing magic
+cookie");
+ return NULL;
+ }
+
+ return new_magic_cookie_handle(cookie);
+}
+
+static char _magic_close__doc__[] =
+"Closes the magic database and deallocates any resources used.\n";
+static PyObject* py_magic_close(PyObject* self, PyObject* args)
+{
+ magic_cookie_hnd* hnd = (magic_cookie_hnd*)self;
+
+ magic_close(hnd->cookie);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static char _magic_error__doc__[] =
+"Returns a textual explanation of the last error or None \
+ if there was no error.\n";
+static PyObject* py_magic_error(PyObject* self, PyObject* args)
+{
+ magic_cookie_hnd* hnd = (magic_cookie_hnd*)self;
+ const char* message = NULL;
+ PyObject* result = NULL;
+
+ message = magic_error(hnd->cookie);
+
+ if(message != NULL)
+ result = PyString_FromString(message);
+ else {
+ Py_INCREF(Py_None);
+ result = Py_None;
+ }
+
+ return result;
+}
+
+static char _magic_file__doc__[] =
+"Returns a textual description of the contents of the argument passed \
+ as a filename or None if an error occurred.\n";
+static PyObject* py_magic_file(PyObject* self, PyObject* args)
+{
+ magic_cookie_hnd* hnd = (magic_cookie_hnd*)self;
+ char* filename = NULL;
+ const char* message = NULL;
+ PyObject* result = NULL;
+
+ if(!(PyArg_ParseTuple(args, "s", &filename)))
+ return NULL;
+
+ message = magic_file(hnd->cookie, filename);
+
+ if(message != NULL)
+ result = PyString_FromString(message);
+ else
+ PyErr_SetString(PyExc_RuntimeError,
+ "failure determining file type");
+
+ return result;
+}
+
+static char _magic_buffer__doc__[] =
+"Returns a textual description of the contents of the argument passed \
+ as a buffer or None if an error occurred.\n";
+static PyObject* py_magic_buffer(PyObject* self, PyObject* args)
+{
+ magic_cookie_hnd* hnd = (magic_cookie_hnd*)self;
+ void* buffer = NULL;
+ int buffer_length = 0;
+ const char* message = NULL;
+ PyObject* result = NULL;
+
+ if(!(PyArg_ParseTuple(args, "s#", (char**)&buffer, &buffer_length)))
+ return NULL;
+
+ message = magic_buffer(hnd->cookie, buffer, buffer_length);
+
+ if(message != NULL)
+ result = PyString_FromString(message);
+ else
+ PyErr_SetString(PyExc_RuntimeError,
+ "failure determining buffer type");
+
+ return result;
+}
+
+static char _magic_setflags__doc__[] =
+"Set flags on the cookie object.\n \
+ Returns -1 on systems that don't support utime(2) or utimes(2) \
+ when MAGIC_PRESERVE_ATIME is set.\n";
+static PyObject* py_magic_setflags(PyObject* self, PyObject* args)
+{
+ magic_cookie_hnd* hnd = (magic_cookie_hnd*)self;
+ int flags;
+ int result;
+
+ if(!(PyArg_ParseTuple(args, "i", &flags)))
+ return NULL;
+
+ result = magic_setflags(hnd->cookie, flags);
+
+ return PyInt_FromLong(result);
+}
+
+static char _magic_check__doc__[] =
+"Check the validity of entries in the colon separated list of database
+files \
+ passed as argument or the default database file if no argument.\n \
+ Returns 0 on success and -1 on failure.\n";
+static PyObject* py_magic_check(PyObject* self, PyObject* args)
+{
+ magic_cookie_hnd* hnd = (magic_cookie_hnd*)self;
+ char* filename = NULL;
+ int result;
+
+ if(!(PyArg_ParseTuple(args, "|s", &filename)))
+ return NULL;
+
+ result = magic_check(hnd->cookie, filename);
+
+ return PyInt_FromLong(result);
+}
+
+static char _magic_compile__doc__[] =
+"Compile entries in the colon separated list of database files \
+ passed as argument or the default database file if no argument.\n \
+ Returns 0 on success and -1 on failure.\n \
+ The compiled files created are named from the basename(1) of each file \
+ argument with \".mgc\" appended to it.\n";
+static PyObject* py_magic_compile(PyObject* self, PyObject* args)
+{
+ magic_cookie_hnd* hnd = (magic_cookie_hnd*)self;
+ char* filename = NULL;
+ int result;
+
+ if(!(PyArg_ParseTuple(args, "|s", &filename)))
+ return NULL;
+
+ result = magic_compile(hnd->cookie, filename);
+
+ return PyInt_FromLong(result);
+}
+
+static char _magic_load__doc__[] =
+"Must be used to load entries in the colon separated list of database files \
+ passed as argument or the default database file if no argument before \
+ any magic queries can be performed.\n \
+ Returns 0 on success and -1 on failure.\n";
+static PyObject* py_magic_load(PyObject* self, PyObject* args)
+{
+ magic_cookie_hnd* hnd = (magic_cookie_hnd*)self;
+ char* filename = NULL;
+ int result;
+
+ if(!(PyArg_ParseTuple(args, "|s", &filename)))
+ return NULL;
+
+ result = magic_load(hnd->cookie, filename);
+
+ return PyInt_FromLong(result);
+}
+
+/* object methods */
+
+static PyMethodDef magic_cookie_hnd_methods[] = {
+ { "close", (PyCFunction)py_magic_close,
+ METH_NOARGS, _magic_close__doc__ },
+ { "error", (PyCFunction)py_magic_error,
+ METH_NOARGS, _magic_error__doc__ },
+ { "file", (PyCFunction)py_magic_file,
+ METH_VARARGS, _magic_file__doc__ },
+ { "buffer", (PyCFunction)py_magic_buffer,
+ METH_VARARGS, _magic_buffer__doc__ },
+ { "setflags", (PyCFunction)py_magic_setflags,
+ METH_VARARGS, _magic_setflags__doc__ },
+ { "check", (PyCFunction)py_magic_check,
+ METH_VARARGS, _magic_check__doc__ },
+ { "compile", (PyCFunction)py_magic_compile,
+ METH_VARARGS, _magic_compile__doc__ },
+ { "load", (PyCFunction)py_magic_load,
+ METH_VARARGS, _magic_load__doc__ },
+ { NULL, NULL }
+};
+
+/* module level methods */
+
+static PyMethodDef magic_methods[] = {
+ { "open", (PyCFunction)py_magic_open,
+ METH_VARARGS, _magic_open__doc__ },
+ { NULL, NULL }
+};
+
+static void py_magic_dealloc(PyObject* self)
+{
+ PyObject_Del(self);
+}
+
+static PyObject* py_magic_getattr(PyObject* self, char* attrname)
+{
+ return Py_FindMethod(magic_cookie_hnd_methods, self, attrname);
+}
+
+PyTypeObject magic_cookie_type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "Magic cookie",
+ sizeof(magic_cookie_hnd),
+ 0,
+ py_magic_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ py_magic_getattr, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+};
+
+/* Initialize constants */
+
+static struct const_vals {
+ const char* const name;
+ unsigned int value;
+} module_const_vals[] = {
+ { "MAGIC_NONE", MAGIC_NONE },
+ { "MAGIC_DEBUG", MAGIC_DEBUG },
+ { "MAGIC_SYMLINK", MAGIC_SYMLINK },
+ { "MAGIC_COMPRESS", MAGIC_COMPRESS },
+ { "MAGIC_DEVICES", MAGIC_DEVICES },
+ { "MAGIC_MIME", MAGIC_MIME },
+ { "MAGIC_CONTINUE", MAGIC_CONTINUE },
+ { "MAGIC_CHECK", MAGIC_CHECK },
+ { "MAGIC_PRESERVE_ATIME", MAGIC_PRESERVE_ATIME },
+ { NULL }
+};
+
+static void const_init(PyObject* dict)
+{
+ struct const_vals* tmp;
+ PyObject *obj;
+
+ for(tmp = module_const_vals; tmp->name; ++tmp) {
+ obj = PyInt_FromLong(tmp->value);
+ PyDict_SetItemString(dict, tmp->name, obj);
+ Py_DECREF(obj);
+ }
+}
+
+/*
+ * Module initialization
+ */
+
+void initmagic(void)
+{
+ PyObject* module;
+ PyObject* dict;
+
+ /* Initialize module */
+
+ module = Py_InitModule("magic", magic_methods);
+ dict = PyModule_GetDict(module);
+
+ magic_error_obj = PyErr_NewException("magic.error", NULL, NULL);
+ PyDict_SetItemString(dict, "error", magic_error_obj);
+
+ magic_cookie_type.ob_type = &PyType_Type;
+
+ /* Initialize constants */
+
+ const_init(dict);
+
+ if(PyErr_Occurred())
+ Py_FatalError("can't initialize module magic");
+}
diff --git a/python/py_magic.h b/python/py_magic.h
new file mode 100644
index 00000000..0129cbb2
--- /dev/null
+++ b/python/py_magic.h
@@ -0,0 +1,29 @@
+/*
+ Python wrappers for magic functions.
+
+ Copyright (C) Brett Funderburg, Deepfile Corp. Austin, TX, US 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _PY_MAGIC_H
+#define _PY_MAGIC_H
+
+typedef struct {
+ PyObject_HEAD
+ magic_t cookie;
+} magic_cookie_hnd;
+
+#endif /* _PY_MAGIC_H */
diff --git a/python/setup.py b/python/setup.py
new file mode 100644
index 00000000..e18c5b03
--- /dev/null
+++ b/python/setup.py
@@ -0,0 +1,24 @@
+To build, make a directory called 'python' in 'src' and then follow the
+instructions in the README.
+
+Unless something got screwed up in the cut and paste, the code should
+compile cleanly and without warnings.
+
+You may need to tinker with the library and include paths specified in the
+distutils build script (setup.py) to make things work on your machine.
+
+The following python script should give you an idea of how things work.
+
+-- begin --
+import magic
+c = magic.open(magic.MAGIC_NONE)
+c.load()
+c.file("/path/to/some/file")
+
+f = file("/path/to/some/file", "r")
+buffer = f.read(4096)
+f.close()
+
+c.buffer(buffer)
+
+c.close()