melib/gpgme bindings renewal

Regenerate libgpgme bindings for 32bit and 64bit targets separately.

This fixes the gpgme bindings tests failing for 32bit targets (which
prior to this commit where cfg'd to run only on x86-64 with #[cfg(target_arch = "x86_64")]

Tests confirm passing with:

    cross test --target i686-unknown-linux-gnu --all-targets --all -- --skip test_cli_subcommands

Note: We don't currently test on 32bit arches on CI, failure was spotted
on downstream Debian's build servers

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
This commit is contained in:
Manos Pitsidianakis 2024-11-22 18:27:49 +02:00
parent 4be6936026
commit 7f8f1cf65f
No known key found for this signature in database
GPG key ID: 7729C7707F7E09D0
9 changed files with 10603 additions and 5468 deletions

32
melib/src/gpgme/README.md Normal file
View file

@ -0,0 +1,32 @@
<!-- SPDX-License-Identifier: EUPL-1.2 OR GPL-3.0-or-later -->
# Interfacing with `libgpgme`
In order to support both 32-bit and 64-bit compilation targets, the generated
bindings for `libgpgme` have been generated twice, once on an 64-bit host and
once on an 32-bit host (`arm-unknown-linux-gnueabihf` in specific).
There are two shell scripts in this directory:
- `./bindgen-gpgme-funcs.sh`: This script invokes `bindgen` CLI to generate **only** bindings for the
functions we need from `libgpgme`.
The output is included inside `./bindings.rs` and wrapped with a declarative
macro that converts the function declarations into type definitions, because this is the only way we
can access functions via symbols with the `libloading` crate.
Otherwise, the conversion would have to be done manually.
Note that running this script to 32-bit and 64-bit hosts should have the same output.
- `./bindgen-gpgme-rest.sh`: This script invokes `bindgen` CLI to generate
bindings for types and global variables from the `libgpgme` header files.
This part is where target pointer width is important, so as a result we have
checked in two source files: `./bindings_rest.rs` for the "normal" world and
`./bindings_rest_32.rs` for the still 32-bit world.
`./bindings.rs` includes the correct version based on the `target_pointer_width` value at compile time.
Is this the best we can do? No, but it's the best we can do for now.
*NOTE*: Generating bindings with `bindgen` on 32-bit hosts should require
appending `-- -D_FILE_OFFSET_BITS=64` at the `bindgen` invocation in those
scripts; the `-- [...]` part means these arguments get redirected to `clang`,
and what happens is we define a preprocessor symbol `_FILE_OFFSET_BITS` with
the value `64`.

View file

@ -0,0 +1,73 @@
#!/bin/zsh
# SPDX-License-Identifier: EUPL-1.2 OR GPL-3.0-or-later
# Find out which functions we call with:
#
# rg call melib/src/gpgme | sed -r -e 's/^.+, (gpgme_[^)]+)[)].*$/\1/p' | sort | sort -u
bindgen \
-o bindings_funcs.rs \
--raw-line "// SPDX-License-Identifier: EUPL-1.2 OR GPL-3.0-or-later" \
--raw-line "" \
--raw-line "" \
--raw-line "convert_to_typedefs! {" \
--generate "functions" \
--generate-block \
--rust-target "1.68" \
--use-core \
--rustfmt-configuration-file `realpath ../../../rustfmt.toml` \
--merge-extern-blocks \
--sort-semantically \
--flexarray-dst \
--wrap-unsafe-ops \
--no-prepend-enum-name \
--blocklist-type FILE \
--blocklist-type _IO_FILE \
--blocklist-type _IO_lock_t \
--allowlist-function gpgme_check_version \
--allowlist-function gpgme_ctx_get_engine_info \
--allowlist-function gpgme_ctx_set_engine_info \
--allowlist-function gpgme_data_new \
--allowlist-function gpgme_data_new_from_file \
--allowlist-function gpgme_data_new_from_mem \
--allowlist-function gpgme_data_read \
--allowlist-function gpgme_data_release \
--allowlist-function gpgme_data_seek \
--allowlist-function gpgme_data_write \
--allowlist-function gpgme_get_armor \
--allowlist-function gpgme_get_ctx_flag \
--allowlist-function gpgme_get_offline \
--allowlist-function gpgme_get_pinentry_mode \
--allowlist-function gpgme_key_ref \
--allowlist-function gpgme_key_unref \
--allowlist-function gpgme_new \
--allowlist-function gpgme_op_decrypt_result \
--allowlist-function gpgme_op_decrypt_start \
--allowlist-function gpgme_op_encrypt_result \
--allowlist-function gpgme_op_encrypt_start \
--allowlist-function gpgme_op_import \
--allowlist-function gpgme_op_import_result \
--allowlist-function gpgme_op_keylist_end \
--allowlist-function gpgme_op_keylist_start \
--allowlist-function gpgme_op_sign_start \
--allowlist-function gpgme_op_verify_result \
--allowlist-function gpgme_op_verify_start \
--allowlist-function gpgme_release \
--allowlist-function gpgme_set_armor \
--allowlist-function gpgme_set_ctx_flag \
--allowlist-function gpgme_set_io_cbs \
--allowlist-function gpgme_set_offline \
--allowlist-function gpgme_set_passphrase_cb \
--allowlist-function gpgme_set_pinentry_mode \
--allowlist-function gpgme_set_protocol \
--allowlist-function gpgme_signers_add \
--allowlist-function gpgme_signers_clear \
--allowlist-function gpgme_strerror_r \
--allowlist-function gpgme_strerror \
--no-size_t-is-usize \
--disable-header-comment \
--emit-diagnostics \
--experimental \
/usr/include/gpgme.h
sed --in-place -e 's/\s*extern "C" [{]//' bindings_funcs.rs

View file

@ -0,0 +1,56 @@
#!/bin/zsh
# SPDX-License-Identifier: EUPL-1.2 OR GPL-3.0-or-later
bindgen \
-o bindings_rest.rs \
--raw-line "// SPDX-License-Identifier: EUPL-1.2 OR GPL-3.0-or-later" \
--ignore-functions \
--bitfield-enum 'gpgme_encrypt_flags_t' \
--bitfield-enum 'gpgme_decrypt_flags_t' \
--bitfield-enum 'gpgme_sigsum_t' \
--impl-debug \
--impl-partialeq \
--with-derive-default \
--with-derive-hash \
--with-derive-partialeq \
--with-derive-partialord \
--with-derive-eq \
--with-derive-ord \
--generate-block \
--generate-cstr \
--rust-target "1.68" \
--use-core \
--rustfmt-configuration-file `realpath ../../../rustfmt.toml` \
--merge-extern-blocks \
--sort-semantically \
--flexarray-dst \
--wrap-unsafe-ops \
--no-prepend-enum-name \
--rustified-enum 'gpgme_status_code_t.*' \
--rustified-enum 'gpg_err_source_t.*' \
--rustified-enum 'gpg_err_code_t.*' \
--rustified-enum 'gpgme_data_encoding_t.*' \
--rustified-enum 'gpgme_data_type_t' \
--rustified-enum 'gpgme_pubkey_algo_t' \
--rustified-enum 'gpgme_hash_algo_t' \
--rustified-enum 'gpgme_sig_mode_t' \
--rustified-enum 'gpgme_validity_t' \
--rustified-enum 'gpgme_tofu_policy_t' \
--rustified-enum 'gpgme_keyorg_t' \
--rustified-enum 'gpgme_protocol_t' \
--rustified-enum 'gpgme_pinentry_mode_t' \
--rustified-enum 'gpgme_event_io_t' \
--rustified-enum 'gpgme_conf_level_t' \
--rustified-enum 'gpgme_conf_type_t' \
--rustified-enum '_gpgme_sig_stat_t' \
--rustified-enum '_gpgme_attr_t' \
--blocklist-type FILE \
--blocklist-type _IO_FILE \
--blocklist-type _IO_lock_t \
--allowlist-var GPGME_VERSION \
--allowlist-type gpgme_io_event_done_data \
--no-size_t-is-usize \
--emit-diagnostics \
--experimental \
--allowlist-file /usr/include/gpgme.h \
/usr/include/gpgme.h

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,110 @@
// SPDX-License-Identifier: EUPL-1.2 OR GPL-3.0-or-later
convert_to_typedefs! {
pub fn gpgme_strerror(err: gpgme_error_t) -> *const ::core::ffi::c_char;
pub fn gpgme_strerror_r(
err: gpg_error_t,
buf: *mut ::core::ffi::c_char,
buflen: size_t,
) -> ::core::ffi::c_int;
pub fn gpgme_new(ctx: *mut gpgme_ctx_t) -> gpgme_error_t;
pub fn gpgme_release(ctx: gpgme_ctx_t);
pub fn gpgme_set_ctx_flag(
ctx: gpgme_ctx_t,
name: *const ::core::ffi::c_char,
value: *const ::core::ffi::c_char,
) -> gpgme_error_t;
pub fn gpgme_get_ctx_flag(
ctx: gpgme_ctx_t,
name: *const ::core::ffi::c_char,
) -> *const ::core::ffi::c_char;
pub fn gpgme_set_protocol(ctx: gpgme_ctx_t, proto: gpgme_protocol_t) -> gpgme_error_t;
pub fn gpgme_set_armor(ctx: gpgme_ctx_t, yes: ::core::ffi::c_int);
pub fn gpgme_get_armor(ctx: gpgme_ctx_t) -> ::core::ffi::c_int;
pub fn gpgme_set_offline(ctx: gpgme_ctx_t, yes: ::core::ffi::c_int);
pub fn gpgme_get_offline(ctx: gpgme_ctx_t) -> ::core::ffi::c_int;
pub fn gpgme_set_pinentry_mode(ctx: gpgme_ctx_t, mode: gpgme_pinentry_mode_t) -> gpgme_error_t;
pub fn gpgme_get_pinentry_mode(ctx: gpgme_ctx_t) -> gpgme_pinentry_mode_t;
pub fn gpgme_set_passphrase_cb(
ctx: gpgme_ctx_t,
cb: gpgme_passphrase_cb_t,
hook_value: *mut ::core::ffi::c_void,
);
pub fn gpgme_ctx_get_engine_info(ctx: gpgme_ctx_t) -> gpgme_engine_info_t;
pub fn gpgme_ctx_set_engine_info(
ctx: gpgme_ctx_t,
proto: gpgme_protocol_t,
file_name: *const ::core::ffi::c_char,
home_dir: *const ::core::ffi::c_char,
) -> gpgme_error_t;
pub fn gpgme_signers_clear(ctx: gpgme_ctx_t);
pub fn gpgme_signers_add(ctx: gpgme_ctx_t, key: gpgme_key_t) -> gpgme_error_t;
pub fn gpgme_set_io_cbs(ctx: gpgme_ctx_t, io_cbs: gpgme_io_cbs_t);
pub fn gpgme_data_read(
dh: gpgme_data_t,
buffer: *mut ::core::ffi::c_void,
size: size_t,
) -> ssize_t;
pub fn gpgme_data_write(
dh: gpgme_data_t,
buffer: *const ::core::ffi::c_void,
size: size_t,
) -> ssize_t;
pub fn gpgme_data_seek(dh: gpgme_data_t, offset: off_t, whence: ::core::ffi::c_int) -> off_t;
pub fn gpgme_data_new(r_dh: *mut gpgme_data_t) -> gpgme_error_t;
pub fn gpgme_data_release(dh: gpgme_data_t);
pub fn gpgme_data_new_from_mem(
r_dh: *mut gpgme_data_t,
buffer: *const ::core::ffi::c_char,
size: size_t,
copy: ::core::ffi::c_int,
) -> gpgme_error_t;
pub fn gpgme_data_new_from_file(
r_dh: *mut gpgme_data_t,
fname: *const ::core::ffi::c_char,
copy: ::core::ffi::c_int,
) -> gpgme_error_t;
pub fn gpgme_key_ref(key: gpgme_key_t);
pub fn gpgme_key_unref(key: gpgme_key_t);
pub fn gpgme_op_encrypt_result(ctx: gpgme_ctx_t) -> gpgme_encrypt_result_t;
pub fn gpgme_op_encrypt_start(
ctx: gpgme_ctx_t,
recp: *mut gpgme_key_t,
flags: gpgme_encrypt_flags_t,
plain: gpgme_data_t,
cipher: gpgme_data_t,
) -> gpgme_error_t;
pub fn gpgme_op_decrypt_result(ctx: gpgme_ctx_t) -> gpgme_decrypt_result_t;
pub fn gpgme_op_decrypt_start(
ctx: gpgme_ctx_t,
cipher: gpgme_data_t,
plain: gpgme_data_t,
) -> gpgme_error_t;
pub fn gpgme_op_sign_start(
ctx: gpgme_ctx_t,
plain: gpgme_data_t,
sig: gpgme_data_t,
flags: gpgme_sig_mode_t,
) -> gpgme_error_t;
pub fn gpgme_op_verify_result(ctx: gpgme_ctx_t) -> gpgme_verify_result_t;
pub fn gpgme_op_verify_start(
ctx: gpgme_ctx_t,
sig: gpgme_data_t,
signed_text: gpgme_data_t,
plaintext: gpgme_data_t,
) -> gpgme_error_t;
pub fn gpgme_op_import_result(ctx: gpgme_ctx_t) -> gpgme_import_result_t;
pub fn gpgme_op_import(ctx: gpgme_ctx_t, keydata: gpgme_data_t) -> gpgme_error_t;
pub fn gpgme_op_keylist_start(
ctx: gpgme_ctx_t,
pattern: *const ::core::ffi::c_char,
secret_only: ::core::ffi::c_int,
) -> gpgme_error_t;
pub fn gpgme_op_keylist_end(ctx: gpgme_ctx_t) -> gpgme_error_t;
pub fn gpgme_check_version(
req_version: *const ::core::ffi::c_char,
) -> *const ::core::ffi::c_char;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -27,7 +27,7 @@ use std::{
ptr::NonNull,
};
use super::*;
use super::{bindings::gpgme_io_event_done_data, *};
#[derive(Debug)]
#[repr(C)]
@ -142,14 +142,14 @@ pub unsafe extern "C" fn gpgme_event_io_cb(
r#type: gpgme_event_io_t,
type_data: *mut c_void,
) {
if r#type == gpgme_event_io_t_GPGME_EVENT_START {
if r#type == gpgme_event_io_t::GPGME_EVENT_START {
return;
}
// SAFETY: This is the iostate reference that was leaked in `Context::new`.
let io_state: IoStateWrapper = unsafe { IoStateWrapper::from_raw(data) };
if r#type == gpgme_event_io_t_GPGME_EVENT_DONE {
if r#type == gpgme_event_io_t::GPGME_EVENT_DONE {
let Some(status) = NonNull::new(type_data.cast::<gpgme_io_event_done_data>()) else {
log::error!("gpgme_event_io_cb DONE event with NULL type_data. This is a gpgme bug.",);
return;
@ -166,7 +166,7 @@ pub unsafe extern "C" fn gpgme_event_io_cb(
return;
}
if r#type == gpgme_event_io_t_GPGME_EVENT_NEXT_KEY {
if r#type == gpgme_event_io_t::GPGME_EVENT_NEXT_KEY {
let Some(ptr) = NonNull::new(type_data.cast::<_gpgme_key>()) else {
log::error!(
"gpgme_event_io_cb NEXT_KEY event with NULL type_data. This is a gpgme bug.",
@ -181,7 +181,7 @@ pub unsafe extern "C" fn gpgme_event_io_cb(
log::error!(
"gpgme_event_io_cb called with unexpected event type: {}",
r#type
r#type as u32
);
}
@ -190,7 +190,12 @@ impl Read for Data {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let result = unsafe {
let (buf, len) = (buf.as_mut_ptr() as *mut _, buf.len());
call!(self.lib, gpgme_data_read)(self.inner.as_ptr(), buf, len)
call!(self.lib, gpgme_data_read)(
self.inner.as_ptr(),
buf,
len.try_into()
.map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?,
)
};
if result >= 0 {
Ok(result as usize)
@ -205,7 +210,12 @@ impl Write for Data {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let result = unsafe {
let (buf, len) = (buf.as_ptr() as *const _, buf.len());
call!(self.lib, gpgme_data_write)(self.inner.as_ptr(), buf, len)
call!(self.lib, gpgme_data_write)(
self.inner.as_ptr(),
buf,
len.try_into()
.map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?,
)
};
if result >= 0 {
Ok(result as usize)
@ -233,10 +243,13 @@ impl Seek for Data {
io::SeekFrom::Current(off) => (off, libc::SEEK_CUR),
};
let result = unsafe {
// Allow .into() for both 32bit and 64bit targets
#[allow(clippy::useless_conversion)]
call!(self.lib, gpgme_data_seek)(
self.inner.as_ptr(),
libc::off_t::try_from(off)
.map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?,
.map_err(|_| io::Error::from_raw_os_error(libc::EOVERFLOW))?
.into(),
whence,
)
};

View file

@ -69,6 +69,14 @@ macro_rules! call {
}};
}
#[allow(
non_camel_case_types,
non_upper_case_globals,
non_snake_case,
clippy::useless_transmute,
clippy::too_many_arguments,
clippy::use_self
)]
pub mod bindings;
#[cfg(test)]
mod tests;
@ -249,11 +257,10 @@ impl Context {
}
},
);
if unsafe { call!(&lib, gpgme_check_version)(GPGME_VERSION.as_bytes().as_ptr()) }.is_null()
{
if unsafe { call!(&lib, gpgme_check_version)(GPGME_VERSION.as_ptr()) }.is_null() {
return Err(Error::new(format!(
"Could not use libgpgme: requested version compatible with {} but got {}",
GPGME_VERSION,
GPGME_VERSION.to_string_lossy(),
unsafe {
CStr::from_ptr(call!(&lib, gpgme_check_version)(std::ptr::null_mut()))
.to_string_lossy()
@ -437,7 +444,10 @@ impl Context {
call!(&self.inner.lib, gpgme_data_new_from_mem)(
&mut ptr,
bytes.as_ptr() as *const ::std::os::raw::c_char,
bytes.len(),
bytes
.len()
.try_into()
.map_err(|_| std::io::Error::from_raw_os_error(libc::EOVERFLOW))?,
1,
),
)?;
@ -465,7 +475,7 @@ impl Context {
let bytes = Pin::new(os_str.as_bytes().to_vec());
let mut ptr = std::ptr::null_mut();
unsafe {
let ret: GpgmeError = call!(&self.inner.lib, gpgme_data_new_from_file)(
let ret: gpgme_error_t = call!(&self.inner.lib, gpgme_data_new_from_file)(
&mut ptr,
bytes.as_ptr() as *const ::std::os::raw::c_char,
1,
@ -719,7 +729,7 @@ impl Context {
self.inner.ptr.as_ptr(),
text.inner.as_mut(),
sig,
gpgme_sig_mode_t_GPGME_SIG_MODE_DETACH,
gpgme_sig_mode_t::GPGME_SIG_MODE_DETACH,
),
)?;
}
@ -988,9 +998,9 @@ impl Context {
call!(&self.inner.lib, gpgme_op_encrypt_start)(
self.inner.ptr.as_ptr(),
raw_keys.as_mut_slice().as_mut_ptr(),
gpgme_encrypt_flags_t_GPGME_ENCRYPT_NO_ENCRYPT_TO
| gpgme_encrypt_flags_t_GPGME_ENCRYPT_NO_COMPRESS
| gpgme_encrypt_flags_t_GPGME_ENCRYPT_ALWAYS_TRUST,
gpgme_encrypt_flags_t::GPGME_ENCRYPT_NO_ENCRYPT_TO
| gpgme_encrypt_flags_t::GPGME_ENCRYPT_NO_COMPRESS
| gpgme_encrypt_flags_t::GPGME_ENCRYPT_ALWAYS_TRUST,
plain.inner.as_mut(),
cipher,
),
@ -1152,7 +1162,7 @@ impl Context {
&self.inner.lib,
call!(&self.inner.lib, gpgme_ctx_set_engine_info)(
self.inner.ptr.as_ptr(),
protocol as u32,
protocol.into(),
file_name
.as_ref()
.map(|c| c.as_ptr())
@ -1173,7 +1183,7 @@ impl Context {
&self.inner.lib,
call!(&self.inner.lib, gpgme_set_protocol)(
self.inner.ptr.as_ptr(),
protocol as u32,
protocol.into(),
),
)?;
}
@ -1216,9 +1226,9 @@ impl Context {
call!(&self.inner.lib, gpgme_set_pinentry_mode)(
self.inner.ptr.as_ptr(),
if cb.is_none() {
gpgme_pinentry_mode_t_GPGME_PINENTRY_MODE_DEFAULT
gpgme_pinentry_mode_t::GPGME_PINENTRY_MODE_DEFAULT
} else {
gpgme_pinentry_mode_t_GPGME_PINENTRY_MODE_LOOPBACK
gpgme_pinentry_mode_t::GPGME_PINENTRY_MODE_LOOPBACK
},
),
)?;
@ -1260,22 +1270,54 @@ pub enum Protocol {
impl From<u32> for Protocol {
fn from(val: u32) -> Self {
match val {
0 => Self::OpenPGP,
1 => Self::CMS,
2 => Self::GPGCONF,
3 => Self::ASSUAN,
4 => Self::G13,
5 => Self::UISERVER,
6 => Self::SPAWN,
254 => Self::DEFAULT,
val if val == gpgme_protocol_t::GPGME_PROTOCOL_OpenPGP as u32 => Self::OpenPGP,
val if val == gpgme_protocol_t::GPGME_PROTOCOL_CMS as u32 => Self::CMS,
val if val == gpgme_protocol_t::GPGME_PROTOCOL_GPGCONF as u32 => Self::GPGCONF,
val if val == gpgme_protocol_t::GPGME_PROTOCOL_ASSUAN as u32 => Self::ASSUAN,
val if val == gpgme_protocol_t::GPGME_PROTOCOL_G13 as u32 => Self::G13,
val if val == gpgme_protocol_t::GPGME_PROTOCOL_UISERVER as u32 => Self::UISERVER,
val if val == gpgme_protocol_t::GPGME_PROTOCOL_SPAWN as u32 => Self::SPAWN,
val if val == gpgme_protocol_t::GPGME_PROTOCOL_DEFAULT as u32 => Self::DEFAULT,
_ => Self::UNKNOWN,
}
}
}
fn gpgme_error_to_string(lib: &libloading::Library, error_code: GpgmeError) -> String {
const ERR_MAX_LEN: usize = 256;
let mut buf: Vec<u8> = vec![0; ERR_MAX_LEN];
impl From<gpgme_protocol_t> for Protocol {
fn from(val: gpgme_protocol_t) -> Self {
match val {
gpgme_protocol_t::GPGME_PROTOCOL_OpenPGP => Self::OpenPGP,
gpgme_protocol_t::GPGME_PROTOCOL_CMS => Self::CMS,
gpgme_protocol_t::GPGME_PROTOCOL_GPGCONF => Self::GPGCONF,
gpgme_protocol_t::GPGME_PROTOCOL_ASSUAN => Self::ASSUAN,
gpgme_protocol_t::GPGME_PROTOCOL_G13 => Self::G13,
gpgme_protocol_t::GPGME_PROTOCOL_UISERVER => Self::UISERVER,
gpgme_protocol_t::GPGME_PROTOCOL_SPAWN => Self::SPAWN,
gpgme_protocol_t::GPGME_PROTOCOL_DEFAULT => Self::DEFAULT,
gpgme_protocol_t::GPGME_PROTOCOL_UNKNOWN => Self::UNKNOWN,
}
}
}
impl From<Protocol> for gpgme_protocol_t {
fn from(val: Protocol) -> Self {
match val {
Protocol::OpenPGP => Self::GPGME_PROTOCOL_OpenPGP,
Protocol::CMS => Self::GPGME_PROTOCOL_CMS,
Protocol::GPGCONF => Self::GPGME_PROTOCOL_GPGCONF,
Protocol::ASSUAN => Self::GPGME_PROTOCOL_ASSUAN,
Protocol::G13 => Self::GPGME_PROTOCOL_G13,
Protocol::UISERVER => Self::GPGME_PROTOCOL_UISERVER,
Protocol::SPAWN => Self::GPGME_PROTOCOL_SPAWN,
Protocol::DEFAULT => Self::GPGME_PROTOCOL_DEFAULT,
Protocol::UNKNOWN => Self::GPGME_PROTOCOL_UNKNOWN,
}
}
}
fn gpgme_error_to_string(lib: &libloading::Library, error_code: gpgme_error_t) -> String {
const ERR_MAX_LEN: bindings::size_t = 256;
let mut buf: Vec<u8> = vec![0; ERR_MAX_LEN as usize];
unsafe {
call!(lib, gpgme_strerror_r)(
error_code,
@ -1290,7 +1332,7 @@ fn gpgme_error_to_string(lib: &libloading::Library, error_code: GpgmeError) -> S
.unwrap_or_else(|err| String::from_utf8_lossy(&err.into_bytes()).to_string())
}
fn gpgme_error_try(lib: &libloading::Library, error_code: GpgmeError) -> Result<()> {
fn gpgme_error_try(lib: &libloading::Library, error_code: gpgme_error_t) -> Result<()> {
if error_code == 0 {
return Ok(());
}
@ -1337,7 +1379,7 @@ impl Drop for Data {
#[repr(C)]
struct GpgmeFd {
fd: Arc<ManuallyDrop<OwnedFd>>,
fnc: GpgmeIOCb,
fnc: gpgme_io_cb_t,
fnc_data: *mut c_void,
idx: usize,
write: bool,