mod.rs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  1. //! netdb implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/netdb.h.html
  2. mod dns;
  3. use core::str::FromStr;
  4. use core::{mem, ptr, str};
  5. use alloc::boxed::Box;
  6. use alloc::str::SplitWhitespace;
  7. use alloc::string::{String, ToString};
  8. use alloc::vec::{IntoIter, Vec};
  9. use c_str::{CStr, CString};
  10. use platform;
  11. use platform::rlb::{Line, RawLineBuffer};
  12. use platform::types::*;
  13. use platform::{Pal, Sys};
  14. use self::dns::{Dns, DnsQuery};
  15. use header::arpa_inet::{htons, inet_aton};
  16. use header::errno::*;
  17. use header::fcntl::O_RDONLY;
  18. use header::netinet_in::{in_addr, sockaddr_in, IPPROTO_UDP};
  19. use header::stdlib::atoi;
  20. use header::strings::strcasecmp;
  21. use header::sys_socket;
  22. use header::sys_socket::constants::{AF_INET, SOCK_DGRAM};
  23. use header::sys_socket::{sockaddr, socklen_t};
  24. use header::time;
  25. use header::time::timespec;
  26. use header::unistd::SEEK_SET;
  27. #[cfg(target_os = "linux")]
  28. #[path = "linux.rs"]
  29. pub mod sys;
  30. #[cfg(target_os = "redox")]
  31. #[path = "redox.rs"]
  32. pub mod sys;
  33. const MAXADDRS: usize = 35;
  34. const MAXALIASES: usize = 35;
  35. struct LookupHost(IntoIter<in_addr>);
  36. impl Iterator for LookupHost {
  37. type Item = in_addr;
  38. fn next(&mut self) -> Option<Self::Item> {
  39. self.0.next()
  40. }
  41. }
  42. #[repr(C)]
  43. pub struct hostent {
  44. h_name: *mut c_char,
  45. h_aliases: *mut *mut c_char,
  46. h_addrtype: c_int,
  47. h_length: c_int,
  48. h_addr_list: *mut *mut c_char,
  49. }
  50. #[repr(C)]
  51. pub struct netent {
  52. n_name: *mut c_char, /* official name of net */
  53. n_aliases: *mut *mut c_char, /* alias list */
  54. n_addrtype: c_int, /* net address type */
  55. n_net: c_ulong, /* network # */
  56. }
  57. #[repr(C)]
  58. pub struct servent {
  59. s_name: *mut c_char, /* official service name */
  60. s_aliases: *mut *mut c_char, /* alias list */
  61. s_port: c_int, /* port # */
  62. s_proto: *mut c_char, /* protocol to use */
  63. }
  64. #[repr(C)]
  65. pub struct protoent {
  66. p_name: *mut c_char, /* official protocol name */
  67. p_aliases: *mut *mut c_char, /* alias list */
  68. p_proto: c_int, /* protocol # */
  69. }
  70. #[repr(C)]
  71. pub struct addrinfo {
  72. ai_flags: c_int, /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
  73. ai_family: c_int, /* PF_xxx */
  74. ai_socktype: c_int, /* SOCK_xxx */
  75. ai_protocol: c_int, /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
  76. ai_addrlen: size_t, /* length of ai_addr */
  77. ai_canonname: *mut c_char, /* canonical name for hostname */
  78. ai_addr: *mut sockaddr, /* binary address */
  79. ai_next: *mut addrinfo, /* next structure in linked list */
  80. }
  81. static mut NETDB: c_int = 0;
  82. static mut NET_ENTRY: netent = netent {
  83. n_name: ptr::null_mut(),
  84. n_aliases: ptr::null_mut(),
  85. n_addrtype: 0,
  86. n_net: 0,
  87. };
  88. static mut NET_NAME: Option<Vec<u8>> = None;
  89. static mut NET_ALIASES: [*const c_char; MAXALIASES] = [ptr::null(); MAXALIASES];
  90. static mut NET_NUM: Option<u64> = None;
  91. static mut N_POS: usize = 0;
  92. static mut NET_STAYOPEN: c_int = 0;
  93. static mut HOSTDB: c_int = 0;
  94. static mut HOST_ENTRY: hostent = hostent {
  95. h_name: ptr::null_mut(),
  96. h_aliases: ptr::null_mut(),
  97. h_addrtype: 0,
  98. h_length: 0,
  99. h_addr_list: ptr::null_mut(),
  100. };
  101. static mut HOST_NAME: Option<Vec<u8>> = None;
  102. static mut HOST_ALIASES: Option<Vec<Vec<u8>>> = None;
  103. static mut _HOST_ALIASES: Option<Vec<*mut i8>> = None;
  104. static mut HOST_ADDR: Option<in_addr> = None;
  105. static mut HOST_ADDR_LIST: [*mut c_char; 2] = [ptr::null_mut(); 2];
  106. static mut _HOST_ADDR_LIST: [u8; 4] = [0u8; 4];
  107. static mut H_POS: usize = 0;
  108. static mut HOST_STAYOPEN: c_int = 0;
  109. #[allow(non_upper_case_globals)]
  110. #[no_mangle]
  111. pub static mut h_errno: c_int = 0;
  112. pub const HOST_NOT_FOUND: c_int = 1;
  113. pub const NO_DATA: c_int = 2;
  114. pub const NO_RECOVERY: c_int = 3;
  115. pub const TRY_AGAIN: c_int = 4;
  116. static mut PROTODB: c_int = 0;
  117. static mut PROTO_ENTRY: protoent = protoent {
  118. p_name: ptr::null_mut(),
  119. p_aliases: ptr::null_mut(),
  120. p_proto: 0 as c_int,
  121. };
  122. static mut PROTO_NAME: Option<Vec<u8>> = None;
  123. static mut PROTO_ALIASES: Option<Vec<Vec<u8>>> = None;
  124. static mut PROTO_NUM: Option<c_int> = None;
  125. static mut P_POS: usize = 0;
  126. static mut PROTO_STAYOPEN: c_int = 0;
  127. static mut SERVDB: c_int = 0;
  128. static mut SERV_ENTRY: servent = servent {
  129. s_name: ptr::null_mut(),
  130. s_aliases: ptr::null_mut(),
  131. s_port: 0 as c_int,
  132. s_proto: ptr::null_mut(),
  133. };
  134. static mut SERV_NAME: Option<Vec<u8>> = None;
  135. static mut SERV_ALIASES: Option<Vec<Vec<u8>>> = None;
  136. static mut SERV_PORT: Option<c_int> = None;
  137. static mut SERV_PROTO: Option<Vec<u8>> = None;
  138. static mut S_POS: usize = 0;
  139. static mut SERV_STAYOPEN: c_int = 0;
  140. const NULL_ALIASES: [*mut c_char; 2] = [ptr::null_mut(); 2];
  141. fn bytes_to_box_str(bytes: &[u8]) -> Box<str> {
  142. Box::from(core::str::from_utf8(bytes).unwrap_or(""))
  143. }
  144. fn lookup_host(host: &str) -> Result<LookupHost, c_int> {
  145. let dns_string = sys::get_dns_server();
  146. let dns_vec: Vec<u8> = dns_string
  147. .trim()
  148. .split(".")
  149. .map(|octet| octet.parse::<u8>().unwrap_or(0))
  150. .collect();
  151. if dns_vec.len() == 4 {
  152. let mut dns_arr = [0u8; 4];
  153. for (i, octet) in dns_vec.iter().enumerate() {
  154. dns_arr[i] = *octet;
  155. }
  156. let dns_addr = unsafe { mem::transmute::<[u8; 4], u32>(dns_arr) };
  157. let mut timespec = timespec::default();
  158. Sys::clock_gettime(time::constants::CLOCK_REALTIME, &mut timespec);
  159. let tid = (timespec.tv_nsec >> 16) as u16;
  160. let packet = Dns {
  161. transaction_id: tid,
  162. flags: 0x0100,
  163. queries: vec![DnsQuery {
  164. name: host.to_string(),
  165. q_type: 0x0001,
  166. q_class: 0x0001,
  167. }],
  168. answers: vec![],
  169. };
  170. let packet_data = packet.compile();
  171. let packet_data_len = packet_data.len();
  172. let packet_data_box = packet_data.into_boxed_slice();
  173. let packet_data_ptr = Box::into_raw(packet_data_box) as *mut _ as *mut c_void;
  174. let dest = sockaddr_in {
  175. sin_family: AF_INET as u16,
  176. sin_port: htons(53),
  177. sin_addr: in_addr { s_addr: dns_addr },
  178. ..Default::default()
  179. };
  180. let dest_ptr = &dest as *const _ as *const sockaddr;
  181. let sock = unsafe {
  182. let sock = sys_socket::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP as i32);
  183. if sys_socket::connect(sock, dest_ptr, mem::size_of_val(&dest) as socklen_t) < 0 {
  184. return Err(EIO);
  185. }
  186. if sys_socket::send(sock, packet_data_ptr, packet_data_len, 0) < 0 {
  187. Box::from_raw(packet_data_ptr);
  188. return Err(EIO);
  189. }
  190. sock
  191. };
  192. unsafe {
  193. Box::from_raw(packet_data_ptr);
  194. }
  195. let i = 0 as socklen_t;
  196. let mut buf = [0u8; 65536];
  197. let buf_ptr = buf.as_mut_ptr() as *mut c_void;
  198. let count = unsafe { sys_socket::recv(sock, buf_ptr, 65536, 0) };
  199. if count < 0 {
  200. return Err(EIO);
  201. }
  202. match Dns::parse(&buf[..count as usize]) {
  203. Ok(response) => {
  204. let mut addrs = vec![];
  205. for answer in response.answers.iter() {
  206. if answer.a_type == 0x0001 && answer.a_class == 0x0001 && answer.data.len() == 4
  207. {
  208. let addr = in_addr {
  209. s_addr: unsafe {
  210. mem::transmute::<[u8; 4], u32>([
  211. answer.data[0],
  212. answer.data[1],
  213. answer.data[2],
  214. answer.data[3],
  215. ])
  216. },
  217. };
  218. addrs.push(addr);
  219. }
  220. }
  221. Ok(LookupHost(addrs.into_iter()))
  222. }
  223. Err(_err) => Err(EINVAL),
  224. }
  225. } else {
  226. Err(EINVAL)
  227. }
  228. }
  229. fn lookup_addr(addr: in_addr) -> Result<Vec<Vec<u8>>, c_int> {
  230. let dns_string = sys::get_dns_server();
  231. let dns_vec: Vec<u8> = dns_string
  232. .trim()
  233. .split('.')
  234. .map(|octet| octet.parse::<u8>().unwrap_or(0))
  235. .collect();
  236. let mut dns_arr = [0u8; 4];
  237. for (i, octet) in dns_vec.iter().enumerate() {
  238. dns_arr[i] = *octet;
  239. }
  240. let mut addr_vec: Vec<u8> = unsafe { mem::transmute::<u32, [u8; 4]>(addr.s_addr).to_vec() };
  241. addr_vec.reverse();
  242. let mut name: Vec<u8> = vec![];
  243. for octet in addr_vec {
  244. for ch in format!("{}", octet).as_bytes() {
  245. name.push(*ch);
  246. }
  247. name.push(b"."[0]);
  248. }
  249. name.pop();
  250. for ch in b".IN-ADDR.ARPA" {
  251. name.push(*ch);
  252. }
  253. if dns_vec.len() == 4 {
  254. let mut timespec = timespec::default();
  255. Sys::clock_gettime(time::constants::CLOCK_REALTIME, &mut timespec);
  256. let tid = (timespec.tv_nsec >> 16) as u16;
  257. let packet = Dns {
  258. transaction_id: tid,
  259. flags: 0x0100,
  260. queries: vec![DnsQuery {
  261. name: String::from_utf8(name).unwrap(),
  262. q_type: 0x000C,
  263. q_class: 0x0001,
  264. }],
  265. answers: vec![],
  266. };
  267. let packet_data = packet.compile();
  268. let packet_data_len = packet_data.len();
  269. let packet_data_box = packet_data.into_boxed_slice();
  270. let packet_data_ptr = Box::into_raw(packet_data_box) as *mut _ as *mut c_void;
  271. let dest = sockaddr_in {
  272. sin_family: AF_INET as u16,
  273. sin_port: htons(53),
  274. sin_addr: in_addr {
  275. s_addr: unsafe { mem::transmute::<[u8; 4], u32>(dns_arr) },
  276. },
  277. ..Default::default()
  278. };
  279. let dest_ptr = &dest as *const _ as *const sockaddr;
  280. let sock = unsafe {
  281. let sock = sys_socket::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP as i32);
  282. if sys_socket::connect(sock, dest_ptr, mem::size_of_val(&dest) as socklen_t) < 0 {
  283. return Err(EIO);
  284. }
  285. sock
  286. };
  287. unsafe {
  288. if sys_socket::send(sock, packet_data_ptr, packet_data_len, 0) < 0 {
  289. return Err(EIO);
  290. }
  291. }
  292. unsafe {
  293. Box::from_raw(packet_data_ptr);
  294. }
  295. let i = mem::size_of::<sockaddr_in>() as socklen_t;
  296. let mut buf = [0u8; 65536];
  297. let buf_ptr = buf.as_mut_ptr() as *mut c_void;
  298. let count = unsafe { sys_socket::recv(sock, buf_ptr, 65536, 0) };
  299. if count < 0 {
  300. return Err(EIO);
  301. }
  302. match Dns::parse(&buf[..count as usize]) {
  303. Ok(response) => {
  304. let mut names = vec![];
  305. for answer in response.answers.iter() {
  306. if answer.a_type == 0x000C && answer.a_class == 0x0001 {
  307. // answer.data is encoded kinda weird.
  308. // Basically length-prefixed strings for each
  309. // subsection of the domain.
  310. // We need to parse this to insert periods where
  311. // they belong (ie at the end of each string)
  312. let data = parse_revdns_answer(&answer.data);
  313. names.push(data);
  314. }
  315. }
  316. Ok(names)
  317. }
  318. Err(_err) => Err(EINVAL),
  319. }
  320. } else {
  321. Err(EINVAL)
  322. }
  323. }
  324. fn parse_revdns_answer(data: &[u8]) -> Vec<u8> {
  325. let mut cursor = 0;
  326. let mut index = 0;
  327. let mut output = data.to_vec();
  328. while index < data.len() - 1 {
  329. let offset = data[index] as usize;
  330. index = cursor + offset + 1;
  331. output[index] = b'.';
  332. cursor = index;
  333. }
  334. //we don't want an extra period at the end
  335. output.pop();
  336. output
  337. }
  338. #[no_mangle]
  339. pub unsafe extern "C" fn endhostent() {
  340. Sys::close(HOSTDB);
  341. HOSTDB = 0;
  342. }
  343. #[no_mangle]
  344. pub unsafe extern "C" fn endnetent() {
  345. Sys::close(NETDB);
  346. NETDB = 0;
  347. }
  348. #[no_mangle]
  349. pub unsafe extern "C" fn endprotoent() {
  350. Sys::close(PROTODB);
  351. PROTODB = 0;
  352. }
  353. #[no_mangle]
  354. pub unsafe extern "C" fn endservent() {
  355. Sys::close(SERVDB);
  356. SERVDB = 0;
  357. }
  358. #[no_mangle]
  359. pub unsafe extern "C" fn gethostbyaddr(
  360. v: *const c_void,
  361. length: socklen_t,
  362. format: c_int,
  363. ) -> *const hostent {
  364. let addr: in_addr = *(v as *mut in_addr);
  365. // check the hosts file first
  366. let mut p: *const hostent;
  367. sethostent(HOST_STAYOPEN);
  368. while {
  369. p = gethostent();
  370. !p.is_null()
  371. } {
  372. let mut cp = (*p).h_addr_list;
  373. loop {
  374. if cp.is_null() {
  375. break;
  376. }
  377. if (*cp).is_null() {
  378. break;
  379. }
  380. let mut cp_slice: [i8; 4] = [0i8; 4];
  381. (*cp).copy_to(cp_slice.as_mut_ptr(), 4);
  382. let cp_s_addr = mem::transmute::<[i8; 4], u32>(cp_slice);
  383. if cp_s_addr == addr.s_addr {
  384. sethostent(HOST_STAYOPEN);
  385. return p;
  386. }
  387. cp = cp.offset(1);
  388. }
  389. }
  390. //TODO actually get aliases
  391. let mut _host_aliases: Vec<Vec<u8>> = Vec::new();
  392. _host_aliases.push(vec![b'\0']);
  393. let mut host_aliases: Vec<*mut i8> = Vec::new();
  394. host_aliases.push(ptr::null_mut());
  395. HOST_ALIASES = Some(_host_aliases);
  396. match lookup_addr(addr) {
  397. Ok(s) => {
  398. _HOST_ADDR_LIST = mem::transmute::<u32, [u8; 4]>(addr.s_addr);
  399. HOST_ADDR_LIST = [_HOST_ADDR_LIST.as_mut_ptr() as *mut c_char, ptr::null_mut()];
  400. let mut host_name = s[0].to_vec();
  401. HOST_NAME = Some(host_name);
  402. HOST_ENTRY = hostent {
  403. h_name: HOST_NAME.as_mut().unwrap().as_mut_ptr() as *mut c_char,
  404. h_aliases: host_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8,
  405. h_addrtype: format,
  406. h_length: length as i32,
  407. h_addr_list: HOST_ADDR_LIST.as_mut_ptr(),
  408. };
  409. &HOST_ENTRY
  410. }
  411. Err(e) => {
  412. platform::errno = e;
  413. ptr::null()
  414. }
  415. }
  416. }
  417. #[no_mangle]
  418. pub unsafe extern "C" fn gethostbyname(name: *const c_char) -> *const hostent {
  419. // check if some idiot gave us an address instead of a name
  420. let name_cstr = CStr::from_ptr(name);
  421. let mut octets = str::from_utf8_unchecked(name_cstr.to_bytes()).split('.');
  422. let mut s_addr = [0u8; 4];
  423. let mut is_addr = true;
  424. for item in &mut s_addr {
  425. if let Some(n) = octets.next().and_then(|x| u8::from_str(x).ok()) {
  426. *item = n;
  427. } else {
  428. is_addr = false;
  429. }
  430. }
  431. if octets.next() != None {
  432. is_addr = false;
  433. }
  434. if is_addr {
  435. let addr = in_addr {
  436. s_addr: mem::transmute::<[u8; 4], u32>(s_addr),
  437. };
  438. return gethostbyaddr(&addr as *const _ as *const c_void, 4, AF_INET);
  439. }
  440. // check the hosts file first
  441. let mut p: *const hostent;
  442. sethostent(HOST_STAYOPEN);
  443. while {
  444. p = gethostent();
  445. !p.is_null()
  446. } {
  447. if strcasecmp((*p).h_name, name) == 0 {
  448. sethostent(HOST_STAYOPEN);
  449. return p;
  450. }
  451. let mut cp = (*p).h_aliases;
  452. loop {
  453. if cp.is_null() {
  454. break;
  455. }
  456. if (*cp).is_null() {
  457. break;
  458. }
  459. if strcasecmp(*cp, name) == 0 {
  460. sethostent(HOST_STAYOPEN);
  461. return p;
  462. }
  463. cp = cp.offset(1);
  464. }
  465. }
  466. let name_cstr = CStr::from_ptr(name);
  467. let mut host = match lookup_host(str::from_utf8_unchecked(name_cstr.to_bytes())) {
  468. Ok(lookuphost) => lookuphost,
  469. Err(e) => {
  470. platform::errno = e;
  471. return ptr::null();
  472. }
  473. };
  474. let host_addr = match host.next() {
  475. Some(result) => result,
  476. None => {
  477. platform::errno = ENOENT;
  478. return ptr::null();
  479. }
  480. };
  481. let host_name: Vec<u8> = name_cstr.to_bytes().to_vec();
  482. HOST_NAME = Some(host_name);
  483. _HOST_ADDR_LIST = mem::transmute::<u32, [u8; 4]>(host_addr.s_addr);
  484. HOST_ADDR_LIST = [_HOST_ADDR_LIST.as_mut_ptr() as *mut c_char, ptr::null_mut()];
  485. HOST_ADDR = Some(host_addr);
  486. //TODO actually get aliases
  487. let mut _host_aliases: Vec<Vec<u8>> = Vec::new();
  488. _host_aliases.push(vec![b'\0']);
  489. let mut host_aliases: Vec<*mut i8> = Vec::new();
  490. host_aliases.push(ptr::null_mut());
  491. host_aliases.push(ptr::null_mut());
  492. HOST_ALIASES = Some(_host_aliases);
  493. HOST_ENTRY = hostent {
  494. h_name: HOST_NAME.as_mut().unwrap().as_mut_ptr() as *mut c_char,
  495. h_aliases: host_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8,
  496. h_addrtype: AF_INET,
  497. h_length: 4,
  498. h_addr_list: HOST_ADDR_LIST.as_mut_ptr(),
  499. };
  500. sethostent(HOST_STAYOPEN);
  501. &HOST_ENTRY as *const hostent
  502. }
  503. #[no_mangle]
  504. pub unsafe extern "C" fn gethostent() -> *const hostent {
  505. if HOSTDB == 0 {
  506. HOSTDB = Sys::open(&CString::new("/etc/hosts").unwrap(), O_RDONLY, 0);
  507. }
  508. let mut rlb = RawLineBuffer::new(HOSTDB);
  509. rlb.seek(H_POS);
  510. let mut r: Box<str> = Box::default();
  511. while r.is_empty() || r.split_whitespace().next() == None || r.starts_with('#') {
  512. r = match rlb.next() {
  513. Line::Some(s) => bytes_to_box_str(s),
  514. _ => {
  515. if HOST_STAYOPEN == 0 {
  516. endhostent();
  517. }
  518. return ptr::null();
  519. }
  520. };
  521. }
  522. rlb.next();
  523. H_POS = rlb.line_pos();
  524. let mut iter: SplitWhitespace = r.split_whitespace();
  525. let mut addr_vec = iter.next().unwrap().as_bytes().to_vec();
  526. addr_vec.push(b'\0');
  527. let addr_cstr = addr_vec.as_slice().as_ptr() as *const i8;
  528. let mut addr = mem::uninitialized();
  529. inet_aton(addr_cstr, &mut addr);
  530. _HOST_ADDR_LIST = mem::transmute::<u32, [u8; 4]>(addr.s_addr);
  531. HOST_ADDR_LIST = [_HOST_ADDR_LIST.as_mut_ptr() as *mut c_char, ptr::null_mut()];
  532. HOST_ADDR = Some(addr);
  533. let mut host_name = iter.next().unwrap().as_bytes().to_vec();
  534. host_name.push(b'\0');
  535. let mut _host_aliases: Vec<Vec<u8>> = Vec::new();
  536. while let Some(s) = iter.next() {
  537. let mut alias = s.as_bytes().to_vec();
  538. alias.push(b'\0');
  539. _host_aliases.push(alias);
  540. }
  541. HOST_ALIASES = Some(_host_aliases);
  542. let mut host_aliases: Vec<*mut i8> = HOST_ALIASES
  543. .as_mut()
  544. .unwrap()
  545. .iter_mut()
  546. .map(|x| x.as_mut_ptr() as *mut i8)
  547. .collect();
  548. host_aliases.push(ptr::null_mut());
  549. host_aliases.push(ptr::null_mut());
  550. HOST_NAME = Some(host_name);
  551. HOST_ENTRY = hostent {
  552. h_name: HOST_NAME.as_mut().unwrap().as_mut_ptr() as *mut c_char,
  553. h_aliases: host_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8,
  554. h_addrtype: AF_INET,
  555. h_length: 4,
  556. h_addr_list: HOST_ADDR_LIST.as_mut_ptr(),
  557. };
  558. _HOST_ALIASES = Some(host_aliases);
  559. if HOST_STAYOPEN == 0 {
  560. endhostent();
  561. }
  562. &HOST_ENTRY as *const hostent
  563. }
  564. pub unsafe extern "C" fn getnetbyaddr(net: u32, net_type: c_int) -> *const netent {
  565. unimplemented!();
  566. }
  567. pub unsafe extern "C" fn getnetbyname(name: *const c_char) -> *const netent {
  568. unimplemented!();
  569. }
  570. pub unsafe extern "C" fn getnetent() -> *const netent {
  571. unimplemented!();
  572. }
  573. #[no_mangle]
  574. pub unsafe extern "C" fn getprotobyname(name: *const c_char) -> *const protoent {
  575. let mut p: *const protoent;
  576. setprotoent(PROTO_STAYOPEN);
  577. while {
  578. p = getprotoent();
  579. !p.is_null()
  580. } {
  581. if strcasecmp((*p).p_name, name) == 0 {
  582. setprotoent(PROTO_STAYOPEN);
  583. return p;
  584. }
  585. let mut cp = (*p).p_aliases;
  586. loop {
  587. if cp.is_null() {
  588. setprotoent(PROTO_STAYOPEN);
  589. break;
  590. }
  591. if (*cp).is_null() {
  592. setprotoent(PROTO_STAYOPEN);
  593. break;
  594. }
  595. if strcasecmp(*cp, name) == 0 {
  596. setprotoent(PROTO_STAYOPEN);
  597. return p;
  598. }
  599. cp = cp.offset(1);
  600. }
  601. }
  602. setprotoent(PROTO_STAYOPEN);
  603. platform::errno = ENOENT;
  604. ptr::null() as *const protoent
  605. }
  606. #[no_mangle]
  607. pub unsafe extern "C" fn getprotobynumber(number: c_int) -> *const protoent {
  608. setprotoent(PROTO_STAYOPEN);
  609. let mut p: *const protoent;
  610. while {
  611. p = getprotoent();
  612. !p.is_null()
  613. } {
  614. if (*p).p_proto == number {
  615. setprotoent(PROTO_STAYOPEN);
  616. return p;
  617. }
  618. }
  619. setprotoent(PROTO_STAYOPEN);
  620. platform::errno = ENOENT;
  621. ptr::null() as *const protoent
  622. }
  623. #[no_mangle]
  624. pub unsafe extern "C" fn getprotoent() -> *const protoent {
  625. if PROTODB == 0 {
  626. PROTODB = Sys::open(&CString::new("/etc/protocols").unwrap(), O_RDONLY, 0);
  627. }
  628. let mut rlb = RawLineBuffer::new(PROTODB);
  629. rlb.seek(P_POS);
  630. let mut r: Box<str> = Box::default();
  631. while r.is_empty() || r.split_whitespace().next() == None || r.starts_with('#') {
  632. r = match rlb.next() {
  633. Line::Some(s) => bytes_to_box_str(s),
  634. _ => {
  635. if PROTO_STAYOPEN == 0 {
  636. endprotoent();
  637. }
  638. return ptr::null();
  639. }
  640. };
  641. }
  642. rlb.next();
  643. P_POS = rlb.line_pos();
  644. let mut iter: SplitWhitespace = r.split_whitespace();
  645. let mut proto_name: Vec<u8> = iter.next().unwrap().as_bytes().to_vec();
  646. proto_name.push(b'\0');
  647. let mut num = iter.next().unwrap().as_bytes().to_vec();
  648. num.push(b'\0');
  649. PROTO_NUM = Some(atoi(num.as_mut_slice().as_mut_ptr() as *mut i8));
  650. let mut _proto_aliases: Vec<Vec<u8>> = Vec::new();
  651. while let Some(s) = iter.next() {
  652. let mut alias = s.as_bytes().to_vec();
  653. alias.push(b'\0');
  654. _proto_aliases.push(alias);
  655. }
  656. let mut proto_aliases: Vec<*mut i8> = _proto_aliases
  657. .iter_mut()
  658. .map(|x| x.as_mut_ptr() as *mut i8)
  659. .collect();
  660. proto_aliases.push(ptr::null_mut());
  661. PROTO_ALIASES = Some(_proto_aliases);
  662. PROTO_NAME = Some(proto_name);
  663. PROTO_ENTRY = protoent {
  664. p_name: PROTO_NAME.as_mut().unwrap().as_mut_slice().as_mut_ptr() as *mut c_char,
  665. p_aliases: proto_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8,
  666. p_proto: PROTO_NUM.unwrap(),
  667. };
  668. if PROTO_STAYOPEN == 0 {
  669. endprotoent();
  670. }
  671. &PROTO_ENTRY as *const protoent
  672. }
  673. #[no_mangle]
  674. pub unsafe extern "C" fn getservbyname(
  675. name: *const c_char,
  676. proto: *const c_char,
  677. ) -> *const servent {
  678. setservent(SERV_STAYOPEN);
  679. let mut p: *const servent;
  680. if proto.is_null() {
  681. while {
  682. p = getservent();
  683. !p.is_null()
  684. } {
  685. if strcasecmp((*p).s_name, name) == 0 {
  686. setservent(SERV_STAYOPEN);
  687. return p;
  688. }
  689. }
  690. } else {
  691. while {
  692. p = getservent();
  693. !p.is_null()
  694. } {
  695. if strcasecmp((*p).s_name, name) == 0 && strcasecmp((*p).s_proto, proto) == 0 {
  696. setservent(SERV_STAYOPEN);
  697. return p;
  698. }
  699. }
  700. }
  701. setservent(SERV_STAYOPEN);
  702. platform::errno = ENOENT;
  703. ptr::null() as *const servent
  704. }
  705. #[no_mangle]
  706. pub unsafe extern "C" fn getservbyport(port: c_int, proto: *const c_char) -> *const servent {
  707. setservent(SERV_STAYOPEN);
  708. let mut p: *const servent;
  709. if proto.is_null() {
  710. while {
  711. p = getservent();
  712. !p.is_null()
  713. } {
  714. if (*p).s_port == port {
  715. setservent(SERV_STAYOPEN);
  716. return p;
  717. }
  718. }
  719. } else {
  720. while {
  721. p = getservent();
  722. !p.is_null()
  723. } {
  724. if (*p).s_port == port && strcasecmp((*p).s_proto, proto) == 0 {
  725. setservent(SERV_STAYOPEN);
  726. return p;
  727. }
  728. }
  729. }
  730. setservent(SERV_STAYOPEN);
  731. platform::errno = ENOENT;
  732. ptr::null()
  733. }
  734. #[no_mangle]
  735. pub unsafe extern "C" fn getservent() -> *const servent {
  736. if SERVDB == 0 {
  737. SERVDB = Sys::open(&CString::new("/etc/services").unwrap(), O_RDONLY, 0);
  738. }
  739. let mut rlb = RawLineBuffer::new(SERVDB);
  740. rlb.seek(S_POS);
  741. let r: Box<str> = Box::default();
  742. loop {
  743. let r = match rlb.next() {
  744. Line::Some(s) => bytes_to_box_str(s),
  745. _ => {
  746. if SERV_STAYOPEN == 0 {
  747. endservent();
  748. }
  749. return ptr::null();
  750. }
  751. };
  752. let mut iter = r.split_whitespace();
  753. let mut serv_name = match iter.next() {
  754. Some(serv_name) => serv_name.as_bytes().to_vec(),
  755. None => continue,
  756. };
  757. serv_name.push(b'\0');
  758. let port_proto = match iter.next() {
  759. Some(port_proto) => port_proto,
  760. None => continue,
  761. };
  762. let mut split = port_proto.split('/');
  763. let mut port = match split.next() {
  764. Some(port) => port.as_bytes().to_vec(),
  765. None => continue,
  766. };
  767. port.push(b'\0');
  768. SERV_PORT =
  769. Some(htons(atoi(port.as_mut_slice().as_mut_ptr() as *mut i8) as u16) as u32 as i32);
  770. let mut proto = match split.next() {
  771. Some(proto) => proto.as_bytes().to_vec(),
  772. None => continue,
  773. };
  774. proto.push(b'\0');
  775. rlb.next();
  776. S_POS = rlb.line_pos();
  777. /*
  778. *let mut _serv_aliases: Vec<Vec<u8>> = Vec::new();
  779. *loop {
  780. * let mut alias = match iter.next() {
  781. * Some(s) => s.as_bytes().to_vec(),
  782. * _ => break
  783. * };
  784. * alias.push(b'\0');
  785. * _serv_aliases.push(alias);
  786. *}
  787. *let mut serv_aliases: Vec<*mut i8> = _serv_aliases.iter_mut().map(|x| x.as_mut_ptr() as *mut i8).collect();
  788. *serv_aliases.push(ptr::null_mut());
  789. *
  790. */
  791. let mut _serv_aliases: Vec<Vec<u8>> = Vec::new();
  792. _serv_aliases.push(vec![b'\0']);
  793. let mut serv_aliases: Vec<*mut i8> = Vec::new();
  794. serv_aliases.push(ptr::null_mut());
  795. serv_aliases.push(ptr::null_mut());
  796. SERV_ALIASES = Some(_serv_aliases);
  797. SERV_NAME = Some(serv_name);
  798. SERV_PROTO = Some(proto);
  799. SERV_ENTRY = servent {
  800. s_name: SERV_NAME.as_mut().unwrap().as_mut_slice().as_mut_ptr() as *mut c_char,
  801. s_aliases: serv_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8,
  802. s_port: SERV_PORT.unwrap(),
  803. s_proto: SERV_PROTO.as_mut().unwrap().as_mut_slice().as_mut_ptr() as *mut c_char,
  804. };
  805. if SERV_STAYOPEN == 0 {
  806. endservent();
  807. }
  808. break &SERV_ENTRY as *const servent;
  809. }
  810. }
  811. #[no_mangle]
  812. pub unsafe extern "C" fn sethostent(stayopen: c_int) {
  813. HOST_STAYOPEN = stayopen;
  814. if HOSTDB == 0 {
  815. HOSTDB = Sys::open(&CString::new("/etc/hosts").unwrap(), O_RDONLY, 0)
  816. } else {
  817. Sys::lseek(HOSTDB, 0, SEEK_SET);
  818. }
  819. H_POS = 0;
  820. }
  821. #[no_mangle]
  822. pub unsafe extern "C" fn setnetent(stayopen: c_int) {
  823. NET_STAYOPEN = stayopen;
  824. if NETDB == 0 {
  825. NETDB = Sys::open(&CString::new("/etc/networks").unwrap(), O_RDONLY, 0)
  826. } else {
  827. Sys::lseek(NETDB, 0, SEEK_SET);
  828. N_POS = 0;
  829. }
  830. }
  831. #[no_mangle]
  832. pub unsafe extern "C" fn setprotoent(stayopen: c_int) {
  833. PROTO_STAYOPEN = stayopen;
  834. if PROTODB == 0 {
  835. PROTODB = Sys::open(&CString::new("/etc/protocols").unwrap(), O_RDONLY, 0)
  836. } else {
  837. Sys::lseek(PROTODB, 0, SEEK_SET);
  838. P_POS = 0;
  839. }
  840. }
  841. #[no_mangle]
  842. pub unsafe extern "C" fn setservent(stayopen: c_int) {
  843. SERV_STAYOPEN = stayopen;
  844. if SERVDB == 0 {
  845. SERVDB = Sys::open(&CString::new("/etc/services").unwrap(), O_RDONLY, 0)
  846. } else {
  847. Sys::lseek(SERVDB, 0, SEEK_SET);
  848. S_POS = 0;
  849. }
  850. }
  851. pub unsafe extern "C" fn getaddrinfo(
  852. node: *const c_char,
  853. service: *const c_char,
  854. hints: *const addrinfo,
  855. res: *mut *mut addrinfo,
  856. ) -> c_int {
  857. unimplemented!();
  858. }
  859. pub unsafe extern "C" fn getnameinfo(
  860. addr: *const sockaddr,
  861. addrlen: socklen_t,
  862. host: *mut c_char,
  863. hostlen: socklen_t,
  864. serv: *mut c_char,
  865. servlen: socklen_t,
  866. flags: c_int,
  867. ) -> c_int {
  868. unimplemented!();
  869. }
  870. pub extern "C" fn freeaddrinfo(res: *mut addrinfo) {
  871. unimplemented!();
  872. }
  873. pub extern "C" fn gai_strerror(errcode: c_int) -> *const c_char {
  874. unimplemented!();
  875. }