use ::libc; pub use crate::stddef_h::size_t; pub use crate::stdlib::__socklen_t; pub use crate::stdlib::__ssize_t; pub use crate::stdlib::__uint16_t; pub use crate::stdlib::__uint32_t; pub use crate::stdlib::__uint64_t; pub use crate::stdlib::__uint8_t; pub use crate::stdlib::__useconds_t; pub use crate::stdlib::ssize_t; pub use crate::stdlib::__pthread_internal_list; pub use crate::stdlib::__pthread_list_t; pub use crate::stdlib::__pthread_mutex_s; pub use crate::stdlib::__socket_type; pub use crate::stdlib::close; pub use crate::stdlib::pthread_attr_t; pub use crate::stdlib::pthread_mutex_t; pub use crate::stdlib::pthread_t; pub use crate::stdlib::read; pub use crate::stdlib::sa_family_t; pub use crate::stdlib::socklen_t; pub use crate::stdlib::u_int16_t; pub use crate::stdlib::u_int32_t; pub use crate::stdlib::u_int64_t; pub use crate::stdlib::u_int8_t; pub use crate::stdlib::uint16_t; pub use crate::stdlib::uint32_t; pub use crate::stdlib::usleep; pub use crate::stdlib::SOCK_CLOEXEC; pub use crate::stdlib::SOCK_DCCP; pub use crate::stdlib::SOCK_DGRAM; pub use crate::stdlib::SOCK_NONBLOCK; pub use crate::stdlib::SOCK_PACKET; pub use crate::stdlib::SOCK_RAW; pub use crate::stdlib::SOCK_RDM; pub use crate::stdlib::SOCK_SEQPACKET; pub use crate::stdlib::SOCK_STREAM; pub use crate::squeezelite_h::buffer; pub use crate::squeezelite_h::disconnect_code; pub use crate::squeezelite_h::lDEBUG; pub use crate::squeezelite_h::lERROR; pub use crate::squeezelite_h::lINFO; pub use crate::squeezelite_h::lSDEBUG; pub use crate::squeezelite_h::lWARN; pub use crate::squeezelite_h::log_level; pub use crate::squeezelite_h::sockfd; pub use crate::squeezelite_h::stream_state; pub use crate::squeezelite_h::streamstate; pub use crate::squeezelite_h::u16_t; pub use crate::squeezelite_h::u32_t; pub use crate::squeezelite_h::u64_t; pub use crate::squeezelite_h::u8_t; pub use crate::squeezelite_h::DISCONNECT; pub use crate::squeezelite_h::DISCONNECT_OK; pub use crate::squeezelite_h::LOCAL_DISCONNECT; pub use crate::squeezelite_h::RECV_HEADERS; pub use crate::squeezelite_h::REMOTE_DISCONNECT; pub use crate::squeezelite_h::SEND_HEADERS; pub use crate::squeezelite_h::STOPPED; pub use crate::squeezelite_h::STREAMING_BUFFERING; pub use crate::squeezelite_h::STREAMING_FILE; pub use crate::squeezelite_h::STREAMING_HTTP; pub use crate::squeezelite_h::STREAMING_WAIT; pub use crate::squeezelite_h::TIMEOUT; pub use crate::squeezelite_h::UNREACHABLE; pub use crate::src::buffer::_buf_cont_write; pub use crate::src::buffer::_buf_inc_writep; pub use crate::src::buffer::_buf_space; pub use crate::src::buffer::buf_destroy; pub use crate::src::buffer::buf_flush; pub use crate::src::buffer::buf_init; pub use crate::src::slimproto::wake_controller; pub use crate::src::utils::connect_timeout; pub use crate::src::utils::logprint; pub use crate::src::utils::logtime; pub use crate::src::utils::set_nonblock; pub use crate::src::utils::touch_memory; use crate::stdlib::__errno_location; use crate::stdlib::exit; use crate::stdlib::free; pub use crate::stdlib::in_addr; pub use crate::stdlib::in_addr_t; pub use crate::stdlib::in_port_t; use crate::stdlib::inet_ntoa; use crate::stdlib::malloc; use crate::stdlib::memcpy; use crate::stdlib::memset; pub use crate::stdlib::nfds_t; pub use crate::stdlib::ntohs; use crate::stdlib::open; pub use crate::stdlib::poll; pub use crate::stdlib::pollfd; use crate::stdlib::pthread_attr_destroy; use crate::stdlib::pthread_attr_init; use crate::stdlib::pthread_attr_setstacksize; use crate::stdlib::pthread_create; use crate::stdlib::pthread_join; use crate::stdlib::pthread_mutex_lock; use crate::stdlib::pthread_mutex_unlock; use crate::stdlib::recv; use crate::stdlib::send; pub use crate::stdlib::sockaddr; pub use crate::stdlib::sockaddr_in; use crate::stdlib::socket; use crate::stdlib::strerror; pub use crate::stdlib::C2RustUnnamed_0; pub use crate::stdlib::MSG_BATCH; pub use crate::stdlib::MSG_CMSG_CLOEXEC; pub use crate::stdlib::MSG_CONFIRM; pub use crate::stdlib::MSG_CTRUNC; pub use crate::stdlib::MSG_DONTROUTE; pub use crate::stdlib::MSG_DONTWAIT; pub use crate::stdlib::MSG_EOR; pub use crate::stdlib::MSG_ERRQUEUE; pub use crate::stdlib::MSG_FASTOPEN; pub use crate::stdlib::MSG_FIN; pub use crate::stdlib::MSG_MORE; pub use crate::stdlib::MSG_NOSIGNAL; pub use crate::stdlib::MSG_OOB; pub use crate::stdlib::MSG_PEEK; pub use crate::stdlib::MSG_PROXY; pub use crate::stdlib::MSG_RST; pub use crate::stdlib::MSG_SYN; pub use crate::stdlib::MSG_TRUNC; pub use crate::stdlib::MSG_TRYHARD; pub use crate::stdlib::MSG_WAITALL; pub use crate::stdlib::MSG_WAITFORONE; pub use crate::stdlib::MSG_ZEROCOPY; /* * Squeezelite - lightweight headless squeezebox emulator * * (c) Adrian Smith 2012-2015, triode1@btinternet.com * Ralph Irving 2015-2017, ralph_irving@hotmail.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ // stream thread static mut loglevel: crate::squeezelite_h::log_level = crate::squeezelite_h::lERROR; static mut buf: crate::squeezelite_h::buffer = crate::squeezelite_h::buffer { buf: 0 as *const crate::squeezelite_h::u8_t as *mut crate::squeezelite_h::u8_t, readp: 0 as *const crate::squeezelite_h::u8_t as *mut crate::squeezelite_h::u8_t, writep: 0 as *const crate::squeezelite_h::u8_t as *mut crate::squeezelite_h::u8_t, wrap: 0 as *const crate::squeezelite_h::u8_t as *mut crate::squeezelite_h::u8_t, size: 0, base_size: 0, mutex: crate::stdlib::pthread_mutex_t { __data: crate::stdlib::__pthread_mutex_s { __lock: 0, __count: 0, __owner: 0, __nusers: 0, __kind: 0, __spins: 0, __elision: 0, __list: crate::stdlib::__pthread_list_t { __prev: 0 as *const crate::stdlib::__pthread_internal_list as *mut crate::stdlib::__pthread_internal_list, __next: 0 as *const crate::stdlib::__pthread_internal_list as *mut crate::stdlib::__pthread_internal_list, }, }, }, }; #[no_mangle] pub static mut streambuf: *mut crate::squeezelite_h::buffer = unsafe { &buf as *const crate::squeezelite_h::buffer as *mut crate::squeezelite_h::buffer }; static mut fd: crate::squeezelite_h::sockfd = 0; #[no_mangle] pub static mut stream: crate::squeezelite_h::streamstate = crate::squeezelite_h::streamstate { state: crate::squeezelite_h::STOPPED, disconnect: crate::squeezelite_h::DISCONNECT_OK, header: 0 as *const libc::c_char as *mut libc::c_char, header_len: 0, sent_headers: false, cont_wait: false, bytes: 0, threshold: 0, meta_interval: 0, meta_next: 0, meta_left: 0, meta_send: false, }; unsafe extern "C" fn send_header() -> bool { let mut ptr = stream.header; let mut len = stream.header_len as libc::c_int; let mut try_0 = 0 as libc::c_int as libc::c_uint; let mut n: crate::stdlib::ssize_t = 0; while len != 0 { n = crate::stdlib::send( fd, ptr as *const libc::c_void, len as crate::stddef_h::size_t, crate::stdlib::MSG_NOSIGNAL as libc::c_int, ); if n <= 0 as libc::c_int as libc::c_long { if n < 0 as libc::c_int as libc::c_long && *crate::stdlib::__errno_location() == 11 as libc::c_int && try_0 < 10 as libc::c_int as libc::c_uint { if loglevel as libc::c_uint >= crate::squeezelite_h::lSDEBUG as libc::c_int as libc::c_uint { try_0 = try_0.wrapping_add(1); crate::src::utils::logprint( b"%s %s:%d retrying (%d) writing to socket\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>( b"send_header\x00", )) .as_ptr(), 114 as libc::c_int, try_0, ); } crate::stdlib::usleep(1000 as libc::c_int as crate::stdlib::__useconds_t); } else { if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d failed writing to socket: %s\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>( b"send_header\x00", )) .as_ptr(), 118 as libc::c_int, crate::stdlib::strerror(*crate::stdlib::__errno_location()), ); } stream.disconnect = crate::squeezelite_h::LOCAL_DISCONNECT; stream.state = crate::squeezelite_h::DISCONNECT; crate::src::slimproto::wake_controller(); return 0 as libc::c_int != 0; } } else { if loglevel as libc::c_uint >= crate::squeezelite_h::lSDEBUG as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d wrote %d bytes to socket\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"send_header\x00")) .as_ptr(), 124 as libc::c_int, n, ); } ptr = ptr.offset(n as isize); len = (len as libc::c_long - n) as libc::c_int } } if loglevel as libc::c_uint >= crate::squeezelite_h::lSDEBUG as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d wrote header\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"send_header\x00")).as_ptr(), 128 as libc::c_int, ); } return 1 as libc::c_int != 0; } static mut running: bool = 1 as libc::c_int != 0; unsafe extern "C" fn _disconnect( mut state: crate::squeezelite_h::stream_state, mut disconnect: crate::squeezelite_h::disconnect_code, ) { stream.state = state; stream.disconnect = disconnect; crate::stdlib::close(fd); fd = -(1 as libc::c_int); crate::src::slimproto::wake_controller(); } unsafe extern "C" fn stream_thread() -> *mut libc::c_void { while running { let mut pollinfo = crate::stdlib::pollfd { fd: 0, events: 0, revents: 0, }; let mut space: crate::stddef_h::size_t = 0; crate::stdlib::pthread_mutex_lock(&mut (*streambuf).mutex); space = if crate::src::buffer::_buf_space(streambuf) < crate::src::buffer::_buf_cont_write(streambuf) { crate::src::buffer::_buf_space(streambuf) } else { crate::src::buffer::_buf_cont_write(streambuf) } as crate::stddef_h::size_t; if fd < 0 as libc::c_int || space == 0 || stream.state as libc::c_uint <= crate::squeezelite_h::STREAMING_WAIT as libc::c_int as libc::c_uint { crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); crate::stdlib::usleep(100000 as libc::c_int as crate::stdlib::__useconds_t); } else if stream.state as libc::c_uint == crate::squeezelite_h::STREAMING_FILE as libc::c_int as libc::c_uint { let mut n = crate::stdlib::read(fd, (*streambuf).writep as *mut libc::c_void, space) as libc::c_int; if n == 0 as libc::c_int { if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d end of stream\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>( b"stream_thread\x00", )) .as_ptr(), 170 as libc::c_int, ); } _disconnect( crate::squeezelite_h::DISCONNECT, crate::squeezelite_h::DISCONNECT_OK, ); } if n > 0 as libc::c_int { crate::src::buffer::_buf_inc_writep(streambuf, n as libc::c_uint); stream.bytes = (stream.bytes as libc::c_ulong).wrapping_add(n as libc::c_ulong) as crate::squeezelite_h::u64_t as crate::squeezelite_h::u64_t; if loglevel as libc::c_uint >= crate::squeezelite_h::lSDEBUG as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d streambuf read %d bytes\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>( b"stream_thread\x00", )) .as_ptr(), 176 as libc::c_int, n, ); } } if n < 0 as libc::c_int { if loglevel as libc::c_uint >= crate::squeezelite_h::lWARN as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d error reading: %s\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>( b"stream_thread\x00", )) .as_ptr(), 179 as libc::c_int, crate::stdlib::strerror(*crate::stdlib::__errno_location()), ); } _disconnect( crate::squeezelite_h::DISCONNECT, crate::squeezelite_h::REMOTE_DISCONNECT, ); } crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); } else { pollinfo.fd = fd; pollinfo.events = 0x1 as libc::c_int as libc::c_short; if stream.state as libc::c_uint == crate::squeezelite_h::SEND_HEADERS as libc::c_int as libc::c_uint { pollinfo.events = (pollinfo.events as libc::c_int | 0x4 as libc::c_int) as libc::c_short } crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); if crate::stdlib::poll( &mut pollinfo, 1 as libc::c_int as crate::stdlib::nfds_t, 100 as libc::c_int, ) != 0 { crate::stdlib::pthread_mutex_lock(&mut (*streambuf).mutex); // check socket has not been closed while in poll if fd < 0 as libc::c_int { crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); } else if pollinfo.revents as libc::c_int & 0x4 as libc::c_int != 0 && stream.state as libc::c_uint == crate::squeezelite_h::SEND_HEADERS as libc::c_int as libc::c_uint { if send_header() { stream.state = crate::squeezelite_h::RECV_HEADERS } stream.header_len = 0 as libc::c_int as crate::stddef_h::size_t; crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); } else { if pollinfo.revents as libc::c_int & (0x1 as libc::c_int | 0x10 as libc::c_int) != 0 { // get response headers if stream.state as libc::c_uint == crate::squeezelite_h::RECV_HEADERS as libc::c_int as libc::c_uint { // read one byte at a time to catch end of header let mut c: libc::c_char = 0; static mut endtok: libc::c_int = 0; let mut n_0 = crate::stdlib::recv( fd, &mut c as *mut libc::c_char as *mut libc::c_void, 1 as libc::c_int as crate::stddef_h::size_t, 0 as libc::c_int, ) as libc::c_int; if n_0 <= 0 as libc::c_int { if n_0 < 0 as libc::c_int && *crate::stdlib::__errno_location() == 11 as libc::c_int { crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); continue; } else { if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d error reading headers: %s\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::< &[u8; 14], &[libc::c_char; 14], >( b"stream_thread\x00" )) .as_ptr(), 229 as libc::c_int, if n_0 != 0 { crate::stdlib::strerror( *crate::stdlib::__errno_location(), ) as *const libc::c_char } else { b"closed\x00" as *const u8 as *const libc::c_char }, ); } _disconnect( crate::squeezelite_h::STOPPED, crate::squeezelite_h::LOCAL_DISCONNECT, ); crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); continue; } } else { *stream.header.offset(stream.header_len as isize) = c; stream.header_len = stream.header_len.wrapping_add(1); if stream.header_len > (4096 as libc::c_int - 1 as libc::c_int) as libc::c_ulong { crate::src::utils::logprint( b"%s %s:%d received headers too long: %u\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>( b"stream_thread\x00", )) .as_ptr(), 239 as libc::c_int, stream.header_len, ); _disconnect( crate::squeezelite_h::DISCONNECT, crate::squeezelite_h::LOCAL_DISCONNECT, ); } if stream.header_len > 1 as libc::c_int as libc::c_ulong && (c as libc::c_int == '\r' as i32 || c as libc::c_int == '\n' as i32) { endtok += 1; if endtok == 4 as libc::c_int { *stream.header.offset(stream.header_len as isize) = '\u{0}' as i32 as libc::c_char; if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d headers: len: %d\n%s\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::< &[u8; 14], &[libc::c_char; 14], >( b"stream_thread\x00" )) .as_ptr(), 247 as libc::c_int, stream.header_len, stream.header, ); } stream.state = if stream.cont_wait as libc::c_int != 0 { crate::squeezelite_h::STREAMING_WAIT as libc::c_int } else { crate::squeezelite_h::STREAMING_BUFFERING as libc::c_int } as crate::squeezelite_h::stream_state; crate::src::slimproto::wake_controller(); } } else { endtok = 0 as libc::c_int } crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); continue; } } else if stream.meta_interval != 0 && stream.meta_next == 0 as libc::c_int as libc::c_uint { if stream.meta_left == 0 as libc::c_int as libc::c_uint { // receive icy meta data // read meta length let mut c_0: crate::squeezelite_h::u8_t = 0; let mut n_1 = crate::stdlib::recv( fd, &mut c_0 as *mut crate::squeezelite_h::u8_t as *mut libc::c_void, 1 as libc::c_int as crate::stddef_h::size_t, 0 as libc::c_int, ) as libc::c_int; if n_1 <= 0 as libc::c_int { if n_1 < 0 as libc::c_int && *crate::stdlib::__errno_location() == 11 as libc::c_int { crate::stdlib::pthread_mutex_unlock( &mut (*streambuf).mutex, ); continue; } else { if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d error reading icy meta: %s\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::< &[u8; 14], &[libc::c_char; 14], >( b"stream_thread\x00" )) .as_ptr(), 271 as libc::c_int, if n_1 != 0 { crate::stdlib::strerror( *crate::stdlib::__errno_location(), ) as *const libc::c_char } else { b"closed\x00" as *const u8 as *const libc::c_char }, ); } _disconnect( crate::squeezelite_h::STOPPED, crate::squeezelite_h::LOCAL_DISCONNECT, ); crate::stdlib::pthread_mutex_unlock( &mut (*streambuf).mutex, ); continue; } } else { stream.meta_left = (16 as libc::c_int * c_0 as libc::c_int) as crate::squeezelite_h::u32_t; stream.header_len = 0 as libc::c_int as crate::stddef_h::size_t } // amount of received meta data // MAX_HEADER must be more than meta max of 16 * 255 } if stream.meta_left != 0 { let mut n_2 = crate::stdlib::recv( fd, stream.header.offset(stream.header_len as isize) as *mut libc::c_void, stream.meta_left as crate::stddef_h::size_t, 0 as libc::c_int, ) as libc::c_int; if n_2 <= 0 as libc::c_int { if n_2 < 0 as libc::c_int && *crate::stdlib::__errno_location() == 11 as libc::c_int { crate::stdlib::pthread_mutex_unlock( &mut (*streambuf).mutex, ); continue; } else { if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d error reading icy meta: %s\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::< &[u8; 14], &[libc::c_char; 14], >( b"stream_thread\x00" )) .as_ptr(), 288 as libc::c_int, if n_2 != 0 { crate::stdlib::strerror( *crate::stdlib::__errno_location(), ) as *const libc::c_char } else { b"closed\x00" as *const u8 as *const libc::c_char }, ); } _disconnect( crate::squeezelite_h::STOPPED, crate::squeezelite_h::LOCAL_DISCONNECT, ); crate::stdlib::pthread_mutex_unlock( &mut (*streambuf).mutex, ); continue; } } else { stream.meta_left = (stream.meta_left as libc::c_uint) .wrapping_sub(n_2 as libc::c_uint) as crate::squeezelite_h::u32_t as crate::squeezelite_h::u32_t; stream.header_len = (stream.header_len as libc::c_ulong) .wrapping_add(n_2 as libc::c_ulong) as crate::stddef_h::size_t as crate::stddef_h::size_t } } if stream.meta_left == 0 as libc::c_int as libc::c_uint { if stream.header_len != 0 { *stream.header.offset(stream.header_len as isize) = '\u{0}' as i32 as libc::c_char; if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d icy meta: len: %u\n%s\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::< &[u8; 14], &[libc::c_char; 14], >( b"stream_thread\x00" )) .as_ptr(), 300 as libc::c_int, stream.header_len, stream.header, ); } stream.meta_send = 1 as libc::c_int != 0; crate::src::slimproto::wake_controller(); } stream.meta_next = stream.meta_interval; crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); continue; } // stream body into streambuf } else { let mut n_3: libc::c_int = 0; space = if crate::src::buffer::_buf_space(streambuf) < crate::src::buffer::_buf_cont_write(streambuf) { crate::src::buffer::_buf_space(streambuf) } else { crate::src::buffer::_buf_cont_write(streambuf) } as crate::stddef_h::size_t; if stream.meta_interval != 0 { space = if space < stream.meta_next as libc::c_ulong { space } else { stream.meta_next as libc::c_ulong } } n_3 = crate::stdlib::recv( fd, (*streambuf).writep as *mut libc::c_void, space, 0 as libc::c_int, ) as libc::c_int; if n_3 == 0 as libc::c_int { if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d end of stream\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>( b"stream_thread\x00", )) .as_ptr(), 320 as libc::c_int, ); } _disconnect( crate::squeezelite_h::DISCONNECT, crate::squeezelite_h::DISCONNECT_OK, ); } if n_3 < 0 as libc::c_int && *crate::stdlib::__errno_location() != 11 as libc::c_int { if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d error reading: %s\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>( b"stream_thread\x00", )) .as_ptr(), 324 as libc::c_int, crate::stdlib::strerror(*crate::stdlib::__errno_location()), ); } _disconnect( crate::squeezelite_h::DISCONNECT, crate::squeezelite_h::REMOTE_DISCONNECT, ); } if n_3 > 0 as libc::c_int { crate::src::buffer::_buf_inc_writep(streambuf, n_3 as libc::c_uint); stream.bytes = (stream.bytes as libc::c_ulong) .wrapping_add(n_3 as libc::c_ulong) as crate::squeezelite_h::u64_t as crate::squeezelite_h::u64_t; if stream.meta_interval != 0 { stream.meta_next = (stream.meta_next as libc::c_uint) .wrapping_sub(n_3 as libc::c_uint) as crate::squeezelite_h::u32_t as crate::squeezelite_h::u32_t } if stream.state as libc::c_uint == crate::squeezelite_h::STREAMING_BUFFERING as libc::c_int as libc::c_uint && stream.bytes > stream.threshold as libc::c_ulong { stream.state = crate::squeezelite_h::STREAMING_HTTP; crate::src::slimproto::wake_controller(); } if loglevel as libc::c_uint >= crate::squeezelite_h::lSDEBUG as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d streambuf read %d bytes\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>( b"stream_thread\x00", )) .as_ptr(), 344 as libc::c_int, n_3, ); } } else { crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); continue; } } } crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); } } else if loglevel as libc::c_uint >= crate::squeezelite_h::lSDEBUG as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d poll timeout\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 14], &[libc::c_char; 14]>( b"stream_thread\x00", )) .as_ptr(), 352 as libc::c_int, ); } } } return 0 as *mut libc::c_void; } static mut thread: crate::stdlib::pthread_t = 0; #[no_mangle] pub unsafe extern "C" fn stream_init( mut level: crate::squeezelite_h::log_level, mut stream_buf_size: libc::c_uint, ) { loglevel = level; if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d init stream\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"stream_init\x00")).as_ptr(), 370 as libc::c_int, ); } if loglevel as libc::c_uint >= crate::squeezelite_h::lDEBUG as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d streambuf size: %u\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"stream_init\x00")).as_ptr(), 371 as libc::c_int, stream_buf_size, ); } crate::src::buffer::buf_init(streambuf, stream_buf_size as crate::stddef_h::size_t); if (*streambuf).buf.is_null() { crate::src::utils::logprint( b"%s %s:%d unable to malloc buffer\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"stream_init\x00")).as_ptr(), 375 as libc::c_int, ); crate::stdlib::exit(0 as libc::c_int); } stream.state = crate::squeezelite_h::STOPPED; stream.header = crate::stdlib::malloc(4096 as libc::c_int as libc::c_ulong) as *mut libc::c_char; *stream.header = '\u{0}' as i32 as libc::c_char; fd = -(1 as libc::c_int); crate::src::utils::touch_memory((*streambuf).buf, (*streambuf).size); let mut attr = crate::stdlib::pthread_attr_t { __size: [0; 56] }; crate::stdlib::pthread_attr_init(&mut attr); crate::stdlib::pthread_attr_setstacksize( &mut attr, (16384 as libc::c_int + 64 as libc::c_int * 1024 as libc::c_int) as crate::stddef_h::size_t, ); crate::stdlib::pthread_create( &mut thread, &mut attr, ::std::mem::transmute::< Option *mut libc::c_void>, Option *mut libc::c_void>, >(Some(::std::mem::transmute::< unsafe extern "C" fn() -> *mut libc::c_void, unsafe extern "C" fn() -> *mut libc::c_void, >(stream_thread))), 0 as *mut libc::c_void, ); crate::stdlib::pthread_attr_destroy(&mut attr); } #[no_mangle] pub unsafe extern "C" fn stream_close() { if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d close stream\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 13], &[libc::c_char; 13]>(b"stream_close\x00")) .as_ptr(), 424 as libc::c_int, ); } crate::stdlib::pthread_mutex_lock(&mut (*streambuf).mutex); running = 0 as libc::c_int != 0; crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); crate::stdlib::pthread_join(thread, 0 as *mut *mut libc::c_void); crate::stdlib::free(stream.header as *mut libc::c_void); crate::src::buffer::buf_destroy(streambuf); } #[no_mangle] pub unsafe extern "C" fn stream_file( mut header: *const libc::c_char, mut header_len: crate::stddef_h::size_t, mut threshold: libc::c_uint, ) { crate::src::buffer::buf_flush(streambuf); crate::stdlib::pthread_mutex_lock(&mut (*streambuf).mutex); stream.header_len = header_len; crate::stdlib::memcpy( stream.header as *mut libc::c_void, header as *const libc::c_void, header_len, ); *stream.header.offset(header_len as isize) = '\u{0}' as i32 as libc::c_char; if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d opening local file: %s\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"stream_file\x00")).as_ptr(), 444 as libc::c_int, stream.header, ); } fd = crate::stdlib::open(stream.header, 0 as libc::c_int); stream.state = crate::squeezelite_h::STREAMING_FILE; if fd < 0 as libc::c_int { if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d can\'t open file: %s\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"stream_file\x00")) .as_ptr(), 454 as libc::c_int, stream.header, ); } stream.state = crate::squeezelite_h::DISCONNECT } crate::src::slimproto::wake_controller(); stream.cont_wait = 0 as libc::c_int != 0; stream.meta_interval = 0 as libc::c_int as crate::squeezelite_h::u32_t; stream.meta_next = 0 as libc::c_int as crate::squeezelite_h::u32_t; stream.meta_left = 0 as libc::c_int as crate::squeezelite_h::u32_t; stream.meta_send = 0 as libc::c_int != 0; stream.sent_headers = 0 as libc::c_int != 0; stream.bytes = 0 as libc::c_int as crate::squeezelite_h::u64_t; stream.threshold = threshold; crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); } unsafe extern "C" fn _tcp_connect( mut ip: crate::squeezelite_h::u32_t, mut port: crate::squeezelite_h::u16_t, ) -> libc::c_int { let mut addr = crate::stdlib::sockaddr_in { sin_family: 0, sin_port: 0, sin_addr: crate::stdlib::in_addr { s_addr: 0 }, sin_zero: [0; 8], }; let mut sock = crate::stdlib::socket( 2 as libc::c_int, crate::stdlib::SOCK_STREAM as libc::c_int, 0 as libc::c_int, ); if sock < 0 as libc::c_int { crate::src::utils::logprint( b"%s %s:%d failed to create socket\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 13], &[libc::c_char; 13]>(b"_tcp_connect\x00")) .as_ptr(), 477 as libc::c_int, ); return -(1 as libc::c_int); } crate::stdlib::memset( &mut addr as *mut crate::stdlib::sockaddr_in as *mut libc::c_void, 0 as libc::c_int, ::std::mem::size_of::() as libc::c_ulong, ); addr.sin_family = 2 as libc::c_int as crate::stdlib::sa_family_t; addr.sin_addr.s_addr = ip; addr.sin_port = port; if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d connecting to %s:%d\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 13], &[libc::c_char; 13]>(b"_tcp_connect\x00")) .as_ptr(), 486 as libc::c_int, crate::stdlib::inet_ntoa(addr.sin_addr), crate::stdlib::ntohs(addr.sin_port) as libc::c_int, ); } crate::src::utils::set_nonblock(sock); if crate::src::utils::connect_timeout( sock, &mut addr as *mut crate::stdlib::sockaddr_in as *mut crate::stdlib::sockaddr, ::std::mem::size_of::() as libc::c_ulong as crate::stdlib::socklen_t, 10 as libc::c_int, ) < 0 as libc::c_int { if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d unable to connect to server\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 13], &[libc::c_char; 13]>(b"_tcp_connect\x00")) .as_ptr(), 492 as libc::c_int, ); } crate::stdlib::close(sock); return -(1 as libc::c_int); } return sock; } #[no_mangle] pub unsafe extern "C" fn stream_sock( mut ip: crate::squeezelite_h::u32_t, mut port: crate::squeezelite_h::u16_t, mut header: *const libc::c_char, mut header_len: crate::stddef_h::size_t, mut threshold: libc::c_uint, mut cont_wait: bool, ) { let mut sock = _tcp_connect(ip, port); if sock < 0 as libc::c_int { crate::stdlib::pthread_mutex_lock(&mut (*streambuf).mutex); stream.state = crate::squeezelite_h::DISCONNECT; stream.disconnect = crate::squeezelite_h::UNREACHABLE; crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); return; } crate::src::buffer::buf_flush(streambuf); crate::stdlib::pthread_mutex_lock(&mut (*streambuf).mutex); fd = sock; stream.state = crate::squeezelite_h::SEND_HEADERS; stream.cont_wait = cont_wait; stream.meta_interval = 0 as libc::c_int as crate::squeezelite_h::u32_t; stream.meta_next = 0 as libc::c_int as crate::squeezelite_h::u32_t; stream.meta_left = 0 as libc::c_int as crate::squeezelite_h::u32_t; stream.meta_send = 0 as libc::c_int != 0; stream.header_len = header_len; crate::stdlib::memcpy( stream.header as *mut libc::c_void, header as *const libc::c_void, header_len, ); *stream.header.offset(header_len as isize) = '\u{0}' as i32 as libc::c_char; if loglevel as libc::c_uint >= crate::squeezelite_h::lINFO as libc::c_int as libc::c_uint { crate::src::utils::logprint( b"%s %s:%d header: %s\n\x00" as *const u8 as *const libc::c_char, crate::src::utils::logtime(), (*::std::mem::transmute::<&[u8; 12], &[libc::c_char; 12]>(b"stream_sock\x00")).as_ptr(), 577 as libc::c_int, stream.header, ); } stream.sent_headers = 0 as libc::c_int != 0; stream.bytes = 0 as libc::c_int as crate::squeezelite_h::u64_t; stream.threshold = threshold; crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); } /* * Squeezelite - lightweight headless squeezebox emulator * * (c) Adrian Smith 2012-2015, triode1@btinternet.com * Ralph Irving 2015-2017, ralph_irving@hotmail.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Additions (c) Paul Hermann, 2015-2017 under the same license terms * -Control of Raspberry pi GPIO for amplifier power * -Launch script on power status change from LMS */ // make may define: PORTAUDIO, SELFPIPE, RESAMPLE, RESAMPLE_MP, VISEXPORT, GPIO, IR, DSD, LINKALL to influence build // build detection // dynamically loaded libraries at run time // !LINKALL // config options // do not reduce as icy-meta max is 4080 /* SUN */ /* SUN */ // printf/scanf formats for u64_t // logging // utils.c (non logging) // buffer.c // _* called with mutex locked // slimproto.c // stream.c #[no_mangle] pub unsafe extern "C" fn stream_disconnect() -> bool { let mut disc = 0 as libc::c_int != 0; crate::stdlib::pthread_mutex_lock(&mut (*streambuf).mutex); if fd != -(1 as libc::c_int) { crate::stdlib::close(fd); fd = -(1 as libc::c_int); disc = 1 as libc::c_int != 0 } stream.state = crate::squeezelite_h::STOPPED; crate::stdlib::pthread_mutex_unlock(&mut (*streambuf).mutex); return disc; }