2
0

mod.rs 28 KB

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