1 use alloc::{boxed::Box, str::SplitWhitespace, vec::Vec};
2 use core::{mem, ptr};
3
4 use crate::unix::platform;
5 use crate::unix::{
6 header::{
7 arpa_inet::inet_aton, fcntl::O_RDONLY, netinet_in::in_addr, sys_socket::constants::AF_INET,
8 unistd::SEEK_SET,
9 },
10 platform::rlb::{Line, RawLineBuffer},
11 };
12
13 use super::{bytes_to_box_str, hostent};
14
15 static mut HOSTDB: ::c_int = -1;
16 pub static mut HOST_ENTRY: hostent = hostent {
17 h_name: ptr::null_mut(),
18 h_aliases: ptr::null_mut(),
19 h_addrtype: 0,
20 h_length: 0,
21 h_addr_list: ptr::null_mut(),
22 };
23 pub static mut HOST_NAME: Option<Vec<u8>> = None;
24 pub static mut HOST_ALIASES: Option<Vec<Vec<u8>>> = None;
25 static mut _HOST_ALIASES: Option<Vec<*mut i8>> = None;
26 pub static mut HOST_ADDR: Option<in_addr> = None;
27 pub static mut HOST_ADDR_LIST: [*mut ::c_char; 2] = [ptr::null_mut(); 2];
28 pub static mut _HOST_ADDR_LIST: [u8; 4] = [0u8; 4];
29 static mut H_POS: usize = 0;
30 pub static mut HOST_STAYOPEN: ::c_int = 0;
31
32 #[no_mangle]
endhostent()33 pub unsafe extern "C" fn endhostent() {
34 if HOSTDB >= 0 {
35 platform::pal::close(HOSTDB);
36 }
37 HOSTDB = -1;
38 }
39
40 #[no_mangle]
sethostent(stayopen: ::c_int)41 pub unsafe extern "C" fn sethostent(stayopen: ::c_int) {
42 HOST_STAYOPEN = stayopen;
43 if HOSTDB < 0 {
44 HOSTDB = platform::pal::open("/etc/hosts".as_ptr() as *const i8, O_RDONLY, 0)
45 } else {
46 platform::pal::lseek(HOSTDB, 0, SEEK_SET);
47 }
48 H_POS = 0;
49 }
50
51 #[no_mangle]
gethostent() -> *mut hostent52 pub unsafe extern "C" fn gethostent() -> *mut hostent {
53 if HOSTDB < 0 {
54 HOSTDB = platform::pal::open("/etc/hosts".as_ptr() as *const i8, O_RDONLY, 0);
55 }
56 let mut rlb = RawLineBuffer::new(HOSTDB);
57 rlb.seek(H_POS);
58
59 let mut r: Box<str> = Box::default();
60 while r.is_empty() || r.split_whitespace().next() == None || r.starts_with('#') {
61 r = match rlb.next() {
62 Line::Some(s) => bytes_to_box_str(s),
63 _ => {
64 if HOST_STAYOPEN == 0 {
65 endhostent();
66 }
67 return ptr::null_mut();
68 }
69 };
70 }
71 rlb.next();
72 H_POS = rlb.line_pos();
73
74 let mut iter: SplitWhitespace = r.split_whitespace();
75
76 let mut addr_vec = iter.next().unwrap().as_bytes().to_vec();
77 addr_vec.push(b'\0');
78 let addr_cstr = addr_vec.as_slice().as_ptr() as *const i8;
79 let mut addr = mem::MaybeUninit::uninit();
80 inet_aton(addr_cstr, addr.as_mut_ptr());
81 let addr = addr.assume_init();
82
83 _HOST_ADDR_LIST = mem::transmute::<u32, [u8; 4]>(addr.s_addr);
84 HOST_ADDR_LIST = [
85 _HOST_ADDR_LIST.as_mut_ptr() as *mut ::c_char,
86 ptr::null_mut(),
87 ];
88
89 HOST_ADDR = Some(addr);
90
91 let mut host_name = iter.next().unwrap().as_bytes().to_vec();
92 host_name.push(b'\0');
93
94 let mut _host_aliases: Vec<Vec<u8>> = Vec::new();
95
96 for s in iter {
97 let mut alias = s.as_bytes().to_vec();
98 alias.push(b'\0');
99 _host_aliases.push(alias);
100 }
101 HOST_ALIASES = Some(_host_aliases);
102
103 let mut host_aliases: Vec<*mut i8> = HOST_ALIASES
104 .as_mut()
105 .unwrap()
106 .iter_mut()
107 .map(|x| x.as_mut_ptr() as *mut i8)
108 .collect();
109 host_aliases.push(ptr::null_mut());
110 host_aliases.push(ptr::null_mut());
111
112 HOST_NAME = Some(host_name);
113
114 HOST_ENTRY = hostent {
115 h_name: HOST_NAME.as_mut().unwrap().as_mut_ptr() as *mut ::c_char,
116 h_aliases: host_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8,
117 h_addrtype: AF_INET,
118 h_length: 4,
119 h_addr_list: HOST_ADDR_LIST.as_mut_ptr(),
120 };
121 _HOST_ALIASES = Some(host_aliases);
122 if HOST_STAYOPEN == 0 {
123 endhostent();
124 }
125 &mut HOST_ENTRY as *mut hostent
126 }
127