/*-------------------------------------------------------------------------*\ * Error translation functions * Make sure important error messages are standard \*-------------------------------------------------------------------------*/ const char *socket_hoststrerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { case HOST_NOT_FOUND: return "host not found"; default: return hstrerror(err); } }
/* Fill in the mad buffer, return number of bytes read, 0 on eof or error */ static size_t fill_buff (struct mp3_data *data) { size_t remaining; ssize_t read_size; unsigned char *read_start; if (data->stream.next_frame != NULL) { remaining = data->stream.bufend - data->stream.next_frame; memmove (data->in_buff, data->stream.next_frame, remaining); read_start = data->in_buff + remaining; read_size = INPUT_BUFFER - remaining; } else { read_start = data->in_buff; read_size = INPUT_BUFFER; remaining = 0; } read_size = io_read (data->io_stream, read_start, read_size); if (read_size < 0) { decoder_error (&data->error, ERROR_FATAL, 0, "read error: %s", io_strerror(data->io_stream)); return 0; } else if (read_size == 0) return 0; mad_stream_buffer(&data->stream, data->in_buff, read_size + remaining); data->stream.error = 0; return read_size; }
static int server_close(lua_State *T) { struct ev_io *w; int ret; luaL_checktype(T, 1, LUA_TUSERDATA); w = lua_touserdata(T, 1); if (w->fd < 0) return io_closed(T); if (w->data != NULL) { lem_debug("interrupting listen"); ev_io_stop(LEM_ w); lua_pushnil(w->data); lua_pushliteral(w->data, "interrupted"); lem_queue(w->data, 2); w->data = NULL; } lem_debug("closing server.."); ret = close(w->fd); w->fd = -1; if (ret) return io_strerror(T, errno); lua_pushboolean(T, 1); return 1; }
/*-------------------------------------------------------------------------*\ * Error translation functions \*-------------------------------------------------------------------------*/ const char *socket_hoststrerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; default: return wstrerror(err); } }
static int stream_close(lua_State *T) { struct stream *s; luaL_checktype(T, 1, LUA_TUSERDATA); s = lua_touserdata(T, 1); if (!s->open) return io_closed(T); if (s->r.data != NULL) { ev_io_stop(LEM_ &s->r); lem_queue(s->r.data, io_closed(s->r.data)); s->r.data = NULL; } if (s->w.data != NULL) { ev_io_stop(LEM_ &s->w); lem_queue(s->w.data, io_closed(s->w.data)); s->w.data = NULL; } s->open = 0; if (close(s->r.fd)) return io_strerror(T, errno); lua_pushboolean(T, 1); return 1; }
/* * stream:write() method */ static int stream__write(lua_State *T, struct stream *s) { ssize_t bytes; int err; while ((bytes = write(s->w.fd, s->out, s->out_len)) > 0) { lem_debug("wrote %ld bytes to fd %d", bytes, s->w.fd); s->out += bytes; s->out_len -= bytes; while (s->out_len == 0) { if (s->idx == lua_gettop(T)) { lua_pushboolean(T, 1); return 1; } s->out = lua_tolstring(T, ++s->idx, &s->out_len); } } err = errno; lem_debug("wrote %ld bytes to fd %d", bytes, s->w.fd); if (bytes < 0 && (err == EAGAIN || err == EINTR)) return 0; s->open = 0; close(s->w.fd); if (bytes == 0 || err == ECONNRESET || err == EPIPE) return io_closed(T); return io_strerror(T, err); }
static void file_write_reap(struct lem_async *a) { struct file *f = (struct file *)a; lua_State *T = f->T; int top; if (f->ret) { f->T = NULL; lem_queue(T, io_strerror(T, f->ret)); return; } top = lua_gettop(T); do { if (f->write.idx == top) { f->T = NULL; lua_pushboolean(T, 1); lem_queue(T, 1); return; } f->write.str = lua_tolstring(T, ++f->write.idx, &f->write.len); } while (f->write.len == 0); lem_async_run(&f->a); }
static struct mp3_data *mp3_open_internal (const char *file, const int buffered) { struct mp3_data *data; data = (struct mp3_data *)xmalloc (sizeof(struct mp3_data)); data->ok = 0; decoder_error_init (&data->error); /* Reset information about the file */ data->freq = 0; data->channels = 0; data->skip_frames = 0; data->bitrate = -1; data->avg_bitrate = -1; /* Open the file */ data->io_stream = io_open (file, buffered); if (io_ok(data->io_stream)) { data->ok = 1; data->size = io_file_size (data->io_stream); mad_stream_init (&data->stream); mad_frame_init (&data->frame); mad_synth_init (&data->synth); if (options_get_int("Mp3IgnoreCRCErrors")) mad_stream_options (&data->stream, MAD_OPTION_IGNORECRC); data->duration = count_time_internal (data); mad_frame_mute (&data->frame); data->stream.next_frame = NULL; data->stream.sync = 0; data->stream.error = MAD_ERROR_NONE; if (io_seek(data->io_stream, SEEK_SET, 0) == (off_t)-1) { decoder_error (&data->error, ERROR_FATAL, 0, "seek failed"); io_close (data->io_stream); mad_stream_finish (&data->stream); mad_frame_finish (&data->frame); mad_synth_finish (&data->synth); data->ok = 0; } data->stream.error = MAD_ERROR_BUFLEN; } else { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open: %s", io_strerror(data->io_stream)); io_close (data->io_stream); } return data; }
/*-------------------------------------------------------------------------*\ * Error translation functions * Make sure important error messages are standard \*-------------------------------------------------------------------------*/ const char *socket_hoststrerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { #if !PE_PLAT_IS_PSVITA case HOST_NOT_FOUND: return "host not found"; #endif default: return "return hstrerror(err)" ; /*return hstrerror(err);*/ } }
/*-------------------------------------------------------------------------*\ * Error translation functions * Make sure important error messages are standard \*-------------------------------------------------------------------------*/ const char *socket_hoststrerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { case HOST_NOT_FOUND: return "host not found"; #ifdef __lv2ppu__ default: return strerror(err); #else default: return hstrerror(err); #endif } }
const char *sock_strerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { case EADDRINUSE: return "address already in use"; case EACCES: return "permission denied"; case ECONNREFUSED: return "connection refused"; case ECONNABORTED: return "closed"; case ECONNRESET: return "closed"; case ETIMEDOUT: return "timedout"; default: return strerror(errno); } }
const char *socket_strerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { case WSAEADDRINUSE: return PIE_ADDRINUSE; case WSAECONNREFUSED : return PIE_CONNREFUSED; case WSAEISCONN: return PIE_ISCONN; case WSAEACCES: return PIE_ACCESS; case WSAECONNABORTED: return PIE_CONNABORTED; case WSAECONNRESET: return PIE_CONNRESET; case WSAETIMEDOUT: return PIE_TIMEDOUT; default: return wstrerror(err); } }
static void file_close_reap(struct lem_async *a) { struct file *f = (struct file *)a; lua_State *T = f->T; f->T = NULL; f->fd = -1; if (f->ret) { lem_queue(T, io_strerror(T, f->ret)); return; } lua_pushboolean(T, 1); lem_queue(T, 1); }
static void file_seek_reap(struct lem_async *a) { struct file *f = (struct file *)a; lua_State *T = f->T; f->T = NULL; if (f->ret) { lem_queue(T, io_strerror(T, f->ret)); return; } lua_pushnumber(T, f->seek.offset); lem_queue(T, 1); }
static int stream_setcork(lua_State *T, int state) { struct stream *s; luaL_checktype(T, 1, LUA_TUSERDATA); s = lua_touserdata(T, 1); if (!s->open) return io_closed(T); if (s->w.data != NULL) return io_busy(T); if (setsockopt(s->w.fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(int))) return io_strerror(T, errno); lua_pushboolean(T, 1); return 1; }
static void *spx_open (const char *file) { struct io_stream *stream; struct spx_data *data; stream = io_open (file, 1); if (io_ok(stream)) data = spx_open_internal (stream); else { data = (struct spx_data *)xmalloc (sizeof(struct spx_data)); decoder_error_init (&data->error); decoder_error (&data->error, ERROR_STREAM, 0, "Can't open file: %s", io_strerror(data->stream)); data->ok = 0; } return data; }
/* * stream:readp() method */ static int stream__readp(lua_State *T, struct stream *s) { ssize_t bytes; int ret; int err; enum lem_preason res; while ((bytes = read(s->r.fd, s->buf.buf + s->buf.end, LEM_INPUTBUF_SIZE - s->buf.end)) > 0) { lem_debug("read %ld bytes from %d", bytes, s->r.fd); s->buf.end += bytes; ret = s->p->process(T, &s->buf); if (ret > 0) return ret; } err = errno; lem_debug("read %ld bytes from %d", bytes, s->r.fd); if (bytes < 0 && (err == EAGAIN || err == EINTR)) return 0; if (bytes == 0 || err == ECONNRESET || err == EPIPE) res = LEM_PCLOSED; else res = LEM_PERROR; s->open = 0; close(s->r.fd); if (s->p->destroy && (ret = s->p->destroy(T, &s->buf, res)) > 0) return ret; lua_settop(T, 0); if (res == LEM_PCLOSED) return io_closed(T); return io_strerror(T, err); }
/* Return the decoder for this stream. */ struct decoder *get_decoder_by_content (struct io_stream *stream) { char buf[8096]; ssize_t res; int i; struct decoder *decoder_by_mime_type; assert (stream != NULL); /* Peek at the start of the stream to check if sufficient data is * available. If not, there is no sense in trying the decoders as * each of them would issue an error. The data is also needed to * get the MIME type. */ logit ("Testing the stream..."); res = io_peek (stream, buf, sizeof (buf)); if (res < 0) { error ("Stream error: %s", io_strerror (stream)); return NULL; } if (res < 512) { logit ("Stream too short"); return NULL; } decoder_by_mime_type = get_decoder_by_mime_type (stream); if (decoder_by_mime_type) return decoder_by_mime_type; for (i = 0; i < plugins_num; i++) { if (plugins[i].decoder->can_decode && plugins[i].decoder->can_decode (stream)) { logit ("Found decoder for stream: %s", plugins[i].name); return plugins[i].decoder; } } error ("Format not supported"); return NULL; }
const char *socket_strerror(int err) { if (err <= 0) return io_strerror(err); switch (err) { #if APIABSTRACTION_PS3 case SYS_NET_EADDRINUSE: return "address already in use"; case SYS_NET_EISCONN: return "already connected"; case SYS_NET_EACCES: return "permission denied"; case SYS_NET_ECONNREFUSED: return "connection refused"; case SYS_NET_ECONNABORTED: return "closed"; case SYS_NET_ECONNRESET: return "closed"; case SYS_NET_ETIMEDOUT: return "timeout"; #else case EADDRINUSE: return "address already in use"; case EISCONN: return "already connected"; case EACCES: return "permission denied"; case ECONNREFUSED: return "connection refused"; case ECONNABORTED: return "closed"; case ECONNRESET: return "closed"; case ETIMEDOUT: return "timeout"; #endif default: return strerror(peusock_errno); } }
static void stream_sendfile_reap(struct lem_async *a) { struct sfhandle *sf = (struct sfhandle *)a; lua_State *T = sf->T; struct stream *s = sf->s; int ret; if (sf->ret == 0) { lua_pushinteger(T, sf->size); ret = 1; } else { if (s->open) close(s->w.fd); s->open = 0; ret = io_strerror(T, sf->ret); } free(sf); s->w.data = NULL; lem_queue(T, ret); }
static int stream_getpeer(lua_State *T) { struct stream *s; union { struct sockaddr all; struct sockaddr_in in; struct sockaddr_in6 in6; } addr; socklen_t len; luaL_checktype(T, 1, LUA_TUSERDATA); s = lua_touserdata(T, 1); if (!s->open) return io_closed(T); len = sizeof(addr); if (getpeername(s->r.fd, &addr.all, &len)) return io_strerror(T, errno); switch (addr.all.sa_family) { case AF_UNIX: { #if defined(__FreeBSD__) || defined(__APPLE__) struct xucred cred; len = sizeof(struct xucred); if (getsockopt(s->r.fd, 0, LOCAL_PEERCRED, &cred, &len)) return io_strerror(T, errno); if (len != sizeof(struct xucred) || cred.cr_version != XUCRED_VERSION) { lua_pushnil(T); lua_pushliteral(T, "version mismatch"); return 2; } lua_pushliteral(T, "*unix"); lua_pushinteger(T, cred.cr_uid); lua_pushinteger(T, cred.cr_gid); #else struct ucred cred; len = sizeof(struct ucred); if (getsockopt(s->r.fd, SOL_SOCKET, SO_PEERCRED, &cred, &len)) return io_strerror(T, errno); lua_pushliteral(T, "*unix"); lua_pushinteger(T, cred.uid); lua_pushinteger(T, cred.gid); #endif return 3; } case AF_INET: { char buf[INET_ADDRSTRLEN]; if (inet_ntop(addr.in.sin_family, &addr.in.sin_addr, buf, sizeof(buf)) == NULL) return io_strerror(T, errno); lua_pushstring(T, buf); lua_pushinteger(T, ntohs(addr.in.sin_port)); return 2; } case AF_INET6: { char buf[INET6_ADDRSTRLEN]; if (inet_ntop(addr.in6.sin6_family, &addr.in6.sin6_addr, buf, sizeof(buf)) == NULL) return io_strerror(T, errno); lua_pushstring(T, buf); lua_pushinteger(T, ntohs(addr.in6.sin6_port)); return 2; } } return io_strerror(T, EINVAL); }
static void *aac_open_internal (struct io_stream *stream, const char *fname) { struct aac_data *data; NeAACDecConfigurationPtr neaac_cfg; unsigned char channels; unsigned long sample_rate; int n; /* init private struct */ data = xcalloc (1, sizeof *data); data->decoder = NeAACDecOpen(); /* set decoder config */ neaac_cfg = NeAACDecGetCurrentConfiguration(data->decoder); neaac_cfg->outputFormat = FAAD_FMT_16BIT; /* force 16 bit audio */ neaac_cfg->downMatrix = 1; /* 5.1 -> stereo */ neaac_cfg->dontUpSampleImplicitSBR = 0; /* upsample, please! */ NeAACDecSetConfiguration(data->decoder, neaac_cfg); if (stream) data->stream = stream; else { data->stream = io_open (fname, 1); if (!io_ok(data->stream)) { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open AAC file: %s", io_strerror(data->stream)); return data; } } /* find a frame */ if (buffer_fill_frame(data) <= 0) { decoder_error (&data->error, ERROR_FATAL, 0, "Not a valid (or unsupported) AAC file"); return data; } /* in case of a bug, make sure there is at least some data * in the buffer for NeAACDecInit() to work with. */ if (buffer_fill_min(data, 256) <= 0) { decoder_error (&data->error, ERROR_FATAL, 0, "AAC file/stream too short"); return data; } /* init decoder, returns the length of the header (if any) */ channels = (unsigned char)data->channels; sample_rate = data->sample_rate; n = NeAACDecInit (data->decoder, buffer_data(data), buffer_length(data), &sample_rate, &channels); data->channels = channels; data->sample_rate = (int)sample_rate; if (n < 0) { decoder_error (&data->error, ERROR_FATAL, 0, "libfaad can't open this stream"); return data; } logit ("sample rate %dHz, channels %d", data->sample_rate, data->channels); if (!data->sample_rate || !data->channels) { decoder_error (&data->error, ERROR_FATAL, 0, "Invalid AAC sound parameters"); return data; } /* skip the header */ logit ("skipping header (%d bytes)", n); buffer_consume (data, n); /*NeAACDecInitDRM(data->decoder, data->sample_rate, data->channels);*/ data->ok = 1; return data; }
/* Read the speex header. Return 0 on error. */ static int read_speex_header (struct spx_data *data) { int packet_count = 0; int stream_init = 0; char *buf; ssize_t nb_read; int header_packets = 2; while (packet_count < header_packets) { /* Get the ogg buffer for writing */ buf = ogg_sync_buffer (&data->oy, 200); /* Read bitstream from input file */ nb_read = io_read (data->stream, buf, 200); if (nb_read < 0) { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open speex file: IO error: %s", io_strerror(data->stream)); return 0; } if (nb_read == 0) { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open speex header"); return 0; } ogg_sync_wrote (&data->oy, nb_read); /* Loop for all complete pages we got (most likely only one) */ while (ogg_sync_pageout(&data->oy, &data->og) == 1) { if (stream_init == 0) { ogg_stream_init(&data->os, ogg_page_serialno(&data->og)); stream_init = 1; } /* Add page to the bitstream */ ogg_stream_pagein (&data->os, &data->og); /* Extract all available packets FIXME: EOS! */ while (ogg_stream_packetout(&data->os, &data->op) == 1) { /* If first packet, process as Speex header */ if (packet_count == 0) { data->st = process_header (data); if (!data->st) { ogg_stream_clear (&data->os); return 0; } data->rate = data->header->rate; data->nchannels = data->header->nb_channels; data->frames_per_packet = data->header->frames_per_packet; /*data->vbr = data->header->vbr; */ if (!data->frames_per_packet) data->frames_per_packet=1; data->output = xmalloc (data->frame_size * data->nchannels * data->frames_per_packet * sizeof(int16_t)); data->output_start = 0; data->output_left = 0; header_packets += data->header->extra_headers; } else if (packet_count == 1) { data->comment_packet_len = data->op.bytes; data->comment_packet = xmalloc ( sizeof(char) * data->comment_packet_len); memcpy (data->comment_packet, data->op.packet, data->comment_packet_len); } packet_count++; } } } return 1; }
/* * file:lock() method */ static void file_lock_work(struct lem_async *a) { struct file *f = (struct file *)a; struct flock fl = { .l_type = f->lock.type, .l_whence = SEEK_SET, .l_start = f->lock.start, .l_len = f->lock.len, }; if (fcntl(f->fd, F_SETLK, &fl) == -1) f->ret = errno; else f->ret = 0; } static void file_lock_reap(struct lem_async *a) { struct file *f = (struct file *)a; lua_State *T = f->T; f->T = NULL; if (f->ret) { lem_queue(T, io_strerror(T, f->ret)); return; } lua_pushboolean(T, 1); lem_queue(T, 1); } static int file_lock(lua_State *T) { static const short mode[] = { F_RDLCK, F_WRLCK, F_UNLCK }; static const char *const modenames[] = { "r", "w", "u", NULL }; struct file *f; int op; lua_Number start; lua_Number len; luaL_checktype(T, 1, LUA_TUSERDATA); op = luaL_checkoption(T, 2, NULL, modenames); start = luaL_optnumber(T, 3, 0); len = luaL_optnumber(T, 4, 0); f = lua_touserdata(T, 1); f->lock.start = (off_t)start; luaL_argcheck(T, (lua_Number)f->lock.start == start, 3, "not an integer in proper range"); f->lock.len = (off_t)len; luaL_argcheck(T, (lua_Number)f->lock.len == len, 4, "not an integer in proper range"); if (f->fd < 0) return io_closed(T); if (f->T != NULL) return io_busy(T); f->T = T; f->lock.type = mode[op]; lem_async_do(&f->a, file_lock_work, file_lock_reap); lua_settop(T, 1); return lua_yield(T, 1); }