i_error(
"%s-client: conn %s: command %s: %s",
"(%u commands pending, %u commands queued)",
const unsigned char *
data;
/* ignore CRLF, which is added at command submission */ /* it is being sent; cannot truly abort it now */ /* we're expecting a reply; cannot truly abort it now */ /* can only destroy it when it is not pending */ /* copy the array and reference the commands to be robust against more than one command disappearing from the list */ for (i = 0; i <
count; i++) {
/* copy the array and reference the commands to be robust against more than one command disappearing from the list */ for (i = 0; i <
count; i++) {
/* we're sending the stream now */ /* finished with the stream */ "Finished reading payload stream");
/* this concludes the dot stream with CRLF.CRLF */ /* done sending payload */ /* the provided payload stream is broken; fail this command separately */ "Broken payload stream");
/* we're in the middle of sending a command, so the connection will also have to be aborted */ "Broken payload stream");
/* normal connection failure */ /* check whether we can send anything */ /* wait until we're fully connected */ "Connection not ready [state=%s]",
/* cannot pipeline; wait for reply */ /* cannot pipeline with previous command; "Blocked while sending");
"Blocked while sending payload");
/* everything sent. move command to wait list. */ /* Add commands to send queue for delayed failure reply "Submitted, but disconnected");
/* pre-login commands get inserted before everything else */ /* not in the send queue anymore; just prepend */ /* insert after indicated command */ /* insert at beginning of queue for priority commands */ /* just append at end of queue */ "i_stream_get_size(%s) failed: %s",
/* size must be known if stream is to be sent in chunks */ "(%u commands pending, %u commands queued)",
/* NOTE: Pipelining is only enabled for certain commands: From RFC 2920, Section 3.1: Once the client SMTP has confirmed that support exists for the pipelining extension, the client SMTP may then elect to transmit groups of SMTP commands in batches without waiting for a response to each individual command. In particular, the commands RSET, MAIL FROM, SEND FROM, SOML FROM, SAML FROM, and RCPT TO can all appear anywhere in a pipelined command group. The EHLO, DATA, VRFY, EXPN, TURN, QUIT, and NOOP commands can only appear as the last command in a group since their success or failure produces a change of state which the client SMTP must accommodate. (NOOP is included in this group so it can be used as a synchronization point.) Additional commands added by other SMTP extensions may only appear as the last command in a group unless otherwise specified by the extensions that define the commands. /* abort the main (possibly unsubmitted) data command */ /* drop all pending commands */ for (i = 0; i <
count; i++) {
/* the main (possibly unsubmitted) data command got aborted */ /* fail the main (possibly unsubmitted) data command so that the caller gets notified */ /* got DATA reply; one command must be pending */ /* submit second stage: which is a command with only a stream */ /* nothing else to do, so drop the context already */ /* got BDAT reply, so there must be ones pending */ /* drop the command from the list */ /* send more BDAT commands if necessary */ /* all of the BDAT commands finished already */ /* send more BDAT commands if possible */ "Failed to read DATA stream: %s",
"Broken payload stream");
/* finished or aborted */ /* pipeline management: determine where to submit the next command */ /* previous BDAT command not completely sent */ /* Keep sending more chunks until pipeline is filled to the limit */ /* data stream size known: record where we left off */ /* data stream size known: record where we left off */ /* the last chunk, which may actually be empty */ /* submit final command */ /* all of the previous BDAT commands got replies already */ /* create the final command early for reference by the caller; it will not be submitted for now. The DATA command is handled in two stages (== command submissions), the BDAT command in one or more. */ /* create context in the final command's pool */ /* capture abort event with our context */ /* Data stream is sent in one go in the second stage. Since the data is sent in a '<CRLF>.<CRLF>'-terminated stream, it size is not /* Submit the initial DATA command */ /* The data stream is sent in multiple chunks. Either the size of the data stream is known or it is not. These cases are handled a little /* Send the first BDAT command(s) */