package zeta.util;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
public class SendMail extends Thread {
public SendMail(String smtpHostname, int smtpPort, String sendFrom, String sendTo, String title, String message) {
this(smtpHostname, smtpPort, null, null, sendFrom, new String[] { sendTo }, title, message);
}
public SendMail(String smtpHostname, int smtpPort, String loginName, String loginPassword, String sendFrom, String sendTo, String title, String message) {
this(smtpHostname, smtpPort, loginName, loginPassword, sendFrom, new String[] { sendTo }, title, message);
}
public SendMail(String smtpHostname, int smtpPort, String loginName, String loginPassword, String sendFrom, String[] sendTo, String title, String message) {
this.smtpHostname = smtpHostname;
this.smtpPort = smtpPort;
this.loginName = loginName;
this.loginPassword = loginPassword;
this.realNameFrom = this.sendFrom = sendFrom;
this.realNameTo = new String[sendTo.length];
this.sendTo = new String[sendTo.length];
System.arraycopy(sendTo, 0, this.realNameTo, 0, sendTo.length);
System.arraycopy(sendTo, 0, this.sendTo, 0, sendTo.length);
this.title = title;
this.message = message;
}
public void setRealNameFrom(String realNameFrom) {
this.realNameFrom = realNameFrom;
}
public void setRealNameTo(String realNameTo) {
setRealNameTo(0, realNameTo);
}
public void setRealNameTo(int idx, String realNameTo) {
this.realNameTo[idx] = realNameTo;
}
public void setPop3Authentication(int pop3Port) {
this.pop3Port = pop3Port;
}
public synchronized void run() {
for (int i = 0; i < sendTo.length; ++i) {
if (!isValidEmailAddressSyntax(sendTo[i])) {
if (verbose) {
System.out.println("E-mail address '" + sendTo[i] + "' is invalid!");
}
successfully = false;
return;
}
}
successfully = true;
Socket socket = null;
try {
if (pop3Port >= 0 && loginName != null && loginPassword != null) {
socket = new Socket(smtpHostname, pop3Port);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "8859_1"));
PrintWriter out = new PrintWriter(socket.getOutputStream());
sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
String s = new String(decoder.decodeBuffer(loginName));
successfully &= sendline(in, out, "USER " + s);
s = new String(decoder.decodeBuffer(loginPassword));
successfully &= sendline(in, out, "PASS " + s);
socket.close();
socket = null;
}
socket = new Socket(smtpHostname, smtpPort);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "8859_1"));
PrintWriter out = new PrintWriter(socket.getOutputStream());
successfully &= sendline(in, out, "HELO " + InetAddress.getLocalHost().getHostName());
if (pop3Port < 0 && loginName != null && loginPassword != null) {
successfully &= sendline(in, out, "AUTH LOGIN");
successfully &= sendline(in, out, loginName);
successfully &= sendline(in, out, loginPassword);
}
for (int i = 0; successfully && i < sendTo.length; ++i) {
if (verbose) {
System.out.print("send to " + sendTo[i]);
System.out.flush();
}
successfully &= sendline(in, out, "MAIL FROM: " + sendFrom);
successfully &= sendline(in, out, "RCPT TO: " + sendTo[i]);
successfully &= sendline(in, out, "DATA");
successfully &= sendline(in, out, "From: " + realNameFrom + "\nTo: " + realNameTo[i] + "\nSubject: " + title + '\n' + message + "\n.");
if (verbose) {
if (successfully) {
System.out.println(" successfully.");
} else {
System.out.println(" error occurred!");
}
}
}
successfully &= sendline(in, out, "QUIT");
} catch (IOException ioe) {
ThrowableHandler.handle(ioe);
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException ioe) {
}
}
}
}
public synchronized boolean isSuccessfully() {
return successfully;
}
public void setVerbose(boolean verbose) {
this.verbose = verbose;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
public static boolean isValidEmailAddressSyntax(String emailAddress) {
int idxAt = -1;
int idxDot = -1;
int l = emailAddress.length();
for (int i = 0; i < l; ++i) {
char c = emailAddress.charAt(i);
if (!Character.isLetterOrDigit(c)) {
if (c == '@') {
idxAt = i;
if (i+1 == l) {
return false;
}
c = emailAddress.charAt(i+1);
if (c == '.' || c == '-') {
return false;
}
} else if (c == '-') {
if (i+1 == l || emailAddress.charAt(i+1) == '.') {
return false;
}
} else if (c == '.') {
idxDot = i;
if (i+1 == l || emailAddress.charAt(i+1) == '-') {
return false;
}
} else if (c == '_') {
if (i+1 == l) {
return false;
}
} else {
return false;
}
}
}
return (l >= 6 && idxAt > 0 && idxAt < idxDot && idxDot+2 < l && l-idxAt <= 68);
}
private boolean sendline(BufferedReader in, PrintWriter out, String data) throws IOException {
if (debug) {
System.out.println(data);
}
out.print(data + '\n');
out.flush();
data = in.readLine();
if (debug) {
System.out.println(">" + data);
}
return (data != null && (data.startsWith("2") || data.startsWith("3") || data.startsWith("+OK")));
}
public static void main(String args[]) {
if (args.length == 8) {
String sendFrom = args[4];
String sendFromEmail = args[4];
int i = sendFrom.lastIndexOf(' ', sendFrom.indexOf('@'));
if (i > 0) {
sendFromEmail = sendFrom.substring(i+1);
sendFrom = "\"" + sendFrom.substring(0, i) + "\"" + sendFrom.substring(i);
}
sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
FileInputStream in = null;
try {
in = new FileInputStream(args[7]);
ByteArrayOutputStream out = new ByteArrayOutputStream(10000);
StreamUtils.writeData(in, out, true, true);
in = null;
String message = out.toString();
in = new FileInputStream(args[5]);
out.reset();
StreamUtils.writeData(in, out, true, true);
StringTokenizer sendTo = new StringTokenizer(out.toString());
List sendToEmail = new ArrayList(sendTo.countTokens());
while (sendTo.hasMoreTokens()) {
String s = sendTo.nextToken().trim();
if (isValidEmailAddressSyntax(s)) {
sendToEmail.add(s);
}
}
String[] sendToEmailArray = new String[sendToEmail.size()];
for (int j = 0; j < sendToEmailArray.length; ++j) {
sendToEmailArray[j] = (String)sendToEmail.get(j);
}
SendMail sendMail = new SendMail(args[0], Integer.parseInt(args[1]), encoder.encode(args[2].getBytes()), encoder.encode(args[3].getBytes()), sendFromEmail, sendToEmailArray, args[6], message);
sendMail.setRealNameFrom(sendFrom);
sendMail.setPop3Authentication(110);
sendMail.setVerbose(true);
sendMail.run();
} catch (IOException ioe) {
ThrowableHandler.handle(ioe);
} finally {
StreamUtils.close(in);
}
} else {
System.out.println("USAGE: <SMTP hostname> <SMTP port> <login name> <login password> <send from> <filename of send to names> <title> <filename of message>");
}
}
private String smtpHostname;
private int smtpPort;
private String loginName;
private String loginPassword;
private String sendFrom;
private String realNameFrom;
private String[] sendTo;
private String[] realNameTo;
private String title;
private String message;
private boolean debug = false;
private boolean verbose = false;
private int pop3Port = -1;
private boolean successfully = false;
}