Newer
Older
//! netdb implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/netdb.h.html
mod dns;
use core::str::FromStr;
use alloc::str::SplitWhitespace;
use alloc::string::ToString;
use alloc::vec::IntoIter;
use platform::rlb::{Line, RawLineBuffer};
use platform::types::*;
use platform::{Pal, Sys};
use header::sys_socket::constants::{AF_INET, SOCK_DGRAM};
use header::sys_socket::{sockaddr, socklen_t};
use header::unistd::SEEK_SET;
#[cfg(target_os = "linux")]
#[path = "linux.rs"]
pub mod sys;
#[cfg(target_os = "redox")]
#[path = "redox.rs"]
pub mod sys;
const MAXADDRS: usize = 35;
const MAXALIASES: usize = 35;
struct LookupHost(IntoIter<in_addr>);
impl Iterator for LookupHost {
type Item = in_addr;
self.0.next()
}
}
#[repr(C)]
pub struct hostent {
h_name: *mut c_char,
h_aliases: *mut *mut c_char,
h_addrtype: c_int,
h_length: c_int,
h_addr_list: *mut *mut c_char,
}
#[repr(C)]
pub struct netent {
n_addrtype: c_int, /* net address type */
n_net: c_ulong, /* network # */
s_port: c_int, /* port # */
s_proto: *mut c_char, /* protocol to use */
ai_flags: c_int, /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
ai_family: c_int, /* PF_xxx */
ai_socktype: c_int, /* SOCK_xxx */
ai_protocol: c_int, /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
ai_addrlen: size_t, /* length of ai_addr */
ai_addr: *mut sockaddr, /* binary address */
ai_next: *mut addrinfo, /* next structure in linked list */
}
static mut NETDB: c_int = 0;
static mut NET_ENTRY: netent = netent {
n_name: ptr::null_mut(),
n_aliases: ptr::null_mut(),
n_addrtype: 0,
n_net: 0,
};
static mut NET_NAME: Option<Vec<u8>> = None;
static mut NET_ALIASES: [*const c_char; MAXALIASES] = [ptr::null(); MAXALIASES];
static mut NET_NUM: Option<u64> = 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(),
};
static mut HOST_NAME: Option<Vec<u8>> = None;
static mut HOST_ALIASES: Option<Vec<Vec<u8>>> = None;
static mut HOST_ADDR: Option<in_addr> = None;
static mut HOST_ADDR_LIST: [*mut c_char; 2] = [ptr::null_mut(); 2];
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;
pub const HOST_NOT_FOUND: c_int = 1;
pub const NO_DATA: c_int = 2;
pub const NO_RECOVERY: c_int = 3;
pub const TRY_AGAIN: c_int = 4;
static mut PROTODB: c_int = 0;
static mut PROTO_ENTRY: protoent = protoent {
p_name: ptr::null_mut(),
p_aliases: ptr::null_mut(),
p_proto: 0 as c_int,
};
static mut PROTO_NAME: Option<Vec<u8>> = None;
static mut PROTO_ALIASES: Option<Vec<Vec<u8>>> = None;
static mut PROTO_NUM: Option<c_int> = None;
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
static mut PROTO_STAYOPEN: c_int = 0;
static mut SERVDB: c_int = 0;
static mut SERV_ENTRY: servent = servent {
s_name: ptr::null_mut(),
s_aliases: ptr::null_mut(),
s_port: 0 as c_int,
s_proto: ptr::null_mut(),
};
static mut SERV_NAME: Option<Vec<u8>> = None;
static mut SERV_ALIASES: Option<Vec<Vec<u8>>> = None;
static mut SERV_PORT: Option<c_int> = None;
static mut SERV_PROTO: Option<Vec<u8>> = None;
static mut S_POS: usize = 0;
static mut SERV_STAYOPEN: c_int = 0;
const NULL_ALIASES: [*mut c_char; 2] = [ptr::null_mut(); 2];
fn bytes_to_box_str(bytes: &[u8]) -> Box<str> {
Box::from(core::str::from_utf8(bytes).unwrap_or(""))
}
fn lookup_host(host: &str) -> Result<LookupHost, c_int> {
let dns_string = sys::get_dns_server();
let dns_vec: Vec<u8> = dns_string
.trim()
.split(".")
.map(|octet| octet.parse::<u8>().unwrap_or(0))
.collect();
if dns_vec.len() == 4 {
for (i, octet) in dns_vec.iter().enumerate() {
dns_arr[i] = *octet;
}
let dns_addr = unsafe { mem::transmute::<[u8; 4], u32>(dns_arr) };
let mut timespec = timespec::default();
Sys::clock_gettime(time::constants::CLOCK_REALTIME, &mut timespec);
let tid = (timespec.tv_nsec >> 16) as u16;
let packet = Dns {
transaction_id: tid,
flags: 0x0100,
queries: vec![DnsQuery {
name: host.to_string(),
q_type: 0x0001,
q_class: 0x0001,
}],
answers: vec![],
};
let packet_data = packet.compile();
let packet_data_len = packet_data.len();
let packet_data_ptr = Box::into_raw(packet_data_box) as *mut _ as *mut c_void;
let sock = unsafe { sys_socket::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP as i32) };
let mut dest = sockaddr_in {
sin_family: AF_INET as u16,
sin_port: htons(53),
let dest_ptr = &mut dest as *mut _ as *mut sockaddr;
unsafe {
if sys_socket::sendto(sock, packet_data_ptr, packet_data_len, 0, dest_ptr, 16) < 0 {
Box::from_raw(packet_data_ptr);
return Err(EIO);
}
}
unsafe {
Box::from_raw(packet_data_ptr);
}
let mut i = 0 as socklen_t;
let buf_ptr = buf.as_mut_ptr() as *mut c_void;
let mut count = -1;
let mut from: sockaddr = Default::default();
let from_ptr = &mut from as *mut sockaddr;
unsafe {
count =
sys_socket::recvfrom(sock, buf_ptr, 65536, 0, from_ptr, &mut i as *mut socklen_t);
}
match Dns::parse(&buf[..count as usize]) {
Ok(response) => {
let mut addrs = vec![];
for answer in response.answers.iter() {
if answer.a_type == 0x0001 && answer.a_class == 0x0001 && answer.data.len() == 4
s_addr: unsafe {
mem::transmute::<[u8; 4], u32>([
answer.data[0],
answer.data[1],
answer.data[2],
answer.data[3],
])
},
};
addrs.push(addr);
}
}
Ok(LookupHost(addrs.into_iter()))
}
Err(_err) => Err(EINVAL),
}
} else {
Err(EINVAL)
}
}
fn lookup_addr(addr: in_addr) -> Result<Vec<Vec<u8>>, c_int> {
let dns_string = sys::get_dns_server();
let dns_vec: Vec<u8> = dns_string
.trim()
.split(".")
.map(|octet| octet.parse::<u8>().unwrap_or(0))
.collect();
for (i, octet) in dns_vec.iter().enumerate() {
dns_arr[i] = *octet;
}
let mut addr_vec: Vec<u8> = unsafe { mem::transmute::<u32, [u8; 4]>(addr.s_addr).to_vec() };
addr_vec.reverse();
let mut name: Vec<u8> = vec![];
for octet in addr_vec {
for ch in format!("{}", octet).as_bytes() {
name.push(*ch);
}
name.push(b"."[0]);
}
name.pop();
for ch in b".IN-ADDR.ARPA" {
name.push(*ch);
}
if dns_vec.len() == 4 {
let mut timespec = timespec::default();
Sys::clock_gettime(time::constants::CLOCK_REALTIME, &mut timespec);
let tid = (timespec.tv_nsec >> 16) as u16;
let packet = Dns {
transaction_id: tid,
flags: 0x0100,
queries: vec![DnsQuery {
name: String::from_utf8(name).unwrap(),
q_type: 0x000C,
q_class: 0x0001,
}],
answers: vec![],
};
let packet_data = packet.compile();
let packet_data_len = packet_data.len();
let packet_data_box = packet_data.into_boxed_slice();
let packet_data_ptr = Box::into_raw(packet_data_box) as *mut _ as *mut c_void;
let sock = unsafe { sys_socket::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP as i32) };
let mut dest = sockaddr_in {
sin_family: AF_INET as u16,
sin_port: htons(53),
sin_addr: in_addr {
},
..Default::default()
};
let dest_ptr = &mut dest as *mut _ as *mut sockaddr;
unsafe {
if sys_socket::sendto(sock, packet_data_ptr, packet_data_len, 0, dest_ptr, 16) < 0 {
return Err(EIO);
}
}
unsafe {
Box::from_raw(packet_data_ptr);
}
let mut i = mem::size_of::<sockaddr_in>() as socklen_t;
let buf_ptr = buf.as_mut_ptr() as *mut c_void;
let mut count = -1;
unsafe {
count =
sys_socket::recvfrom(sock, buf_ptr, 65536, 0, dest_ptr, &mut i as *mut socklen_t);
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
}
match Dns::parse(&buf[..count as usize]) {
Ok(response) => {
let mut names = vec![];
for answer in response.answers.iter() {
if answer.a_type == 0x000C && answer.a_class == 0x0001 {
// answer.data is encoded kinda weird.
// Basically length-prefixed strings for each
// subsection of the domain.
// We need to parse this to insert periods where
// they belong (ie at the end of each string)
let data = parse_revdns_answer(answer.data.clone());
names.push(data);
}
}
Ok(names)
}
Err(_err) => Err(EINVAL),
}
} else {
Err(EINVAL)
}
}
fn parse_revdns_answer(data: Vec<u8>) -> Vec<u8> {
let mut cursor = 0;
let mut offset = 0;
let mut index = 0;
let mut output = data.clone();
while index < data.len() - 1 {
offset = data[index] as usize;
index = cursor + offset + 1;
output[index] = '.' as u8;
cursor = index;
}
//we don't want an extra period at the end
output.pop();
output
}
#[no_mangle]
pub unsafe extern "C" fn endhostent() {
Sys::close(HOSTDB);
HOSTDB = 0;
}
#[no_mangle]
pub unsafe extern "C" fn endnetent() {
Sys::close(NETDB);
NETDB = 0;
}
#[no_mangle]
pub unsafe extern "C" fn endprotoent() {
Sys::close(PROTODB);
PROTODB = 0;
}
#[no_mangle]
pub unsafe extern "C" fn endservent() {
Sys::close(SERVDB);
SERVDB = 0;
}
#[no_mangle]
pub unsafe extern "C" fn gethostbyaddr(
v: *const c_void,
length: socklen_t,
format: c_int,
) -> *const hostent {
let addr: in_addr = *(v as *mut in_addr);
// check the hosts file first
let mut p: *const hostent;
sethostent(HOST_STAYOPEN);
let mut cp = (*p).h_addr_list;
loop {
if cp.is_null() {
break;
}
if (*cp).is_null() {
break;
}
if cp_s_addr == addr.s_addr {
sethostent(HOST_STAYOPEN);
return p;
}
cp = cp.offset(1);
}
}
//TODO actually get aliases
let mut _host_aliases: Vec<Vec<u8>> = Vec::new();
_host_aliases.push(vec![b'\0']);
host_aliases.push(ptr::null_mut());
HOST_ALIASES = Some(_host_aliases);
match lookup_addr(addr) {
Ok(s) => {
HOST_ADDR_LIST = [_HOST_ADDR_LIST.as_mut_ptr() as *mut c_char, ptr::null_mut()];
let mut host_name = s[0].to_vec();
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,
Err(e) => {
platform::errno = e;
return ptr::null();
}
}
}
#[no_mangle]
pub unsafe extern "C" fn gethostbyname(name: *const c_char) -> *const hostent {
// check if some idiot gave us an address instead of a name
let mut octets = str::from_utf8_unchecked(c_str(name)).split('.');
for i in 0..4 {
if let Some(n) = octets.next().and_then(|x| u8::from_str(x).ok()) {
s_addr[i] = n;
} else {
is_addr = false;
}
}
if octets.next() != None {
is_addr = false;
}
if is_addr == true {
let addr = in_addr {
};
return gethostbyaddr(&addr as *const _ as *const c_void, 4, AF_INET);
}
// check the hosts file first
let mut p: *const hostent;
sethostent(HOST_STAYOPEN);
if strcasecmp((*p).h_name, name) == 0 {
sethostent(HOST_STAYOPEN);
return p;
}
let mut cp = (*p).h_aliases;
loop {
if cp.is_null() {
break;
}
if (*cp).is_null() {
break;
}
if strcasecmp(*cp, name) == 0 {
sethostent(HOST_STAYOPEN);
return p;
}
cp = cp.offset(1);
}
}
let mut host = match lookup_host(str::from_utf8_unchecked(c_str(name))) {
Ok(lookuphost) => lookuphost,
Err(e) => {
platform::errno = e;
return ptr::null();
}
};
let host_addr = match host.next() {
Some(result) => result,
None => {
platform::errno = ENOENT;
return ptr::null();
}
};
let host_name: Vec<u8> = c_str(name).to_vec();
HOST_NAME = Some(host_name);
_HOST_ADDR_LIST = mem::transmute::<u32, [u8; 4]>(host_addr.s_addr);
HOST_ADDR_LIST = [_HOST_ADDR_LIST.as_mut_ptr() as *mut c_char, ptr::null_mut()];
HOST_ADDR = Some(host_addr);
//TODO actually get aliases
let mut _host_aliases: Vec<Vec<u8>> = Vec::new();
_host_aliases.push(vec![b'\0']);
host_aliases.push(ptr::null_mut());
host_aliases.push(ptr::null_mut());
HOST_ALIASES = Some(_host_aliases);
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,
};
sethostent(HOST_STAYOPEN);
&HOST_ENTRY as *const hostent
}
#[no_mangle]
pub unsafe extern "C" fn gethostent() -> *const 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<str> = 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),
_ => {
return ptr::null();
}
};
}
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 = [_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<u8>> = Vec::new();
loop {
let mut alias = match iter.next() {
Some(s) => 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,
if HOST_STAYOPEN == 0 {
endhostent();
}
&HOST_ENTRY as *const hostent
}
pub unsafe extern "C" fn getnetbyaddr(net: u32, net_type: c_int) -> *const netent {
unimplemented!();
}
pub unsafe extern "C" fn getnetbyname(name: *const c_char) -> *const netent {
unimplemented!();
}
pub unsafe extern "C" fn getnetent() -> *const netent {
unimplemented!();
}
#[no_mangle]
pub unsafe extern "C" fn getprotobyname(name: *const c_char) -> *const protoent {
let mut p: *const protoent;
setprotoent(PROTO_STAYOPEN);
if strcasecmp((*p).p_name, name) == 0 {
setprotoent(PROTO_STAYOPEN);
return p;
}
let mut cp = (*p).p_aliases;
loop {
if cp == ptr::null_mut() {
setprotoent(PROTO_STAYOPEN);
break;
}
if (*cp) == ptr::null_mut() {
setprotoent(PROTO_STAYOPEN);
break;
}
platform::errno = ENOENT;
ptr::null() as *const protoent
}
#[no_mangle]
pub unsafe extern "C" fn getprotobynumber(number: c_int) -> *const protoent {
setprotoent(PROTO_STAYOPEN);
let mut p: *const protoent;
if (*p).p_proto == number {
setprotoent(PROTO_STAYOPEN);
return p;
}
}
setprotoent(PROTO_STAYOPEN);
platform::errno = ENOENT;
ptr::null() as *const protoent
#[no_mangle]
pub unsafe extern "C" fn getprotoent() -> *const protoent {
if PROTODB == 0 {
PROTODB = Sys::open(&CString::new("/etc/protocols").unwrap(), O_RDONLY, 0);
}
let mut rlb = RawLineBuffer::new(PROTODB);
rlb.seek(P_POS);
let mut r: Box<str> = 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),
_ => {
};
}
rlb.next();
P_POS = rlb.line_pos();
let mut iter: SplitWhitespace = r.split_whitespace();
let mut proto_name: Vec<u8> = iter.next().unwrap().as_bytes().to_vec();
proto_name.push(b'\0');
let mut num = iter.next().unwrap().as_bytes().to_vec();
num.push(b'\0');
PROTO_NUM = Some(atoi(num.as_mut_slice().as_mut_ptr() as *mut i8));
let mut _proto_aliases: Vec<Vec<u8>> = Vec::new();
loop {
let mut alias = match iter.next() {
Some(s) => s.as_bytes().to_vec(),
let mut proto_aliases: Vec<*mut i8> = _proto_aliases
.iter_mut()
.map(|x| x.as_mut_ptr() as *mut i8)
.collect();
proto_aliases.push(ptr::null_mut());
PROTO_ALIASES = Some(_proto_aliases);
PROTO_NAME = Some(proto_name);
p_name: PROTO_NAME.as_mut().unwrap().as_mut_slice().as_mut_ptr() as *mut c_char,
p_aliases: proto_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8,
if PROTO_STAYOPEN == 0 {
endprotoent();
}
&PROTO_ENTRY as *const protoent
}
#[no_mangle]
pub unsafe extern "C" fn getservbyname(
name: *const c_char,
setservent(SERV_STAYOPEN);
let mut p: *const servent;
if proto.is_null() {
if strcasecmp((*p).s_name, name) == 0 {
setservent(SERV_STAYOPEN);
return p;
}
}
} else {
if strcasecmp((*p).s_name, name) == 0 && strcasecmp((*p).s_proto, proto) == 0 {
setservent(SERV_STAYOPEN);
return p;
}
}
}
setservent(SERV_STAYOPEN);
platform::errno = ENOENT;
ptr::null() as *const servent
}
#[no_mangle]
pub unsafe extern "C" fn getservbyport(port: c_int, proto: *const c_char) -> *const servent {
setservent(SERV_STAYOPEN);
let mut p: *const servent;
if proto.is_null() {
while {
p = getservent();
p != ptr::null()
} {
if (*p).s_port == port {
setservent(SERV_STAYOPEN);
return p;
}
if (*p).s_port == port && strcasecmp((*p).s_proto, proto) == 0 {
setservent(SERV_STAYOPEN);
return p;
}
}
}
setservent(SERV_STAYOPEN);
platform::errno = ENOENT;
ptr::null()
}
#[no_mangle]
pub unsafe extern "C" fn getservent() -> *const servent {
if SERVDB == 0 {
SERVDB = Sys::open(&CString::new("/etc/services").unwrap(), O_RDONLY, 0);
}
let mut rlb = RawLineBuffer::new(SERVDB);
rlb.seek(S_POS);
let mut r: Box<str> = Box::default();
loop {
let mut r = match rlb.next() {
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
let mut iter = r.split_whitespace();
let mut serv_name = match iter.next() {
Some(serv_name) => serv_name.as_bytes().to_vec(),
None => continue
};
serv_name.push(b'\0');
let port_proto = match iter.next() {
Some(port_proto) => port_proto,
None => continue
};
let mut split = port_proto.split("/");
let mut port = match split.next() {
Some(port) => port.as_bytes().to_vec(),
None => continue
};
port.push(b'\0');
SERV_PORT = Some(htons(atoi(port.as_mut_slice().as_mut_ptr() as *mut i8) as u16) as u32 as i32);
let mut proto = match split.next() {
Some(proto) => proto.as_bytes().to_vec(),
None => continue
};
proto.push(b'\0');
rlb.next();
S_POS = rlb.line_pos();
/*
*let mut _serv_aliases: Vec<Vec<u8>> = Vec::new();
*loop {
* let mut alias = match iter.next() {
* Some(s) => s.as_bytes().to_vec(),
* _ => break
* };
* alias.push(b'\0');
* _serv_aliases.push(alias);
*}
*let mut serv_aliases: Vec<*mut i8> = _serv_aliases.iter_mut().map(|x| x.as_mut_ptr() as *mut i8).collect();
*serv_aliases.push(ptr::null_mut());
*
*/
let mut _serv_aliases: Vec<Vec<u8>> = Vec::new();
_serv_aliases.push(vec![b'\0']);
let mut serv_aliases: Vec<*mut i8> = Vec::new();
serv_aliases.push(ptr::null_mut());
serv_aliases.push(ptr::null_mut());
SERV_ALIASES = Some(_serv_aliases);
SERV_NAME = Some(serv_name);
SERV_PROTO = Some(proto);
SERV_ENTRY = servent {
s_name: SERV_NAME.as_mut().unwrap().as_mut_slice().as_mut_ptr() as *mut c_char,
s_aliases: serv_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8,
s_port: SERV_PORT.unwrap(),
s_proto: SERV_PROTO.as_mut().unwrap().as_mut_slice().as_mut_ptr() as *mut c_char,
};
if SERV_STAYOPEN == 0 {
endservent();
}
break &SERV_ENTRY as *const 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 {
}
H_POS = 0;
}
#[no_mangle]
pub unsafe extern "C" fn setnetent(stayopen: c_int) {
NET_STAYOPEN = stayopen;
if NETDB == 0 {
NETDB = Sys::open(&CString::new("/etc/networks").unwrap(), O_RDONLY, 0)
} else {
}
}
#[no_mangle]
pub unsafe extern "C" fn setprotoent(stayopen: c_int) {
PROTO_STAYOPEN = stayopen;
if PROTODB == 0 {
PROTODB = Sys::open(&CString::new("/etc/protocols").unwrap(), O_RDONLY, 0)
} else {
}
}
#[no_mangle]
pub unsafe extern "C" fn setservent(stayopen: c_int) {
SERV_STAYOPEN = stayopen;
if SERVDB == 0 {
SERVDB = Sys::open(&CString::new("/etc/services").unwrap(), O_RDONLY, 0)
} else {
}
}
pub unsafe extern "C" fn getaddrinfo(
node: *const c_char,
service: *const c_char,
hints: *const addrinfo,
unimplemented!();
}
pub unsafe extern "C" fn getnameinfo(
addr: *const sockaddr,
addrlen: socklen_t,
host: *mut c_char,
hostlen: socklen_t,
serv: *mut c_char,
servlen: socklen_t,