diff options
author | Justus Winter <justus@pep-project.org> | 2017-11-23 14:34:45 +0100 |
---|---|---|
committer | Justus Winter <justus@pep-project.org> | 2017-11-23 14:36:36 +0100 |
commit | 9a5725fe55eb5e49cee09712364ac7b7dcefde51 (patch) | |
tree | 4f0b3b5e86a02236a06c503e8adcc03fc6fc1d7e | |
parent | 8cdab3036cfd2111fd3719abc38ab334bc72ebdc (diff) |
Add a foreign function interface.
- For now, we keep the ffi in this crate, later on we may want to
move it to sequoia-ffi.
- Example code how to use the library from C is added as well.
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | examples/Makefile | 3 | ||||
-rw-r--r-- | examples/example.c | 44 | ||||
-rw-r--r-- | src/ffi.rs | 40 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/sequoia.h | 10 |
6 files changed, 100 insertions, 0 deletions
@@ -4,6 +4,7 @@ version = "0.1.0" authors = ["Neal H. Walfield <neal@gnu.org>"] [dependencies] +libc = "0.2.33" nom = "3.2.0" num = "0.1.40" num-derive = "0.1.41" @@ -13,6 +14,7 @@ bzip2 = "0.3.2" [lib] name = "sequoia" path = "src/lib.rs" +crate-type = ["lib", "dylib"] [[bin]] doc = false diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 00000000..59007930 --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,3 @@ +CFLAGS = -I../src -O0 -g -Wall +LDFLAGS = -L../target/debug -lsequoia +all: example diff --git a/examples/example.c b/examples/example.c new file mode 100644 index 00000000..ae727b43 --- /dev/null +++ b/examples/example.c @@ -0,0 +1,44 @@ +#define _GNU_SOURCE +#include <error.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include <sequoia.h> + +int +main (int argc, char **argv) +{ + struct stat st; + int fd; + char *b; + struct sq_tpk *tpk; + + if (argc != 2) + error (1, 0, "Usage: %s <file>", argv[0]); + + if (stat (argv[1], &st)) + error (1, errno, "%s", argv[1]); + + fd = open (argv[1], O_RDONLY); + if (fd == -1) + error (1, errno, "%s", argv[1]); + + b = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (b == MAP_FAILED) + error (1, errno, "mmap"); + + tpk = sq_tpk_from_bytes (b, st.st_size); + if (tpk == NULL) + error (1, 0, "sq_tpk_from_bytes failed"); + + sq_tpk_dump (tpk); + sq_tpk_free (tpk); + munmap (b, st.st_size); + close (fd); + return 0; +} diff --git a/src/ffi.rs b/src/ffi.rs new file mode 100644 index 00000000..3a7b1c66 --- /dev/null +++ b/src/ffi.rs @@ -0,0 +1,40 @@ +extern crate libc; +use self::libc::{uint8_t, size_t}; + +use std::ptr; +use std::slice; +use keys::TPK; +use openpgp; + +#[no_mangle] +pub extern "system" fn sq_tpk_from_bytes(b: *const uint8_t, len: size_t) -> *mut TPK { + assert!(!b.is_null()); + let bytes = unsafe { + slice::from_raw_parts(b, len as usize) + }; + let m = openpgp::Message::from_bytes(bytes); + + if let Some(tpk) = m.ok().and_then(|m| TPK::from_message(m)) { + Box::into_raw(Box::new(tpk)) + } else { + ptr::null_mut() + } +} + +#[no_mangle] +pub extern "system" fn sq_tpk_dump(tpk: *mut TPK) { + assert!(!tpk.is_null()); + unsafe { + println!("{:?}", *tpk); + } +} + +#[no_mangle] +pub extern "system" fn sq_tpk_free(tpk: *mut TPK) { + if tpk.is_null() { + return + } + unsafe { + drop(Box::from_raw(tpk)); + } +} @@ -14,3 +14,4 @@ pub mod openpgp; pub mod keys; pub mod key_store; pub mod net; +pub mod ffi; diff --git a/src/sequoia.h b/src/sequoia.h new file mode 100644 index 00000000..0853b9aa --- /dev/null +++ b/src/sequoia.h @@ -0,0 +1,10 @@ +#ifndef SEQUOIA_H +#define SEQUOIA_H + +struct sq_tpk; + +struct sq_tpk *sq_tpk_from_bytes (const char *b, size_t len); +void sq_tpk_dump (const struct sq_tpk *tpk); +void sq_tpk_free (struct sq_tpk *tpk); + +#endif |