static void qmqpd_receive(QMQPD_STATE *state) { /* * Open a queue file. This must be first so that we can simplify the * error logging and always include the queue ID information. */ qmqpd_open_file(state); /* * Read and ignore the over-all netstring length indicator. */ state->where = "receiving QMQP packet header"; (void) netstring_get_length(state->client); /* * XXX Read the message content into memory, because Postfix expects to * store the sender before storing the message content. Fixing that * requires changes to pickup, cleanup, qmgr, and perhaps elsewhere, so * that will have to happen later when I have more time. However, QMQP is * used for mailing list distribution, so the bulk of the volume is * expected to be not message content but recipients, and recipients are * not accumulated in memory. */ qmqpd_read_content(state); /* * Read and write the envelope sender. */ qmqpd_copy_sender(state); /* * Record some session attributes. */ qmqpd_write_attributes(state); /* * Read and write the envelope recipients, including the optional big * brother recipient. */ qmqpd_copy_recipients(state); /* * Start the message content segment, prepend our own Received: header, * and write the message content. */ if (state->err == 0) qmqpd_write_content(state); /* * Close the queue file. */ qmqpd_close_file(state); /* * Report the completion status to the client. */ qmqpd_send_status(state); }
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); }
static void read_length(int event, void *context) { SINK_STATE *state = (SINK_STATE *) context; switch (vstream_setjmp(state->stream)) { default: msg_panic("unknown error reading input"); case NETSTRING_ERR_TIME: msg_panic("attempt to read non-readable socket"); /* NOTREACHED */ case NETSTRING_ERR_EOF: msg_warn("lost connection"); disconnect(state); return; case NETSTRING_ERR_FORMAT: msg_warn("netstring format error"); disconnect(state); return; case NETSTRING_ERR_SIZE: msg_warn("netstring size error"); disconnect(state); return; /* * Include the netstring terminator in the read byte count. This * violates abstractions. */ case 0: state->count = netstring_get_length(state->stream) + 1; read_data(event, context); return; } }