diff options
author | Justus Winter <justus@pep-project.org> | 2017-11-30 18:52:45 +0100 |
---|---|---|
committer | Justus Winter <justus@pep-project.org> | 2017-12-01 13:54:28 +0100 |
commit | 8659731e6ecd694e7fa87799497aeb0338b7292c (patch) | |
tree | c5a9f0b6a30a6052ae063945506c90d890409bab /src | |
parent | e55151e501270875731cb89e83dd4e16402de025 (diff) |
Create context objects.
- Context objects can be used to tweak the library configuration.
Currently, a home and lib directory can be set. Reasonable
defaults are provided.
- Add ffi functions.
Diffstat (limited to 'src')
-rw-r--r-- | src/ffi.rs | 48 | ||||
-rw-r--r-- | src/lib.rs | 65 | ||||
-rw-r--r-- | src/sequoia.h | 5 |
3 files changed, 117 insertions, 1 deletions
@@ -1,10 +1,56 @@ extern crate libc; -use self::libc::{uint8_t, size_t}; +use self::libc::{uint8_t, c_char, size_t}; +use std::ffi::CStr; use std::ptr; use std::slice; +use std::str; + use keys::TPK; use openpgp; +use super::Context; + +/// Create a context object. +/// +/// If `home` is not `NULL`, it is used as directory containing shared +/// state and rendezvous nodes. If `lib` is not `NULL`, it is used as +/// directory containing backend servers. If either argument is +/// `NULL`, a reasonable default is used. +/// +/// Returns `NULL` on errors. +#[no_mangle] +pub extern "system" fn sq_context_new(home: *const c_char, + lib: *const c_char) -> *mut Context { + let home = unsafe { + if home.is_null() { None } else { Some(CStr::from_ptr(home)) } + }; + let lib = unsafe { + if lib.is_null() { None } else { Some(CStr::from_ptr(lib)) } + }; + + let mut pre = Context::new(); + + if let Some(home) = home { + pre = pre.home(home.to_string_lossy().as_ref()); + } + if let Some(lib) = lib { + pre = pre.lib(lib.to_string_lossy().as_ref()); + } + + if let Ok(context) = pre.finalize() { + Box::into_raw(Box::new(context)) + } else { + ptr::null_mut() + } +} + +/// Free a context. +#[no_mangle] +pub extern "system" fn sq_context_free(context: *mut Context) { + unsafe { + drop(Box::from_raw(context)); + } +} #[no_mangle] pub extern "system" fn sq_tpk_from_bytes(b: *const uint8_t, len: size_t) -> *mut TPK { @@ -16,3 +16,68 @@ pub mod key_store; pub mod net; pub mod ffi; pub mod armor; + +use std::env; +use std::fs; +use std::io; +use std::path::{Path, PathBuf}; + +/// A `&Context` is required for many operations. +pub struct Context { + home: PathBuf, + lib: PathBuf, +} + +fn prefix() -> PathBuf { + /* XXX: Windows support. */ + PathBuf::from(option_env!("PREFIX").or(Some("/usr/local")).unwrap()) +} + +impl Context { + /// Create a `Pre(Context)` with reasonable defaults. `Pre(Context)`s + /// can be modified, and have to be finalized in order to turn + /// them into a Context. + pub fn new() -> Pre { + Pre(Context { + home: env::home_dir().unwrap_or(env::temp_dir()) + .join(".sequoia"), + lib: prefix().join("lib").join("sequoia"), + }) + } + + /// Return the directory containing shared state and rendezvous + /// nodes. + pub fn home(&self) -> &Path { + &self.home + } + + /// Return the directory containing backend servers. + pub fn lib(&self) -> &Path { + &self.lib + } +} + +/// A `Pre(Context)` is a context object that can be modified. +pub struct Pre(Context); + +impl Pre { + /// Finalize the configuration and return a `Context`. + pub fn finalize(self) -> io::Result<Context> { + let c = self.0; + fs::create_dir_all(c.home())?; + Ok(c) + } + + /// Set the directory containing shared state and rendezvous + /// nodes. + pub fn home<P: AsRef<Path>>(mut self, new: P) -> Self { + self.0.home = PathBuf::new().join(new); + self + } + + /// Set the directory containing backend servers. + pub fn lib<P: AsRef<Path>>(mut self, new: P) -> Self { + self.0.lib = PathBuf::new().join(new); + self + } +} diff --git a/src/sequoia.h b/src/sequoia.h index 0853b9aa..7b3f9cf2 100644 --- a/src/sequoia.h +++ b/src/sequoia.h @@ -1,6 +1,11 @@ #ifndef SEQUOIA_H #define SEQUOIA_H +struct sq_context; + +struct sq_context *sq_context_new(const char *home, const char *lib); +void sq_context_free(struct sq_context *context); + struct sq_tpk; struct sq_tpk *sq_tpk_from_bytes (const char *b, size_t len); |