summaryrefslogtreecommitdiff
path: root/python/libmu_py/sieve.c
diff options
context:
space:
mode:
Diffstat (limited to 'python/libmu_py/sieve.c')
-rw-r--r--python/libmu_py/sieve.c349
1 files changed, 349 insertions, 0 deletions
diff --git a/python/libmu_py/sieve.c b/python/libmu_py/sieve.c
new file mode 100644
index 000000000..39b1922e8
--- /dev/null
+++ b/python/libmu_py/sieve.c
@@ -0,0 +1,349 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2009-2024 Free Software Foundation, Inc.
+
+ 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 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "libmu_py.h"
+
+#define PY_MODULE "sieve"
+#define PY_CSNAME "SieveMachineType"
+
+static PyObject *
+_repr (PyObject *self)
+{
+ char buf[80];
+ sprintf (buf, "<" PY_MODULE "." PY_CSNAME " instance at %p>", self);
+ return PyUnicode_FromString (buf);
+}
+
+static PyTypeObject PySieveMachineType = {
+ .ob_base = { PyObject_HEAD_INIT(NULL) },
+ .tp_name = PY_MODULE "." PY_CSNAME,
+ .tp_basicsize = sizeof (PySieveMachine),
+ .tp_dealloc = (destructor)_py_dealloc,
+ .tp_repr = _repr,
+ .tp_str = _repr,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_doc = "",
+};
+
+PySieveMachine *
+PySieveMachine_NEW ()
+{
+ return (PySieveMachine *)PyObject_NEW (PySieveMachine, &PySieveMachineType);
+}
+
+int
+PySieveMachine_Check (PyObject *x)
+{
+ return x->ob_type == &PySieveMachineType;
+}
+
+struct _mu_py_sieve_logger {
+ PyObject *py_debug_printer;
+ PyObject *py_error_printer;
+ PyObject *py_parse_error_printer;
+ PyObject *py_action_printer;
+};
+
+static PyObject *
+api_sieve_machine_init (PyObject *self, PyObject *args)
+{
+ int status;
+ PySieveMachine *py_mach;
+ mu_stream_t str, estr;
+
+ if (!PyArg_ParseTuple (args, "O!", &PySieveMachineType, &py_mach))
+ return NULL;
+
+ status = mu_memory_stream_create (&str, MU_STREAM_RDWR);
+ if (status)
+ return _ro (PyLong_FromLong (status));
+ status = mu_log_stream_create (&estr, str);
+ mu_stream_unref (str);
+ if (status)
+ return _ro (PyLong_FromLong (status));
+
+ status = mu_sieve_machine_create (&py_mach->mach);
+ if (status == 0)
+ mu_sieve_set_diag_stream (py_mach->mach, estr);
+ mu_stream_unref (estr);
+ return _ro (PyLong_FromLong (status));
+}
+
+static PyObject *
+api_sieve_machine_error_text (PyObject *self, PyObject *args)
+{
+ int status;
+ PySieveMachine *py_mach;
+ mu_stream_t estr;
+ mu_transport_t trans[2];
+ PyObject *retval;
+ mu_off_t length = 0;
+
+ if (!PyArg_ParseTuple (args, "O!", &PySieveMachineType, &py_mach))
+ return NULL;
+ if (!py_mach->mach)
+ PyErr_SetString (PyExc_RuntimeError, "Uninitialized Sieve machine");
+
+ mu_sieve_get_diag_stream (py_mach->mach, &estr);
+ status = mu_stream_ioctl (estr, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET,
+ trans);
+ if (status == 0)
+ {
+ mu_stream_t str = (mu_stream_t) trans[0];
+
+ mu_stream_size (str, &length);
+ status = mu_stream_ioctl (str, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET,
+ trans);
+ mu_stream_truncate (str, 0);
+ }
+
+ if (status)
+ PyErr_SetString (PyExc_RuntimeError, mu_strerror (status));
+ retval = PyUnicode_FromStringAndSize ((char*) trans[0], length);
+
+ mu_stream_unref (estr);
+ return _ro (retval);
+}
+
+static PyObject *
+api_sieve_machine_destroy (PyObject *self, PyObject *args)
+{
+ PySieveMachine *py_mach;
+
+ if (!PyArg_ParseTuple (args, "O!", &PySieveMachineType, &py_mach))
+ return NULL;
+
+ if (py_mach->mach)
+ {
+ struct _mu_py_sieve_logger *s = mu_sieve_get_data (py_mach->mach);
+ if (s)
+ free (s);
+ mu_sieve_machine_destroy (&py_mach->mach);
+ }
+ return _ro (Py_None);
+}
+
+static PyObject *
+api_sieve_compile (PyObject *self, PyObject *args)
+{
+ int status;
+ char *name;
+ PySieveMachine *py_mach;
+
+ if (!PyArg_ParseTuple (args, "O!s", &PySieveMachineType, &py_mach, &name))
+ return NULL;
+
+ status = mu_sieve_compile (py_mach->mach, name);
+ return _ro (PyLong_FromLong (status));
+}
+
+static PyObject *
+api_sieve_disass (PyObject *self, PyObject *args)
+{
+ int status;
+ PySieveMachine *py_mach;
+
+ if (!PyArg_ParseTuple (args, "O!", &PySieveMachineType, &py_mach))
+ return NULL;
+
+ status = mu_sieve_disass (py_mach->mach);
+ return _ro (PyLong_FromLong (status));
+}
+
+static PyObject *
+api_sieve_mailbox (PyObject *self, PyObject *args)
+{
+ int status;
+ PySieveMachine *py_mach;
+ PyMailbox *py_mbox;
+
+ if (!PyArg_ParseTuple (args, "O!O", &PySieveMachineType, &py_mach, &py_mbox))
+ return NULL;
+
+ if (!PyMailbox_Check ((PyObject *)py_mbox))
+ {
+ PyErr_SetString (PyExc_TypeError, "");
+ return NULL;
+ }
+
+ status = mu_sieve_mailbox (py_mach->mach, py_mbox->mbox);
+ return _ro (PyLong_FromLong (status));
+}
+
+static PyObject *
+api_sieve_message (PyObject *self, PyObject *args)
+{
+ int status;
+ PySieveMachine *py_mach;
+ PyMessage *py_msg;
+
+ if (!PyArg_ParseTuple (args, "O!O", &PySieveMachineType, &py_mach, &py_msg))
+ return NULL;
+
+ if (!PyMessage_Check ((PyObject *)py_msg))
+ {
+ PyErr_SetString (PyExc_TypeError, "");
+ return NULL;
+ }
+
+ status = mu_sieve_message (py_mach->mach, py_msg->msg);
+ return _ro (PyLong_FromLong (status));
+}
+
+static void
+_sieve_action_printer (mu_sieve_machine_t mach,
+ const char *action, const char *fmt, va_list ap)
+{
+ PyObject *py_args;
+ PyObject *py_dict = PyDict_New ();
+ PyStream *py_stm;
+
+ if (!py_dict)
+ return;
+ py_stm = PyStream_NEW ();
+ if (py_stm)
+ {
+ PyMessage *py_msg = PyMessage_NEW ();
+ char *buf = NULL;
+ size_t buflen = 0;
+
+ if (py_msg)
+ {
+ PyStream *py_stm = PyStream_NEW ();
+ if (py_stm)
+ {
+ size_t msgno;
+
+ mu_sieve_get_diag_stream (mach, &py_stm->stm);
+ msgno = mu_sieve_get_message_num (mach);
+
+ py_msg->msg = mu_sieve_get_message (mach);
+ Py_INCREF (py_msg);
+
+ PyDict_SetItemString (py_dict, "msgno",
+ PyLong_FromSize_t (msgno));
+ PyDict_SetItemString (py_dict, "msg", (PyObject *)py_msg);
+ PyDict_SetItemString (py_dict, "action",
+ PyUnicode_FromString (mu_prstr (action)));
+
+ if (mu_vasnprintf (&buf, &buflen, fmt, ap))
+ {
+ mu_stream_destroy (&py_stm->stm);
+ return;
+ }
+ PyDict_SetItemString (py_dict, "text",
+ PyUnicode_FromString (mu_prstr (buf)));
+ free (buf);
+
+ py_args = PyTuple_New (1);
+ if (py_args)
+ {
+ struct _mu_py_sieve_logger *s = mu_sieve_get_data (mach);
+ PyObject *py_fnc = s->py_action_printer;
+
+ Py_INCREF (py_dict);
+ PyTuple_SetItem (py_args, 0, py_dict);
+
+ if (py_fnc && PyCallable_Check (py_fnc))
+ PyObject_CallObject (py_fnc, py_args);
+
+ Py_DECREF (py_dict);
+ Py_DECREF (py_args);
+ }
+ }
+ }
+ }
+}
+
+static PyObject *
+api_sieve_set_logger (PyObject *self, PyObject *args)
+{
+ PySieveMachine *py_mach;
+ PyObject *py_fnc;
+
+ if (!PyArg_ParseTuple (args, "O!O", &PySieveMachineType, &py_mach, &py_fnc))
+ return NULL;
+
+ if (py_fnc && PyCallable_Check (py_fnc)) {
+ mu_sieve_machine_t mach = py_mach->mach;
+ struct _mu_py_sieve_logger *s = mu_sieve_get_data (mach);
+ s->py_action_printer = py_fnc;
+ Py_INCREF (py_fnc);
+ mu_sieve_set_logger (py_mach->mach, _sieve_action_printer);
+ }
+ else {
+ PyErr_SetString (PyExc_TypeError, "");
+ return NULL;
+ }
+ return _ro (Py_None);
+}
+
+static PyMethodDef methods[] = {
+ { "machine_init", (PyCFunction) api_sieve_machine_init, METH_VARARGS,
+ "Create and initialize new Sieve 'machine'." },
+
+ { "machine_destroy", (PyCFunction) api_sieve_machine_destroy, METH_VARARGS,
+ "Destroy Sieve 'machine'." },
+
+ { "errortext", (PyCFunction) api_sieve_machine_error_text, METH_VARARGS,
+ "Return the most recent error description." },
+
+ { "compile", (PyCFunction) api_sieve_compile, METH_VARARGS,
+ "Compile the sieve script from the file 'name'." },
+
+ { "disass", (PyCFunction) api_sieve_disass, METH_VARARGS,
+ "Dump the disassembled code of the sieve machine 'mach'." },
+
+ { "mailbox", (PyCFunction) api_sieve_mailbox, METH_VARARGS,
+ "Execute the code from the given instance of sieve machine "
+ "'mach' over each message in the mailbox 'mbox'." },
+
+ { "message", (PyCFunction) api_sieve_message, METH_VARARGS,
+ "Execute the code from the given instance of sieve machine "
+ "'mach' over the 'message'. " },
+
+ { "set_logger", (PyCFunction) api_sieve_set_logger, METH_VARARGS,
+ "" },
+
+ { NULL, NULL, 0, NULL }
+};
+
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ PY_MODULE,
+ NULL,
+ -1,
+ methods
+};
+
+int
+mu_py_init_sieve (void)
+{
+ PySieveMachineType.tp_new = PyType_GenericNew;
+ return PyType_Ready (&PySieveMachineType);
+}
+
+void
+_mu_py_attach_sieve (void)
+{
+ PyObject *m;
+ if ((m = _mu_py_attach_module (&moduledef)))
+ {
+ Py_INCREF (&PySieveMachineType);
+ PyModule_AddObject (m, PY_CSNAME, (PyObject *)&PySieveMachineType);
+ }
+}

Return to:

Send suggestions and report system problems to the System administrator.