diff --git a/src/header/netdb/host.rs b/src/header/netdb/host.rs new file mode 100644 index 0000000000..cde8a138e3 --- /dev/null +++ b/src/header/netdb/host.rs @@ -0,0 +1,125 @@ +use alloc::boxed::Box; +use alloc::str::SplitWhitespace; +use alloc::vec::Vec; +use core::{mem, ptr}; + +use c_str::CString; +use header::arpa_inet::inet_aton; +use header::fcntl::O_RDONLY; +use header::netinet_in::in_addr; +use header::sys_socket::constants::AF_INET; +use header::unistd::SEEK_SET; +use platform::{Pal, Sys}; +use platform::rlb::{Line, RawLineBuffer}; +use platform::types::*; + +use super::{bytes_to_box_str, hostent}; + +static mut HOSTDB: c_int = -1; +pub static mut HOST_ENTRY: hostent = hostent { + h_name: ptr::null_mut(), + h_aliases: ptr::null_mut(), + h_addrtype: 0, + h_length: 0, + h_addr_list: ptr::null_mut(), +}; +pub static mut HOST_NAME: Option> = None; +pub static mut HOST_ALIASES: Option>> = None; +static mut _HOST_ALIASES: Option> = None; +pub static mut HOST_ADDR: Option = None; +pub static mut HOST_ADDR_LIST: [*mut c_char; 2] = [ptr::null_mut(); 2]; +pub static mut _HOST_ADDR_LIST: [u8; 4] = [0u8; 4]; +static mut H_POS: usize = 0; +pub static mut HOST_STAYOPEN: c_int = 0; + +#[no_mangle] +pub unsafe extern "C" fn endhostent() { + if HOSTDB >= 0 { + Sys::close(HOSTDB); + } + HOSTDB = -1; +} + +#[no_mangle] +pub unsafe extern "C" fn sethostent(stayopen: c_int) { + HOST_STAYOPEN = stayopen; + if HOSTDB < 0 { + HOSTDB = Sys::open(&CString::new("/etc/hosts").unwrap(), O_RDONLY, 0) + } else { + Sys::lseek(HOSTDB, 0, SEEK_SET); + } + H_POS = 0; +} + +#[no_mangle] +pub unsafe extern "C" fn gethostent() -> *mut hostent { + if HOSTDB < 0 { + HOSTDB = Sys::open(&CString::new("/etc/hosts").unwrap(), O_RDONLY, 0); + } + let mut rlb = RawLineBuffer::new(HOSTDB); + rlb.seek(H_POS); + + let mut r: Box = Box::default(); + while r.is_empty() || r.split_whitespace().next() == None || r.starts_with('#') { + r = match rlb.next() { + Line::Some(s) => bytes_to_box_str(s), + _ => { + if HOST_STAYOPEN == 0 { + endhostent(); + } + return ptr::null_mut(); + } + }; + } + rlb.next(); + H_POS = rlb.line_pos(); + + let mut iter: SplitWhitespace = r.split_whitespace(); + + let mut addr_vec = iter.next().unwrap().as_bytes().to_vec(); + addr_vec.push(b'\0'); + let addr_cstr = addr_vec.as_slice().as_ptr() as *const i8; + let mut addr = mem::uninitialized(); + inet_aton(addr_cstr, &mut addr); + + _HOST_ADDR_LIST = mem::transmute::(addr.s_addr); + HOST_ADDR_LIST = [_HOST_ADDR_LIST.as_mut_ptr() as *mut c_char, ptr::null_mut()]; + + HOST_ADDR = Some(addr); + + let mut host_name = iter.next().unwrap().as_bytes().to_vec(); + host_name.push(b'\0'); + + let mut _host_aliases: Vec> = Vec::new(); + + while let Some(s) = iter.next() { + let mut alias = s.as_bytes().to_vec(); + alias.push(b'\0'); + _host_aliases.push(alias); + } + HOST_ALIASES = Some(_host_aliases); + + let mut host_aliases: Vec<*mut i8> = HOST_ALIASES + .as_mut() + .unwrap() + .iter_mut() + .map(|x| x.as_mut_ptr() as *mut i8) + .collect(); + host_aliases.push(ptr::null_mut()); + host_aliases.push(ptr::null_mut()); + + HOST_NAME = Some(host_name); + + HOST_ENTRY = hostent { + h_name: HOST_NAME.as_mut().unwrap().as_mut_ptr() as *mut c_char, + h_aliases: host_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8, + h_addrtype: AF_INET, + h_length: 4, + h_addr_list: HOST_ADDR_LIST.as_mut_ptr(), + }; + _HOST_ALIASES = Some(host_aliases); + if HOST_STAYOPEN == 0 { + endhostent(); + } + &mut HOST_ENTRY as *mut hostent +} diff --git a/src/header/netdb/mod.rs b/src/header/netdb/mod.rs index e4ddb548bc..d0bc75a1dd 100644 --- a/src/header/netdb/mod.rs +++ b/src/header/netdb/mod.rs @@ -10,7 +10,7 @@ use alloc::str::SplitWhitespace; use alloc::vec::Vec; use c_str::{CStr, CString}; -use header::arpa_inet::{htons, inet_aton}; +use header::arpa_inet::htons; use header::errno::*; use header::fcntl::O_RDONLY; use header::netinet_in::{in_addr, sockaddr_in}; @@ -32,7 +32,10 @@ pub mod sys; #[path = "redox.rs"] pub mod sys; -use self::lookup::{lookup_addr, lookup_host}; +pub use self::host::*; +pub mod host; + +pub use self::lookup::*; pub mod lookup; const MAXADDRS: usize = 35; @@ -125,23 +128,6 @@ static mut NET_NUM: Option = None; static mut N_POS: usize = 0; static mut NET_STAYOPEN: c_int = 0; -static mut HOSTDB: c_int = 0; -static mut HOST_ENTRY: hostent = hostent { - h_name: ptr::null_mut(), - h_aliases: ptr::null_mut(), - h_addrtype: 0, - h_length: 0, - h_addr_list: ptr::null_mut(), -}; -static mut HOST_NAME: Option> = None; -static mut HOST_ALIASES: Option>> = None; -static mut _HOST_ALIASES: Option> = None; -static mut HOST_ADDR: Option = None; -static mut HOST_ADDR_LIST: [*mut c_char; 2] = [ptr::null_mut(); 2]; -static mut _HOST_ADDR_LIST: [u8; 4] = [0u8; 4]; -static mut H_POS: usize = 0; -static mut HOST_STAYOPEN: c_int = 0; - #[allow(non_upper_case_globals)] #[no_mangle] pub static mut h_errno: c_int = 0; @@ -182,12 +168,6 @@ fn bytes_to_box_str(bytes: &[u8]) -> Box { Box::from(core::str::from_utf8(bytes).unwrap_or("")) } -#[no_mangle] -pub unsafe extern "C" fn endhostent() { - Sys::close(HOSTDB); - HOSTDB = 0; -} - #[no_mangle] pub unsafe extern "C" fn endnetent() { Sys::close(NETDB); @@ -363,79 +343,6 @@ pub unsafe extern "C" fn gethostbyname(name: *const c_char) -> *mut hostent { &mut HOST_ENTRY as *mut hostent } -#[no_mangle] -pub unsafe extern "C" fn gethostent() -> *mut hostent { - if HOSTDB == 0 { - HOSTDB = Sys::open(&CString::new("/etc/hosts").unwrap(), O_RDONLY, 0); - } - let mut rlb = RawLineBuffer::new(HOSTDB); - rlb.seek(H_POS); - - let mut r: Box = Box::default(); - while r.is_empty() || r.split_whitespace().next() == None || r.starts_with('#') { - r = match rlb.next() { - Line::Some(s) => bytes_to_box_str(s), - _ => { - if HOST_STAYOPEN == 0 { - endhostent(); - } - return ptr::null_mut(); - } - }; - } - rlb.next(); - H_POS = rlb.line_pos(); - - let mut iter: SplitWhitespace = r.split_whitespace(); - - let mut addr_vec = iter.next().unwrap().as_bytes().to_vec(); - addr_vec.push(b'\0'); - let addr_cstr = addr_vec.as_slice().as_ptr() as *const i8; - let mut addr = mem::uninitialized(); - inet_aton(addr_cstr, &mut addr); - - _HOST_ADDR_LIST = mem::transmute::(addr.s_addr); - HOST_ADDR_LIST = [_HOST_ADDR_LIST.as_mut_ptr() as *mut c_char, ptr::null_mut()]; - - HOST_ADDR = Some(addr); - - let mut host_name = iter.next().unwrap().as_bytes().to_vec(); - host_name.push(b'\0'); - - let mut _host_aliases: Vec> = Vec::new(); - - while let Some(s) = iter.next() { - let mut alias = s.as_bytes().to_vec(); - alias.push(b'\0'); - _host_aliases.push(alias); - } - HOST_ALIASES = Some(_host_aliases); - - let mut host_aliases: Vec<*mut i8> = HOST_ALIASES - .as_mut() - .unwrap() - .iter_mut() - .map(|x| x.as_mut_ptr() as *mut i8) - .collect(); - host_aliases.push(ptr::null_mut()); - host_aliases.push(ptr::null_mut()); - - HOST_NAME = Some(host_name); - - HOST_ENTRY = hostent { - h_name: HOST_NAME.as_mut().unwrap().as_mut_ptr() as *mut c_char, - h_aliases: host_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8, - h_addrtype: AF_INET, - h_length: 4, - h_addr_list: HOST_ADDR_LIST.as_mut_ptr(), - }; - _HOST_ALIASES = Some(host_aliases); - if HOST_STAYOPEN == 0 { - endhostent(); - } - &mut HOST_ENTRY as *mut hostent -} - pub unsafe extern "C" fn getnetbyaddr(net: u32, net_type: c_int) -> *mut netent { unimplemented!(); } @@ -707,17 +614,6 @@ pub unsafe extern "C" fn getservent() -> *mut servent { } } -#[no_mangle] -pub unsafe extern "C" fn sethostent(stayopen: c_int) { - HOST_STAYOPEN = stayopen; - if HOSTDB == 0 { - HOSTDB = Sys::open(&CString::new("/etc/hosts").unwrap(), O_RDONLY, 0) - } else { - Sys::lseek(HOSTDB, 0, SEEK_SET); - } - H_POS = 0; -} - #[no_mangle] pub unsafe extern "C" fn setnetent(stayopen: c_int) { NET_STAYOPEN = stayopen;