int colonIndex = argument.indexOf(":");
sender = argument.substring(colonIndex + 1);
argument = argument.substring(0, colonIndex);
}
if (session.getState().containsKey(SMTPSession.SENDER)) {
return new SMTPResponse(SMTPRetCode.BAD_SEQUENCE, DSNStatus
.getStatus(DSNStatus.PERMANENT, DSNStatus.DELIVERY_OTHER)
+ " Sender already specified");
} else if (!session.getConnectionState().containsKey(
SMTPSession.CURRENT_HELO_MODE)
&& session.useHeloEhloEnforcement()) {
return new SMTPResponse(SMTPRetCode.BAD_SEQUENCE, DSNStatus
.getStatus(DSNStatus.PERMANENT, DSNStatus.DELIVERY_OTHER)
+ " Need HELO or EHLO before MAIL");
} else if (argument == null
|| !argument.toUpperCase(Locale.US).equals("FROM")
|| sender == null) {
return new SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,
DSNStatus.getStatus(DSNStatus.PERMANENT,
DSNStatus.DELIVERY_INVALID_ARG)
+ " Usage: MAIL FROM:<sender>");
} else {
sender = sender.trim();
// the next gt after the first lt ... AUTH may add more <>
int lastChar = sender.indexOf('>', sender.indexOf('<'));
// Check to see if any options are present and, if so, whether they
// are correctly formatted
// (separated from the closing angle bracket by a ' ').
if ((lastChar > 0) && (sender.length() > lastChar + 2)
&& (sender.charAt(lastChar + 1) == ' ')) {
String mailOptionString = sender.substring(lastChar + 2);
// Remove the options from the sender
sender = sender.substring(0, lastChar + 1);
StringTokenizer optionTokenizer = new StringTokenizer(
mailOptionString, " ");
while (optionTokenizer.hasMoreElements()) {
String mailOption = optionTokenizer.nextToken();
int equalIndex = mailOption.indexOf('=');
String mailOptionName = mailOption;
String mailOptionValue = "";
if (equalIndex > 0) {
mailOptionName = mailOption.substring(0, equalIndex)
.toUpperCase(Locale.US);
mailOptionValue = mailOption.substring(equalIndex + 1);
}
// Handle the SIZE extension keyword
if (paramHooks.containsKey(mailOptionName)) {
MailParametersHook hook = paramHooks.get(mailOptionName);
SMTPResponse res = calcDefaultSMTPResponse(hook.doMailParameter(session, mailOptionName, mailOptionValue));
if (res != null) {
return res;
}
} else {
// Unexpected option attached to the Mail command
if (session.getLogger().isDebugEnabled()) {
StringBuilder debugBuffer = new StringBuilder(128)
.append(
"MAIL command had unrecognized/unexpected option ")
.append(mailOptionName).append(
" with value ").append(
mailOptionValue);
session.getLogger().debug(debugBuffer.toString());
}
}
}
}
if (session.useAddressBracketsEnforcement()
&& (!sender.startsWith("<") || !sender.endsWith(">"))) {
if (session.getLogger().isInfoEnabled()) {
StringBuilder errorBuffer = new StringBuilder(128).append(
"Error parsing sender address: ").append(sender)
.append(": did not start and end with < >");
session.getLogger().info(errorBuffer.toString());
}
return new SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,
DSNStatus.getStatus(DSNStatus.PERMANENT,
DSNStatus.ADDRESS_SYNTAX_SENDER)
+ " Syntax error in MAIL command");
}
MailAddress senderAddress = null;
if (session.useAddressBracketsEnforcement()
|| (sender.startsWith("<") && sender.endsWith(">"))) {
// Remove < and >
sender = sender.substring(1, sender.length() - 1);
}
if (sender.length() == 0) {
// This is the <> case. Let senderAddress == null
} else {
if (sender.indexOf("@") < 0) {
sender = sender
+ "@"
+ getDefaultDomain();
}
try {
senderAddress = new MailAddress(sender);
} catch (Exception pe) {
if (session.getLogger().isInfoEnabled()) {
StringBuilder errorBuffer = new StringBuilder(256)
.append("Error parsing sender address: ")
.append(sender).append(": ").append(
pe.getMessage());
session.getLogger().info(errorBuffer.toString());
}
return new SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,
DSNStatus.getStatus(DSNStatus.PERMANENT,
DSNStatus.ADDRESS_SYNTAX_SENDER)
+ " Syntax error in sender address");
}
}