home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
- /*
- * state machine to speak SMTP
- */
-
- /* Please leave outside of ifdef for windows precompiled headers */
- #include "rosetta.h"
- #include "mkutils.h"
-
- #if defined(MOZILLA_CLIENT) || defined(LIBNET_SMTP)
- #if defined(MOZ_MAIL_NEWS) || defined(MOZ_MAIL_COMPOSE)
-
- #include "mkgeturl.h"
- #include "mksmtp.h"
- #include "mime.h"
- #include "glhist.h"
- #include "mktcp.h"
- #include "mkparse.h"
- #include "msgcom.h"
- #include "msgnet.h"
- #include "xp_time.h"
- #include "xp_thrmo.h"
- #include "merrors.h"
- #include "ssl.h"
- #include "imap.h"
-
- #include "xp_error.h"
- #include "prefapi.h"
-
- #ifdef AUTH_SKEY_DEFINED
- extern int btoa8(char *out, char*in);
- #endif
-
- extern void NET_SetPopPassword2(const char *password);
-
- /* for XP_GetString() */
- #include "xpgetstr.h"
- extern int XP_PROGRESS_MAILSENT;
- extern int MK_COULD_NOT_GET_USERS_MAIL_ADDRESS;
- extern int MK_COULD_NOT_LOGIN_TO_SMTP_SERVER;
- extern int MK_ERROR_SENDING_DATA_COMMAND;
- extern int MK_ERROR_SENDING_FROM_COMMAND;
- extern int MK_ERROR_SENDING_MESSAGE;
- extern int MK_ERROR_SENDING_RCPT_COMMAND;
- extern int MK_OUT_OF_MEMORY;
- extern int MK_SMTP_SERVER_ERROR;
- extern int MK_TCP_READ_ERROR;
- extern int XP_MESSAGE_SENT_WAITING_MAIL_REPLY;
- extern int MK_MSG_DELIV_MAIL;
- extern int MK_MSG_NO_SMTP_HOST;
- extern int MK_MIME_NO_RECIPIENTS;
-
- extern int MK_POP3_USERNAME_UNDEFINED;
- extern int MK_POP3_PASSWORD_UNDEFINED;
- extern int XP_PASSWORD_FOR_POP3_USER;
- extern int XP_RETURN_RECEIPT_NOT_SUPPORT;
- extern int XP_SENDMAIL_BAD_TLS;
-
- #define SMTP_PORT 25
-
- /* definitions of state for the state machine design
- */
- #define SMTP_RESPONSE 0
- #define SMTP_START_CONNECT 1
- #define SMTP_FINISH_CONNECT 2
- #define SMTP_LOGIN_RESPONSE 3
- #define SMTP_SEND_HELO_RESPONSE 4
- #define SMTP_SEND_VRFY_RESPONSE 5
- #define SMTP_SEND_MAIL_RESPONSE 6
- #define SMTP_SEND_RCPT_RESPONSE 7
- #define SMTP_SEND_DATA_RESPONSE 8
- #define SMTP_SEND_POST_DATA 9
- #define SMTP_SEND_MESSAGE_RESPONSE 10
- #define SMTP_DONE 11
- #define SMTP_ERROR_DONE 12
- #define SMTP_FREE 13
- #define SMTP_EXTN_LOGIN_RESPONSE 14
- #define SMTP_SEND_EHLO_RESPONSE 15
-
- #define SMTP_SEND_AUTH_LOGIN_USERNAME 16
- #define SMTP_SEND_AUTH_LOGIN_PASSWORD 17
- #define SMTP_AUTH_LOGIN_RESPONSE 18
- #define SMTP_AUTH_RESPONSE 19
-
-
- HG08747
-
- /* structure to hold data pertaining to the active state of
- * a transfer in progress.
- *
- */
- typedef struct _SMTPConData {
- int next_state; /* the next state or action to be taken */
- int next_state_after_response; /* the state after the response one */
- Bool pause_for_read; /* Pause now for next read? */
- #ifdef XP_WIN
- Bool calling_netlib_all_the_time;
- #endif
- char *response_text;
- int response_code;
- char *data_buffer;
- int32 data_buffer_size;
- char *address_copy;
- char *mail_to_address_ptr;
- int mail_to_addresses_left;
- TCP_ConData * tcp_con_data;
- int continuation_response;
- char *hostname;
- char *verify_address;
- void *write_post_data_data; /* a data object for the
- * WritePostData function
- */
- int32 total_amt_written;
- uint32 total_message_size;
- unsigned long last_time;
- XP_Bool ehlo_dsn_enabled;
- XP_Bool auth_login_enabled;
- HG60917
- } SMTPConData;
-
- /* macro's to simplify variable names */
- #define CD_NEXT_STATE cd->next_state
- #define CD_NEXT_STATE_AFTER_RESPONSE cd->next_state_after_response
- #define CD_PAUSE_FOR_READ cd->pause_for_read
- #define CD_RESPONSE_TXT cd->response_text
- #define CD_RESPONSE_CODE cd->response_code
- #define CD_DATA_BUFFER cd->data_buffer
- #define CD_DATA_BUFFER_SIZE cd->data_buffer_size
- #define CD_ADDRESS_COPY cd->address_copy
- #define CD_MAIL_TO_ADDRESS_PTR cd->mail_to_address_ptr
- #define CD_MAIL_TO_ADDRESSES_LEFT cd->mail_to_addresses_left
- #define CD_TCP_CON_DATA cd->tcp_con_data
- #define CD_CONTINUATION_RESPONSE cd->continuation_response
- #define CD_HOSTNAME cd->hostname
- #define CD_VERIFY_ADDRESS cd->verify_address
- #define CD_TOTAL_AMT_WRITTEN cd->total_amt_written
- #define CD_TOTAL_MESSAGE_SIZE cd->total_message_size
- #define CD_EHLO_DSN_ENABLED cd->ehlo_dsn_enabled
-
- #define CD_AUTH_LOGIN_ENABLED cd->auth_login_enabled
- HG82493
-
- #define CE_URL_S cur_entry->URL_s
- #define CE_SOCK cur_entry->socket
- #define CE_CON_SOCK cur_entry->con_sock
- #define CE_STATUS cur_entry->status
- #define CE_WINDOW_ID cur_entry->window_id
- #define CE_BYTES_RECEIVED cur_entry->bytes_received
- #define CE_FORMAT_OUT cur_entry->format_out
-
- PRIVATE char *net_smtp_relay_host=0;
- PRIVATE char *net_smtp_password=0;
-
- /* forward decl */
- PRIVATE int32 net_ProcessMailto (ActiveEntry *cur_entry);
-
- /* fix Mac warning of missing prototype */
- MODULE_PRIVATE char *
- NET_MailRelayHost(MWContext *context);
-
- MODULE_PRIVATE char *
- NET_MailRelayHost(MWContext *context)
- {
- if(net_smtp_relay_host)
- return(net_smtp_relay_host);
- else
- return(""); /* caller now checks for empty string and returns MK_MSG_NO_SMTP_HOST */
- }
-
- PUBLIC void
- NET_SetMailRelayHost(char * host)
- {
- char * at = NULL;
-
- /*
- ** If we are called with data like "fred@bedrock.com", then we will
- ** help the user by ignoring the stuff before the "@". People with
- ** @ signs in their host names will be hosed. They also can't possibly
- ** be current happy internet users.
- */
- if (host) at = XP_STRCHR(host, '@');
- if (at != NULL) host = at + 1;
- StrAllocCopy(net_smtp_relay_host, host);
- }
-
- /*
- * gets user domian name out from FE_UsersMailAddress()
- */
- PRIVATE const char *
- net_smtp_get_user_domain_name()
- {
- const char *mail_addr, *at_sign = NULL;
- mail_addr = FE_UsersMailAddress();
- at_sign = XP_STRCHR(mail_addr, '@');
- return (at_sign ? at_sign+1 : mail_addr);
- }
-
- /* RFC 1891 -- extended smtp value encoding scheme
-
- 5. Additional parameters for RCPT and MAIL commands
-
- The extended RCPT and MAIL commands are issued by a client when it wishes to request a DSN from the
- server, under certain conditions, for a particular recipient. The extended RCPT and MAIL commands are
- identical to the RCPT and MAIL commands defined in [1], except that one or more of the following parameters
- appear after the sender or recipient address, respectively. The general syntax for extended SMTP commands is
- defined in [4].
-
- NOTE: Although RFC 822 ABNF is used to describe the syntax of these parameters, they are not, in the
- language of that document, "structured field bodies". Therefore, while parentheses MAY appear within an
- emstp-value, they are not recognized as comment delimiters.
-
- The syntax for "esmtp-value" in [4] does not allow SP, "=", control characters, or characters outside the
- traditional ASCII range of 1- 127 decimal to be transmitted in an esmtp-value. Because the ENVID and
- ORCPT parameters may need to convey values outside this range, the esmtp-values for these parameters are
- encoded as "xtext". "xtext" is formally defined as follows:
-
- xtext = *( xchar / hexchar )
-
- xchar = any ASCII CHAR between "!" (33) and "~" (126) inclusive, except for "+" and "=".
-
- ; "hexchar"s are intended to encode octets that cannot appear
- ; as ASCII characters within an esmtp-value.
-
- hexchar = ASCII "+" immediately followed by two upper case hexadecimal digits
-
- When encoding an octet sequence as xtext:
-
- + Any ASCII CHAR between "!" and "~" inclusive, except for "+" and "=",
- MAY be encoded as itself. (A CHAR in this range MAY instead be encoded as a "hexchar", at the
- implementor's discretion.)
-
- + ASCII CHARs that fall outside the range above must be encoded as
- "hexchar".
-
- */
- /* caller must free the return buffer */
- PRIVATE char *
- esmtp_value_encode(char *addr)
- {
- char *buffer = XP_ALLOC(512); /* esmpt ORCPT allow up to 500 chars encoded addresses */
- char *bp = buffer, *bpEnd = buffer+500;
- int len, i;
-
- if (!buffer) return NULL;
-
- *bp=0;
- if (! addr || *addr == 0) /* this will never happen */
- return buffer;
-
- for (i=0, len=XP_STRLEN(addr); i < len && bp < bpEnd; i++)
- {
- if (*addr >= 0x21 &&
- *addr <= 0x7E &&
- *addr != '+' &&
- *addr != '=')
- {
- *bp++ = *addr++;
- }
- else
- {
- PR_snprintf(bp, bpEnd-bp, "+%.2X", ((int)*addr++));
- bp += XP_STRLEN(bp);
- }
- }
- *bp=0;
- return buffer;
- }
-
- /*
- * gets the response code from the nntp server and the
- * response line
- *
- * returns the TCP return code from the read
- */
- PRIVATE int
- net_smtp_response (ActiveEntry * cur_entry)
- {
- char * line;
- char cont_char;
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
-
- CE_STATUS = NET_BufferedReadLine(CE_SOCK, &line, &CD_DATA_BUFFER,
- &CD_DATA_BUFFER_SIZE, &CD_PAUSE_FOR_READ);
-
- if(CE_STATUS == 0)
- {
- CD_NEXT_STATE = SMTP_ERROR_DONE;
- CD_PAUSE_FOR_READ = FALSE;
- CE_URL_S->error_msg = NET_ExplainErrorDetails(MK_SMTP_SERVER_ERROR,
- CD_RESPONSE_TXT);
- CE_STATUS = MK_SMTP_SERVER_ERROR;
- return(MK_SMTP_SERVER_ERROR);
- }
-
- /* if TCP error of if there is not a full line yet return
- */
- if(CE_STATUS < 0)
- {
- CE_URL_S->error_msg =
- NET_ExplainErrorDetails(MK_TCP_READ_ERROR, SOCKET_ERRNO);
-
- /* return TCP error
- */
- return MK_TCP_READ_ERROR;
- }
- else if(!line)
- {
- return CE_STATUS;
- }
-
- TRACEMSG(("SMTP Rx: %s\n", line));
-
- cont_char = ' '; /* default */
- sscanf(line, "%d%c", &CD_RESPONSE_CODE, &cont_char);
-
- if(CD_CONTINUATION_RESPONSE == -1)
- {
- if (cont_char == '-') /* begin continuation */
- CD_CONTINUATION_RESPONSE = CD_RESPONSE_CODE;
-
- if(XP_STRLEN(line) > 3)
- StrAllocCopy(CD_RESPONSE_TXT, line+4);
- }
- else
- { /* have to continue */
- if (CD_CONTINUATION_RESPONSE == CD_RESPONSE_CODE && cont_char == ' ')
- CD_CONTINUATION_RESPONSE = -1; /* ended */
-
- StrAllocCat(CD_RESPONSE_TXT, "\n");
- if(XP_STRLEN(line) > 3)
- StrAllocCat(CD_RESPONSE_TXT, line+4);
- }
-
- if(CD_CONTINUATION_RESPONSE == -1) /* all done with this response? */
- {
- CD_NEXT_STATE = CD_NEXT_STATE_AFTER_RESPONSE;
- CD_PAUSE_FOR_READ = FALSE; /* don't pause */
- }
-
- return(0); /* everything ok */
- }
-
- PRIVATE int
- net_smtp_login_response(ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
- char buffer[356];
-
- if(CD_RESPONSE_CODE != 220)
- {
- CE_URL_S->error_msg = NET_ExplainErrorDetails(MK_COULD_NOT_LOGIN_TO_SMTP_SERVER);
- return(MK_COULD_NOT_LOGIN_TO_SMTP_SERVER);
- }
-
-
- PR_snprintf(buffer, sizeof(buffer), "HELO %.256s" CRLF,
- net_smtp_get_user_domain_name());
-
- TRACEMSG(("Tx: %s", buffer));
-
- CE_STATUS = (int) NET_BlockingWrite(CE_SOCK, buffer, XP_STRLEN(buffer));
-
- CD_NEXT_STATE = SMTP_RESPONSE;
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_SEND_HELO_RESPONSE;
- CD_PAUSE_FOR_READ = TRUE;
-
- return(CE_STATUS);
- }
-
-
- PRIVATE int
- net_smtp_extension_login_response(ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
- char buffer[356];
-
- if(CD_RESPONSE_CODE != 220)
- {
- CE_URL_S->error_msg = NET_ExplainErrorDetails(MK_COULD_NOT_LOGIN_TO_SMTP_SERVER);
- return(MK_COULD_NOT_LOGIN_TO_SMTP_SERVER);
- }
-
- PR_snprintf(buffer, sizeof(buffer), "EHLO %.256s" CRLF,
- net_smtp_get_user_domain_name());
-
- TRACEMSG(("Tx: %s", buffer));
-
- CE_STATUS = (int) NET_BlockingWrite(CE_SOCK, buffer, XP_STRLEN(buffer));
-
- CD_NEXT_STATE = SMTP_RESPONSE;
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_SEND_EHLO_RESPONSE;
- CD_PAUSE_FOR_READ = TRUE;
-
- return(CE_STATUS);
- }
-
-
- PRIVATE int
- net_smtp_send_helo_response(ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
- char buffer[620];
- const char *mail_add = FE_UsersMailAddress();
-
- /* don't check for a HELO response because it can be bogus and
- * we don't care
- */
-
- if(!mail_add)
- {
- CE_URL_S->error_msg = NET_ExplainErrorDetails(MK_COULD_NOT_GET_USERS_MAIL_ADDRESS);
- return(MK_COULD_NOT_GET_USERS_MAIL_ADDRESS);
- }
-
- if(CD_VERIFY_ADDRESS)
- {
- PR_snprintf(buffer, sizeof(buffer), "VRFY %.256s" CRLF, CD_VERIFY_ADDRESS);
- }
- else
- {
- /* else send the MAIL FROM: command */
- char *s = MSG_MakeFullAddress (NULL, mail_add);
- if (!s)
- {
- CE_URL_S->error_msg = NET_ExplainErrorDetails(MK_OUT_OF_MEMORY);
- return(MK_OUT_OF_MEMORY);
- }
- if (CE_URL_S->msg_pane) {
- if (MSG_RequestForReturnReceipt(CE_URL_S->msg_pane)) {
- if (CD_EHLO_DSN_ENABLED) {
- PR_snprintf(buffer, sizeof(buffer),
- "MAIL FROM:<%.256s> RET=FULL ENVID=NS40112696JT" CRLF,
- s);
- }
- else {
- FE_Alert (CE_WINDOW_ID, XP_GetString(XP_RETURN_RECEIPT_NOT_SUPPORT));
- PR_snprintf(buffer, sizeof(buffer), "MAIL FROM:<%.256s>" CRLF, s);
- }
- }
- else if (MSG_SendingMDNInProgress(CE_URL_S->msg_pane)) {
- PR_snprintf(buffer, sizeof(buffer), "MAIL FROM:<%.256s>" CRLF, "");
- }
- else {
- PR_snprintf(buffer, sizeof(buffer), "MAIL FROM:<%.256s>" CRLF, s);
- }
- }
- else {
- PR_snprintf(buffer, sizeof(buffer), "MAIL FROM:<%.256s>" CRLF, s);
- }
- XP_FREE (s);
- }
-
- TRACEMSG(("Tx: %s", buffer));
- CE_STATUS = (int) NET_BlockingWrite(CE_SOCK, buffer, XP_STRLEN(buffer));
-
- CD_NEXT_STATE = SMTP_RESPONSE;
-
- if(CD_VERIFY_ADDRESS)
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_SEND_VRFY_RESPONSE;
- else
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_SEND_MAIL_RESPONSE;
- CD_PAUSE_FOR_READ = TRUE;
-
- return(CE_STATUS);
- }
-
-
- PRIVATE int
- net_smtp_send_ehlo_response(ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
-
- if (CD_RESPONSE_CODE != 250) {
- /* EHLO not implemented */
- char buffer[384];
-
- HG85890
-
- PR_snprintf(buffer, sizeof(buffer), "HELO %.256s" CRLF,
- net_smtp_get_user_domain_name());
-
- TRACEMSG(("Tx: %s", buffer));
-
- CE_STATUS = (int) NET_BlockingWrite(CE_SOCK, buffer, XP_STRLEN(buffer));
-
- CD_NEXT_STATE = SMTP_RESPONSE;
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_SEND_HELO_RESPONSE;
- CD_PAUSE_FOR_READ = TRUE;
- return (CE_STATUS);
- }
- else {
- char *ptr = NULL;
- HG09714
-
- ptr = strcasestr(CD_RESPONSE_TXT, "DSN");
- CD_EHLO_DSN_ENABLED = (ptr && XP_TO_UPPER(*(ptr-1)) != 'X');
- /* should we use auth login */
- PREF_GetBoolPref("mail.auth_login", &(CD_AUTH_LOGIN_ENABLED));
- if (CD_AUTH_LOGIN_ENABLED) {
- /* okay user has set to use skey
- let's see does the server have the capability */
- CD_AUTH_LOGIN_ENABLED = (NULL != strcasestr(CD_RESPONSE_TXT, "AUTH=LOGIN"));
- }
-
-
- HG90967
- CD_NEXT_STATE = CD_NEXT_STATE_AFTER_RESPONSE = SMTP_AUTH_RESPONSE;
-
- HG59852
- return (CE_STATUS);
- }
- }
-
-
- PRIVATE int
- net_smtp_auth_login_response(ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
-
- switch (CD_RESPONSE_CODE/100) {
- case 2:
- {
- char *pop_password = (char *)NET_GetPopPassword();
- CD_NEXT_STATE = SMTP_SEND_HELO_RESPONSE;
- if (pop_password == NULL)
- NET_SetPopPassword2(net_smtp_password);
- #ifdef MOZ_MAIL_NEWS
- if ( IMAP_GetPassword() == NULL )
- IMAP_SetPassword(net_smtp_password);
- #endif /* MOZ_MAIL_NEWS */
- XP_FREEIF(pop_password);
- }
- break;
- case 3:
- CD_NEXT_STATE = SMTP_SEND_AUTH_LOGIN_PASSWORD;
- break;
- case 5:
- default:
- {
- char* pop_username = (char *) NET_GetPopUsername();
- /* NET_GetPopUsername () returns pointer to the cached
- * username. It did *NOT* alloc a new string
- */
- XP_FREEIF(net_smtp_password);
- if (FE_PromptUsernameAndPassword(cur_entry->window_id,
- NULL, &pop_username, &net_smtp_password)) {
- CD_NEXT_STATE = SMTP_SEND_AUTH_LOGIN_USERNAME;
- /* FE_PromptUsernameAndPassword() always alloc a new string
- * for pop_username. The caller has to free it.
- */
- XP_FREEIF(pop_username);
- }
- else {
- /* User hit cancel, but since the client and server both say
- * they want auth login we're just going to return an error
- * and not let the msg be sent to the server
- */
- CE_STATUS = MK_POP3_PASSWORD_UNDEFINED;
- }
- }
- break;
- }
-
- return (CE_STATUS);
- }
-
- PRIVATE int
- net_smtp_auth_login_username(ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
- char buffer[512];
- char *pop_username = (char *) NET_GetPopUsername();
- char *base64Str = NULL;
-
- if (!pop_username || !*pop_username)
- return (MK_POP3_USERNAME_UNDEFINED);
-
- #ifdef MOZ_MAIL_NEWS
- base64Str = NET_Base64Encode(pop_username,
- XP_STRLEN(pop_username));
- if (base64Str) {
- PR_snprintf(buffer, sizeof(buffer), "AUTH LOGIN %.256s" CRLF, base64Str);
- TRACEMSG(("Tx: %s", buffer));
-
- CE_STATUS = (int) NET_BlockingWrite(CE_SOCK, buffer, XP_STRLEN(buffer));
- CD_NEXT_STATE = SMTP_RESPONSE;
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_AUTH_LOGIN_RESPONSE;
- CD_PAUSE_FOR_READ = TRUE;
- XP_FREEIF(base64Str);
-
- return (CE_STATUS);
- }
- #endif /* MOZ_MAIL_NEWS */
-
- return -1;
- }
-
- PRIVATE int
- net_smtp_auth_login_password(ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
- char buffer[1024];
-
- /* use cached smtp password first
- * if not then use cached pop password
- * if pop password undefined
- * sync with smtp password
- */
-
- if (!net_smtp_password || !*net_smtp_password) {
- XP_FREEIF(net_smtp_password); /* in case its an empty string */
- net_smtp_password = (char *) NET_GetPopPassword();
- }
-
- if (!net_smtp_password || !*net_smtp_password) {
- char *fmt = XP_GetString (XP_PASSWORD_FOR_POP3_USER);
- char host[256];
- int len = 256;
-
- XP_MEMSET(host, 0, 256);
- PREF_GetCharPref("network.hosts.smtp_server", host, &len);
-
- PR_snprintf(buffer, sizeof (buffer),
- fmt, NET_GetPopUsername(), host);
- XP_FREEIF(net_smtp_password);
- net_smtp_password = FE_PromptPassword(cur_entry->window_id, buffer);
- if (!net_smtp_password)
- return MK_POP3_PASSWORD_UNDEFINED;
- }
-
- XP_ASSERT(net_smtp_password);
-
- if (net_smtp_password) {
- char *base64Str = NULL;
-
- #ifdef MOZ_MAIL_NEWS
- base64Str = NET_Base64Encode(net_smtp_password, XP_STRLEN(net_smtp_password));
- #endif /* MOZ_MAIL_NEWS */
-
- if (base64Str) {
- PR_snprintf(buffer, sizeof(buffer), "%.256s" CRLF, base64Str);
- TRACEMSG(("Tx: %s", buffer));
-
- CE_STATUS = (int) NET_BlockingWrite(CE_SOCK, buffer, XP_STRLEN(buffer));
- CD_NEXT_STATE = SMTP_RESPONSE;
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_AUTH_LOGIN_RESPONSE;
- CD_PAUSE_FOR_READ = TRUE;
- XP_FREEIF(base64Str);
-
- return (CE_STATUS);
- }
- }
-
- return -1;
- }
-
- PRIVATE int
- net_smtp_send_vrfy_response(ActiveEntry *cur_entry)
- {
- #if 0
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
- char buffer[512];
-
- if(CD_RESPONSE_CODE == 250 || CD_RESPONSE_CODE == 251)
- return(MK_USER_VERIFIED_BY_SMTP);
- else
- return(MK_USER_NOT_VERIFIED_BY_SMTP);
- #else
- XP_ASSERT(0);
- return(-1);
- #endif
- }
-
- PRIVATE int
- net_smtp_send_mail_response(ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
- char buffer[1024];
-
- if(CD_RESPONSE_CODE != 250)
- {
- CE_URL_S->error_msg =
- NET_ExplainErrorDetails(MK_ERROR_SENDING_FROM_COMMAND,
- CD_RESPONSE_TXT);
- return(MK_ERROR_SENDING_FROM_COMMAND);
- }
-
- /* Send the RCPT TO: command */
- if (CD_EHLO_DSN_ENABLED &&
- (CE_URL_S->msg_pane &&
- MSG_RequestForReturnReceipt(CE_URL_S->msg_pane)))
- {
- char *encodedAddress = esmtp_value_encode(CD_MAIL_TO_ADDRESS_PTR);
-
- if (encodedAddress) {
- PR_snprintf(buffer, sizeof(buffer),
- "RCPT TO:<%.256s> NOTIFY=SUCCESS,FAILURE ORCPT=rfc822;%.500s" CRLF,
- CD_MAIL_TO_ADDRESS_PTR, encodedAddress);
- XP_FREEIF(encodedAddress);
- }
- else {
- CE_STATUS = MK_OUT_OF_MEMORY;
- return (CE_STATUS);
- }
- }
- else
- {
- PR_snprintf(buffer, sizeof(buffer), "RCPT TO:<%.256s>" CRLF, CD_MAIL_TO_ADDRESS_PTR);
- }
- /* take the address we sent off the list (move the pointer to just
- past the terminating null.) */
- CD_MAIL_TO_ADDRESS_PTR += XP_STRLEN (CD_MAIL_TO_ADDRESS_PTR) + 1;
- CD_MAIL_TO_ADDRESSES_LEFT--;
-
- TRACEMSG(("Tx: %s", buffer));
-
- CE_STATUS = (int) NET_BlockingWrite(CE_SOCK, buffer, XP_STRLEN(buffer));
-
- CD_NEXT_STATE = SMTP_RESPONSE;
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_SEND_RCPT_RESPONSE;
- CD_PAUSE_FOR_READ = TRUE;
-
- return(CE_STATUS);
- }
-
- PRIVATE int
- net_smtp_send_rcpt_response(ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
- char buffer[16];
-
- if(CD_RESPONSE_CODE != 250 && CD_RESPONSE_CODE != 251)
- {
- CE_URL_S->error_msg =
- NET_ExplainErrorDetails(MK_ERROR_SENDING_RCPT_COMMAND,
- CD_RESPONSE_TXT);
- return(MK_ERROR_SENDING_RCPT_COMMAND);
- }
-
- if(CD_MAIL_TO_ADDRESSES_LEFT > 0)
- {
- /* more senders to RCPT to
- */
- CD_NEXT_STATE = SMTP_SEND_MAIL_RESPONSE;
- return(0);
- }
-
- /* else send the RCPT TO: command */
- XP_STRCPY(buffer, "DATA" CRLF);
-
- TRACEMSG(("Tx: %s", buffer));
-
- CE_STATUS = (int) NET_BlockingWrite(CE_SOCK, buffer, XP_STRLEN(buffer));
-
- CD_NEXT_STATE = SMTP_RESPONSE;
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_SEND_DATA_RESPONSE;
- CD_PAUSE_FOR_READ = TRUE;
-
- return(CE_STATUS);
- }
-
- PRIVATE int
- net_smtp_send_data_response(ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
- char * command=0;
-
- if(CD_RESPONSE_CODE != 354)
- {
- CE_URL_S->error_msg = NET_ExplainErrorDetails(
- MK_ERROR_SENDING_DATA_COMMAND,
- CD_RESPONSE_TXT ? CD_RESPONSE_TXT : "");
- return(MK_ERROR_SENDING_DATA_COMMAND);
- }
-
- #ifdef XP_UNIX
- {
- const char * FE_UsersRealMailAddress(void); /* definition */
- const char *real_name = FE_UsersRealMailAddress();
- char *s = (real_name ? MSG_MakeFullAddress (NULL, real_name) : 0);
- if (real_name && !s)
- {
- CE_URL_S->error_msg = NET_ExplainErrorDetails(MK_OUT_OF_MEMORY);
- return(MK_OUT_OF_MEMORY);
- }
- if(real_name)
- {
- char buffer[512];
- PR_snprintf(buffer, sizeof(buffer), "Sender: %.256s" CRLF, real_name);
- StrAllocCat(command, buffer);
- if(!command)
- {
- CE_URL_S->error_msg = NET_ExplainErrorDetails(MK_OUT_OF_MEMORY);
- return(MK_OUT_OF_MEMORY);
- }
- }
- }
-
- TRACEMSG(("sending extra unix header: %s", command));
-
- CE_STATUS = (int) NET_BlockingWrite(CE_SOCK, command, XP_STRLEN(command));
- if(CE_STATUS < 0)
- {
- TRACEMSG(("Error sending message"));
- }
- #endif /* XP_UNIX */
-
- /* set connect select since we need to select on
- * writes
- */
- NET_ClearReadSelect(CE_WINDOW_ID, CE_SOCK);
- NET_SetConnectSelect(CE_WINDOW_ID, CE_SOCK);
- #ifdef XP_WIN
- cd->calling_netlib_all_the_time = TRUE;
- NET_SetCallNetlibAllTheTime(CE_WINDOW_ID, "mksmtp");
- #endif
- CE_CON_SOCK = CE_SOCK;
-
- FREE(command);
-
- CD_NEXT_STATE = SMTP_SEND_POST_DATA;
- CD_PAUSE_FOR_READ = FALSE; /* send data directly */
-
- NET_Progress(CE_WINDOW_ID, XP_GetString(MK_MSG_DELIV_MAIL));
-
- /* get the size of the message */
- if(CE_URL_S->post_data_is_file)
- {
- XP_StatStruct stat_entry;
-
- if(-1 != XP_Stat(CE_URL_S->post_data,
- &stat_entry,
- xpFileToPost))
- CD_TOTAL_MESSAGE_SIZE = stat_entry.st_size;
- }
- else
- {
- CD_TOTAL_MESSAGE_SIZE = CE_URL_S->post_data_size;
- }
-
-
- return(CE_STATUS);
- }
-
- PRIVATE int
- net_smtp_send_post_data(ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
- unsigned long curtime;
-
- /* returns 0 on done and negative on error
- * positive if it needs to continue.
- */
- CE_STATUS = NET_WritePostData(CE_WINDOW_ID, CE_URL_S,
- CE_SOCK,
- &cd->write_post_data_data,
- TRUE);
-
- cd->pause_for_read = TRUE;
-
- if(CE_STATUS == 0)
- {
- /* normal done
- */
- XP_STRCPY(cd->data_buffer, CRLF "." CRLF);
- TRACEMSG(("sending %s", cd->data_buffer));
- CE_STATUS = (int) NET_BlockingWrite(CE_SOCK,
- cd->data_buffer,
- XP_STRLEN(cd->data_buffer));
-
- NET_Progress(CE_WINDOW_ID,
- XP_GetString(XP_MESSAGE_SENT_WAITING_MAIL_REPLY));
-
- NET_ClearConnectSelect(CE_WINDOW_ID, CE_SOCK);
- #ifdef XP_WIN
- if(cd->calling_netlib_all_the_time)
- {
- cd->calling_netlib_all_the_time = FALSE;
- NET_ClearCallNetlibAllTheTime(CE_WINDOW_ID, "mksmtp");
- }
- #endif
- NET_SetReadSelect(CE_WINDOW_ID, CE_SOCK);
- CE_CON_SOCK = 0;
-
- CD_NEXT_STATE = SMTP_RESPONSE;
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_SEND_MESSAGE_RESPONSE;
- return(0);
- }
-
- CD_TOTAL_AMT_WRITTEN += CE_STATUS;
-
- /* Update the thermo and the status bar. This is done by hand, rather
- than using the FE_GraphProgress* functions, because there seems to be
- no way to make FE_GraphProgress shut up and not display anything more
- when all the data has arrived. At the end, we want to show the
- "message sent; waiting for reply" status; FE_GraphProgress gets in
- the way of that. See bug #23414. */
-
- curtime = XP_TIME();
- if (curtime != cd->last_time) {
- FE_Progress(CE_WINDOW_ID, XP_ProgressText(CD_TOTAL_MESSAGE_SIZE,
- CD_TOTAL_AMT_WRITTEN,
- 0, 0));
- cd->last_time = curtime;
- }
-
- if(CD_TOTAL_MESSAGE_SIZE)
- FE_SetProgressBarPercent(CE_WINDOW_ID,
- CD_TOTAL_AMT_WRITTEN*100/CD_TOTAL_MESSAGE_SIZE);
-
- return(CE_STATUS);
- }
-
-
-
- PRIVATE int
- net_smtp_send_message_response(ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
-
- if(CD_RESPONSE_CODE != 250)
- {
- CE_URL_S->error_msg = NET_ExplainErrorDetails(MK_ERROR_SENDING_MESSAGE,
- CD_RESPONSE_TXT);
- return(MK_ERROR_SENDING_MESSAGE);
- }
-
- NET_Progress(CE_WINDOW_ID, XP_GetString(XP_PROGRESS_MAILSENT));
-
- /* else */
- CD_NEXT_STATE = SMTP_DONE;
- return(MK_NO_DATA);
- }
-
-
- PRIVATE int32
- net_MailtoLoad (ActiveEntry * cur_entry)
- {
- /* get memory for Connection Data */
- SMTPConData * cd = XP_NEW(SMTPConData);
- int32 pref = 0;
-
- cur_entry->con_data = cd;
- if(!cur_entry->con_data)
- {
- CE_URL_S->error_msg = NET_ExplainErrorDetails(MK_OUT_OF_MEMORY);
- CE_STATUS = MK_OUT_OF_MEMORY;
- return (CE_STATUS);
- }
-
- /* GH_UpdateGlobalHistory(cur_entry->URL_s); */
-
- /* init */
- XP_MEMSET(cd, 0, sizeof(SMTPConData));
-
- CD_CONTINUATION_RESPONSE = -1; /* init */
-
- CE_SOCK = NULL;
- HG61365
-
- /* make a copy of the address
- */
- if(CE_URL_S->method == URL_POST_METHOD)
- {
- int status=0;
- char *addrs1 = 0;
- char *addrs2 = 0;
- CD_NEXT_STATE = SMTP_START_CONNECT;
-
- /* Remove duplicates from the list, to prevent people from getting
- more than one copy (the SMTP host may do this too, or it may not.)
- This causes the address list to be parsed twice; this probably
- doesn't matter.
- */
- addrs1 = MSG_RemoveDuplicateAddresses (CE_URL_S->address+7, 0);
-
- /* Extract just the mailboxes from the full RFC822 address list.
- This means that people can post to mailto: URLs which contain
- full RFC822 address specs, and we will still send the right
- thing in the SMTP RCPT command.
- */
- if (addrs1 && *addrs1)
- {
- status = MSG_ParseRFC822Addresses (addrs1, 0, &addrs2);
- FREEIF (addrs1);
- }
-
- if (status < 0) return status;
-
- if (status == 0 || addrs2 == 0)
- {
- CD_NEXT_STATE = SMTP_ERROR_DONE;
- CD_PAUSE_FOR_READ = FALSE;
- CE_STATUS = MK_MIME_NO_RECIPIENTS;
- CE_URL_S->error_msg = NET_ExplainErrorDetails(CE_STATUS);
- return CE_STATUS;
- }
-
- CD_ADDRESS_COPY = addrs2;
- CD_MAIL_TO_ADDRESS_PTR = CD_ADDRESS_COPY;
- CD_MAIL_TO_ADDRESSES_LEFT = status;
- return(net_ProcessMailto(cur_entry));
- }
- else
- {
- /* parse special headers and stuff from the search data in the
- URL address. This data is of the form
-
- mailto:TO_FIELD?FIELD1=VALUE1&FIELD2=VALUE2
-
- where TO_FIELD may be empty, VALUEn may (for now) only be
- one of "cc", "bcc", "subject", "newsgroups", "references",
- and "attachment".
-
- "to" is allowed as a field/value pair as well, for consistency.
-
- One additional parameter is allowed, which does not correspond
- to a visible field: "newshost". This is the NNTP host (and port)
- to connect to if newsgroups are specified. If the value of this
- field ends in "/secure", then SSL will be used.
-
- Each parameter may appear only once, but the order doesn't
- matter. All values must be URL-encoded.
- */
- char *parms = NET_ParseURL (CE_URL_S->address, GET_SEARCH_PART);
- char *rest = parms;
- char *from = 0; /* internal only */
- char *reply_to = 0; /* internal only */
- char *to = 0;
- char *cc = 0;
- char *bcc = 0;
- char *fcc = 0; /* internal only */
- char *newsgroups = 0;
- char *followup_to = 0;
- char *html_part = 0; /* internal only */
- char *organization = 0; /* internal only */
- char *subject = 0;
- char *references = 0;
- char *attachment = 0; /* internal only */
- char *body = 0;
- char *other_random_headers = 0; /* unused (for now) */
- char *priority = 0;
- char *newshost = 0; /* internal only */
- XP_Bool encrypt_p = FALSE;
- XP_Bool sign_p = FALSE; /* internal only */
-
- char *newspost_url = 0;
- XP_Bool force_plain_text = FALSE;
- MSG_Pane *cpane = 0;
-
- to = NET_ParseURL (CE_URL_S->address, GET_PATH_PART);
-
- if (rest && *rest == '?')
- {
- /* start past the '?' */
- rest++;
- rest = XP_STRTOK (rest, "&");
- while (rest && *rest)
- {
- char *token = rest;
- char *value = 0;
- char *eq = XP_STRCHR (token, '=');
- if (eq)
- {
- value = eq+1;
- *eq = 0;
- }
- switch (*token)
- {
- case 'A': case 'a':
- if (!strcasecomp (token, "attachment") &&
- CE_URL_S->internal_url)
- StrAllocCopy (attachment, value);
- break;
- case 'B': case 'b':
- if (!strcasecomp (token, "bcc"))
- {
- if (bcc && *bcc)
- {
- StrAllocCat (bcc, ", ");
- StrAllocCat (bcc, value);
- }
- else
- {
- StrAllocCopy (bcc, value);
- }
- }
- else if (!strcasecomp (token, "body"))
- {
- if (body && *body)
- {
- StrAllocCat (body, "\n");
- StrAllocCat (body, value);
- }
- else
- {
- StrAllocCopy (body, value);
- }
- }
- break;
- case 'C': case 'c':
- if (!strcasecomp (token, "cc"))
- {
- if (cc && *cc)
- {
- StrAllocCat (cc, ", ");
- StrAllocCat (cc, value);
- }
- else
- {
- StrAllocCopy (cc, value);
- }
- }
- break;
- case 'E': case 'e':
- if (!strcasecomp (token, "encrypt") ||
- !strcasecomp (token, "encrypted"))
- encrypt_p = (!strcasecomp(value, "true") ||
- !strcasecomp(value, "yes"));
- break;
- case 'F': case 'f':
- if (!strcasecomp (token, "followup-to"))
- StrAllocCopy (followup_to, value);
- else if (!strcasecomp (token, "from") &&
- CE_URL_S->internal_url)
- StrAllocCopy (from, value);
- else if (!strcasecomp (token, "force-plain-text") &&
- CE_URL_S->internal_url)
- force_plain_text = TRUE;
- break;
- case 'H': case 'h':
- if (!strcasecomp(token, "html-part") &&
- CE_URL_S->internal_url) {
- StrAllocCopy(html_part, value);
- }
- case 'N': case 'n':
- if (!strcasecomp (token, "newsgroups"))
- StrAllocCopy (newsgroups, value);
- else if (!strcasecomp (token, "newshost") &&
- CE_URL_S->internal_url)
- StrAllocCopy (newshost, value);
- break;
- case 'O': case 'o':
- if (!strcasecomp (token, "organization") &&
- CE_URL_S->internal_url)
- StrAllocCopy (organization, value);
- break;
- case 'R': case 'r':
- if (!strcasecomp (token, "references"))
- StrAllocCopy (references, value);
- else if (!strcasecomp (token, "reply-to") &&
- CE_URL_S->internal_url)
- StrAllocCopy (reply_to, value);
- break;
- case 'S': case 's':
- if(!strcasecomp (token, "subject"))
- StrAllocCopy (subject, value);
- else if ((!strcasecomp (token, "sign") ||
- !strcasecomp (token, "signed")) &&
- CE_URL_S->internal_url)
- sign_p = (!strcasecomp(value, "true") ||
- !strcasecomp(value, "yes"));
- break;
- case 'P': case 'p':
- if (!strcasecomp (token, "priority"))
- StrAllocCopy (priority, value);
- break;
- case 'T': case 't':
- if (!strcasecomp (token, "to"))
- {
- if (to && *to)
- {
- StrAllocCat (to, ", ");
- StrAllocCat (to, value);
- }
- else
- {
- StrAllocCopy (to, value);
- }
- }
- break;
- }
- if (eq)
- *eq = '='; /* put it back */
- rest = XP_STRTOK (0, "&");
- }
- }
-
- FREEIF (parms);
- if (to)
- NET_UnEscape (to);
- if (cc)
- NET_UnEscape (cc);
- if (subject)
- NET_UnEscape (subject);
- if (newsgroups)
- NET_UnEscape (newsgroups);
- if (references)
- NET_UnEscape (references);
- if (attachment)
- NET_UnEscape (attachment);
- if (body)
- NET_UnEscape (body);
- if (newshost)
- NET_UnEscape (newshost);
-
- if(newshost)
- {
- char *prefix = "news://";
- char *slash = XP_STRRCHR (newshost, '/');
- if (slash && !strcasecomp (slash, "/secure"))
- {
- *slash = 0;
- prefix = "snews://";
- }
- newspost_url = (char *) XP_ALLOC (XP_STRLEN (prefix) +
- XP_STRLEN (newshost) + 10);
- if (newspost_url)
- {
- XP_STRCPY (newspost_url, prefix);
- XP_STRCAT (newspost_url, newshost);
- XP_STRCAT (newspost_url, "/");
- }
- }
- else
- {
- XP_Bool newsServerIsSecure = FALSE;
- PREF_GetBoolPref("news.server_is_secure", &newsServerIsSecure);
-
- if (newsServerIsSecure)
- newspost_url = XP_STRDUP("snews:");
- else
- newspost_url = XP_STRDUP ("news:");
- }
-
- /* Tell the message library and front end to pop up an edit window.
- */
- cpane = MSG_ComposeMessage (CE_WINDOW_ID,
- from, reply_to, to, cc, bcc, fcc,
- newsgroups, followup_to, organization,
- subject, references, other_random_headers,
- priority, attachment, newspost_url, body,
- encrypt_p, sign_p, force_plain_text,
- html_part);
-
- if (cpane && CE_URL_S->fe_data) {
- /* Tell libmsg what to do after deliver the message */
- MSG_SetPostDeliveryActionInfo (cpane, CE_URL_S->fe_data);
- }
-
- FREEIF(from);
- FREEIF(reply_to);
- FREEIF(to);
- FREEIF(cc);
- FREEIF(bcc);
- FREEIF(fcc);
- FREEIF(newsgroups);
- FREEIF(followup_to);
- FREEIF(html_part);
- FREEIF(organization);
- FREEIF(subject);
- FREEIF(references);
- FREEIF(attachment);
- FREEIF(body);
- FREEIF(other_random_headers);
- FREEIF(newshost);
- FREEIF(priority);
- FREEIF(newspost_url);
-
- CE_STATUS = MK_NO_DATA;
- XP_FREE(cd); /* no one else is gonna do it! */
- return(-1);
- }
- }
-
-
-
-
- /*
- We have connected to the mail relay and the type of authorization/login required
- has been established. Before we actually send our name and password check
- and see if we should do anything else for the selected auth mode.
- */
-
- PRIVATE int
- NET_CheckAuthResponse (ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
- int err = 0;
-
- HG54978
-
- if (CD_AUTH_LOGIN_ENABLED)
- {
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_AUTH_LOGIN_RESPONSE;
- CD_NEXT_STATE = SMTP_SEND_AUTH_LOGIN_USERNAME;
- return (CE_STATUS);
- }
- CD_NEXT_STATE = SMTP_SEND_HELO_RESPONSE;
- return (CE_STATUS);
- }
-
-
-
-
- /*
- * returns negative if the transfer is finished or error'd out
- *
- * returns zero or more if the transfer needs to be continued.
- */
- PRIVATE int32
- net_ProcessMailto (ActiveEntry *cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
- char *mail_relay_host;
-
- TRACEMSG(("Entering NET_ProcessSMTP"));
-
- CD_PAUSE_FOR_READ = FALSE; /* already paused; reset */
-
- while(!CD_PAUSE_FOR_READ)
- {
-
- TRACEMSG(("In NET_ProcessSMTP with state: %d", CD_NEXT_STATE));
-
- switch(CD_NEXT_STATE) {
-
- case SMTP_RESPONSE:
- net_smtp_response (cur_entry);
- break;
-
- case SMTP_START_CONNECT:
- mail_relay_host = NET_MailRelayHost(CE_WINDOW_ID);
- if (XP_STRLEN(mail_relay_host) == 0)
- {
- CE_STATUS = MK_MSG_NO_SMTP_HOST;
- break;
- }
- CE_STATUS = NET_BeginConnect(NET_MailRelayHost(CE_WINDOW_ID),
- NULL,
- "SMTP",
- SMTP_PORT,
- &CE_SOCK,
- FALSE,
- &CD_TCP_CON_DATA,
- CE_WINDOW_ID,
- &CE_URL_S->error_msg,
- cur_entry->socks_host,
- cur_entry->socks_port);
- CD_PAUSE_FOR_READ = TRUE;
- if(CE_STATUS == MK_CONNECTED)
- {
- CD_NEXT_STATE = SMTP_RESPONSE;
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_EXTN_LOGIN_RESPONSE;
- NET_SetReadSelect(CE_WINDOW_ID, CE_SOCK);
- }
- else if(CE_STATUS > -1)
- {
- CE_CON_SOCK = CE_SOCK; /* set con_sock so we can select on it */
- NET_SetConnectSelect(CE_WINDOW_ID, CE_CON_SOCK);
- CD_NEXT_STATE = SMTP_FINISH_CONNECT;
- }
- break;
-
- case SMTP_FINISH_CONNECT:
- CE_STATUS = NET_FinishConnect(NET_MailRelayHost(CE_WINDOW_ID),
- "SMTP",
- SMTP_PORT,
- &CE_SOCK,
- &CD_TCP_CON_DATA,
- CE_WINDOW_ID,
- &CE_URL_S->error_msg);
-
- CD_PAUSE_FOR_READ = TRUE;
- HG18931
- if(CE_STATUS == MK_CONNECTED)
- {
- CD_NEXT_STATE = SMTP_RESPONSE;
- CD_NEXT_STATE_AFTER_RESPONSE = SMTP_EXTN_LOGIN_RESPONSE;
- NET_ClearConnectSelect(CE_WINDOW_ID, CE_CON_SOCK);
- CE_CON_SOCK = NULL; /* reset con_sock so we don't select on it */
- NET_SetReadSelect(CE_WINDOW_ID, CE_SOCK);
- }
- else
- {
- /* unregister the old CE_SOCK from the select list
- * and register the new value in the case that it changes
- */
- if(CE_CON_SOCK != CE_SOCK)
- {
- NET_ClearConnectSelect(CE_WINDOW_ID, CE_CON_SOCK);
- CE_CON_SOCK = CE_SOCK;
- NET_SetConnectSelect(CE_WINDOW_ID, CE_CON_SOCK);
- }
- }
- break;
-
- case SMTP_AUTH_RESPONSE:
- CE_STATUS = NET_CheckAuthResponse(cur_entry);
- break;
-
- case SMTP_LOGIN_RESPONSE:
- CE_STATUS = net_smtp_login_response(cur_entry);
- break;
-
- case SMTP_EXTN_LOGIN_RESPONSE:
- CE_STATUS = net_smtp_extension_login_response(cur_entry);
- break;
-
- case SMTP_SEND_HELO_RESPONSE:
- CE_STATUS = net_smtp_send_helo_response(cur_entry);
- break;
-
- case SMTP_SEND_EHLO_RESPONSE:
- CE_STATUS = net_smtp_send_ehlo_response(cur_entry);
- break;
-
- case SMTP_AUTH_LOGIN_RESPONSE:
- CE_STATUS = net_smtp_auth_login_response(cur_entry);
- break;
-
- case SMTP_SEND_AUTH_LOGIN_USERNAME:
- CE_STATUS = net_smtp_auth_login_username(cur_entry);
- break;
-
- case SMTP_SEND_AUTH_LOGIN_PASSWORD:
- CE_STATUS = net_smtp_auth_login_password(cur_entry);
- break;
-
- case SMTP_SEND_VRFY_RESPONSE:
- CE_STATUS = net_smtp_send_vrfy_response(cur_entry);
- break;
-
- case SMTP_SEND_MAIL_RESPONSE:
- CE_STATUS = net_smtp_send_mail_response(cur_entry);
- break;
-
- case SMTP_SEND_RCPT_RESPONSE:
- CE_STATUS = net_smtp_send_rcpt_response(cur_entry);
- break;
-
- case SMTP_SEND_DATA_RESPONSE:
- CE_STATUS = net_smtp_send_data_response(cur_entry);
- break;
-
- case SMTP_SEND_POST_DATA:
- CE_STATUS = net_smtp_send_post_data(cur_entry);
- break;
-
- case SMTP_SEND_MESSAGE_RESPONSE:
- CE_STATUS = net_smtp_send_message_response(cur_entry);
- break;
-
- case SMTP_DONE:
- NET_BlockingWrite(CE_SOCK, "QUIT", 4);
- NET_ClearReadSelect(CE_WINDOW_ID, CE_SOCK);
- PR_Close(CE_SOCK);
- CD_NEXT_STATE = SMTP_FREE;
- break;
-
- case SMTP_ERROR_DONE:
- if(CE_SOCK != NULL)
- {
- /* we only send out quit if user interrupt
- * else must be server error which may not be
- * able to blocking write command
- */
- if (CE_STATUS == MK_INTERRUPTED)
- NET_BlockingWrite(CE_SOCK, "QUIT", 4);
- NET_ClearReadSelect(CE_WINDOW_ID, CE_SOCK);
- NET_ClearConnectSelect(CE_WINDOW_ID, CE_SOCK);
- #ifdef XP_WIN
- if(cd->calling_netlib_all_the_time)
- {
- cd->calling_netlib_all_the_time = FALSE;
- NET_ClearCallNetlibAllTheTime(CE_WINDOW_ID, "mksmtp");
- }
- #endif /* XP_WIN */
- NET_ClearDNSSelect(CE_WINDOW_ID, CE_SOCK);
- PR_Close(CE_SOCK);
- }
- CD_NEXT_STATE = SMTP_FREE;
- break;
-
- case SMTP_FREE:
- FREEIF(CD_DATA_BUFFER);
- FREEIF(CD_ADDRESS_COPY);
- FREEIF(CD_RESPONSE_TXT);
- if(CD_TCP_CON_DATA)
- NET_FreeTCPConData(CD_TCP_CON_DATA);
- if (cd->write_post_data_data)
- NET_free_write_post_data_object((struct WritePostDataData *)
- cd->write_post_data_data);
- FREE(cd);
-
- return(-1); /* final end */
-
- default: /* should never happen !!! */
- TRACEMSG(("SMTP: BAD STATE!"));
- CD_NEXT_STATE = SMTP_ERROR_DONE;
- break;
- }
-
- /* check for errors during load and call error
- * state if found
- */
- if(CE_STATUS < 0 && CD_NEXT_STATE != SMTP_FREE)
- {
- CD_NEXT_STATE = SMTP_ERROR_DONE;
- /* don't exit! loop around again and do the free case */
- CD_PAUSE_FOR_READ = FALSE;
- }
- } /* while(!CD_PAUSE_FOR_READ) */
-
- return(CE_STATUS);
- }
-
- /* abort the connection in progress
- */
- PRIVATE int32
- net_InterruptMailto(ActiveEntry * cur_entry)
- {
- SMTPConData * cd = (SMTPConData *)cur_entry->con_data;
-
- CD_NEXT_STATE = SMTP_ERROR_DONE;
- CE_STATUS = MK_INTERRUPTED;
-
- return(net_ProcessMailto(cur_entry));
- }
-
- /* Free any memory that might be used in caching etc.
- */
- PRIVATE void
- net_CleanupMailto(void)
- {
- /* nothing so far needs freeing */
- return;
- }
-
- MODULE_PRIVATE void
- NET_InitMailtoProtocol(void)
- {
- static NET_ProtoImpl mailto_proto_impl;
-
- mailto_proto_impl.init = net_MailtoLoad;
- mailto_proto_impl.process = net_ProcessMailto;
- mailto_proto_impl.interrupt = net_InterruptMailto;
- mailto_proto_impl.cleanup = net_CleanupMailto;
-
- NET_RegisterProtocolImplementation(&mailto_proto_impl, MAILTO_TYPE_URL);
- }
-
- #endif /* defined(MOZ_MAIL_NEWS) || defined(MOZ_MAIL_COMPOSE) */
- #endif /* defined(MOZILLA_CLIENT) || defined(LIBNET_SMTP) */
-