squeezers/src/stream.rs
Micha Glave 33155c6ce2 Adding a transpiled version of [Ralph Irving's squeezelite](https://github.com/ralph-irving/squeezelite).
Transpiled by c2rust:

`c2rust transpile --binary main compile_commands.json -r --reduce-type-annotations -o ../squeezers -- -I/usr/lib/clang/9.0.1/include`
2020-04-01 13:55:11 +02:00

1129 lines
53 KiB
Rust

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 <http://www.gnu.org/licenses/>.
*
*/
// 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<unsafe extern "C" fn() -> *mut libc::c_void>,
Option<unsafe extern "C" fn(_: *mut libc::c_void) -> *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::<crate::stdlib::sockaddr_in>() 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::<crate::stdlib::sockaddr_in>() 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 <http://www.gnu.org/licenses/>.
*
* 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;
}