summaryrefslogtreecommitdiffstats
path: root/melib
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2020-10-05 18:43:08 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2020-10-05 21:10:00 +0300
commit23ca41e3e878abb9e9206e984b6c1e1d2b905aaa (patch)
tree0a3c053b304fa349cfa999d3bdb2b1814ca7632a /melib
parentb9c07bacef256e781a2f6884f9e01f8f211d4741 (diff)
add libgpgme feature
Diffstat (limited to 'melib')
-rw-r--r--melib/Cargo.toml3
-rw-r--r--melib/src/email.rs3
-rw-r--r--melib/src/email/attachment_types.rs90
-rw-r--r--melib/src/email/attachments.rs140
-rw-r--r--melib/src/email/pgp.rs (renamed from melib/src/email/signatures.rs)21
-rw-r--r--melib/src/gpgme/bindings.rs10965
-rw-r--r--melib/src/gpgme/io.rs155
-rw-r--r--melib/src/gpgme/mod.rs798
-rw-r--r--melib/src/lib.rs31
9 files changed, 12150 insertions, 56 deletions
diff --git a/melib/Cargo.toml b/melib/Cargo.toml
index 72efcea4..f16b63fa 100644
--- a/melib/Cargo.toml
+++ b/melib/Cargo.toml
@@ -56,9 +56,9 @@ default = ["unicode_algorithms", "imap_backend", "maildir_backend", "mbox_backen
debug-tracing = []
deflate_compression = ["flate2", ]
+gpgme = []
http = ["isahc"]
http-static = ["isahc", "isahc/static-curl"]
-tls = ["native-tls"]
imap_backend = ["tls"]
jmap_backend = ["http", "serde_json"]
maildir_backend = ["notify", "memmap"]
@@ -66,5 +66,6 @@ mbox_backend = ["notify", "memmap"]
notmuch_backend = []
smtp = ["tls", "base64"]
sqlite3 = ["rusqlite", ]
+tls = ["native-tls"]
unicode_algorithms = ["unicode-segmentation"]
vcard = []
diff --git a/melib/src/email.rs b/melib/src/email.rs
index 6e31cdb0..5ebaa6ab 100644
--- a/melib/src/email.rs
+++ b/melib/src/email.rs
@@ -97,7 +97,7 @@ pub mod headers;
pub mod list_management;
pub mod mailto;
pub mod parser;
-pub mod signatures;
+pub mod pgp;
pub use address::{Address, MessageID, References, StrBuild, StrBuilder};
pub use attachments::{Attachment, AttachmentBuilder};
@@ -219,6 +219,7 @@ impl core::fmt::Debug for Envelope {
.field("Message-ID", &self.message_id_display())
.field("In-Reply-To", &self.in_reply_to_display())
.field("References", &self.references)
+ .field("Flags", &self.flags)
.field("Hash", &self.hash)
.finish()
}
diff --git a/melib/src/email/attachment_types.rs b/melib/src/email/attachment_types.rs
index 3d8afeb6..0dcf5dbb 100644
--- a/melib/src/email/attachment_types.rs
+++ b/melib/src/email/attachment_types.rs
@@ -135,6 +135,7 @@ impl Display for Charset {
pub enum MultipartType {
Alternative,
Digest,
+ Encrypted,
Mixed,
Related,
Signed,
@@ -148,13 +149,18 @@ impl Default for MultipartType {
impl Display for MultipartType {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
- match self {
- MultipartType::Alternative => write!(f, "multipart/alternative"),
- MultipartType::Digest => write!(f, "multipart/digest"),
- MultipartType::Mixed => write!(f, "multipart/mixed"),
- MultipartType::Related => write!(f, "multipart/related"),
- MultipartType::Signed => write!(f, "multipart/signed"),
- }
+ write!(
+ f,
+ "{}",
+ match self {
+ MultipartType::Alternative => "multipart/alternative",
+ MultipartType::Digest => "multipart/digest",
+ MultipartType::Encrypted => "multipart/encrypted",
+ MultipartType::Mixed => "multipart/mixed",
+ MultipartType::Related => "multipart/related",
+ MultipartType::Signed => "multipart/signed",
+ }
+ )
}
}
@@ -166,6 +172,8 @@ impl From<&[u8]> for MultipartType {
MultipartType::Alternative
} else if val.eq_ignore_ascii_case(b"digest") {
MultipartType::Digest
+ } else if val.eq_ignore_ascii_case(b"encrypted") {
+ MultipartType::Encrypted
} else if val.eq_ignore_ascii_case(b"signed") {
MultipartType::Signed
} else if val.eq_ignore_ascii_case(b"related") {
@@ -209,6 +217,74 @@ impl Default for ContentType {
}
}
+impl PartialEq<&str> for ContentType {
+ fn eq(&self, other: &&str) -> bool {
+ match (self, *other) {
+ (
+ ContentType::Text {
+ kind: Text::Plain, ..
+ },
+ "text/plain",
+ ) => true,
+ (
+ ContentType::Text {
+ kind: Text::Html, ..
+ },
+ "text/html",
+ ) => true,
+ (
+ ContentType::Multipart {
+ kind: MultipartType::Alternative,
+ ..
+ },
+ "multipart/alternative",
+ ) => true,
+ (
+ ContentType::Multipart {
+ kind: MultipartType::Digest,
+ ..
+ },
+ "multipart/digest",
+ ) => true,
+ (
+ ContentType::Multipart {
+ kind: MultipartType::Encrypted,
+ ..
+ },
+ "multipart/encrypted",
+ ) => true,
+ (
+ ContentType::Multipart {
+ kind: MultipartType::Mixed,
+ ..
+ },
+ "multipart/mixed",
+ ) => true,
+ (
+ ContentType::Multipart {
+ kind: MultipartType::Related,
+ ..
+ },
+ "multipart/related",
+ ) => true,
+ (
+ ContentType::Multipart {
+ kind: MultipartType::Signed,
+ ..
+ },
+ "multipart/signed",
+ ) => true,
+ (ContentType::PGPSignature, "application/pgp-signature") => true,
+ (ContentType::MessageRfc822, "message/rfc822") => true,
+ (ContentType::Other { tag, .. }, _) => {
+ other.eq_ignore_ascii_case(&String::from_utf8_lossy(&tag))
+ }
+ (ContentType::OctetStream { .. }, "application/octet-stream") => true,
+ _ => false,
+ }
+ }
+}
+
impl Display for ContentType {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
match self {
diff --git a/melib/src/email/attachments.rs b/melib/src/email/attachments.rs
index 65506737..6c6c4aa4 100644
--- a/melib/src/email/attachments.rs
+++ b/melib/src/email/attachments.rs
@@ -351,16 +351,14 @@ pub struct Attachment {
impl fmt::Debug for Attachment {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "Attachment {{\n content_type: {:?},\n content_transfer_encoding: {:?},\n raw: Vec of {} bytes\n, body:\n{}\n}}",
- self.content_type,
- self.content_transfer_encoding,
- self.raw.len(),
- {
- let mut text = Vec::with_capacity(4096);
- self.get_text_recursive(&mut text);
- std::str::from_utf8(&text).map(std::string::ToString::to_string).unwrap_or_else(|e| format!("Unicode error {}", e))
- }
- )
+ let mut text = Vec::with_capacity(4096);
+ self.get_text_recursive(&mut text);
+ f.debug_struct("Attachment")
+ .field("content_type", &self.content_type)
+ .field("content_transfer_encoding", &self.content_transfer_encoding)
+ .field("raw bytes length", &self.raw.len())
+ .field("body", &String::from_utf8_lossy(&text))
+ .finish()
}
}
@@ -371,44 +369,63 @@ impl fmt::Display for Attachment {
match Mail::new(self.body.display_bytes(&self.raw).to_vec(), None) {
Ok(wrapper) => write!(
f,
- "message/rfc822: {} - {} - {}",
+ "{} - {} - {} [message/rfc822] {}",
wrapper.date(),
wrapper.field_from_to_string(),
- wrapper.subject()
+ wrapper.subject(),
+ crate::Bytes(self.raw.len()),
+ ),
+ Err(err) => write!(
+ f,
+ "could not parse: {} [message/rfc822] {}",
+ err,
+ crate::Bytes(self.raw.len()),
),
- Err(e) => write!(f, "{}", e),
}
}
- ContentType::PGPSignature => write!(f, "pgp signature {}", self.mime_type()),
- ContentType::OctetStream { ref name } => {
- write!(f, "{}", name.clone().unwrap_or_else(|| self.mime_type()))
+ ContentType::PGPSignature => write!(f, "pgp signature [{}]", self.mime_type()),
+ ContentType::OctetStream { .. } | ContentType::Other { .. } => {
+ if let Some(name) = self.filename() {
+ write!(
+ f,
+ "\"{}\", [{}] {}",
+ name,
+ self.mime_type(),
+ crate::Bytes(self.raw.len())
+ )
+ } else {
+ write!(
+ f,
+ "Data attachment [{}] {}",
+ self.mime_type(),
+ crate::Bytes(self.raw.len())
+ )
+ }
}
- ContentType::Other {
- name: Some(ref name),
- ..
- } => write!(f, "\"{}\", [{}]", name, self.mime_type()),
- ContentType::Other { .. } => write!(f, "Data attachment of type {}", self.mime_type()),
- ContentType::Text { ref parameters, .. }
- if parameters
- .iter()
- .any(|(name, _)| name.eq_ignore_ascii_case(b"name")) =>
- {
- let name = String::from_utf8_lossy(
- parameters
- .iter()
- .find(|(name, _)| name.eq_ignore_ascii_case(b"name"))
- .map(|(_, value)| value)
- .unwrap(),
- );
- write!(f, "\"{}\", [{}]", name, self.mime_type())
+ ContentType::Text { .. } => {
+ if let Some(name) = self.filename() {
+ write!(
+ f,
+ "\"{}\", [{}] {}",
+ name,
+ self.mime_type(),
+ crate::Bytes(self.raw.len())
+ )
+ } else {
+ write!(
+ f,
+ "Text attachment [{}] {}",
+ self.mime_type(),
+ crate::Bytes(self.raw.len())
+ )
+ }
}
- ContentType::Text { .. } => write!(f, "Text attachment of type {}", self.mime_type()),
ContentType::Multipart {
parts: ref sub_att_vec,
..
} => write!(
f,
- "{} attachment with {} subs",
+ "{} attachment with {} parts",
self.mime_type(),
sub_att_vec.len()
),
@@ -627,6 +644,16 @@ impl Attachment {
}
}
+ pub fn is_encrypted(&self) -> bool {
+ match self.content_type {
+ ContentType::Multipart {
+ kind: MultipartType::Encrypted,
+ ..
+ } => true,
+ _ => false,
+ }
+ }
+
pub fn is_signed(&self) -> bool {
match self.content_type {
ContentType::Multipart {
@@ -641,7 +668,7 @@ impl Attachment {
let mut ret = String::with_capacity(2 * self.raw.len());
fn into_raw_helper(a: &Attachment, ret: &mut String) {
ret.push_str(&format!(
- "Content-Transfer-Encoding: {}\n",
+ "Content-Transfer-Encoding: {}\r\n",
a.content_transfer_encoding
));
match &a.content_type {
@@ -667,7 +694,7 @@ impl Attachment {
}
}
- ret.push_str("\n\n");
+ ret.push_str("\r\n\r\n");
ret.push_str(&String::from_utf8_lossy(a.body()));
}
ContentType::Multipart {
@@ -680,36 +707,36 @@ impl Attachment {
if *kind == MultipartType::Signed {
ret.push_str("; micalg=pgp-sha512; protocol=\"application/pgp-signature\"");
}
- ret.push('\n');
+ ret.push_str("\r\n");
- let boundary_start = format!("\n--{}\n", boundary);
+ let boundary_start = format!("\r\n--{}\r\n", boundary);
for p in parts {
ret.push_str(&boundary_start);
into_raw_helper(p, ret);
}
- ret.push_str(&format!("--{}--\n\n", boundary));
+ ret.push_str(&format!("--{}--\r\n\r\n", boundary));
}
ContentType::MessageRfc822 => {
- ret.push_str(&format!("Content-Type: {}\n\n", a.content_type));
+ ret.push_str(&format!("Content-Type: {}\r\n\r\n", a.content_type));
ret.push_str(&String::from_utf8_lossy(a.body()));
}
ContentType::PGPSignature => {
- ret.push_str(&format!("Content-Type: {}\n\n", a.content_type));
+ ret.push_str(&format!("Content-Type: {}\r\n\r\n", a.content_type));
ret.push_str(&String::from_utf8_lossy(a.body()));
}
ContentType::OctetStream { ref name } => {
if let Some(name) = name {
ret.push_str(&format!(
- "Content-Type: {}; name={}\n\n",
+ "Content-Type: {}; name={}\r\n\r\n",
a.content_type, name
));
} else {
- ret.push_str(&format!("Content-Type: {}\n\n", a.content_type));
+ ret.push_str(&format!("Content-Type: {}\r\n\r\n", a.content_type));
}
ret.push_str(&BASE64_MIME.encode(a.body()).trim());
}
_ => {
- ret.push_str(&format!("Content-Type: {}\n\n", a.content_type));
+ ret.push_str(&format!("Content-Type: {}\r\n\r\n", a.content_type));
ret.push_str(&String::from_utf8_lossy(a.body()));
}
}
@@ -752,9 +779,18 @@ impl Attachment {
h.eq_ignore_ascii_case(b"name") | h.eq_ignore_ascii_case(b"filename")
})
.map(|(_, v)| String::from_utf8_lossy(v).to_string()),
- ContentType::Other { name, .. } | ContentType::OctetStream { name, .. } => name.clone(),
+ ContentType::Other { .. } | ContentType::OctetStream { .. } => {
+ self.content_type.name().map(|s| s.to_string())
+ }
_ => None,
})
+ .map(|s| {
+ crate::email::parser::encodings::phrase(s.as_bytes(), false)
+ .map(|(_, v)| v)
+ .ok()
+ .and_then(|n| String::from_utf8(n).ok())
+ .unwrap_or_else(|| s)
+ })
.map(|n| n.replace(|c| std::path::is_separator(c) || c.is_ascii_control(), "_"))
}
}
@@ -806,6 +842,16 @@ fn decode_rec_helper<'a, 'b>(a: &'a Attachment, filter: &mut Option<Filter<'b>>)
vec.extend(decode_helper(a, filter));
vec
}
+ MultipartType::Encrypted => {
+ let mut vec = Vec::new();
+ for a in parts {
+ if a.content_type == "application/octet-stream" {
+ vec.extend(decode_rec_helper(a, filter));
+ }
+ }
+ vec.extend(decode_helper(a, filter));
+ vec
+ }
_ => {
let mut vec = Vec::new();
for a in parts {
diff --git a/melib/src/email/signatures.rs b/melib/src/email/pgp.rs
index 121434a5..d3dd2ced 100644
--- a/melib/src/email/signatures.rs
+++ b/melib/src/email/pgp.rs
@@ -134,3 +134,24 @@ pub fn verify_signature(a: &Attachment) -> Result<(Vec<u8>, &[u8])> {
)),
}
}
+
+#[derive(Debug, Clone, Default)]
+pub struct DecryptionMetadata {
+ pub recipients: Vec<Recipient>,
+ pub file_name: Option<String>,
+ pub session_key: Option<String>,
+ pub is_mime: bool,
+}
+
+#[derive(Debug, Clone)]
+pub struct Recipient {
+ pub keyid: Option<String>,
+ pub status: Result<()>,
+}
+
+#[derive(Debug, Clone, Default)]
+pub struct SignatureMetadata {
+ pub signatures: Vec<Recipient>,
+ pub file_name: Option<String>,
+ pub is_mime: bool,
+}
diff --git a/melib/src/gpgme/bindings.rs b/melib/src/gpgme/bindings.rs
new file mode 100644
index 00000000..e41abfa8
--- /dev/null
+++ b/melib/src/gpgme/bindings.rs
@@ -0,0 +1,10965 @@
+/*
+ * melib - gpgme module
+ *
+ * Copyright 2020 Manos Pitsidianakis
+ *
+ * This file is part of meli.
+ *
+ * meli 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * meli 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 meli. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#![allow(non_camel_case_types)]
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#![allow(unused)]
+#![allow(dead_code)]
+
+/* automatically generated by rust-bindgen */
+
+#[repr(C)]
+#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub struct __BindgenBitfieldUnit<Storage, Align> {
+ storage: Storage,
+ align: [Align; 0],
+}
+impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align> {
+ #[inline]
+ pub const fn new(storage: Storage) -> Self {
+ Self { storage, align: [] }
+ }
+}
+impl<Storage, Align> __BindgenBitfieldUnit<Storage, Align>
+where
+ Storage: AsRef<[u8]> + AsMut<[u8]>,
+{
+ #[inline]
+ pub fn get_bit(&self, index: usize) -> bool {
+ debug_assert!(index / 8 < self.storage.as_ref().len());
+ let byte_index = index / 8;
+ let byte = self.storage.as_ref()[byte_index];
+ let bit_index = if cfg!(target_endian = "big") {
+ 7 - (index % 8)
+ } else {
+ index % 8
+ };
+ let mask = 1 << bit_index;
+ byte & mask == mask
+ }
+ #[inline]
+ pub fn set_bit(&mut self, index: usize, val: bool) {
+ debug_assert!(index / 8 < self.storage.as_ref().len());
+ let byte_index = index / 8;
+ let byte = &mut self.storage.as_mut()[byte_index];
+ let bit_index = if cfg!(target_endian = "big") {
+ 7 - (index % 8)
+ } else {
+ index % 8
+ };
+ let mask = 1 << bit_index;
+ if val {
+ *byte |= mask;
+ } else {
+ *byte &= !mask;
+ }
+ }
+ #[inline]
+ pub fn get(&self, bit_offset: usize, bit_width: u8) -> u64 {
+ debug_assert!(bit_width <= 64);
+ debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
+ debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
+ let mut val = 0;
+ for i in 0..(bit_width as usize) {
+ if self.get_bit(i + bit_offset) {
+ let index = if cfg!(target_endian = "big") {
+ bit_width as usize - 1 - i
+ } else {
+ i
+ };
+ val |= 1 << index;
+ }
+ }
+ val
+ }
+ #[inline]
+ pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {
+ debug_assert!(bit_width <= 64);
+ debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
+ debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
+ for i in 0..(bit_width as usize) {
+ let mask = 1 << i;
+ let val_bit_is_set = val & mask == mask;
+ let index = if cfg!(target_endian = "big") {
+ bit_width as usize - 1 - i
+ } else {
+ i
+ };
+ self.set_bit(index + bit_offset, val_bit_is_set);
+ }
+ }
+}
+pub const _STDIO_H: u32 = 1;
+pub const _FEATURES_H: u32 = 1;
+pub const _DEFAULT_SOURCE: u32 = 1;
+pub const __USE_ISOC11: u32 = 1;
+pub const __USE_ISOC99: u32 = 1;
+pub const __USE_ISOC95: u32 = 1;
+pub const __USE_POSIX_IMPLICITLY: u32 = 1;
+pub const _POSIX_SOURCE: u32 = 1;
+pub const _POSIX_C_SOURCE: u32 = 200809;
+pub const __USE_POSIX: u32 = 1;
+pub const __USE_POSIX2: u32 = 1;
+pub const __USE_POSIX199309: u32 = 1;
+pub const __USE_POSIX199506: u32 = 1;
+pub const __USE_XOPEN2K: u32 = 1;
+pub const __USE_XOPEN2K8: u32 = 1;
+pub const _ATFILE_SOURCE: u32 = 1;
+pub const __USE_MISC: u32 = 1;
+pub const __USE_ATFILE: u32 = 1;
+pub const __USE_FORTIFY_LEVEL: u32 = 0;
+pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0;
+pub const _STDC_PREDEF_H: u32 = 1;
+pub const __STDC_IEC_559__: u32 = 1;
+pub const __STDC_IEC_559_COMPLEX__: u32 = 1;
+pub const __STDC_ISO_10646__: u32 = 201706;
+pub const __GNU_LIBRARY__: u32 = 6;
+pub const __GLIBC__: u32 = 2;
+pub const __GLIBC_MINOR__: u32 = 28;
+pub const _SYS_CDEFS_H: u32 = 1;
+pub const __glibc_c99_flexarr_available: u32 = 1;
+pub const __WORDSIZE: u32 = 64;
+pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1;
+pub const __SYSCALL_WORDSIZE: u32 = 64;
+pub const __HAVE_GENERIC_SELECTION: u32 = 1;
+pub const __GLIBC_USE_LIB_EXT2: u32 = 0;
+pub const __GLIBC_USE_IEC_60559_BFP_EXT: u32 = 0;
+pub const __GLIBC_USE_IEC_60559_FUNCS_EXT: u32 = 0;
+pub const __GLIBC_USE_IEC_60559_TYPES_EXT: u32 = 0;
+pub const __GNUC_VA_LIST: u32 = 1;
+pub const _BITS_TYPES_H: u32 = 1;
+pub const _BITS_TYPESIZES_H: u32 = 1;
+pub const __OFF_T_MATCHES_OFF64_T: u32 = 1;
+pub const __INO_T_MATCHES_INO64_T: u32 = 1;
+pub const __RLIM_T_MATCHES_RLIM64_T: u32 = 1;
+pub const __FD_SETSIZE: u32 = 1024;
+pub const _____fpos_t_defined: u32 = 1;
+pub const ____mbstate_t_defined: u32 = 1;
+pub const _____fpos64_t_defined: u32 = 1;
+pub const ____FILE_defined: u32 = 1;
+pub const __FILE_defined: u32 = 1;
+pub const __struct_FILE_defined: u32 = 1;
+pub const _IO_EOF_SEEN: u32 = 16;
+pub const _IO_ERR_SEEN: u32 = 32;
+pub const _IO_USER_LOCK: u32 = 32768;
+pub const _IOFBF: u32 = 0;
+pub const _IOLBF: u32 = 1;
+pub const _IONBF: u32 = 2;
+pub const BUFSIZ: u32 = 8192;
+pub const EOF: i32 = -1;
+pub const SEEK_SET: u32 = 0;
+pub const SEEK_CUR: u32 = 1;
+pub const SEEK_END: u32 = 2;
+pub const P_tmpdir: &'static [u8; 5usize] = b"/tmp\0";
+pub const _BITS_STDIO_LIM_H: u32 = 1;
+pub const L_tmpnam: u32 = 20;
+pub const TMP_MAX: u32 = 238328;
+pub const FILENAME_MAX: u32 = 4096;
+pub const L_ctermid: u32 = 9;
+pub const FOPEN_MAX: u32 = 16;
+pub const _TIME_H: u32 = 1;
+pub const _BITS_TIME_H: u32 = 1;
+pub const CLOCK_REALTIME: u32 = 0;
+pub const CLOCK_MONOTONIC: u32 = 1;
+pub const CLOCK_PROCESS_CPUTIME_ID: u32 = 2;
+pub const CLOCK_THREAD_CPUTIME_ID: u32 = 3;
+pub const CLOCK_MONOTONIC_RAW: u32 = 4;
+pub const CLOCK_REALTIME_COARSE: u32 = 5;
+pub const CLOCK_MONOTONIC_COARSE: u32 = 6;
+pub const CLOCK_BOOTTIME: u32 = 7;
+pub const CLOCK_REALTIME_ALARM: u32 = 8;
+pub const CLOCK_BOOTTIME_ALARM: u32 = 9;
+pub const CLOCK_TAI: u32 = 11;
+pub const TIMER_ABSTIME: u32 = 1;
+pub const __clock_t_defined: u32 = 1;
+pub const __time_t_defined: u32 = 1;
+pub const __struct_tm_defined: u32 = 1;
+pub const _STRUCT_TIMESPEC: u32 = 1;
+pub const __clockid_t_defined: u32 = 1;
+pub const __timer_t_defined: u32 = 1;
+pub const __itimerspec_defined: u32 = 1;
+pub const _BITS_TYPES_LOCALE_T_H: u32 = 1;
+pub const _BITS_TYPES___LOCALE_T_H: u32 = 1;
+pub const TIME_UTC: u32 = 1;
+pub const GPG_ERROR_H: u32 = 1;
+pub const GPGRT_H: u32 = 1;
+pub const GPG_ERROR_VERSION: &'static [u8; 5usize] = b"1.35\0";
+pub const GPGRT_VERSION: &'static [u8; 5usize] = b"1.35\0";
+pub const GPG_ERROR_VERSION_NUMBER: u32 = 74496;
+pub const GPGRT_VERSION_NUMBER: u32 = 74496;
+pub const GPG_ERR_SYSTEM_ERROR: u32 = 32768;
+pub const GPG_ERR_SOURCE_SHIFT: u32 = 24;
+pub const GPGRT_HAVE_MACRO_FUNCTION: u32 = 1;
+pub const GPG_ERR_INITIALIZED: u32 = 1;
+pub const _SYS_TYPES_H: u32 = 1;
+pub const _BITS_STDINT_INTN_H: u32 = 1;
+pub const __BIT_TYPES_DEFINED__: u32 = 1;
+pub const _ENDIAN_H: u32 = 1;
+pub const __LITTLE_ENDIAN: u32 = 1234;
+pub const __BIG_ENDIAN: u32 = 4321;
+pub const __PDP_ENDIAN: u32 = 3412;
+pub const __BYTE_ORDER: u32 = 1234;
+pub const __FLOAT_WORD_ORDER: u32 = 1234;
+pub const LITTLE_ENDIAN: u32 = 1234;
+pub const BIG_ENDIAN: u32 = 4321;
+pub const PDP_ENDIAN: u32 = 3412;
+pub const BYTE_ORDER: u32 = 1234;
+pub const _BITS_BYTESWAP_H: u32 = 1;
+pub const _BITS_UINTN_IDENTITY_H: u32 = 1;
+pub const _SYS_SELECT_H: u32 = 1;
+pub const __FD_ZERO_STOS: &'static [u8; 6usize] = b"stosq\0";
+pub const __sigset_t_defined: u32 = 1;
+pub const __timeval_defined: u32 = 1;
+pub const FD_SETSIZE: u32 = 1024;
+pub const _BITS_PTHREADTYPES_COMMON_H: u32 = 1;
+pub const _THREAD_SHARED_TYPES_H: u32 = 1;
+pub const _BITS_PTHREADTYPES_ARCH_H: u32 = 1;
+pub const __SIZEOF_PTHREAD_MUTEX_T: u32 = 40;
+pub const __SIZEOF_PTHREAD_ATTR_T: u32 = 56;
+pub const __SIZEOF_PTHREAD_RWLOCK_T: u32 = 56;
+pub const __SIZEOF_PTHREAD_BARRIER_T: u32 = 32;
+pub const __SIZEOF_PTHREAD_MUTEXATTR_T: u32 = 4;
+pub const __SIZEOF_PTHREAD_COND_T: u32 = 48;
+pub const __SIZEOF_PTHREAD_CONDATTR_T: u32 = 4;
+pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: u32 = 8;
+pub const __SIZEOF_PTHREAD_BARRIERATTR_T: u32 = 4;
+pub const __PTHREAD_MUTEX_LOCK_ELISION: u32 = 1;
+pub const __PTHREAD_MUTEX_NUSERS_AFTER_KIND: u32 = 0;
+pub const __PTHREAD_MUTEX_USE_UNION: u32 = 0;
+pub const __PTHREAD_RWLOCK_INT_FLAGS_SHARED: u32 = 1;
+pub const __PTHREAD_MUTEX_HAVE_PREV: u32 = 1;
+pub const __have_pthread_attr_t: u32 = 1;
+pub const GPGRT_LOG_WITH_PREFIX: u32 = 1;
+pub const GPGRT_LOG_WITH_TIME: u32 = 2;
+pub const GPGRT_LOG_WITH_PID: u32 = 4;
+pub const GPGRT_LOG_RUN_DETACHED: u32 = 256;
+pub const GPGRT_LOG_NO_REGISTRY: u32 = 512;
+pub const GPGRT_SPAWN_NONBLOCK: u32 = 16;
+pub const GPGRT_SPAWN_RUN_ASFW: u32 = 64;
+pub const GPGRT_SPAWN_DETACHED: u32 = 128;
+pub const GPGME_VERSION: &'static [u8; 7usize] = b"1.12.0\0";
+pub const GPGME_VERSION_NUMBER: u32 = 68608;
+pub const GPGME_KEYLIST_MODE_LOCAL: u32 = 1;
+pub const GPGME_KEYLIST_MODE_EXTERN: u32 = 2;
+pub const GPGME_KEYLIST_MODE_SIGS: u32 = 4;
+pub const GPGME_KEYLIST_MODE_SIG_NOTATIONS: u32 = 8;
+pub const GPGME_KEYLIST_MODE_WITH_SECRET: u32 = 16;
+pub const GPGME_KEYLIST_MODE_WITH_TOFU: u32 = 32;
+pub const GPGME_KEYLIST_MODE_EPHEMERAL: u32 = 128;
+pub const GPGME_KEYLIST_MODE_VALIDATE: u32 = 256;
+pub const GPGME_KEYLIST_MODE_LOCATE: u32 = 3;
+pub const GPGME_EXPORT_MODE_EXTERN: u32 = 2;
+pub const GPGME_EXPORT_MODE_MINIMAL: u32 = 4;
+pub const GPGME_EXPORT_MODE_SECRET: u32 = 16;
+pub const GPGME_EXPORT_MODE_RAW: u32 = 32;
+pub const GPGME_EXPORT_MODE_PKCS12: u32 = 64;
+pub const GPGME_EXPORT_MODE_NOUID: u32 = 128;
+pub const GPGME_AUDITLOG_DEFAULT: u32 = 0;
+pub const GPGME_AUDITLOG_HTML: u32 = 1;
+pub const GPGME_AUDITLOG_DIAG: u32 = 2;
+pub const GPGME_AUDITLOG_WITH_HELP: u32 = 128;
+pub const GPGME_SIG_NOTATION_HUMAN_READABLE: u32 = 1;
+pub const GPGME_SIG_NOTATION_CRITICAL: u32 = 2;
+pub const GPGME_INCLUDE_CERTS_DEFAULT: i32 = -256;
+pub const GPGME_IMPORT_NEW: u32 = 1;
+pub const GPGME_IMPORT_UID: u32 = 2;
+pub const GPGME_IMPORT_SIG: u32 = 4;
+pub const GPGME_IMPORT_SUBKEY: u32 = 8;
+pub const GPGME_IMPORT_SECRET: u32 = 16;
+pub const GPGME_CREATE_SIGN: u32 = 1;
+pub const GPGME_CREATE_ENCR: u32 = 2;
+pub const GPGME_CREATE_CERT: u32 = 4;
+pub const GPGME_CREATE_AUTH: u32 = 8;
+pub const GPGME_CREATE_NOPASSWD: u32 = 128;
+pub const GPGME_CREATE_SELFSIGNED: u32 = 256;
+pub const GPGME_CREATE_NOSTORE: u32 = 512;
+pub const GPGME_CREATE_WANTPUB: u32 = 1024;
+pub const GPGME_CREATE_WANTSEC: u32 = 2048;
+pub const GPGME_CREATE_FORCE: u32 = 4096;
+pub const GPGME_CREATE_NOEXPIRE: u32 = 8192;
+pub const GPGME_DELETE_ALLOW_SECRET: u32 = 1;
+pub const GPGME_DELETE_FORCE: u32 = 2;
+pub const GPGME_KEYSIGN_LOCAL: u32 = 128;
+pub const GPGME_KEYSIGN_LFSEP: u32 = 256;
+pub const GPGME_KEYSIGN_NOEXPIRE: u32 = 512;
+pub const GPGME_INTERACT_CARD: u32 = 1;
+pub const GPGME_SPAWN_DETACHED: u32 = 1;
+pub const GPGME_SPAWN_ALLOW_SET_FG: u32 = 2;
+pub const GPGME_SPAWN_SHOW_WINDOW: u32 = 4;
+pub const GPGME_CONF_GROUP: u32 = 1;
+pub const GPGME_CONF_OPTIONAL: u32 = 2;
+pub const GPGME_CONF_LIST: u32 = 4;
+pub const GPGME_CONF_RUNTIME: u32 = 8;
+pub const GPGME_CONF_DEFAULT: u32 = 16;
+pub const GPGME_CONF_DEFAULT_DESC: u32 = 32;
+pub const GPGME_CONF_NO_ARG_DESC: u32 = 64;
+pub const GPGME_CONF_NO_CHANGE: u32 = 128;
+pub type va_list = __builtin_va_list;
+pub type __gnuc_va_list = __builtin_va_list;
+pub type __u_char = ::std::os::raw::c_uchar;
+pub type __u_short = ::std::os::raw::c_ushort;
+pub type __u_int = ::std::os::raw::c_uint;
+pub type __u_long = ::std::os::raw::c_ulong;
+pub type __int8_t = ::std::os::raw::c_schar;
+pub type __uint8_t = ::std::os::raw::c_uchar;
+pub type __int16_t = ::std::os::raw::c_short;
+pub type __uint16_t = ::std::os::raw::c_ushort;
+pub type __int32_t = ::std::os::raw::c_int;
+pub type __uint32_t = ::std::os::raw::c_uint;
+pub type __int64_t = ::std::os::raw::c_long;
+pub type __uint64_t = ::std::os::raw::c_ulong;
+pub type __int_least8_t = __int8_t;
+pub type __uint_least8_t = __uint8_t;
+pub type __int_least16_t = __int16_t;
+pub type __uint_least16_t = __uint16_t;
+pub type __int_least32_t = __int32_t;
+pub type __uint_least32_t = __uint32_t;
+pub type __int_least64_t = __int64_t;
+pub type __uint_least64_t = __uint64_t;
+pub type __quad_t = ::std::os::raw::c_long;
+pub type __u_quad_t = ::std::os::raw::c_ulong;
+pub type __intmax_t = ::std::os::raw::c_long;
+pub type __uintmax_t = ::std::os::raw::c_ulong;
+pub type __dev_t = ::std::os::raw::c_ulong;
+pub type __uid_t = ::std::os::raw::c_uint;
+pub type __gid_t = ::std::os::raw::c_uint;
+pub type __ino_t = ::std::os::raw::c_ulong;
+pub type __ino64_t = ::std::os::raw::c_ulong;
+pub type __mode_t = ::std::os::raw::c_uint;
+pub type __nlink_t = ::std::os::raw::c_ulong;
+pub type __off_t = ::std::os::raw::c_long;
+pub type __off64_t = ::std::os::raw::c_long;
+pub type __pid_t = ::std::os::raw::c_int;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct __fsid_t {
+ pub __val: [::std::os::raw::c_int; 2usize],
+}
+#[test]
+fn bindgen_test_layout___fsid_t() {
+ assert_eq!(
+ ::std::mem::size_of::<__fsid_t>(),
+ 8usize,
+ concat!("Size of: ", stringify!(__fsid_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<__fsid_t>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(__fsid_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<__fsid_t>())).__val as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(__fsid_t),
+ "::",
+ stringify!(__val)
+ )
+ );
+}
+pub type __clock_t = ::std::os::raw::c_long;
+pub type __rlim_t = ::std::os::raw::c_ulong;
+pub type __rlim64_t = ::std::os::raw::c_ulong;
+pub type __id_t = ::std::os::raw::c_uint;
+pub type __time_t = ::std::os::raw::c_long;
+pub type __useconds_t = ::std::os::raw::c_uint;
+pub type __suseconds_t = ::std::os::raw::c_long;
+pub type __daddr_t = ::std::os::raw::c_int;
+pub type __key_t = ::std::os::raw::c_int;
+pub type __clockid_t = ::std::os::raw::c_int;
+pub type __timer_t = *mut ::std::os::raw::c_void;
+pub type __blksize_t = ::std::os::raw::c_long;
+pub type __blkcnt_t = ::std::os::raw::c_long;
+pub type __blkcnt64_t = ::std::os::raw::c_long;
+pub type __fsblkcnt_t = ::std::os::raw::c_ulong;
+pub type __fsblkcnt64_t = ::std::os::raw::c_ulong;
+pub type __fsfilcnt_t = ::std::os::raw::c_ulong;
+pub type __fsfilcnt64_t = ::std::os::raw::c_ulong;
+pub type __fsword_t = ::std::os::raw::c_long;
+pub type __ssize_t = ::std::os::raw::c_long;
+pub type __syscall_slong_t = ::std::os::raw::c_long;
+pub type __syscall_ulong_t = ::std::os::raw::c_ulong;
+pub type __loff_t = __off64_t;
+pub type __caddr_t = *mut ::std::os::raw::c_char;
+pub type __intptr_t = ::std::os::raw::c_long;
+pub type __socklen_t = ::std::os::raw::c_uint;
+pub type __sig_atomic_t = ::std::os::raw::c_int;
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct __mbstate_t {
+ pub __count: ::std::os::raw::c_int,
+ pub __value: __mbstate_t__bindgen_ty_1,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union __mbstate_t__bindgen_ty_1 {
+ pub __wch: ::std::os::raw::c_uint,
+ pub __wchb: [::std::os::raw::c_char; 4usize],
+ _bindgen_union_align: u32,
+}
+#[test]
+fn bindgen_test_layout___mbstate_t__bindgen_ty_1() {
+ assert_eq!(
+ ::std::mem::size_of::<__mbstate_t__bindgen_ty_1>(),
+ 4usize,
+ concat!("Size of: ", stringify!(__mbstate_t__bindgen_ty_1))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<__mbstate_t__bindgen_ty_1>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(__mbstate_t__bindgen_ty_1))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<__mbstate_t__bindgen_ty_1>())).__wch as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(__mbstate_t__bindgen_ty_1),
+ "::",
+ stringify!(__wch)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<__mbstate_t__bindgen_ty_1>())).__wchb as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(__mbstate_t__bindgen_ty_1),
+ "::",
+ stringify!(__wchb)
+ )
+ );
+}
+#[test]
+fn bindgen_test_layout___mbstate_t() {
+ assert_eq!(
+ ::std::mem::size_of::<__mbstate_t>(),
+ 8usize,
+ concat!("Size of: ", stringify!(__mbstate_t))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<__mbstate_t>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(__mbstate_t))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<__mbstate_t>())).__count as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(__mbstate_t),
+ "::",
+ stringify!(__count)