From 310a01f1a2589acb600c91a3cc9d6aca09443d86 Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Fri, 3 Jul 2020 10:09:58 +0200 Subject: pkgs/profpatsch/xdg-open/mini-url: envvar instead of substitute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s a lot simpler to just export the parsed attribute as envvars. Remove the substitute stuff (it already went into the el_substitute lib anyway) and replace the xpathexec0 code with the function from the el_exec lib. --- pkgs/profpatsch/xdg-open/mini-url.rs | 263 ++--------------------------------- 1 file changed, 11 insertions(+), 252 deletions(-) (limited to 'pkgs/profpatsch/xdg-open/mini-url.rs') diff --git a/pkgs/profpatsch/xdg-open/mini-url.rs b/pkgs/profpatsch/xdg-open/mini-url.rs index b59d3a75..ad2578cc 100644 --- a/pkgs/profpatsch/xdg-open/mini-url.rs +++ b/pkgs/profpatsch/xdg-open/mini-url.rs @@ -1,206 +1,7 @@ -extern crate errno; -extern crate libc; +extern crate el_exec; -use std::ffi::{OsString}; -use std::os::unix::ffi::OsStringExt; -use std::ffi::{CStr, CString}; - -// TODO: move the execline stuff into a different library - -#[repr(C)] -pub struct Stralloc_C { - s: *mut libc::c_char, - len: libc::size_t, - a: libc::size_t -} - -fn stralloc_zero() -> Stralloc_C { - Stralloc_C { - s: std::ptr::null_mut(), - len: 0, - a: 0 - } -} - -#[link(name = "skarnet")] -extern "C" { - fn stralloc_free(sa: *mut Stralloc_C); - fn stralloc_ready_tuned( - sa: *mut Stralloc_C, - n: libc::size_t, - base: libc::size_t, - a: libc::size_t, - b: libc::size_t, - ) -> libc::c_int; - - fn stralloc_catb( - sa: *mut Stralloc_C, - s: *const libc::c_char, - len: libc::size_t - ) -> libc::c_int; - - fn stralloc_copyb( - sa: *mut Stralloc_C, - s: *const libc::c_char, - len: libc::size_t - ) -> libc::c_int; - - fn xpathexec0( - argv: *const *const libc::c_char - ); - fn xpathexec_run( - file: *const libc::c_char, - argv: *const *const libc::c_char, - envp: *const *const libc::c_char - ); -} - -fn stralloc_ready(sa: *mut Stralloc_C, n: libc::size_t) { - unsafe { - if (stralloc_ready_tuned(sa, n, 8, 1, 8) == 0) { - panic!("{}", errno::errno()); - } - } -} - -struct Stralloc(Stralloc_C); - -impl Stralloc { - fn new() -> Self { - let mut sa = stralloc_zero(); - unsafe { - stralloc_ready(&mut sa, 0); - } - Stralloc(sa) - } -} - -impl AsMut for Stralloc { - fn as_mut(&mut self) -> &mut Stralloc_C { - match self { - Stralloc(s) => s - } - } -} - -impl AsRef for Stralloc { - fn as_ref(&self) -> &Stralloc_C { - match self { - Stralloc(s) => s - } - } -} - -impl<'a> From<&mut [u8]> for Stralloc { - fn from(s: &mut [u8]) -> Self { - let mut sa = stralloc_zero(); - let ptr = s.as_mut_ptr() as *mut libc::c_char; - unsafe { - if stralloc_copyb(&mut sa, ptr, s.len()) == 0 { - panic!("{}", errno::errno()); - } - } - Stralloc(sa) - } -} - -// TODO not sure if stralloc will always be a contiguous block? -// that’s the precondition for from_raw_parts -impl AsRef<[u8]> for Stralloc_C { - fn as_ref(&self) -> &[u8] { - let ptr = self.s as *const u8; - unsafe { - std::slice::from_raw_parts(ptr, self.len) - } - } -} - -impl Drop for Stralloc { - fn drop(&mut self) { - match self { - Stralloc(inner) => { - unsafe { - stralloc_free(inner); - } - } - } - } -} - - -#[repr(C)] -#[derive(Debug)] -pub struct Elsubst_C -{ - var: libc::size_t, - value: libc::size_t, - // values are \0-separated strings, - // and n is the amount of elements in one such string - n: libc::c_uint -} - -#[link(name = "execline")] -extern "C" { - fn el_substitute( - dst: *mut Stralloc_C, - src: *const libc::c_char, - len: libc::size_t, - // length is given by nsubst - vars: *const libc::c_char, - // length is given by nsubst - values: *const libc::c_char, - - substs: *const Elsubst_C, - nsubst: libc::size_t - ) -> libc::c_int; -} - -struct Subst<'a> { - var: &'a CStr, - value: &'a CStr, -} - -fn simple_substitute<'a, 'b>(subst: &[Subst<'a>], src: &CStr) -> CString { - let len = src.to_bytes_with_nul().len() as libc::size_t; - let src = src.as_ptr() as *const libc::c_char; - let mut vars : Vec = Vec::new(); - let mut values : Vec = Vec::new(); - let mut substs : Vec = Vec::new(); - let mut var_i = 0; - let mut value_i = 0; - for s in subst { - let var = s.var.to_bytes_with_nul(); - let value = s.value.to_bytes_with_nul(); - vars.extend_from_slice(var); - values.extend_from_slice(value); - substs.push(Elsubst_C { - // these index into the vars/values arrays given to el_substitute - var: var_i, - value: value_i, - // we don’t deal with split values here - n: 1 - }); - var_i += var.len(); - value_i += value.len(); - } - let nsubst = subst.len(); - let mut dst = stralloc_zero(); - unsafe { - if el_substitute( - &mut dst, - src, - len, - vars.as_ptr() as *const libc::c_char, - values.as_ptr() as *const libc::c_char, - substs.as_ptr() as *const Elsubst_C, - nsubst - ) == -1 { - panic!("{}", errno::errno()); - } - // el_substitute returns a \0-delim C string - CStr::from_bytes_with_nul_unchecked(dst.as_ref()).to_owned() - } -} +use std::os::unix::ffi::OsStrExt; +use std::ffi::{CString}; #[derive(Clone, Debug, PartialEq, Eq,)] struct Parsed<'a> { @@ -269,25 +70,6 @@ fn mini_parse_http(url: &str) -> Result { } -fn write_netstring(mut w: W, s: &str) -> std::io::Result<()> { - write!(w, "{}:{},", s.len(), s) -} - -fn to_cstrings(s: Vec) -> Vec { - s.into_iter() - .map(|s: OsString| CString::new(s.into_vec()).unwrap()) - .collect::>() -} - -fn to_c_argv(s: Vec) -> (Vec, Vec<*const libc::c_char>) { - let mut c_ptr_args = s.iter() - .map(|s| s.as_ptr()) - .collect::>(); - c_ptr_args.push(std::ptr::null()); - (s, c_ptr_args) -} - - fn main() -> std::io::Result<()> { let args = std::env::args().collect::>(); let prog_index = 2; @@ -303,39 +85,16 @@ fn main() -> std::io::Result<()> { } ); - // println!("{:#?}", mini_parse_http(&args[1]).unwrap()); + let args = std::env::args_os().into_iter() + .map(|arg| CString::new(arg.as_bytes()).unwrap()) + .collect::>(); - let subst = |s: &CString| simple_substitute(&vec![ - Subst{ - var: &CString::new(b"host".to_vec()).unwrap(), - value: &CString::new(domain).unwrap() - }, - Subst{ - var: &CString::new(b"port".to_vec()).unwrap(), - value: &CString::new(port).unwrap(), - }, - Subst{ - var: &CString::new(b"protocol".to_vec()).unwrap(), - value: &CString::new(protocol.string()).unwrap() - }, - Subst{ - var: &CString::new(b"path".to_vec()).unwrap(), - value: &CString::new(path).unwrap() - }, - - ], s); + std::env::set_var("host", domain); + std::env::set_var("port", port); + std::env::set_var("protocol", protocol.string()); + std::env::set_var("path", path); - - // TODO: replace this bit by xpathexec0 from el_exec.rs - - let cstring_argv = to_cstrings(std::env::args_os().collect::>()); - let (c_strings, c_argv) = to_c_argv(cstring_argv.iter().map(subst).collect::>()); - - unsafe { - xpathexec0( - c_argv[prog_index..].as_ptr() as *const *const libc::c_char - ) - } + el_exec::xpathexec0(&args[prog_index..]); Ok(()) } -- cgit 1.4.1