2015-05-05 17:09:44 +00:00
|
|
|
|
/*
|
2016-06-07 14:07:33 +00:00
|
|
|
|
# Copyright (C) 2016 g10 Code GmbH
|
2015-05-05 17:09:44 +00:00
|
|
|
|
# Copyright (C) 2004,2008 Igor Belyi <belyi@users.sourceforge.net>
|
|
|
|
|
# Copyright (C) 2002 John Goerzen <jgoerzen@complete.org>
|
|
|
|
|
#
|
|
|
|
|
# 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.
|
|
|
|
|
#
|
|
|
|
|
# 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, write to the Free Software
|
|
|
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
*/
|
2016-07-28 13:44:38 +00:00
|
|
|
|
%module gpgme
|
2015-05-05 17:09:44 +00:00
|
|
|
|
%include "cpointer.i"
|
|
|
|
|
%include "cstring.i"
|
|
|
|
|
|
python: do not export HAVE_CXX11 definition
* lang/python/gpgme.i: ignore HAVE_CXX11 in SWIG interface
--
If there are two distinct builds (a) and (b) of gpgme which both build
python bindings, and build (a) also happens to build the C++ bindings,
then the generated gpg/gpgme.py file from build (a) will not be usable
with the .so generated in build (b), despite them being exactly the
same, and having nothing to do with C++.
In particular, it will fail with:
-----------
File "…/gpg/__init__.py", line 99, in <module>
from . import core
File "…/gpg/core.py", line 10, in <module>
from . import gpgme
File "…/gpg/gpgme.py", line 152, in <module>
HAVE_CXX11 = _gpgme.HAVE_CXX11
AttributeError: module 'gpg._gpgme' has no attribute 'HAVE_CXX11'
-----------
By asking SWIG to ignore this definition, we stabilize the generated
.py and the .so, ensuring that they are more cleanly interoperable.
2018-10-18 02:23:59 +00:00
|
|
|
|
/* no need to record whether GPGME's c++ bindings were built
|
|
|
|
|
concurrently with the python bindings */
|
|
|
|
|
%ignore HAVE_CXX11;
|
|
|
|
|
|
2018-09-20 15:28:25 +00:00
|
|
|
|
%{
|
|
|
|
|
/* We use public symbols (eg. "_obsolete_class") which are marked as
|
|
|
|
|
* deprecated but we need to keep them. Silence the warning. */
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
|
|
|
%}
|
|
|
|
|
|
2016-06-14 11:28:37 +00:00
|
|
|
|
/* Generate doc strings for all methods.
|
|
|
|
|
|
|
|
|
|
This will generate docstrings of the form
|
|
|
|
|
|
|
|
|
|
gpgme_op_encrypt(ctx, recp, flags, plain, cipher) -> gpgme_error_t
|
|
|
|
|
|
|
|
|
|
which we transform into
|
|
|
|
|
|
|
|
|
|
ctx.op_encrypt(recp, flags, plain, cipher) -> gpgme_error_t
|
|
|
|
|
|
|
|
|
|
for automagically wrapped functions. */
|
2015-05-05 17:09:44 +00:00
|
|
|
|
%feature("autodoc", "0");
|
|
|
|
|
|
|
|
|
|
|
2016-06-14 11:28:37 +00:00
|
|
|
|
/* Allow use of Unicode objects, bytes, and None for strings. */
|
2016-09-12 15:11:19 +00:00
|
|
|
|
%typemap(in) const char *(PyObject *encodedInput = NULL) {
|
2015-05-05 17:09:44 +00:00
|
|
|
|
if ($input == Py_None)
|
|
|
|
|
$1 = NULL;
|
2016-05-12 09:21:58 +00:00
|
|
|
|
else if (PyUnicode_Check($input))
|
2016-09-12 15:11:19 +00:00
|
|
|
|
{
|
|
|
|
|
encodedInput = PyUnicode_AsUTF8String($input);
|
|
|
|
|
if (encodedInput == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
$1 = PyBytes_AsString(encodedInput);
|
|
|
|
|
}
|
2015-05-05 17:09:44 +00:00
|
|
|
|
else if (PyBytes_Check($input))
|
|
|
|
|
$1 = PyBytes_AsString($input);
|
|
|
|
|
else {
|
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
2016-05-12 09:21:58 +00:00
|
|
|
|
"arg %d: expected str, bytes, or None, got %s",
|
2015-05-05 17:09:44 +00:00
|
|
|
|
$argnum, $input->ob_type->tp_name);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-09-12 15:11:19 +00:00
|
|
|
|
%typemap(freearg) const char * {
|
|
|
|
|
Py_XDECREF(encodedInput$argnum);
|
|
|
|
|
}
|
2015-05-05 17:09:44 +00:00
|
|
|
|
|
2016-05-23 13:41:06 +00:00
|
|
|
|
/* Likewise for a list of strings. */
|
2016-09-12 15:11:19 +00:00
|
|
|
|
%typemap(in) const char *[] (void *vector = NULL,
|
|
|
|
|
size_t size,
|
|
|
|
|
PyObject **pyVector = NULL) {
|
2016-05-23 13:41:06 +00:00
|
|
|
|
/* Check if is a list */
|
|
|
|
|
if (PyList_Check($input)) {
|
2016-09-12 15:11:19 +00:00
|
|
|
|
size_t i, j;
|
|
|
|
|
size = PyList_Size($input);
|
2016-06-07 14:07:33 +00:00
|
|
|
|
$1 = (char **) (vector = malloc((size+1) * sizeof(char *)));
|
2016-09-12 15:11:19 +00:00
|
|
|
|
pyVector = calloc(sizeof *pyVector, size);
|
2016-05-23 13:41:06 +00:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
|
PyObject *o = PyList_GetItem($input,i);
|
|
|
|
|
if (PyUnicode_Check(o))
|
2016-09-12 15:11:19 +00:00
|
|
|
|
{
|
|
|
|
|
pyVector[i] = PyUnicode_AsUTF8String(o);
|
|
|
|
|
if (pyVector[i] == NULL)
|
|
|
|
|
{
|
|
|
|
|
free(vector);
|
|
|
|
|
for (j = 0; j < i; j++)
|
|
|
|
|
Py_XDECREF(pyVector[j]);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
$1[i] = PyBytes_AsString(pyVector[i]);
|
|
|
|
|
}
|
2016-05-23 13:41:06 +00:00
|
|
|
|
else if (PyString_Check(o))
|
|
|
|
|
$1[i] = PyString_AsString(o);
|
|
|
|
|
else {
|
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
|
"arg %d: list must contain only str or bytes, got %s "
|
|
|
|
|
"at position %d",
|
|
|
|
|
$argnum, o->ob_type->tp_name, i);
|
|
|
|
|
free($1);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$1[i] = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
|
"arg %d: expected a list of str or bytes, got %s",
|
|
|
|
|
$argnum, $input->ob_type->tp_name);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
%typemap(freearg) const char *[] {
|
2016-09-12 15:11:19 +00:00
|
|
|
|
size_t i;
|
2016-06-07 14:07:33 +00:00
|
|
|
|
free(vector$argnum);
|
2016-09-12 15:11:19 +00:00
|
|
|
|
for (i = 0; i < size$argnum; i++)
|
|
|
|
|
Py_XDECREF(pyVector$argnum[i]);
|
2016-05-23 13:41:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-09-26 14:45:21 +00:00
|
|
|
|
/* Release returned buffers as necessary. */
|
2017-02-14 15:16:05 +00:00
|
|
|
|
%typemap(newfree) char * "gpgme_free($1);";
|
2015-05-05 17:09:44 +00:00
|
|
|
|
%newobject gpgme_data_release_and_get_mem;
|
2017-02-14 15:30:30 +00:00
|
|
|
|
%newobject gpgme_pubkey_algo_string;
|
|
|
|
|
%newobject gpgme_addrspec_from_uid;
|
2015-05-05 17:09:44 +00:00
|
|
|
|
|
|
|
|
|
%typemap(arginit) gpgme_key_t [] {
|
|
|
|
|
$1 = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
%typemap(in) gpgme_key_t [] {
|
|
|
|
|
int i, numb = 0;
|
|
|
|
|
if (!PySequence_Check($input)) {
|
|
|
|
|
PyErr_Format(PyExc_ValueError, "arg %d: Expected a list of gpgme_key_t",
|
|
|
|
|
$argnum);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
if((numb = PySequence_Length($input)) != 0) {
|
|
|
|
|
$1 = (gpgme_key_t*)malloc((numb+1)*sizeof(gpgme_key_t));
|
|
|
|
|
for(i=0; i<numb; i++) {
|
|
|
|
|
PyObject *pypointer = PySequence_GetItem($input, i);
|
|
|
|
|
|
|
|
|
|
/* input = $input, 1 = $1, 1_descriptor = $1_descriptor */
|
|
|
|
|
/* &1_descriptor = $&1_descriptor *1_descriptor = $*1_descriptor */
|
|
|
|
|
|
2016-09-26 14:45:21 +00:00
|
|
|
|
/* Following code is from swig's python.swg. */
|
2015-05-05 17:09:44 +00:00
|
|
|
|
if ((SWIG_ConvertPtr(pypointer,(void **) &$1[i], $*1_descriptor,SWIG_POINTER_EXCEPTION | $disown )) == -1) {
|
2017-02-16 13:42:17 +00:00
|
|
|
|
Py_DECREF(pypointer);
|
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
|
"arg %d: list must contain only gpgme_key_ts, got %s "
|
|
|
|
|
"at position %d",
|
|
|
|
|
$argnum, pypointer->ob_type->tp_name, i);
|
|
|
|
|
free($1);
|
2015-05-05 17:09:44 +00:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
Py_DECREF(pypointer);
|
|
|
|
|
}
|
|
|
|
|
$1[numb] = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
%typemap(freearg) gpgme_key_t [] {
|
|
|
|
|
if ($1) free($1);
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-26 14:45:21 +00:00
|
|
|
|
/* Special handling for references to our objects. */
|
2016-06-08 15:56:33 +00:00
|
|
|
|
%typemap(in) gpgme_data_t DATAIN (gpgme_data_t wrapper = NULL,
|
2016-07-11 14:34:15 +00:00
|
|
|
|
PyObject *bytesio = NULL,
|
|
|
|
|
Py_buffer view, int have_view = 0) {
|
2016-06-06 11:11:15 +00:00
|
|
|
|
/* If we create a temporary wrapper object, we will store it in
|
|
|
|
|
wrapperN, where N is $argnum. Here in this fragment, SWIG will
|
|
|
|
|
automatically append $argnum. */
|
2016-06-08 15:56:33 +00:00
|
|
|
|
memset(&view, 0, sizeof view);
|
2015-05-05 17:09:44 +00:00
|
|
|
|
if ($input == Py_None)
|
|
|
|
|
$1 = NULL;
|
|
|
|
|
else {
|
2016-06-08 15:56:33 +00:00
|
|
|
|
PyObject *pypointer;
|
2016-10-28 20:45:49 +00:00
|
|
|
|
pypointer = _gpg_obj2gpgme_data_t($input, $argnum, &wrapper,
|
2016-06-08 15:56:33 +00:00
|
|
|
|
&bytesio, &view);
|
|
|
|
|
if (pypointer == NULL)
|
2015-05-05 17:09:44 +00:00
|
|
|
|
return NULL;
|
2016-07-11 14:34:15 +00:00
|
|
|
|
have_view = !! view.obj;
|
2015-05-05 17:09:44 +00:00
|
|
|
|
|
|
|
|
|
/* input = $input, 1 = $1, 1_descriptor = $1_descriptor */
|
|
|
|
|
|
2016-09-26 14:45:21 +00:00
|
|
|
|
/* Following code is from swig's python.swg. */
|
2015-05-05 17:09:44 +00:00
|
|
|
|
|
|
|
|
|
if ((SWIG_ConvertPtr(pypointer,(void **) &$1, $1_descriptor,
|
|
|
|
|
SWIG_POINTER_EXCEPTION | $disown )) == -1) {
|
|
|
|
|
Py_DECREF(pypointer);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
Py_DECREF(pypointer);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-11 14:34:15 +00:00
|
|
|
|
#if HAVE_DATA_H
|
|
|
|
|
/* If we are doing an in-tree build, we can use the internal
|
|
|
|
|
representation of struct gpgme_data for an very efficient check if
|
|
|
|
|
the buffer has been modified. */
|
|
|
|
|
%{
|
2016-09-29 07:30:58 +00:00
|
|
|
|
#include "data.h" /* For struct gpgme_data. */
|
2016-07-11 14:34:15 +00:00
|
|
|
|
%}
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-06-06 11:11:15 +00:00
|
|
|
|
%typemap(freearg) gpgme_data_t DATAIN {
|
2016-06-08 15:56:33 +00:00
|
|
|
|
/* See whether we need to update the Python buffer. */
|
2016-07-11 14:34:15 +00:00
|
|
|
|
if (resultobj && wrapper$argnum && view$argnum.buf)
|
2016-06-08 15:56:33 +00:00
|
|
|
|
{
|
2016-07-11 14:34:15 +00:00
|
|
|
|
int dirty;
|
|
|
|
|
char *new_data = NULL;
|
|
|
|
|
size_t new_size;
|
|
|
|
|
|
|
|
|
|
#if HAVE_DATA_H
|
|
|
|
|
new_data = wrapper$argnum->data.mem.buffer;
|
|
|
|
|
new_size = wrapper$argnum->data.mem.length;
|
|
|
|
|
dirty = new_data != NULL;
|
|
|
|
|
#else
|
|
|
|
|
new_data = gpgme_data_release_and_get_mem (wrapper$argnum, &new_size);
|
|
|
|
|
wrapper$argnum = NULL;
|
|
|
|
|
dirty = new_size != view$argnum.len
|
|
|
|
|
|| memcmp (new_data, view$argnum.buf, view$argnum.len);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (dirty)
|
2016-06-08 15:56:33 +00:00
|
|
|
|
{
|
2016-07-11 14:34:15 +00:00
|
|
|
|
/* The buffer is dirty. */
|
|
|
|
|
if (view$argnum.readonly)
|
2016-06-08 15:56:33 +00:00
|
|
|
|
{
|
|
|
|
|
Py_XDECREF(resultobj);
|
|
|
|
|
resultobj = NULL;
|
2016-07-11 14:34:15 +00:00
|
|
|
|
PyErr_SetString(PyExc_ValueError,
|
|
|
|
|
"cannot update read-only buffer");
|
2016-06-08 15:56:33 +00:00
|
|
|
|
}
|
2016-07-11 14:34:15 +00:00
|
|
|
|
|
|
|
|
|
/* See if we need to truncate the buffer. */
|
|
|
|
|
if (resultobj && view$argnum.len != new_size)
|
2016-06-08 15:56:33 +00:00
|
|
|
|
{
|
2016-07-11 14:34:15 +00:00
|
|
|
|
if (bytesio$argnum == NULL)
|
2016-06-08 15:56:33 +00:00
|
|
|
|
{
|
|
|
|
|
Py_XDECREF(resultobj);
|
|
|
|
|
resultobj = NULL;
|
2016-07-11 14:34:15 +00:00
|
|
|
|
PyErr_SetString(PyExc_ValueError, "cannot resize buffer");
|
2016-06-08 15:56:33 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2016-07-11 14:34:15 +00:00
|
|
|
|
PyObject *retval;
|
|
|
|
|
PyBuffer_Release(&view$argnum);
|
|
|
|
|
assert(view$argnum.obj == NULL);
|
|
|
|
|
retval = PyObject_CallMethod(bytesio$argnum, "truncate",
|
|
|
|
|
"l", (long) new_size);
|
|
|
|
|
if (retval == NULL)
|
2016-06-08 15:56:33 +00:00
|
|
|
|
{
|
|
|
|
|
Py_XDECREF(resultobj);
|
|
|
|
|
resultobj = NULL;
|
|
|
|
|
}
|
2016-07-11 14:34:15 +00:00
|
|
|
|
else
|
2016-06-08 15:56:33 +00:00
|
|
|
|
{
|
2016-07-11 14:34:15 +00:00
|
|
|
|
Py_DECREF(retval);
|
|
|
|
|
|
|
|
|
|
retval = PyObject_CallMethod(bytesio$argnum,
|
|
|
|
|
"getbuffer", NULL);
|
|
|
|
|
if (retval == NULL
|
|
|
|
|
|| PyObject_GetBuffer(retval, &view$argnum,
|
|
|
|
|
PyBUF_SIMPLE|PyBUF_WRITABLE) < 0)
|
|
|
|
|
{
|
|
|
|
|
Py_XDECREF(resultobj);
|
|
|
|
|
resultobj = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Py_XDECREF(retval);
|
|
|
|
|
|
|
|
|
|
if (resultobj && view$argnum.len
|
|
|
|
|
!= new_size)
|
|
|
|
|
{
|
|
|
|
|
Py_XDECREF(resultobj);
|
|
|
|
|
resultobj = NULL;
|
|
|
|
|
PyErr_Format(PyExc_ValueError,
|
|
|
|
|
"Expected buffer of length %zu, got %zi",
|
|
|
|
|
new_size,
|
|
|
|
|
view$argnum.len);
|
|
|
|
|
}
|
2016-06-08 15:56:33 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-11 14:34:15 +00:00
|
|
|
|
if (resultobj)
|
|
|
|
|
memcpy(view$argnum.buf, new_data, new_size);
|
2016-06-08 15:56:33 +00:00
|
|
|
|
}
|
2016-07-11 14:34:15 +00:00
|
|
|
|
#if ! HAVE_DATA_H
|
|
|
|
|
free (new_data);
|
|
|
|
|
#endif
|
2016-06-08 15:56:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-06-06 11:11:15 +00:00
|
|
|
|
/* Free the temporary wrapper, if any. */
|
2016-06-08 15:56:33 +00:00
|
|
|
|
if (wrapper$argnum)
|
|
|
|
|
gpgme_data_release(wrapper$argnum);
|
|
|
|
|
Py_XDECREF (bytesio$argnum);
|
2016-07-11 14:34:15 +00:00
|
|
|
|
if (have_view$argnum && view$argnum.buf)
|
2016-06-08 15:56:33 +00:00
|
|
|
|
PyBuffer_Release(&view$argnum);
|
2016-06-06 11:11:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-05-05 17:09:44 +00:00
|
|
|
|
%apply gpgme_data_t DATAIN {gpgme_data_t plain, gpgme_data_t cipher,
|
|
|
|
|
gpgme_data_t sig, gpgme_data_t signed_text,
|
|
|
|
|
gpgme_data_t plaintext, gpgme_data_t keydata,
|
|
|
|
|
gpgme_data_t pubkey, gpgme_data_t seckey,
|
2017-03-21 11:32:31 +00:00
|
|
|
|
gpgme_data_t out, gpgme_data_t data};
|
2015-05-05 17:09:44 +00:00
|
|
|
|
|
2016-05-27 12:04:28 +00:00
|
|
|
|
/* SWIG has problems interpreting ssize_t, off_t or gpgme_error_t in
|
|
|
|
|
gpgme.h. */
|
2016-09-26 11:04:35 +00:00
|
|
|
|
%typemap(out) ssize_t, gpgme_error_t, gpgme_err_code_t, gpgme_err_source_t, gpg_error_t {
|
2015-05-05 17:09:44 +00:00
|
|
|
|
$result = PyLong_FromLong($1);
|
|
|
|
|
}
|
2016-09-26 11:04:35 +00:00
|
|
|
|
|
|
|
|
|
%typemap(in) ssize_t, gpgme_error_t, gpgme_err_code_t, gpgme_err_source_t, gpg_error_t {
|
|
|
|
|
if (PyLong_Check($input))
|
|
|
|
|
$1 = PyLong_AsLong($input);
|
|
|
|
|
#if PY_MAJOR_VERSION < 3
|
|
|
|
|
else if (PyInt_Check($input))
|
|
|
|
|
$1 = PyInt_AsLong($input);
|
|
|
|
|
#endif
|
|
|
|
|
else
|
|
|
|
|
PyErr_SetString(PyExc_TypeError, "Numeric argument expected");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
%typemap(out) off_t {
|
|
|
|
|
#if _FILE_OFFSET_BITS == 64
|
|
|
|
|
$result = PyLong_FromLongLong($1);
|
|
|
|
|
#else
|
|
|
|
|
$result = PyLong_FromLong($1);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
%typemap(in) off_t {
|
|
|
|
|
if (PyLong_Check($input))
|
|
|
|
|
#if _FILE_OFFSET_BITS == 64
|
|
|
|
|
$1 = PyLong_AsLongLong($input);
|
|
|
|
|
#else
|
|
|
|
|
$1 = PyLong_AsLong($input);
|
|
|
|
|
#endif
|
|
|
|
|
#if PY_MAJOR_VERSION < 3
|
|
|
|
|
else if (PyInt_Check($input))
|
|
|
|
|
$1 = PyInt_AsLong($input);
|
|
|
|
|
#endif
|
|
|
|
|
else
|
|
|
|
|
PyErr_SetString(PyExc_TypeError, "Numeric argument expected");
|
2015-05-05 17:09:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-09-26 11:16:59 +00:00
|
|
|
|
/* Those are for gpgme_data_read() and gpgme_strerror_r(). */
|
2015-05-05 17:09:44 +00:00
|
|
|
|
%typemap(in) (void *buffer, size_t size), (char *buf, size_t buflen) {
|
2016-09-26 11:16:59 +00:00
|
|
|
|
{
|
|
|
|
|
long tmp$argnum;
|
|
|
|
|
if (PyLong_Check($input))
|
|
|
|
|
tmp$argnum = PyLong_AsLong($input);
|
|
|
|
|
#if PY_MAJOR_VERSION < 3
|
|
|
|
|
else if (PyInt_Check($input))
|
|
|
|
|
tmp$argnum = PyInt_AsLong($input);
|
|
|
|
|
#endif
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
PyErr_SetString(PyExc_TypeError, "Numeric argument expected");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tmp$argnum < 0) {
|
|
|
|
|
PyErr_SetString(PyExc_ValueError, "Positive integer expected");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
$2 = (size_t) tmp$argnum;
|
|
|
|
|
$1 = ($1_ltype) malloc($2+1);
|
|
|
|
|
}
|
2015-05-05 17:09:44 +00:00
|
|
|
|
}
|
|
|
|
|
%typemap(argout) (void *buffer, size_t size), (char *buf, size_t buflen) {
|
|
|
|
|
Py_XDECREF($result); /* Blow away any previous result */
|
|
|
|
|
if (result < 0) { /* Check for I/O error */
|
|
|
|
|
free($1);
|
2016-05-27 12:04:28 +00:00
|
|
|
|
return PyErr_SetFromErrno(PyExc_RuntimeError);
|
2015-05-05 17:09:44 +00:00
|
|
|
|
}
|
|
|
|
|
$result = PyBytes_FromStringAndSize($1,result);
|
|
|
|
|
free($1);
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-12 15:44:54 +00:00
|
|
|
|
/* For gpgme_data_write, but should be universal. */
|
2016-09-12 15:11:19 +00:00
|
|
|
|
%typemap(in) (const void *buffer, size_t size)(PyObject *encodedInput = NULL) {
|
2016-06-08 15:04:02 +00:00
|
|
|
|
Py_ssize_t ssize;
|
|
|
|
|
|
2016-05-12 15:44:54 +00:00
|
|
|
|
if ($input == Py_None)
|
|
|
|
|
$1 = NULL, $2 = 0;
|
|
|
|
|
else if (PyUnicode_Check($input))
|
2016-09-12 15:11:19 +00:00
|
|
|
|
{
|
|
|
|
|
encodedInput = PyUnicode_AsUTF8String($input);
|
|
|
|
|
if (encodedInput == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (PyBytes_AsStringAndSize(encodedInput, (char **) &$1, &ssize) == -1)
|
|
|
|
|
{
|
|
|
|
|
Py_DECREF(encodedInput);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-05-12 15:44:54 +00:00
|
|
|
|
else if (PyBytes_Check($input))
|
2016-06-08 15:04:02 +00:00
|
|
|
|
PyBytes_AsStringAndSize($input, (char **) &$1, &ssize);
|
2016-05-12 15:44:54 +00:00
|
|
|
|
else {
|
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
|
"arg %d: expected str, bytes, or None, got %s",
|
|
|
|
|
$argnum, $input->ob_type->tp_name);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2016-06-08 15:04:02 +00:00
|
|
|
|
|
|
|
|
|
if (! $1)
|
|
|
|
|
$2 = 0;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
assert (ssize >= 0);
|
|
|
|
|
$2 = (size_t) ssize;
|
|
|
|
|
}
|
2016-05-12 15:44:54 +00:00
|
|
|
|
}
|
2016-09-12 15:11:19 +00:00
|
|
|
|
%typemap(freearg) (const void *buffer, size_t size) {
|
|
|
|
|
Py_XDECREF(encodedInput$argnum);
|
|
|
|
|
}
|
2016-05-12 15:44:54 +00:00
|
|
|
|
|
2016-09-26 14:45:21 +00:00
|
|
|
|
/* Make types containing 'next' field to be lists. */
|
2015-05-05 17:09:44 +00:00
|
|
|
|
%ignore next;
|
2016-07-28 09:16:35 +00:00
|
|
|
|
%typemap(out) gpgme_sig_notation_t, gpgme_subkey_t,
|
2016-06-14 15:33:12 +00:00
|
|
|
|
gpgme_key_sig_t, gpgme_user_id_t, gpgme_invalid_key_t,
|
|
|
|
|
gpgme_recipient_t, gpgme_new_signature_t, gpgme_signature_t,
|
|
|
|
|
gpgme_import_status_t, gpgme_conf_arg_t, gpgme_conf_opt_t,
|
|
|
|
|
gpgme_conf_comp_t, gpgme_tofu_info_t {
|
2015-05-05 17:09:44 +00:00
|
|
|
|
int i;
|
|
|
|
|
int size = 0;
|
|
|
|
|
$1_ltype curr;
|
|
|
|
|
for (curr = $1; curr != NULL; curr = curr->next) {
|
|
|
|
|
size++;
|
|
|
|
|
}
|
|
|
|
|
$result = PyList_New(size);
|
|
|
|
|
for (i=0,curr=$1; i<size; i++,curr=curr->next) {
|
|
|
|
|
PyObject *o = SWIG_NewPointerObj(SWIG_as_voidptr(curr), $1_descriptor, %newpointer_flags);
|
|
|
|
|
PyList_SetItem($result, i, o);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-14 15:33:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Wrap the fragile result objects into robust Python ones. */
|
2016-12-01 20:15:12 +00:00
|
|
|
|
%define wrapresult(cls, name)
|
|
|
|
|
%typemap(out) cls {
|
2016-06-14 15:33:12 +00:00
|
|
|
|
PyObject *fragile;
|
|
|
|
|
fragile = SWIG_NewPointerObj(SWIG_as_voidptr($1), $1_descriptor,
|
|
|
|
|
%newpointer_flags);
|
2016-12-01 20:15:12 +00:00
|
|
|
|
$result = _gpg_wrap_result(fragile, name);
|
2016-06-14 15:33:12 +00:00
|
|
|
|
Py_DECREF(fragile);
|
|
|
|
|
}
|
2016-12-01 20:15:12 +00:00
|
|
|
|
%enddef
|
|
|
|
|
|
|
|
|
|
wrapresult(gpgme_encrypt_result_t, "EncryptResult")
|
|
|
|
|
wrapresult(gpgme_decrypt_result_t, "DecryptResult")
|
|
|
|
|
wrapresult(gpgme_sign_result_t, "SignResult")
|
|
|
|
|
wrapresult(gpgme_verify_result_t, "VerifyResult")
|
|
|
|
|
wrapresult(gpgme_import_result_t, "ImportResult")
|
|
|
|
|
wrapresult(gpgme_genkey_result_t, "GenkeyResult")
|
|
|
|
|
wrapresult(gpgme_keylist_result_t, "KeylistResult")
|
|
|
|
|
wrapresult(gpgme_vfs_mount_result_t, "VFSMountResult")
|
2016-06-14 15:33:12 +00:00
|
|
|
|
|
2016-07-28 09:16:35 +00:00
|
|
|
|
%typemap(out) gpgme_engine_info_t {
|
|
|
|
|
int i;
|
|
|
|
|
int size = 0;
|
|
|
|
|
$1_ltype curr;
|
|
|
|
|
for (curr = $1; curr != NULL; curr = curr->next) {
|
|
|
|
|
size++;
|
|
|
|
|
}
|
|
|
|
|
$result = PyList_New(size);
|
2016-09-14 12:34:14 +00:00
|
|
|
|
if ($result == NULL)
|
|
|
|
|
return NULL; /* raise */
|
2016-07-28 09:16:35 +00:00
|
|
|
|
for (i=0,curr=$1; i<size; i++,curr=curr->next) {
|
|
|
|
|
PyObject *fragile, *o;
|
|
|
|
|
fragile = SWIG_NewPointerObj(SWIG_as_voidptr(curr), $1_descriptor,
|
|
|
|
|
%newpointer_flags);
|
2016-09-14 12:34:14 +00:00
|
|
|
|
if (fragile == NULL)
|
|
|
|
|
{
|
|
|
|
|
Py_DECREF($result);
|
|
|
|
|
return NULL; /* raise */
|
|
|
|
|
}
|
2016-10-28 20:45:49 +00:00
|
|
|
|
o = _gpg_wrap_result(fragile, "EngineInfo");
|
2016-07-28 09:16:35 +00:00
|
|
|
|
Py_DECREF(fragile);
|
2016-09-14 12:34:14 +00:00
|
|
|
|
if (o == NULL)
|
|
|
|
|
{
|
|
|
|
|
Py_DECREF($result);
|
|
|
|
|
return NULL; /* raise */
|
|
|
|
|
}
|
2016-07-28 09:16:35 +00:00
|
|
|
|
PyList_SetItem($result, i, o);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-14 15:33:12 +00:00
|
|
|
|
|
|
|
|
|
|
2016-09-16 12:56:29 +00:00
|
|
|
|
/* Include mapper for interact callbacks. */
|
|
|
|
|
%typemap(in) (gpgme_interact_cb_t fnc, void *fnc_value) {
|
2016-06-13 17:16:30 +00:00
|
|
|
|
if (! PyTuple_Check($input))
|
2016-09-16 12:56:29 +00:00
|
|
|
|
return PyErr_Format(PyExc_TypeError, "interact callback must be a tuple");
|
2016-06-13 17:16:30 +00:00
|
|
|
|
if (PyTuple_Size($input) != 2 && PyTuple_Size($input) != 3)
|
|
|
|
|
return PyErr_Format(PyExc_TypeError,
|
2016-09-16 12:56:29 +00:00
|
|
|
|
"interact callback must be a tuple of size 2 or 3");
|
2016-06-13 17:16:30 +00:00
|
|
|
|
|
2016-10-28 20:45:49 +00:00
|
|
|
|
$1 = (gpgme_interact_cb_t) _gpg_interact_cb;
|
2016-06-13 17:16:30 +00:00
|
|
|
|
$2 = $input;
|
2015-05-05 17:09:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-07-28 10:40:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The assuan protocol callbacks. */
|
|
|
|
|
%typemap(in) (gpgme_assuan_data_cb_t data_cb, void *data_cb_value) {
|
|
|
|
|
if ($input == Py_None)
|
|
|
|
|
$1 = $2 = NULL;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (! PyTuple_Check($input))
|
|
|
|
|
return PyErr_Format(PyExc_TypeError, "callback must be a tuple");
|
|
|
|
|
if (PyTuple_Size($input) != 2)
|
|
|
|
|
return PyErr_Format(PyExc_TypeError,
|
|
|
|
|
"callback must be a tuple of size 2");
|
|
|
|
|
if (! PyCallable_Check(PyTuple_GetItem($input, 1)))
|
|
|
|
|
return PyErr_Format(PyExc_TypeError, "second item must be callable");
|
2016-10-28 20:45:49 +00:00
|
|
|
|
$1 = _gpg_assuan_data_cb;
|
2016-07-28 10:40:54 +00:00
|
|
|
|
$2 = $input;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
%typemap(in) (gpgme_assuan_inquire_cb_t inq_cb, void *inq_cb_value) {
|
|
|
|
|
if ($input == Py_None)
|
|
|
|
|
$1 = $2 = NULL;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (! PyTuple_Check($input))
|
|
|
|
|
return PyErr_Format(PyExc_TypeError, "callback must be a tuple");
|
|
|
|
|
if (PyTuple_Size($input) != 2)
|
|
|
|
|
return PyErr_Format(PyExc_TypeError,
|
|
|
|
|
"callback must be a tuple of size 2");
|
|
|
|
|
if (! PyCallable_Check(PyTuple_GetItem($input, 1)))
|
|
|
|
|
return PyErr_Format(PyExc_TypeError, "second item must be callable");
|
2016-10-28 20:45:49 +00:00
|
|
|
|
$1 = _gpg_assuan_inquire_cb;
|
2016-07-28 10:40:54 +00:00
|
|
|
|
$2 = $input;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
%typemap(in) (gpgme_assuan_status_cb_t stat_cb, void *stat_cb_value) {
|
|
|
|
|
if ($input == Py_None)
|
|
|
|
|
$1 = $2 = NULL;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (! PyTuple_Check($input))
|
|
|
|
|
return PyErr_Format(PyExc_TypeError, "callback must be a tuple");
|
|
|
|
|
if (PyTuple_Size($input) != 2)
|
|
|
|
|
return PyErr_Format(PyExc_TypeError,
|
|
|
|
|
"callback must be a tuple of size 2");
|
|
|
|
|
if (! PyCallable_Check(PyTuple_GetItem($input, 1)))
|
|
|
|
|
return PyErr_Format(PyExc_TypeError, "second item must be callable");
|
2016-10-28 20:45:49 +00:00
|
|
|
|
$1 = _gpg_assuan_status_cb;
|
2016-07-28 10:40:54 +00:00
|
|
|
|
$2 = $input;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-03 22:12:37 +00:00
|
|
|
|
|
|
|
|
|
/* With SWIG, you can define default arguments for parameters.
|
|
|
|
|
* While it's legal in C++ it is not in C, so we cannot change the
|
|
|
|
|
* already existing gpgme.h. We need, however, to declare the function
|
|
|
|
|
* *before* SWIG loads it from gpgme.h. Hence, we define it here. */
|
|
|
|
|
gpgme_error_t gpgme_op_keylist_start (gpgme_ctx_t ctx,
|
|
|
|
|
const char *pattern="",
|
|
|
|
|
int secret_only=0);
|
|
|
|
|
|
2017-08-22 15:48:25 +00:00
|
|
|
|
/* The whence argument is surprising in Python-land,
|
|
|
|
|
because BytesIO or StringIO objects do not require it.
|
|
|
|
|
It defaults to SEEK_SET. Let's do that for Data objects, too */
|
|
|
|
|
off_t gpgme_data_seek (gpgme_data_t dh, off_t offset, int whence=SEEK_SET);
|
|
|
|
|
|
2016-05-31 14:21:06 +00:00
|
|
|
|
/* Include the unmodified <gpgme.h> for cc, and the cleaned-up local
|
|
|
|
|
version for SWIG. We do, however, want to hide certain fields on
|
|
|
|
|
some structs, which we provide prior to including the version for
|
|
|
|
|
SWIG. */
|
2016-06-08 15:56:33 +00:00
|
|
|
|
%{
|
2016-09-26 09:35:40 +00:00
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-06-08 15:56:33 +00:00
|
|
|
|
#include <gpgme.h>
|
|
|
|
|
%}
|
2016-05-31 14:21:06 +00:00
|
|
|
|
|
|
|
|
|
/* This is for notations, where we want to hide the length fields, and
|
2018-09-20 15:28:25 +00:00
|
|
|
|
* the unused bit field block. We silence the warning. */
|
|
|
|
|
%warnfilter(302) _gpgme_sig_notation;
|
2016-05-31 14:21:06 +00:00
|
|
|
|
struct _gpgme_sig_notation
|
|
|
|
|
{
|
|
|
|
|
struct _gpgme_sig_notation *next;
|
|
|
|
|
|
|
|
|
|
/* If NAME is a null pointer, then VALUE contains a policy URL
|
|
|
|
|
rather than a notation. */
|
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
|
|
/* The value of the notation data. */
|
|
|
|
|
char *value;
|
|
|
|
|
|
|
|
|
|
/* The accumulated flags. */
|
|
|
|
|
gpgme_sig_notation_flags_t flags;
|
|
|
|
|
|
|
|
|
|
/* Notation data is human-readable. */
|
|
|
|
|
unsigned int human_readable : 1;
|
|
|
|
|
|
|
|
|
|
/* Notation data is critical. */
|
|
|
|
|
unsigned int critical : 1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Now include our local modified version. Any structs defined above
|
|
|
|
|
are ignored. */
|
2016-09-26 09:35:40 +00:00
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
%include "config.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2015-05-05 17:09:44 +00:00
|
|
|
|
%include "gpgme.h"
|
|
|
|
|
|
2016-05-24 15:22:08 +00:00
|
|
|
|
%include "errors.i"
|
2015-05-05 17:09:44 +00:00
|
|
|
|
|
2016-09-26 14:45:21 +00:00
|
|
|
|
/* Generating and handling pointers-to-pointers. */
|
2015-05-05 17:09:44 +00:00
|
|
|
|
|
|
|
|
|
%pointer_functions(gpgme_ctx_t, gpgme_ctx_t_p);
|
|
|
|
|
%pointer_functions(gpgme_data_t, gpgme_data_t_p);
|
|
|
|
|
%pointer_functions(gpgme_key_t, gpgme_key_t_p);
|
|
|
|
|
%pointer_functions(gpgme_error_t, gpgme_error_t_p);
|
|
|
|
|
%pointer_functions(gpgme_trust_item_t, gpgme_trust_item_t_p);
|
|
|
|
|
%pointer_functions(gpgme_engine_info_t, gpgme_engine_info_t_p);
|
|
|
|
|
|
2016-09-26 14:45:21 +00:00
|
|
|
|
/* Helper functions. */
|
2015-05-05 17:09:44 +00:00
|
|
|
|
|
|
|
|
|
%{
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
%}
|
|
|
|
|
FILE *fdopen(int fildes, const char *mode);
|
|
|
|
|
|
2016-07-28 08:20:20 +00:00
|
|
|
|
/* We include both headers in the generated c code... */
|
2015-05-05 17:09:44 +00:00
|
|
|
|
%{
|
|
|
|
|
#include "helpers.h"
|
2016-07-28 08:20:20 +00:00
|
|
|
|
#include "private.h"
|
2016-06-08 15:56:33 +00:00
|
|
|
|
|
2016-07-28 12:51:20 +00:00
|
|
|
|
/* SWIG runtime support for helpers.c */
|
2016-06-08 15:56:33 +00:00
|
|
|
|
PyObject *
|
2016-10-28 20:45:49 +00:00
|
|
|
|
_gpg_wrap_gpgme_data_t(gpgme_data_t data)
|
2016-06-08 15:56:33 +00:00
|
|
|
|
{
|
2016-12-20 17:01:27 +00:00
|
|
|
|
/*
|
|
|
|
|
* If SWIG is invoked without -builtin, the macro SWIG_NewPointerObj
|
|
|
|
|
* expects a variable named "self".
|
|
|
|
|
*
|
|
|
|
|
* XXX: It is not quite clear why passing NULL as self is okay, but
|
|
|
|
|
* it works with -builtin, and it seems to work just fine without
|
|
|
|
|
* it too.
|
|
|
|
|
*/
|
|
|
|
|
PyObject* self = NULL;
|
|
|
|
|
(void) self;
|
|
|
|
|
return SWIG_NewPointerObj(data, SWIGTYPE_p_gpgme_data, 0);
|
2016-06-08 15:56:33 +00:00
|
|
|
|
}
|
2016-06-13 17:16:30 +00:00
|
|
|
|
|
|
|
|
|
gpgme_ctx_t
|
2016-10-28 20:45:49 +00:00
|
|
|
|
_gpg_unwrap_gpgme_ctx_t(PyObject *wrapped)
|
2016-06-13 17:16:30 +00:00
|
|
|
|
{
|
|
|
|
|
gpgme_ctx_t result;
|
|
|
|
|
if (SWIG_ConvertPtr(wrapped,
|
|
|
|
|
(void **) &result,
|
|
|
|
|
SWIGTYPE_p_gpgme_context,
|
|
|
|
|
SWIG_POINTER_EXCEPTION) == -1)
|
|
|
|
|
return NULL;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2015-05-05 17:09:44 +00:00
|
|
|
|
%}
|
2016-06-08 15:56:33 +00:00
|
|
|
|
|
2016-07-28 08:20:20 +00:00
|
|
|
|
/* ... but only the public definitions here. They will be exposed to
|
|
|
|
|
the Python world, so let's be careful. */
|
2015-05-05 17:09:44 +00:00
|
|
|
|
%include "helpers.h"
|
2016-12-20 17:02:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
%define genericrepr(cls)
|
|
|
|
|
%pythoncode %{
|
|
|
|
|
def __repr__(self):
|
|
|
|
|
names = [name for name in dir(self)
|
|
|
|
|
if not name.startswith("_") and name != "this"]
|
|
|
|
|
props = ", ".join(("{}={!r}".format(name, getattr(self, name))
|
|
|
|
|
for name in names)
|
|
|
|
|
)
|
|
|
|
|
return "cls({})".format(props)
|
|
|
|
|
%}
|
|
|
|
|
|
|
|
|
|
%enddef
|
|
|
|
|
|
|
|
|
|
%extend _gpgme_key {
|
|
|
|
|
genericrepr(Key)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
%extend _gpgme_subkey {
|
|
|
|
|
genericrepr(SubKey)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
%extend _gpgme_key_sig {
|
|
|
|
|
genericrepr(KeySig)
|
|
|
|
|
};
|
2017-02-14 14:55:20 +00:00
|
|
|
|
|
|
|
|
|
%extend _gpgme_user_id {
|
|
|
|
|
genericrepr(UID)
|
|
|
|
|
};
|
2017-02-17 16:07:05 +00:00
|
|
|
|
|
|
|
|
|
%extend _gpgme_tofu_info {
|
|
|
|
|
genericrepr(TofuInfo)
|
|
|
|
|
};
|