/*********************************************************************** * * smtp_perform() * * This is the actual DO function for SMTP. Transfer a mail, send a command * or get some data according to the options previously setup. */ static CURLcode smtp_perform(struct connectdata *conn, bool *connected, bool *dophase_done) { /* This is SMTP and no proxy */ CURLcode result = CURLE_OK; struct Curl_easy *data = conn->data; struct SMTP *smtp = data->req.protop; DEBUGF(infof(conn->data, "DO phase starts\n")); if(data->set.opt_no_body) { /* Requested no body means no transfer */ smtp->transfer = FTPTRANSFER_INFO; } *dophase_done = FALSE; /* not done yet */ /* Store the first recipient (or NULL if not specified) */ smtp->rcpt = data->set.mail_rcpt; /* Initial data character is the first character in line: it is implicitly preceded by a virtual CRLF. */ smtp->trailing_crlf = TRUE; smtp->eob = 2; /* Start the first command in the DO phase */ if((data->set.upload || data->set.mimepost.kind) && data->set.mail_rcpt) /* MAIL transfer */ result = smtp_perform_mail(conn); else /* SMTP based command (VRFY, EXPN, NOOP, RSET or HELP) */ result = smtp_perform_command(conn); if(result) return result; /* Run the state-machine */ result = smtp_multi_statemach(conn, dophase_done); *connected = conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) DEBUGF(infof(conn->data, "DO phase is complete\n")); return result; }
/* For command responses */ static CURLcode smtp_state_command_resp(struct connectdata *conn, int smtpcode, smtpstate instate) { CURLcode result = CURLE_OK; struct Curl_easy *data = conn->data; struct SMTP *smtp = data->req.protop; char *line = data->state.buffer; size_t len = strlen(line); (void)instate; /* no use for this yet */ if((smtp->rcpt && smtpcode/100 != 2 && smtpcode != 553 && smtpcode != 1) || (!smtp->rcpt && smtpcode/100 != 2 && smtpcode != 1)) { failf(data, "Command failed: %d", smtpcode); result = CURLE_RECV_ERROR; } else { /* Temporarily add the LF character back and send as body to the client */ if(!data->set.opt_no_body) { line[len] = '\n'; result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1); line[len] = '\0'; } if(smtpcode != 1) { if(smtp->rcpt) { smtp->rcpt = smtp->rcpt->next; if(smtp->rcpt) { /* Send the next command */ result = smtp_perform_command(conn); } else /* End of DO phase */ state(conn, SMTP_STOP); } else /* End of DO phase */ state(conn, SMTP_STOP); } } return result; }
/*********************************************************************** * * smtp_perform() * * This is the actual DO function for SMTP. Transfer a mail, send a command * or get some data according to the options previously setup. */ static CURLcode smtp_perform(struct connectdata *conn, bool *connected, bool *dophase_done) { /* This is SMTP and no proxy */ CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; struct SMTP *smtp = data->req.protop; DEBUGF(infof(conn->data, "DO phase starts\n")); if(data->set.opt_no_body) { /* Requested no body means no transfer */ smtp->transfer = FTPTRANSFER_INFO; } *dophase_done = FALSE; /* not done yet */ /* Store the first recipient (or NULL if not specified) */ smtp->rcpt = data->set.mail_rcpt; /* Start the first command in the DO phase */ if(data->set.upload && data->set.mail_rcpt) /* MAIL transfer */ result = smtp_perform_mail(conn); else /* SMTP based command (VRFY, EXPN, NOOP, RSET or HELP) */ result = smtp_perform_command(conn); if(result) return result; /* Run the state-machine */ result = smtp_multi_statemach(conn, dophase_done); *connected = conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) DEBUGF(infof(conn->data, "DO phase is complete\n")); return result; }