/* for RCPT responses */ static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode, smtpstate instate) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; (void)instate; /* no use for this yet */ if(smtpcode/100 != 2) { failf(data, "Access denied: %d", smtpcode); result = CURLE_LOGIN_DENIED; state(conn, SMTP_STOP); } else { struct smtp_conn *smtpc = &conn->proto.smtpc; if(smtpc->rcpt) { smtpc->rcpt = smtpc->rcpt->next; result = smtp_rcpt_to(conn); /* if we failed or still is in RCPT sending, return */ if(result || smtpc->rcpt) return result; } /* send DATA */ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "DATA"); if(result) return result; state(conn, SMTP_DATA); } return result; }
/* For RCPT responses */ static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode, smtpstate instate) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; struct SMTP *smtp = data->state.proto.smtp; (void)instate; /* no use for this yet */ if(smtpcode/100 != 2) { failf(data, "RCPT failed: %d", smtpcode); result = CURLE_SEND_ERROR; state(conn, SMTP_STOP); } else { if(smtp->rcpt) { smtp->rcpt = smtp->rcpt->next; result = smtp_rcpt_to(conn); /* If we failed or still are sending RCPT data then return */ if(result || smtp->rcpt) return result; } /* Send the DATA command */ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "DATA"); if(result) return result; state(conn, SMTP_DATA); } return result; }
/* Called by: */ int smtp_decode_req(struct hi_thr* hit, struct hi_io* io) { struct hi_pdu* req = io->cur_pdu; D("smtp_state(%d) scan(%.*s)", io->ad.smtp.state, (int)MIN(7, req->ap - req->scan), req->scan); switch (io->ad.smtp.state) { case SMTP_START: return smtp_ehlo(hit, io, req); case SMTP_MAIN: return smtp_mail_from(hit, io, req); case SMTP_TO: return smtp_rcpt_to(hit, io, req); case SMTP_MORE0: case SMTP_MORE1: case SMTP_MORE2: return smtp_data(hit, io, req); case SMTP_WAIT: case SMTP_STATUS: D("Unexpected state %x", io->ad.smtp.state); case SMTP_END: return smtp_mail_from(hit, io, req); default: NEVERNEVER("impossible SMTP state %d", io->ad.smtp.state); } return 0; }
/* for MAIL responses */ static CURLcode smtp_state_mail_resp(struct connectdata *conn, int smtpcode, smtpstate instate) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; (void)instate; /* no use for this yet */ if(smtpcode/100 != 2) { failf(data, "Access denied: %d", smtpcode); result = CURLE_LOGIN_DENIED; state(conn, SMTP_STOP); } else { struct smtp_conn *smtpc = &conn->proto.smtpc; smtpc->rcpt = data->set.mail_rcpt; result = smtp_rcpt_to(conn); } return result; }
/* For MAIL responses */ static CURLcode smtp_state_mail_resp(struct connectdata *conn, int smtpcode, smtpstate instate) { CURLcode result = CURLE_OK; struct SessionHandle *data = conn->data; struct SMTP *smtp = data->state.proto.smtp; (void)instate; /* no use for this yet */ if(smtpcode/100 != 2) { failf(data, "MAIL failed: %d", smtpcode); result = CURLE_SEND_ERROR; state(conn, SMTP_STOP); } else { smtp->rcpt = data->set.mail_rcpt; result = smtp_rcpt_to(conn); } return result; }
int mutt_smtp_send (const ADDRESS* from, const ADDRESS* to, const ADDRESS* cc, const ADDRESS* bcc, const char *msgfile, int eightbit) { CONNECTION *conn; ACCOUNT account; const char* envfrom; char buf[1024]; int ret = -1; /* it might be better to synthesize an envelope from from user and host * but this condition is most likely arrived at accidentally */ if (EnvFrom) envfrom = EnvFrom->mailbox; else if (from) envfrom = from->mailbox; else { mutt_error (_("No from address given")); return -1; } if (smtp_fill_account (&account) < 0) return ret; if (!(conn = mutt_conn_find (NULL, &account))) return -1; Esmtp = eightbit; do { /* send our greeting */ if (( ret = smtp_open (conn))) break; FREE (&AuthMechs); /* send the sender's address */ ret = snprintf (buf, sizeof (buf), "MAIL FROM:<%s>", envfrom); if (eightbit && mutt_bit_isset (Capabilities, EIGHTBITMIME)) { safe_strncat (buf, sizeof (buf), " BODY=8BITMIME", 15); ret += 14; } if (DsnReturn && mutt_bit_isset (Capabilities, DSN)) ret += snprintf (buf + ret, sizeof (buf) - ret, " RET=%s", DsnReturn); safe_strncat (buf, sizeof (buf), "\r\n", 3); if (mutt_socket_write (conn, buf) == -1) { ret = smtp_err_write; break; } if ((ret = smtp_get_resp (conn))) break; /* send the recipient list */ if ((ret = smtp_rcpt_to (conn, to)) || (ret = smtp_rcpt_to (conn, cc)) || (ret = smtp_rcpt_to (conn, bcc))) break; /* send the message data */ if ((ret = smtp_data (conn, msgfile))) break; mutt_socket_write (conn, "QUIT\r\n"); ret = 0; } while (0); if (conn) mutt_socket_close (conn); if (ret == smtp_err_read) mutt_error (_("SMTP session failed: read error")); else if (ret == smtp_err_write) mutt_error (_("SMTP session failed: write error")); else if (ret == smtp_err_code) mutt_error (_("Invalid server response")); return ret; }