コード例 #1
0
ファイル: run_decoder.c プロジェクト: raumzeitlabor/mpd
size_t
decoder_read(G_GNUC_UNUSED struct decoder *decoder,
	     struct input_stream *is,
	     void *buffer, size_t length)
{
	return input_stream_read(is, buffer, length, NULL);
}
コード例 #2
0
ファイル: decoder_api.c プロジェクト: azuwis/mpd
size_t decoder_read(struct decoder *decoder,
		    struct input_stream *is,
		    void *buffer, size_t length)
{
	size_t nbytes;

	assert(decoder == NULL ||
	       dc.state == DECODE_STATE_START ||
	       dc.state == DECODE_STATE_DECODE);
	assert(is != NULL);
	assert(buffer != NULL);

	if (length == 0)
		return 0;

	while (true) {
		/* XXX don't allow decoder==NULL */
		if (decoder != NULL &&
		    /* ignore the SEEK command during initialization,
		       the plugin should handle that after it has
		       initialized successfully */
		    (dc.command != DECODE_COMMAND_SEEK ||
		     (dc.state != DECODE_STATE_START && !decoder->seeking)) &&
		    dc.command != DECODE_COMMAND_NONE)
			return 0;

		nbytes = input_stream_read(is, buffer, length);
		if (nbytes > 0 || input_stream_eof(is))
			return nbytes;

		/* sleep for a fraction of a second! */
		/* XXX don't sleep, wait for an event instead */
		g_usleep(10000);
	}
}
コード例 #3
0
static int
dump_input_stream(struct input_stream *is)
{
	GError *error = NULL;
	char buffer[4096];
	size_t num_read;
	ssize_t num_written;

	/* wait until the stream becomes ready */

	while (!is->ready) {
		int ret = input_stream_buffer(is, &error);
		if (ret < 0) {
			/* error */
			g_warning("%s", error->message);
			g_error_free(error);
			return 2;
		}

		if (ret == 0)
			/* nothing was buffered - wait */
			g_usleep(10000);
	}

	/* print meta data */

	if (is->mime != NULL)
		g_printerr("MIME type: %s\n", is->mime);

	/* read data and tags from the stream */

	while (!input_stream_eof(is)) {
		struct tag *tag = input_stream_tag(is);
		if (tag != NULL) {
			g_printerr("Received a tag:\n");
			tag_save(stderr, tag);
			tag_free(tag);
		}

		num_read = input_stream_read(is, buffer, sizeof(buffer),
					     &error);
		if (num_read == 0) {
			if (error != NULL) {
				g_warning("%s", error->message);
				g_error_free(error);
			}

			break;
		}

		num_written = write(1, buffer, num_read);
		if (num_written <= 0)
			break;
	}

	return 0;
}
コード例 #4
0
/**
 * Simple data fetcher.
 * @param url path or url of data to fetch.
 * @return data fetched, or NULL on error. Must be freed with g_free.
 */
static char *
lastfm_get(const char *url, GMutex *mutex, GCond *cond)
{
	struct input_stream *input_stream;
	GError *error = NULL;
	char buffer[4096];
	size_t length = 0, nbytes;

	input_stream = input_stream_open(url, mutex, cond, &error);
	if (input_stream == NULL) {
		if (error != NULL) {
			g_warning("%s", error->message);
			g_error_free(error);
		}

		return NULL;
	}

	g_mutex_lock(mutex);

	input_stream_wait_ready(input_stream);

	do {
		nbytes = input_stream_read(input_stream, buffer + length,
					   sizeof(buffer) - length, &error);
		if (nbytes == 0) {
			if (error != NULL) {
				g_warning("%s", error->message);
				g_error_free(error);
			}

			if (input_stream_eof(input_stream))
				break;

			/* I/O error */
			g_mutex_unlock(mutex);
			input_stream_close(input_stream);
			return NULL;
		}

		length += nbytes;
	} while (length < sizeof(buffer));

	g_mutex_unlock(mutex);

	input_stream_close(input_stream);
	return g_strndup(buffer, length);
}
コード例 #5
0
static ya_result
zdb_zone_axfr_input_stream_read(input_stream* stream_, u8* buffer, u32 len)
{
    zdb_zone_axfr_input_stream_data* stream = (zdb_zone_axfr_input_stream_data*)stream_->data;
    bool first_chance_eof = FALSE;
    
    for(;;)
    {    
        ya_result n = input_stream_read(&stream->filtered, buffer, len);
        
        // ERROR or SUCCESS
        
        if(n != 0)
        {
            /* log_debug("zdb_zone_axfr_input_stream_read: got %d", n); */
            
            return n;
        }
        
        // EOF ... or is it ?

        if(first_chance_eof)
        {
            // already broken once : EOF
            
            /* log_debug("zdb_zone_axfr_input_stream_read: final EOF"); */

            return 0;
        }

        if((stream->zone->axfr_timestamp != 0) || (stream->zone->axfr_serial != stream->serial))
        {
            // file written OR file written and a new one starts to be written => done
            
            /* log_debug("zdb_zone_axfr_input_stream_read: first chance EOF"); */

            first_chance_eof = TRUE;
        }
        else
        {
            // just wait
            
            /* log_debug("zdb_zone_axfr_input_stream_read: wait"); */
        }

        usleep(100000); // 10ms
    }
}
コード例 #6
0
static sf_count_t
sndfile_vio_read(void *ptr, sf_count_t count, void *user_data)
{
	struct input_stream *is = user_data;
	GError *error = NULL;
	size_t nbytes;

	nbytes = input_stream_read(is, ptr, count, &error);
	if (nbytes == 0 && error != NULL) {
		g_warning("%s", error->message);
		g_error_free(error);
		return -1;
	}

	return nbytes;
}
コード例 #7
0
static ssize_t
audiofile_file_read(AFvirtualfile *vfile, void *data, size_t length)
{
	struct input_stream *is = (struct input_stream *) vfile->closure;
	GError *error = NULL;
	size_t nbytes;

	nbytes = input_stream_read(is, data, length, &error);
	if (nbytes == 0 && error != NULL) {
		g_warning("%s", error->message);
		g_error_free(error);
		return -1;
	}

	return nbytes;
}
コード例 #8
0
ファイル: decoder_api.c プロジェクト: radioanonymous/mpd
size_t decoder_read(struct decoder *decoder,
		    struct input_stream *is,
		    void *buffer, size_t length)
{
	const struct decoder_control *dc =
		decoder != NULL ? decoder->dc : NULL;
	GError *error = NULL;
	size_t nbytes;

	assert(decoder == NULL ||
	       dc->state == DECODE_STATE_START ||
	       dc->state == DECODE_STATE_DECODE);
	assert(is != NULL);
	assert(buffer != NULL);

	if (length == 0)
		return 0;

	while (true) {
		/* XXX don't allow decoder==NULL */
		if (decoder != NULL &&
		    /* ignore the SEEK command during initialization,
		       the plugin should handle that after it has
		       initialized successfully */
		    (dc->command != DECODE_COMMAND_SEEK ||
		     (dc->state != DECODE_STATE_START && !decoder->seeking)) &&
		    dc->command != DECODE_COMMAND_NONE)
			return 0;

		nbytes = input_stream_read(is, buffer, length, &error);

		if (G_UNLIKELY(nbytes == 0 && error != NULL)) {
			g_warning("%s", error->message);
			g_error_free(error);
			return 0;
		}

		if (nbytes > 0 || input_stream_eof(is))
			return nbytes;

		/* sleep for a fraction of a second! */
		/* XXX don't sleep, wait for an event instead */
		g_usleep(10000);
	}
}
コード例 #9
0
ファイル: bz2_archive_plugin.c プロジェクト: Acidburn0zzz/mpd
static bool
bz2_fillbuffer(struct bz2_input_stream *bis, GError **error_r)
{
	size_t count;
	bz_stream *bzstream;

	bzstream = &bis->bzstream;

	if (bzstream->avail_in > 0)
		return true;

	count = input_stream_read(bis->archive->istream,
				  bis->buffer, sizeof(bis->buffer),
				  error_r);
	if (count == 0)
		return false;

	bzstream->next_in = bis->buffer;
	bzstream->avail_in = count;
	return true;
}
コード例 #10
0
static ya_result
buffer_input_stream_read(input_stream* stream, u8* buffer, u32 len)
{
    buffer_input_stream_data* data = (buffer_input_stream_data*)stream->data;
    u8* src = data->buffer;

    ya_result ret;

    u32 remaining = data->buffer_size - data->buffer_offset;

    if(len <= remaining)
    {
        MEMCOPY(buffer, &src[data->buffer_offset], len);
        data->buffer_offset += len;

        /* There are still some bytes available */

        return len;
    }

    /* len >= remaining : copy what remains in the buffer */

    MEMCOPY(buffer, &src[data->buffer_offset], remaining);
    len -= remaining;
    buffer += remaining;

    /* NOTE: at this point the internal buffer is empty */

    if(len >= data->buffer_maxsize)
    {
        /* It would be pointless to buffer a read bigger than the buffer */

        data->buffer_offset = data->buffer_size; /* mark the buffer as "empty" */

        if(ISOK(ret = input_stream_read(&data->filtered, buffer, len)))
        {
            return remaining + ret; /* the chunk we've read from the buffer +
				   the chunk we've read from the stream */
        }
        else // 'remaining' bytes may have been copied already, if so, return that before the error
        {
            return (remaining > 0)?remaining:ret;
        }
    }

#ifdef DEBUG
    memset(data->buffer, 0xee, data->buffer_maxsize);
#endif

    // What remains to read is smaller than the buffer max size:
    // read a full buffer

    if((ret = input_stream_read(&data->filtered, data->buffer, data->buffer_maxsize)) <= 0)
    {
        data->buffer_size = 0;
        data->buffer_offset = 0;
        
        // 'remaining' bytes may have been copied already, if so, return that before the error

        return (remaining > 0) ? remaining : ERROR /* eof */;
    }
    
    if(len > ret)
    {
        len = ret;
    }

    MEMCOPY(buffer, data->buffer, len); /* starts at offset 0 */

    data->buffer_size = ret;
    data->buffer_offset = len;

    return remaining + len;
}
コード例 #11
0
ya_result
buffer_input_stream_read_line(input_stream* stream, char* buffer, u32 len)
{
    assert(stream->vtbl == &buffer_input_stream_vtbl);
    
    buffer_input_stream_data* data = (buffer_input_stream_data*)stream->data;
    
    assert(data->buffer_offset <= data->buffer_size); 
    
    char *src = (char*)data->buffer;
    
    if(len == 0)
    {
        return BUFFER_WOULD_OVERFLOW;
    }
    
    len--;

    u32 total = 0;
    
    /*
     * look for '\n' in the remaining bytes
     */

    char *b = &src[data->buffer_offset];
    s32 n = data->buffer_size - data->buffer_offset;
    
    if(n == 0)
    {
        if((n = input_stream_read(&data->filtered, (u8*)src, data->buffer_maxsize)) <= 0)
        {
            data->buffer_offset = 0;
            data->buffer_size = 0;
            
            return n /* eof */;
        }
        
        data->buffer_offset = 0;
        data->buffer_size = n;
        b = src;
    }
    
    for(;;)
    { 
        
        n = MIN((s32)len, n);
        
#if 0 /* fix */
#else
        //
        char *eol = (char*)memchr(b, '\n', n);
        if(eol != NULL)
        {
            ++eol;
            u32 len = eol - b;
            data->buffer_offset = eol - src;
            memcpy(buffer, b, len);
            buffer[len] = '\0';
            return total + len;
        }
        memcpy(buffer, b, n);
        buffer += n;
#endif
        //
        total += n;
        len -= (s32)n;
        
        if(len == 0)
        {
            data->buffer_offset += len;
            
            *buffer = '\0';
            
            return total;
        }

       /* What remains to read is smaller than the buffer max size */

        data->buffer_offset = 0;

        if((n = input_stream_read(&data->filtered, (u8*)src, data->buffer_maxsize)) <= 0)
        {
            data->buffer_size = 0;
            
            *buffer = '\0';

            return (total > 0) ? total : ERROR /* eof */;
        }
        
        data->buffer_size = n;

        b = src;
    }
}
コード例 #12
0
ファイル: buffer_input_stream.c プロジェクト: koodaamo/yadifa
ya_result
buffer_input_stream_read_line(input_stream* stream, char* buffer, u32 len)
{
    assert(stream->vtbl == &buffer_input_stream_vtbl);
    
    buffer_input_stream_data* data = (buffer_input_stream_data*)stream->data;
    
    assert(data->buffer_offset <= data->buffer_size); 
    
    char *src = (char*)data->buffer;
    
    if(len == 0)
    {
        return ERROR;
    }
    
    len--;

    u32 total = 0;
    
    /*
     * look for '\n' in the remaining bytes
     */

    char *b = &src[data->buffer_offset];
    s32 n = data->buffer_size - data->buffer_offset;
    
    if(n == 0)
    {
        if((n = input_stream_read(&data->filtered, (u8*)src, data->buffer_maxsize)) <= 0)
        {
            data->buffer_offset = 0;
            data->buffer_size = 0;
            
            return n /* eof */;
        }
        
        data->buffer_offset = 0;
        data->buffer_size = n;
        b = src;
    }
    
    for(;;)
    { 
        
        n = MIN((s32)len, n);
        
        char *l = &b[n]; 
        char *p = b;

        while(p < l)
        {
            char c = *p++;
            *buffer++ = c;

            if(c == '\n')
            {
                data->buffer_offset = p - src;
                
                *buffer = '\0';

                return total + p - b;
            }
        }
        
        total += n;
        len -= (s32)n;
        
        if(len == 0)
        {
            data->buffer_offset += len;
            
            *buffer = '\0';
            
            return total;
        }

    #   /* What remains to read is smaller than the buffer max size */

        data->buffer_offset = 0;

        if((n = input_stream_read(&data->filtered, (u8*)src, data->buffer_maxsize)) <= 0)
        {
            data->buffer_size = 0;
            
            *buffer = '\0';

            return (total > 0) ? total : ERROR /* eof */;
        }
        
        data->buffer_size = n;

        b = src;
    }
}
コード例 #13
0
ファイル: audiofile_plugin.c プロジェクト: azuwis/mpd
static ssize_t
audiofile_file_read(AFvirtualfile *vfile, void *data, size_t nbytes)
{
	struct input_stream *is = (struct input_stream *) vfile->closure;
	return input_stream_read(is, data, nbytes);
}
コード例 #14
0
static ya_result
xfr_input_stream_read(input_stream *is, u8 *buffer, u32 len)
{
    xfr_input_stream_data *data = (xfr_input_stream_data*)is->data;
    input_stream *source_stream = &data->source_stream;
    message_data *message = data->message;
#if DNSCORE_HAS_TSIG_SUPPORT
    const tsig_item *tsig = message->tsig.tsig;
#endif
    packet_unpack_reader_data *reader = &data->reader;
    
    if(FAIL(data->last_error))
    {
        return data->last_error;
    }
    
    ya_result return_value = SUCCESS;
    
    /* while there is not enough bytes on the input */
    
    while(pipe_stream_read_available(&data->pipe_stream_input) < len)
    {
        /* read the packet and write on the output (so it can be read back on the input) */
        
        if(FAIL(return_value = xfr_input_stream_read_packet(data)))
        {
            break;
        }

        if(data->eos)
        {
            break;
        }
        
        if(data->ancount > 0)
        {
            break;
        }

        /* next TCP chunk */
        
#ifdef DEBUG
        memset(&message->buffer[0], 0xee, sizeof(message->buffer));
#endif
        
        u16 tcplen;
        
        return_value = input_stream_read_nu16(source_stream, &tcplen); /* this is wrong ... */

        if(return_value != 2)
        {
#ifdef DEBUG
            log_debug("xfr_input_stream_read: next message is %ld bytes long", return_value);
#endif
            break;
        }

        if(tcplen == 0)
        {
            return_value = UNEXPECTED_EOF;
            break;
        }

        if(FAIL(return_value = input_stream_read_fully(source_stream, message->buffer, tcplen)))
        {
            break;
        }
        
#if DEBUG_XFR_INPUT_STREAM
        log_memdump(g_system_logger, MSG_DEBUG1, &message->buffer[0], tcplen, 32);
#endif
        
        message->received = return_value;


#ifdef DEBUG
        memset(&message->buffer[tcplen], 0xdd, DNSPACKET_MAX_LENGTH + 1 - tcplen);
#endif
        /*
         * Check the headers
         */

        const u64 *h64 = (u64*)message->buffer;
        const u64 m64 = AXFR_NEXT_MESSAGE_HEADER_MASK;
        const u64 r64 = AXFR_NEXT_MESSAGE_HEADER_RESULT;

        if(((*h64&m64) != r64) || (MESSAGE_NS(message->buffer) != 0))
        {
            u8 code = MESSAGE_RCODE(message->buffer);

            if(code != 0)
            {
                return_value = MAKE_DNSMSG_ERROR(code);
            }
            else
            {
                return_value = UNPROCESSABLE_MESSAGE;
            }
            
            break;
        }
#if DNSCORE_HAS_TSIG_SUPPORT
        if((data->last_message_had_tsig = (tsig != NULL)))
        {
            /* verify the TSIG
             *
             * AR > 0
             * skip ALL the records until the last AR
             * it MUST be a TSIG
             * It's the first TSIG answering to our query
             * verify it
             *
             */

            message->tsig.tsig = NULL;

            if(FAIL(return_value = tsig_message_extract(message)))
            {
                break;
            }
            
            if((return_value == 1) && (message->tsig.tsig != tsig))
            {
                /* This is not the one we started with */

                log_debug("xfr_input_stream: signature key does not match");

                return_value = TSIG_BADSIG;
                break;
            }

            if(FAIL(return_value = tsig_verify_tcp_next_message(message)))
            {
                break;
            }
        }
#endif
        message_header *header = (message_header*)message->buffer;
        
        data->ancount = ntohs(header->ancount);

        packet_reader_init(reader, message->buffer, message->received);
        reader->offset = DNS_HEADER_LENGTH;

        u16 n = ntohs(header->qdcount);
        
        while(n > 0)
        {
            if(FAIL(return_value = packet_reader_skip_fqdn(reader)))
            {
                break;
            }

            packet_reader_skip(reader, 4);

            n--;
        }
    } // for(;;) /* process all TCP chunks */
    
    if(ISOK(return_value))
    {
        if((return_value = pipe_stream_read_available(&data->pipe_stream_input)) > 0) // never fails
        {
            if(FAIL(return_value = input_stream_read(&data->pipe_stream_input, buffer, len)))
            {
#if DNSCORE_HAS_TSIG_SUPPORT
                if(data->need_cleanup_tsig)
                {
                    tsig_verify_tcp_last_message(message);
                    data->need_cleanup_tsig = FALSE;
                }
#endif
            }
        }
        else
        {
            // here, return_value == 0
#if DNSCORE_HAS_TSIG_SUPPORT
            if(tsig != NULL)
            {
                tsig_verify_tcp_last_message(message);
                data->need_cleanup_tsig = FALSE;

                if(!data->last_message_had_tsig)
                {
                    /*
                     * The stream didn't end with a TSIG
                     * It's bad.
                     *
                     */

                    log_err("xfr_input_stream: TSIG enabled answer didn't ended with a signed packet");

                    return_value = TSIG_BADSIG;
                }
            }
#endif
        }
    }
    else
    {
#if DNSCORE_HAS_TSIG_SUPPORT
        // cleanup
        tsig_verify_tcp_last_message(message);
        data->need_cleanup_tsig = FALSE;
#endif
    }
    
    data->last_error = return_value;

    return return_value;
}
コード例 #15
0
ファイル: run_input.c プロジェクト: Acidburn0zzz/mpd
static int
dump_input_stream(struct input_stream *is)
{
	GError *error = NULL;
	char buffer[4096];
	size_t num_read;
	ssize_t num_written;

	input_stream_lock(is);

	/* wait until the stream becomes ready */

	input_stream_wait_ready(is);

	if (!input_stream_check(is, &error)) {
		g_warning("%s", error->message);
		g_error_free(error);
		input_stream_unlock(is);
		return EXIT_FAILURE;
	}

	/* print meta data */

	if (is->mime != NULL)
		g_printerr("MIME type: %s\n", is->mime);

	/* read data and tags from the stream */

	while (!input_stream_eof(is)) {
		struct tag *tag = input_stream_tag(is);
		if (tag != NULL) {
			g_printerr("Received a tag:\n");
			tag_save(stderr, tag);
			tag_free(tag);
		}

		num_read = input_stream_read(is, buffer, sizeof(buffer),
					     &error);
		if (num_read == 0) {
			if (error != NULL) {
				g_warning("%s", error->message);
				g_error_free(error);
			}

			break;
		}

		num_written = write(1, buffer, num_read);
		if (num_written <= 0)
			break;
	}

	if (!input_stream_check(is, &error)) {
		g_warning("%s", error->message);
		g_error_free(error);
		input_stream_unlock(is);
		return EXIT_FAILURE;
	}

	input_stream_unlock(is);

	return 0;
}
コード例 #16
-1
/**
 * Read JSON data and parse it using the given YAJL parser.
 * @param url URL of the JSON data.
 * @param hand YAJL parser handle.
 * @return -1 on error, 0 on success.
 */
static int
soundcloud_parse_json(const char *url, yajl_handle hand, GMutex* mutex, GCond* cond)
{
	struct input_stream *input_stream;
	GError *error = NULL;
	char buffer[4096];
	unsigned char *ubuffer = (unsigned char *)buffer;
	size_t nbytes;

	input_stream = input_stream_open(url, mutex, cond, &error);
	if (input_stream == NULL) {
		if (error != NULL) {
			g_warning("%s", error->message);
			g_error_free(error);
		}
		return -1;
	}

	g_mutex_lock(mutex);
	input_stream_wait_ready(input_stream);

	yajl_status stat;
	int done = 0;

	while (!done) {
		nbytes = input_stream_read(input_stream, buffer, sizeof(buffer), &error);
		if (nbytes == 0) {
			if (error != NULL) {
				g_warning("%s", error->message);
				g_error_free(error);
			}
			if (input_stream_eof(input_stream)) {
				done = true;
			} else {
				g_mutex_unlock(mutex);
				input_stream_close(input_stream);
				return -1;
			}
		}

		if (done)
			stat = yajl_parse_complete(hand);
		else
			stat = yajl_parse(hand, ubuffer, nbytes);

		if (stat != yajl_status_ok &&
			stat != yajl_status_insufficient_data)
		{
			unsigned char *str = yajl_get_error(hand, 1, ubuffer, nbytes);
			g_warning("%s", str);
			yajl_free_error(hand, str);
			break;
		}
	}

	g_mutex_unlock(mutex);
	input_stream_close(input_stream);

	return 0;
}