/* libvinny - a collection of more or less useful classes Copyright (C) 1998, Vincent Partington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Patched by IDM */ package org.gjt.vinny.beans; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Serializable; import java.io.StringReader; import java.io.Writer; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.StringTokenizer; /** * The MailBean is a simple bean to send email messages * from JSP pages. *

* Using bean introspection and the fact that JSP pages may throw * IOExceptions, usage can be very simple: *

* <BEAN name="mailer" type="nl.nmg.beans.MailBean"></BEAN>
* <% mailer.send() %>
*

* For more robust usage, the request parameter would be checked and * nice error message written on an IOException. * * @author Vincent Partington * @version 1.1, 1998/09/12 */ public class MailBean implements Serializable { private String server, from, to, cc, bcc, subject, contentType, body, encoding; private int port; private static String localHostName = "localhost"; static { try { localHostName = InetAddress.getLocalHost().getHostName(); } catch(UnknownHostException uhexc) { // } } /** * Allocates a new MailBean. The following properties are set: *

*

*/ public MailBean() { server = "mail"; from = "unknown-sender@somewhere.com"; to = "unknown-recipient@somewhere.com"; cc = null; subject = ""; contentType = null; body = ""; encoding = null; port = 25; } /** * Returns the SMTP server. * * @return the SMTP server */ public String getServer() { return server; } /** * Sets the SMTP server * * @param server the SMTP server */ public void setServer(String server) { if(server != null && server.length() > 0) { this.server = server; } else { this.server = "mail"; } } /** * Returns the sender of the message. * * @return the From: header value */ public String getFrom() { return from; } /** * Sets the sender of the message. The sender email * address can be specified in one of the following ways: * *

* If from is null or empty, the * sender is set to "unknown-sender@somewhere.com". * * @param from the email address of the sender */ public void setFrom(String from) { if(from != null && from.length() > 0) { this.from = from; } else { this.from = "unknown-sender@somewhere.com"; } } /** * Returns the recipients of the message. * * @return the To: header value */ public String getTo() { return to; } /** * Sets the recipients of the message. The recipient email * addresses are separated by comma's and may be specified * in one of the following ways: *

*

* If to is null or empty, the * sender is set to "unknown-recipient@somewhere.com". * * @param the email address of the recipient */ public void setTo(String to) { if(to != null && to.length() > 0) { this.to = to; } else { this.to = "unknown-recipient@somewhere.com"; } } /** * Sets the message body encoding. * null means platform default encoding */ public void setEncoding(String enc) { encoding = enc; } /** * Returns current message body encoding, null if using default */ public String getEncoding() { return encoding; } /** * Sets the mail server port. 25 is default value */ public void setPort(int port) { this.port = port; } /** * Returns the mail server communication port */ public int getPort() { return port; } /** * Returns the additional recipients of the message. * * @return the Cc: header value */ public String getCc() { return cc; } /** * Sets the additional recipients of the message. The recipient * email addresses are separated by comma's and may be specified * in one of the following ways: *

* * @param the email addresses of the additional recipients */ public void setCc(String cc) { if(cc != null && cc.length() > 0) { this.cc = cc; } else { this.cc = null; } } /** * Returns the invisible recipients of the message. * * @return the Bcc: header value * (which is not actually sent) */ public String getBcc() { return bcc; } /** * Sets the invisible recipients of the message. The recipient * email addresses are separated by comma's and may be specified * in one of the following ways: * * * @param the email addresses of the additional recipients */ public void setBcc(String bcc) { if(bcc != null && bcc.length() > 0) { this.bcc = bcc; } else { this.bcc = null; } } /** * Returns the subject of the message. * * @return the Subject: header value */ public String getSubject() { return subject; } /** * Sets the subject of the message. *

* If subject is null or empty, * the subject is set to "<No subject specified>". * * @param subject the subject to set */ public void setSubject(String subject) { if(subject != null && subject.length() > 0) { this.subject = subject; } else { this.subject = ""; } } /** * Returns the content-type of the message. * * @return the Content-Type: header value */ public String getContentType() { return contentType; } /** * Sets the content-type of the message. * * @param contentType the content-type to set */ public void setContentType(String contentType) { if(contentType != null && contentType.length() > 0) { this.contentType = contentType; } else { this.contentType = null; } } /** * Returns the body of the message. * * @return the body */ public String getBody() { return body; } /** * Sets the body of the message. *

* If body is null, * the body is set to the empty string. * * @param body the body to set */ public void setBody(String body) { if(body != null) { this.body = body; } else { this.body = ""; } } /** * Sends the email message. * * @exception IOException if there was an I/O or SMTP error */ public void send() throws IOException { Socket socket; BufferedReader sockIn; Writer sockOut; BufferedReader bodyIn; String line; // make connection to mail server socket = new Socket(server, port); sockIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); try { OutputStreamWriter osw = (encoding == null) ? new OutputStreamWriter(socket.getOutputStream()) : new OutputStreamWriter(socket.getOutputStream(),encoding); sockOut = new BufferedWriter(osw); try { checkReply(sockIn); sendCommand(sockOut, "HELO " + localHostName); checkReply(sockIn); // send envelope sendCommand(sockOut, "MAIL FROM: " + getRealAddress(from)); checkReply(sockIn); sendRecipients(sockIn, sockOut, to); sendRecipients(sockIn, sockOut, cc); sendRecipients(sockIn, sockOut, bcc); sendCommand(sockOut, "DATA"); checkReply(sockIn); // send message writeHeader(sockOut, "From", from); writeHeader(sockOut, "To", to); if(cc != null) { writeHeader(sockOut, "Cc", cc); } writeHeader(sockOut, "Subject", subject); if(contentType != null) { writeHeader(sockOut, "MIME-Version", "1.0"); writeHeader(sockOut, "Content-Type", contentType); } sockOut.write("\015\012"); bodyIn = new BufferedReader(new StringReader(body)); while((line = bodyIn.readLine()) != null) { if(line.equals(".")) { sockOut.write("..\015\012"); } else { sockOut.write(line); sockOut.write("\015\012"); } } sockOut.write(".\015\012"); sockOut.flush(); checkReply(sockIn); sendCommand(sockOut, "QUIT"); } finally { sockOut.close(); } } finally { sockIn.close(); } } private String getRealAddress(String addr) { int i, j; i = addr.indexOf('('); if(i != -1) { return addr.substring(0, i).trim(); } i = addr.indexOf('<'); if(i != -1) { j = addr.indexOf('>', i); if(j != -1) { return addr.substring(i+1, j).trim(); } } return addr.trim(); } private void sendRecipients(BufferedReader sockIn, Writer sockOut, String addrs) throws IOException { StringTokenizer toker; String addr; if(addrs != null) { toker = new StringTokenizer(addrs, ","); while(toker.hasMoreTokens()) { addr = toker.nextToken().trim(); if(addr.length() > 0) { sendCommand(sockOut, "RCPT TO: " + getRealAddress(addr)); checkReply(sockIn); } } } } private void writeHeader(Writer sockOut, String key, String value) throws IOException { BufferedReader valueIn; String line; boolean first = true; valueIn = new BufferedReader(new StringReader(value)); try { while((line = valueIn.readLine()) != null) { if(first) { sockOut.write(key); sockOut.write(": "); first = false; } else { sockOut.write("\t"); } sockOut.write(line); sockOut.write("\015\012"); } } finally { valueIn.close(); } } /* * These two methods were written by Thornton Rose. There was no copyright * notice on the source, and it was on www.developer.com, so I hope it's * cool to use them here. */ private void sendCommand(Writer sockOut, String command) throws IOException { sockOut.write(command); sockOut.write("\015\012"); sockOut.flush(); } private void checkReply(BufferedReader sockIn) throws IOException { String reply; char statusCode; reply = sockIn.readLine(); statusCode = reply.charAt(0); if(statusCode == '4' || statusCode == '5') { throw new IOException("SMTP Error: " + reply); } } }