コード例 #1
0
ssize_t netstring_get_length(VSTREAM *stream)
{
    const char *myname = "netstring_get_length";
    ssize_t len = 0;
    int     ch;

    for (;;) {
	switch (ch = VSTREAM_GETC(stream)) {
	case VSTREAM_EOF:
	    netstring_except(stream, vstream_ftimeout(stream) ?
			     NETSTRING_ERR_TIME : NETSTRING_ERR_EOF);
	case ':':
	    if (msg_verbose > 1)
		msg_info("%s: read netstring length %ld", myname, (long) len);
	    return (len);
	default:
	    if (!ISDIGIT(ch))
		netstring_except(stream, NETSTRING_ERR_FORMAT);
	    len = len * 10 + ch - '0';
	    /* vstream_fread() would read zero bytes. Reject input anyway. */
	    if (len < 0)
		netstring_except(stream, NETSTRING_ERR_SIZE);
	    break;
	}
    }
}
コード例 #2
0
ファイル: qmqp-sink.c プロジェクト: DabeDotCom/postfix
static void read_data(int unused_event, void *context)
{
    SINK_STATE *state = (SINK_STATE *) context;
    int     fd = vstream_fileno(state->stream);
    int     count;

    /*
     * Refill the VSTREAM buffer, if necessary.
     */
    if (VSTREAM_GETC(state->stream) == VSTREAM_EOF)
	netstring_except(state->stream, vstream_ftimeout(state->stream) ?
			 NETSTRING_ERR_TIME : NETSTRING_ERR_EOF);
    state->count--;

    /*
     * Flush the VSTREAM buffer. As documented, vstream_fseek() discards
     * unread input.
     */
    if ((count = vstream_peek(state->stream)) > 0) {
	state->count -= count;
	if (state->count <= 0) {
	    send_reply(state);
	    return;
	}
	vstream_fpurge(state->stream, VSTREAM_PURGE_BOTH);
    }

    /*
     * Do not block while waiting for the arrival of more data.
     */
    event_disable_readwrite(fd);
    event_enable_read(fd, read_data, context);
}
コード例 #3
0
VSTRING *netstring_get_data(VSTREAM *stream, VSTRING *buf, ssize_t len)
{
    const char *myname = "netstring_get_data";

    /*
     * Allocate buffer space.
     */
    VSTRING_RESET(buf);
    VSTRING_SPACE(buf, len);

    /*
     * Read the payload and absorb the terminator.
     */
    if (vstream_fread(stream, STR(buf), len) != len)
	netstring_except(stream, vstream_ftimeout(stream) ?
			 NETSTRING_ERR_TIME : NETSTRING_ERR_EOF);
    if (msg_verbose > 1)
	msg_info("%s: read netstring data %.*s",
		 myname, (int) (len < 30 ? len : 30), STR(buf));
    netstring_get_terminator(stream);

    /*
     * Position the buffer.
     */
    VSTRING_AT_OFFSET(buf, len);
    return (buf);
}
コード例 #4
0
VSTRING *netstring_get(VSTREAM *stream, VSTRING *buf, ssize_t limit)
{
    ssize_t len;

    len = netstring_get_length(stream);
    if (limit && len > limit)
	netstring_except(stream, NETSTRING_ERR_SIZE);
    netstring_get_data(stream, buf, len);
    return (buf);
}
コード例 #5
0
void    netstring_get_terminator(VSTREAM *stream)
{
    if (VSTREAM_GETC(stream) != ',')
	netstring_except(stream, NETSTRING_ERR_FORMAT);
}