mod.rs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. //! netdb implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xns/netdb.h.html
  2. mod dns;
  3. use core::str::FromStr;
  4. use core::{mem, ptr, slice, str};
  5. use alloc::boxed::Box;
  6. use alloc::str::SplitWhitespace;
  7. use alloc::vec::Vec;
  8. use c_str::{CStr, CString};
  9. use header::arpa_inet::htons;
  10. use header::errno::*;
  11. use header::fcntl::O_RDONLY;
  12. use header::netinet_in::{in_addr, sockaddr_in};
  13. use header::stdlib::atoi;
  14. use header::strings::strcasecmp;
  15. use header::sys_socket::constants::AF_INET;
  16. use header::sys_socket::{sockaddr, socklen_t};
  17. use header::unistd::SEEK_SET;
  18. use platform;
  19. use platform::rlb::{Line, RawLineBuffer};
  20. use platform::types::*;
  21. use platform::{Pal, Sys};
  22. #[cfg(target_os = "linux")]
  23. #[path = "linux.rs"]
  24. pub mod sys;
  25. #[cfg(target_os = "redox")]
  26. #[path = "redox.rs"]
  27. pub mod sys;
  28. pub use self::host::*;
  29. pub mod host;
  30. pub use self::lookup::*;
  31. pub mod lookup;
  32. const MAXADDRS: usize = 35;
  33. const MAXALIASES: usize = 35;
  34. #[repr(C)]
  35. pub struct hostent {
  36. h_name: *mut c_char,
  37. h_aliases: *mut *mut c_char,
  38. h_addrtype: c_int,
  39. h_length: c_int,
  40. h_addr_list: *mut *mut c_char,
  41. }
  42. #[repr(C)]
  43. pub struct netent {
  44. n_name: *mut c_char, /* official name of net */
  45. n_aliases: *mut *mut c_char, /* alias list */
  46. n_addrtype: c_int, /* net address type */
  47. n_net: c_ulong, /* network # */
  48. }
  49. #[repr(C)]
  50. pub struct protoent {
  51. p_name: *mut c_char, /* official protocol name */
  52. p_aliases: *mut *mut c_char, /* alias list */
  53. p_proto: c_int, /* protocol # */
  54. }
  55. #[repr(C)]
  56. pub struct servent {
  57. s_name: *mut c_char, /* official service name */
  58. s_aliases: *mut *mut c_char, /* alias list */
  59. s_port: c_int, /* port # */
  60. s_proto: *mut c_char, /* protocol to use */
  61. }
  62. #[repr(C)]
  63. pub struct addrinfo {
  64. ai_flags: c_int, /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
  65. ai_family: c_int, /* PF_xxx */
  66. ai_socktype: c_int, /* SOCK_xxx */
  67. ai_protocol: c_int, /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
  68. ai_addrlen: size_t, /* length of ai_addr */
  69. ai_canonname: *mut c_char, /* canonical name for hostname */
  70. ai_addr: *mut sockaddr, /* binary address */
  71. ai_next: *mut addrinfo, /* next structure in linked list */
  72. }
  73. pub const AI_PASSIVE: c_int = 0x0001;
  74. pub const AI_CANONNAME: c_int = 0x0002;
  75. pub const AI_NUMERICHOST: c_int = 0x0004;
  76. pub const AI_V4MAPPED: c_int = 0x0008;
  77. pub const AI_ALL: c_int = 0x0010;
  78. pub const AI_ADDRCONFIG: c_int = 0x0020;
  79. pub const AI_NUMERICSERV: c_int = 0x0400;
  80. pub const EAI_BADFLAGS: c_int = -1;
  81. pub const EAI_NONAME: c_int = -2;
  82. pub const EAI_AGAIN: c_int = -3;
  83. pub const EAI_FAIL: c_int = -4;
  84. pub const EAI_NODATA: c_int = -5;
  85. pub const EAI_FAMILY: c_int = -6;
  86. pub const EAI_SOCKTYPE: c_int = -7;
  87. pub const EAI_SERVICE: c_int = -8;
  88. pub const EAI_ADDRFAMILY: c_int = -9;
  89. pub const EAI_MEMORY: c_int = -10;
  90. pub const EAI_SYSTEM: c_int = -11;
  91. pub const EAI_OVERFLOW: c_int = -12;
  92. pub const NI_MAXHOST: c_int = 1025;
  93. pub const NI_MAXSERV: c_int = 32;
  94. pub const NI_NUMERICHOST: c_int = 0x0001;
  95. pub const NI_NUMERICSERV: c_int = 0x0002;
  96. pub const NI_NOFQDN: c_int = 0x0004;
  97. pub const NI_NAMEREQD: c_int = 0x0008;
  98. pub const NI_DGRAM: c_int = 0x0010;
  99. static mut NETDB: c_int = 0;
  100. static mut NET_ENTRY: netent = netent {
  101. n_name: ptr::null_mut(),
  102. n_aliases: ptr::null_mut(),
  103. n_addrtype: 0,
  104. n_net: 0,
  105. };
  106. static mut NET_NAME: Option<Vec<u8>> = None;
  107. static mut NET_ALIASES: [*const c_char; MAXALIASES] = [ptr::null(); MAXALIASES];
  108. static mut NET_NUM: Option<u64> = None;
  109. static mut N_POS: usize = 0;
  110. static mut NET_STAYOPEN: c_int = 0;
  111. #[allow(non_upper_case_globals)]
  112. #[no_mangle]
  113. pub static mut h_errno: c_int = 0;
  114. pub const HOST_NOT_FOUND: c_int = 1;
  115. pub const NO_DATA: c_int = 2;
  116. pub const NO_RECOVERY: c_int = 3;
  117. pub const TRY_AGAIN: c_int = 4;
  118. static mut PROTODB: c_int = 0;
  119. static mut PROTO_ENTRY: protoent = protoent {
  120. p_name: ptr::null_mut(),
  121. p_aliases: ptr::null_mut(),
  122. p_proto: 0 as c_int,
  123. };
  124. static mut PROTO_NAME: Option<Vec<u8>> = None;
  125. static mut PROTO_ALIASES: Option<Vec<Vec<u8>>> = None;
  126. static mut PROTO_NUM: Option<c_int> = None;
  127. static mut P_POS: usize = 0;
  128. static mut PROTO_STAYOPEN: c_int = 0;
  129. static mut SERVDB: c_int = 0;
  130. static mut SERV_ENTRY: servent = servent {
  131. s_name: ptr::null_mut(),
  132. s_aliases: ptr::null_mut(),
  133. s_port: 0 as c_int,
  134. s_proto: ptr::null_mut(),
  135. };
  136. static mut SERV_NAME: Option<Vec<u8>> = None;
  137. static mut SERV_ALIASES: Option<Vec<Vec<u8>>> = None;
  138. static mut SERV_PORT: Option<c_int> = None;
  139. static mut SERV_PROTO: Option<Vec<u8>> = None;
  140. static mut S_POS: usize = 0;
  141. static mut SERV_STAYOPEN: c_int = 0;
  142. const NULL_ALIASES: [*mut c_char; 2] = [ptr::null_mut(); 2];
  143. fn bytes_to_box_str(bytes: &[u8]) -> Box<str> {
  144. Box::from(core::str::from_utf8(bytes).unwrap_or(""))
  145. }
  146. #[no_mangle]
  147. pub unsafe extern "C" fn endnetent() {
  148. Sys::close(NETDB);
  149. NETDB = 0;
  150. }
  151. #[no_mangle]
  152. pub unsafe extern "C" fn endprotoent() {
  153. Sys::close(PROTODB);
  154. PROTODB = 0;
  155. }
  156. #[no_mangle]
  157. pub unsafe extern "C" fn endservent() {
  158. Sys::close(SERVDB);
  159. SERVDB = 0;
  160. }
  161. #[no_mangle]
  162. pub unsafe extern "C" fn gethostbyaddr(
  163. v: *const c_void,
  164. length: socklen_t,
  165. format: c_int,
  166. ) -> *mut hostent {
  167. let addr: in_addr = *(v as *mut in_addr);
  168. // check the hosts file first
  169. let mut p: *mut hostent;
  170. sethostent(HOST_STAYOPEN);
  171. while {
  172. p = gethostent();
  173. !p.is_null()
  174. } {
  175. let mut cp = (*p).h_addr_list;
  176. loop {
  177. if cp.is_null() {
  178. break;
  179. }
  180. if (*cp).is_null() {
  181. break;
  182. }
  183. let mut cp_slice: [i8; 4] = [0i8; 4];
  184. (*cp).copy_to(cp_slice.as_mut_ptr(), 4);
  185. let cp_s_addr = mem::transmute::<[i8; 4], u32>(cp_slice);
  186. if cp_s_addr == addr.s_addr {
  187. sethostent(HOST_STAYOPEN);
  188. return p;
  189. }
  190. cp = cp.offset(1);
  191. }
  192. }
  193. //TODO actually get aliases
  194. let mut _host_aliases: Vec<Vec<u8>> = Vec::new();
  195. _host_aliases.push(vec![b'\0']);
  196. let mut host_aliases: Vec<*mut i8> = Vec::new();
  197. host_aliases.push(ptr::null_mut());
  198. HOST_ALIASES = Some(_host_aliases);
  199. match lookup_addr(addr) {
  200. Ok(s) => {
  201. _HOST_ADDR_LIST = mem::transmute::<u32, [u8; 4]>(addr.s_addr);
  202. HOST_ADDR_LIST = [_HOST_ADDR_LIST.as_mut_ptr() as *mut c_char, ptr::null_mut()];
  203. let mut host_name = s[0].to_vec();
  204. HOST_NAME = Some(host_name);
  205. HOST_ENTRY = hostent {
  206. h_name: HOST_NAME.as_mut().unwrap().as_mut_ptr() as *mut c_char,
  207. h_aliases: host_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8,
  208. h_addrtype: format,
  209. h_length: length as i32,
  210. h_addr_list: HOST_ADDR_LIST.as_mut_ptr(),
  211. };
  212. &mut HOST_ENTRY
  213. }
  214. Err(e) => {
  215. platform::errno = e;
  216. ptr::null_mut()
  217. }
  218. }
  219. }
  220. #[no_mangle]
  221. pub unsafe extern "C" fn gethostbyname(name: *const c_char) -> *mut hostent {
  222. // check if some idiot gave us an address instead of a name
  223. let name_cstr = CStr::from_ptr(name);
  224. let mut octets = str::from_utf8_unchecked(name_cstr.to_bytes()).split('.');
  225. let mut s_addr = [0u8; 4];
  226. let mut is_addr = true;
  227. for item in &mut s_addr {
  228. if let Some(n) = octets.next().and_then(|x| u8::from_str(x).ok()) {
  229. *item = n;
  230. } else {
  231. is_addr = false;
  232. }
  233. }
  234. if octets.next() != None {
  235. is_addr = false;
  236. }
  237. if is_addr {
  238. let addr = in_addr {
  239. s_addr: mem::transmute::<[u8; 4], u32>(s_addr),
  240. };
  241. return gethostbyaddr(&addr as *const _ as *const c_void, 4, AF_INET);
  242. }
  243. // check the hosts file first
  244. let mut p: *mut hostent;
  245. sethostent(HOST_STAYOPEN);
  246. while {
  247. p = gethostent();
  248. !p.is_null()
  249. } {
  250. if strcasecmp((*p).h_name, name) == 0 {
  251. sethostent(HOST_STAYOPEN);
  252. return p;
  253. }
  254. let mut cp = (*p).h_aliases;
  255. loop {
  256. if cp.is_null() {
  257. break;
  258. }
  259. if (*cp).is_null() {
  260. break;
  261. }
  262. if strcasecmp(*cp, name) == 0 {
  263. sethostent(HOST_STAYOPEN);
  264. return p;
  265. }
  266. cp = cp.offset(1);
  267. }
  268. }
  269. let name_cstr = CStr::from_ptr(name);
  270. let mut host = match lookup_host(str::from_utf8_unchecked(name_cstr.to_bytes())) {
  271. Ok(lookuphost) => lookuphost,
  272. Err(e) => {
  273. platform::errno = e;
  274. return ptr::null_mut();
  275. }
  276. };
  277. let host_addr = match host.next() {
  278. Some(result) => result,
  279. None => {
  280. platform::errno = ENOENT;
  281. return ptr::null_mut();
  282. }
  283. };
  284. let host_name: Vec<u8> = name_cstr.to_bytes().to_vec();
  285. HOST_NAME = Some(host_name);
  286. _HOST_ADDR_LIST = mem::transmute::<u32, [u8; 4]>(host_addr.s_addr);
  287. HOST_ADDR_LIST = [_HOST_ADDR_LIST.as_mut_ptr() as *mut c_char, ptr::null_mut()];
  288. HOST_ADDR = Some(host_addr);
  289. //TODO actually get aliases
  290. let mut _host_aliases: Vec<Vec<u8>> = Vec::new();
  291. _host_aliases.push(vec![b'\0']);
  292. let mut host_aliases: Vec<*mut i8> = Vec::new();
  293. host_aliases.push(ptr::null_mut());
  294. host_aliases.push(ptr::null_mut());
  295. HOST_ALIASES = Some(_host_aliases);
  296. HOST_ENTRY = hostent {
  297. h_name: HOST_NAME.as_mut().unwrap().as_mut_ptr() as *mut c_char,
  298. h_aliases: host_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8,
  299. h_addrtype: AF_INET,
  300. h_length: 4,
  301. h_addr_list: HOST_ADDR_LIST.as_mut_ptr(),
  302. };
  303. sethostent(HOST_STAYOPEN);
  304. &mut HOST_ENTRY as *mut hostent
  305. }
  306. pub unsafe extern "C" fn getnetbyaddr(net: u32, net_type: c_int) -> *mut netent {
  307. unimplemented!();
  308. }
  309. pub unsafe extern "C" fn getnetbyname(name: *const c_char) -> *mut netent {
  310. unimplemented!();
  311. }
  312. pub unsafe extern "C" fn getnetent() -> *mut netent {
  313. unimplemented!();
  314. }
  315. #[no_mangle]
  316. pub unsafe extern "C" fn getprotobyname(name: *const c_char) -> *mut protoent {
  317. let mut p: *mut protoent;
  318. setprotoent(PROTO_STAYOPEN);
  319. while {
  320. p = getprotoent();
  321. !p.is_null()
  322. } {
  323. if strcasecmp((*p).p_name, name) == 0 {
  324. setprotoent(PROTO_STAYOPEN);
  325. return p;
  326. }
  327. let mut cp = (*p).p_aliases;
  328. loop {
  329. if cp.is_null() {
  330. setprotoent(PROTO_STAYOPEN);
  331. break;
  332. }
  333. if (*cp).is_null() {
  334. setprotoent(PROTO_STAYOPEN);
  335. break;
  336. }
  337. if strcasecmp(*cp, name) == 0 {
  338. setprotoent(PROTO_STAYOPEN);
  339. return p;
  340. }
  341. cp = cp.offset(1);
  342. }
  343. }
  344. setprotoent(PROTO_STAYOPEN);
  345. platform::errno = ENOENT;
  346. ptr::null_mut() as *mut protoent
  347. }
  348. #[no_mangle]
  349. pub unsafe extern "C" fn getprotobynumber(number: c_int) -> *mut protoent {
  350. setprotoent(PROTO_STAYOPEN);
  351. let mut p: *mut protoent;
  352. while {
  353. p = getprotoent();
  354. !p.is_null()
  355. } {
  356. if (*p).p_proto == number {
  357. setprotoent(PROTO_STAYOPEN);
  358. return p;
  359. }
  360. }
  361. setprotoent(PROTO_STAYOPEN);
  362. platform::errno = ENOENT;
  363. ptr::null_mut() as *mut protoent
  364. }
  365. #[no_mangle]
  366. pub unsafe extern "C" fn getprotoent() -> *mut protoent {
  367. if PROTODB == 0 {
  368. PROTODB = Sys::open(&CString::new("/etc/protocols").unwrap(), O_RDONLY, 0);
  369. }
  370. let mut rlb = RawLineBuffer::new(PROTODB);
  371. rlb.seek(P_POS);
  372. let mut r: Box<str> = Box::default();
  373. while r.is_empty() || r.split_whitespace().next() == None || r.starts_with('#') {
  374. r = match rlb.next() {
  375. Line::Some(s) => bytes_to_box_str(s),
  376. _ => {
  377. if PROTO_STAYOPEN == 0 {
  378. endprotoent();
  379. }
  380. return ptr::null_mut();
  381. }
  382. };
  383. }
  384. rlb.next();
  385. P_POS = rlb.line_pos();
  386. let mut iter: SplitWhitespace = r.split_whitespace();
  387. let mut proto_name: Vec<u8> = iter.next().unwrap().as_bytes().to_vec();
  388. proto_name.push(b'\0');
  389. let mut num = iter.next().unwrap().as_bytes().to_vec();
  390. num.push(b'\0');
  391. PROTO_NUM = Some(atoi(num.as_mut_slice().as_mut_ptr() as *mut i8));
  392. let mut _proto_aliases: Vec<Vec<u8>> = Vec::new();
  393. while let Some(s) = iter.next() {
  394. let mut alias = s.as_bytes().to_vec();
  395. alias.push(b'\0');
  396. _proto_aliases.push(alias);
  397. }
  398. let mut proto_aliases: Vec<*mut i8> = _proto_aliases
  399. .iter_mut()
  400. .map(|x| x.as_mut_ptr() as *mut i8)
  401. .collect();
  402. proto_aliases.push(ptr::null_mut());
  403. PROTO_ALIASES = Some(_proto_aliases);
  404. PROTO_NAME = Some(proto_name);
  405. PROTO_ENTRY = protoent {
  406. p_name: PROTO_NAME.as_mut().unwrap().as_mut_slice().as_mut_ptr() as *mut c_char,
  407. p_aliases: proto_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8,
  408. p_proto: PROTO_NUM.unwrap(),
  409. };
  410. if PROTO_STAYOPEN == 0 {
  411. endprotoent();
  412. }
  413. &mut PROTO_ENTRY as *mut protoent
  414. }
  415. #[no_mangle]
  416. pub unsafe extern "C" fn getservbyname(name: *const c_char, proto: *const c_char) -> *mut servent {
  417. setservent(SERV_STAYOPEN);
  418. let mut p: *mut servent;
  419. if proto.is_null() {
  420. while {
  421. p = getservent();
  422. !p.is_null()
  423. } {
  424. if strcasecmp((*p).s_name, name) == 0 {
  425. setservent(SERV_STAYOPEN);
  426. return p;
  427. }
  428. }
  429. } else {
  430. while {
  431. p = getservent();
  432. !p.is_null()
  433. } {
  434. if strcasecmp((*p).s_name, name) == 0 && strcasecmp((*p).s_proto, proto) == 0 {
  435. setservent(SERV_STAYOPEN);
  436. return p;
  437. }
  438. }
  439. }
  440. setservent(SERV_STAYOPEN);
  441. platform::errno = ENOENT;
  442. ptr::null_mut() as *mut servent
  443. }
  444. #[no_mangle]
  445. pub unsafe extern "C" fn getservbyport(port: c_int, proto: *const c_char) -> *mut servent {
  446. setservent(SERV_STAYOPEN);
  447. let mut p: *mut servent;
  448. if proto.is_null() {
  449. while {
  450. p = getservent();
  451. !p.is_null()
  452. } {
  453. if (*p).s_port == port {
  454. setservent(SERV_STAYOPEN);
  455. return p;
  456. }
  457. }
  458. } else {
  459. while {
  460. p = getservent();
  461. !p.is_null()
  462. } {
  463. if (*p).s_port == port && strcasecmp((*p).s_proto, proto) == 0 {
  464. setservent(SERV_STAYOPEN);
  465. return p;
  466. }
  467. }
  468. }
  469. setservent(SERV_STAYOPEN);
  470. platform::errno = ENOENT;
  471. ptr::null_mut()
  472. }
  473. #[no_mangle]
  474. pub unsafe extern "C" fn getservent() -> *mut servent {
  475. if SERVDB == 0 {
  476. SERVDB = Sys::open(&CString::new("/etc/services").unwrap(), O_RDONLY, 0);
  477. }
  478. let mut rlb = RawLineBuffer::new(SERVDB);
  479. rlb.seek(S_POS);
  480. let r: Box<str> = Box::default();
  481. loop {
  482. let r = match rlb.next() {
  483. Line::Some(s) => bytes_to_box_str(s),
  484. _ => {
  485. if SERV_STAYOPEN == 0 {
  486. endservent();
  487. }
  488. return ptr::null_mut();
  489. }
  490. };
  491. let mut iter = r.split_whitespace();
  492. let mut serv_name = match iter.next() {
  493. Some(serv_name) => serv_name.as_bytes().to_vec(),
  494. None => continue,
  495. };
  496. serv_name.push(b'\0');
  497. let port_proto = match iter.next() {
  498. Some(port_proto) => port_proto,
  499. None => continue,
  500. };
  501. let mut split = port_proto.split('/');
  502. let mut port = match split.next() {
  503. Some(port) => port.as_bytes().to_vec(),
  504. None => continue,
  505. };
  506. port.push(b'\0');
  507. SERV_PORT =
  508. Some(htons(atoi(port.as_mut_slice().as_mut_ptr() as *mut i8) as u16) as u32 as i32);
  509. let mut proto = match split.next() {
  510. Some(proto) => proto.as_bytes().to_vec(),
  511. None => continue,
  512. };
  513. proto.push(b'\0');
  514. rlb.next();
  515. S_POS = rlb.line_pos();
  516. /*
  517. *let mut _serv_aliases: Vec<Vec<u8>> = Vec::new();
  518. *loop {
  519. * let mut alias = match iter.next() {
  520. * Some(s) => s.as_bytes().to_vec(),
  521. * _ => break
  522. * };
  523. * alias.push(b'\0');
  524. * _serv_aliases.push(alias);
  525. *}
  526. *let mut serv_aliases: Vec<*mut i8> = _serv_aliases.iter_mut().map(|x| x.as_mut_ptr() as *mut i8).collect();
  527. *serv_aliases.push(ptr::null_mut());
  528. *
  529. */
  530. let mut _serv_aliases: Vec<Vec<u8>> = Vec::new();
  531. _serv_aliases.push(vec![b'\0']);
  532. let mut serv_aliases: Vec<*mut i8> = Vec::new();
  533. serv_aliases.push(ptr::null_mut());
  534. serv_aliases.push(ptr::null_mut());
  535. SERV_ALIASES = Some(_serv_aliases);
  536. SERV_NAME = Some(serv_name);
  537. SERV_PROTO = Some(proto);
  538. SERV_ENTRY = servent {
  539. s_name: SERV_NAME.as_mut().unwrap().as_mut_slice().as_mut_ptr() as *mut c_char,
  540. s_aliases: serv_aliases.as_mut_slice().as_mut_ptr() as *mut *mut i8,
  541. s_port: SERV_PORT.unwrap(),
  542. s_proto: SERV_PROTO.as_mut().unwrap().as_mut_slice().as_mut_ptr() as *mut c_char,
  543. };
  544. if SERV_STAYOPEN == 0 {
  545. endservent();
  546. }
  547. break &mut SERV_ENTRY as *mut servent;
  548. }
  549. }
  550. #[no_mangle]
  551. pub unsafe extern "C" fn setnetent(stayopen: c_int) {
  552. NET_STAYOPEN = stayopen;
  553. if NETDB == 0 {
  554. NETDB = Sys::open(&CString::new("/etc/networks").unwrap(), O_RDONLY, 0)
  555. } else {
  556. Sys::lseek(NETDB, 0, SEEK_SET);
  557. N_POS = 0;
  558. }
  559. }
  560. #[no_mangle]
  561. pub unsafe extern "C" fn setprotoent(stayopen: c_int) {
  562. PROTO_STAYOPEN = stayopen;
  563. if PROTODB == 0 {
  564. PROTODB = Sys::open(&CString::new("/etc/protocols").unwrap(), O_RDONLY, 0)
  565. } else {
  566. Sys::lseek(PROTODB, 0, SEEK_SET);
  567. P_POS = 0;
  568. }
  569. }
  570. #[no_mangle]
  571. pub unsafe extern "C" fn setservent(stayopen: c_int) {
  572. SERV_STAYOPEN = stayopen;
  573. if SERVDB == 0 {
  574. SERVDB = Sys::open(&CString::new("/etc/services").unwrap(), O_RDONLY, 0)
  575. } else {
  576. Sys::lseek(SERVDB, 0, SEEK_SET);
  577. S_POS = 0;
  578. }
  579. }
  580. #[no_mangle]
  581. pub unsafe extern "C" fn getaddrinfo(
  582. node: *const c_char,
  583. service: *const c_char,
  584. hints: *const addrinfo,
  585. res: *mut *mut addrinfo,
  586. ) -> c_int {
  587. //TODO: getaddrinfo
  588. let node_opt = if node.is_null() {
  589. None
  590. } else {
  591. Some(CStr::from_ptr(node))
  592. };
  593. let service_opt = if service.is_null() {
  594. None
  595. } else {
  596. Some(CStr::from_ptr(service))
  597. };
  598. let hints_opt = if hints.is_null() { None } else { Some(&*hints) };
  599. eprintln!(
  600. "getaddrinfo({:?}, {:?})",
  601. node_opt.map(|c| str::from_utf8_unchecked(c.to_bytes())),
  602. service_opt.map(|c| str::from_utf8_unchecked(c.to_bytes()))
  603. );
  604. platform::errno = ENOSYS;
  605. EAI_SYSTEM
  606. }
  607. #[no_mangle]
  608. pub unsafe extern "C" fn getnameinfo(
  609. addr: *const sockaddr,
  610. addrlen: socklen_t,
  611. host: *mut c_char,
  612. hostlen: socklen_t,
  613. serv: *mut c_char,
  614. servlen: socklen_t,
  615. flags: c_int,
  616. ) -> c_int {
  617. //TODO: getnameinfo
  618. if addrlen as usize != mem::size_of::<sockaddr_in>() {
  619. return EAI_FAMILY;
  620. }
  621. let addr = &*(addr as *const sockaddr_in);
  622. let host_opt = if host.is_null() {
  623. None
  624. } else {
  625. Some(slice::from_raw_parts_mut(host, hostlen as usize))
  626. };
  627. let serv_opt = if serv.is_null() {
  628. None
  629. } else {
  630. Some(slice::from_raw_parts_mut(serv, servlen as usize))
  631. };
  632. eprintln!("getnameinfo({:p}, {}, {:#x})", addr, addrlen, flags);
  633. platform::errno = ENOSYS;
  634. EAI_SYSTEM
  635. }
  636. #[no_mangle]
  637. pub unsafe extern "C" fn freeaddrinfo(res: *mut addrinfo) {
  638. let mut ai = res;
  639. while !ai.is_null() {
  640. let bai = Box::from_raw(ai);
  641. ai = (*ai).ai_next;
  642. drop(bai);
  643. }
  644. }
  645. #[no_mangle]
  646. pub extern "C" fn gai_strerror(errcode: c_int) -> *const c_char {
  647. match errcode {
  648. EAI_BADFLAGS => c_str!("Invalid flags"),
  649. EAI_NONAME => c_str!("Name does not resolve"),
  650. EAI_AGAIN => c_str!("Try again"),
  651. EAI_FAIL => c_str!("Non-recoverable error"),
  652. EAI_NODATA => c_str!("Unknown error"),
  653. EAI_FAMILY => c_str!("Unrecognized address family or invalid length"),
  654. EAI_SOCKTYPE => c_str!("Unrecognized socket type"),
  655. EAI_SERVICE => c_str!("Unrecognized service"),
  656. EAI_ADDRFAMILY => c_str!("Address family for name not supported"),
  657. EAI_MEMORY => c_str!("Out of memory"),
  658. EAI_SYSTEM => c_str!("System error"),
  659. EAI_OVERFLOW => c_str!("Overflow"),
  660. _ => c_str!("Unknown error"),
  661. }
  662. .as_ptr()
  663. }