0N/A/*
2362N/A * Copyright (c) 1995, 2003, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.net.smtp;
0N/A
0N/Aimport java.util.StringTokenizer;
0N/Aimport java.io.*;
0N/Aimport java.net.*;
0N/Aimport sun.net.TransferProtocolClient;
0N/A
0N/A/**
0N/A * This class implements the SMTP client.
0N/A * You can send a piece of mail by creating a new SmtpClient, calling
0N/A * the "to" method to add destinations, calling "from" to name the
0N/A * sender, calling startMessage to return a stream to which you write
0N/A * the message (with RFC733 headers) and then you finally close the Smtp
0N/A * Client.
0N/A *
0N/A * @author James Gosling
0N/A */
0N/A
0N/Apublic class SmtpClient extends TransferProtocolClient {
0N/A
0N/A String mailhost;
0N/A SmtpPrintStream message;
0N/A
0N/A /**
0N/A * issue the QUIT command to the SMTP server and close the connection.
0N/A */
0N/A public void closeServer() throws IOException {
0N/A if (serverIsOpen()) {
0N/A closeMessage();
0N/A issueCommand("QUIT\r\n", 221);
0N/A super.closeServer();
0N/A }
0N/A }
0N/A
0N/A void issueCommand(String cmd, int expect) throws IOException {
0N/A sendServer(cmd);
0N/A int reply;
0N/A while ((reply = readServerResponse()) != expect)
0N/A if (reply != 220) {
0N/A throw new SmtpProtocolException(getResponseString());
0N/A }
0N/A }
0N/A
0N/A private void toCanonical(String s) throws IOException {
0N/A if (s.startsWith("<"))
0N/A issueCommand("rcpt to: " + s + "\r\n", 250);
0N/A else
0N/A issueCommand("rcpt to: <" + s + ">\r\n", 250);
0N/A }
0N/A
0N/A public void to(String s) throws IOException {
0N/A int st = 0;
0N/A int limit = s.length();
0N/A int pos = 0;
0N/A int lastnonsp = 0;
0N/A int parendepth = 0;
0N/A boolean ignore = false;
0N/A while (pos < limit) {
0N/A int c = s.charAt(pos);
0N/A if (parendepth > 0) {
0N/A if (c == '(')
0N/A parendepth++;
0N/A else if (c == ')')
0N/A parendepth--;
0N/A if (parendepth == 0)
0N/A if (lastnonsp > st)
0N/A ignore = true;
0N/A else
0N/A st = pos + 1;
0N/A } else if (c == '(')
0N/A parendepth++;
0N/A else if (c == '<')
0N/A st = lastnonsp = pos + 1;
0N/A else if (c == '>')
0N/A ignore = true;
0N/A else if (c == ',') {
0N/A if (lastnonsp > st)
0N/A toCanonical(s.substring(st, lastnonsp));
0N/A st = pos + 1;
0N/A ignore = false;
0N/A } else {
0N/A if (c > ' ' && !ignore)
0N/A lastnonsp = pos + 1;
0N/A else if (st == pos)
0N/A st++;
0N/A }
0N/A pos++;
0N/A }
0N/A if (lastnonsp > st)
0N/A toCanonical(s.substring(st, lastnonsp));
0N/A }
0N/A
0N/A public void from(String s) throws IOException {
0N/A if (s.startsWith("<"))
0N/A issueCommand("mail from: " + s + "\r\n", 250);
0N/A else
0N/A issueCommand("mail from: <" + s + ">\r\n", 250);
0N/A }
0N/A
0N/A /** open a SMTP connection to host <i>host</i>. */
0N/A private void openServer(String host) throws IOException {
0N/A mailhost = host;
0N/A openServer(mailhost, 25);
0N/A issueCommand("helo "+InetAddress.getLocalHost().getHostName()+"\r\n", 250);
0N/A }
0N/A
0N/A public PrintStream startMessage() throws IOException {
0N/A issueCommand("data\r\n", 354);
0N/A try {
0N/A message = new SmtpPrintStream(serverOutput, this);
0N/A } catch (UnsupportedEncodingException e) {
0N/A throw new InternalError(encoding+" encoding not found");
0N/A }
0N/A return message;
0N/A }
0N/A
0N/A void closeMessage() throws IOException {
0N/A if (message != null)
0N/A message.close();
0N/A }
0N/A
0N/A /** New SMTP client connected to host <i>host</i>. */
0N/A public SmtpClient (String host) throws IOException {
0N/A super();
0N/A if (host != null) {
0N/A try {
0N/A openServer(host);
0N/A mailhost = host;
0N/A return;
0N/A } catch(Exception e) {
0N/A }
0N/A }
0N/A try {
0N/A String s;
0N/A mailhost = java.security.AccessController.doPrivileged(
0N/A new sun.security.action.GetPropertyAction("mail.host"));
0N/A if (mailhost != null) {
0N/A openServer(mailhost);
0N/A return;
0N/A }
0N/A } catch(Exception e) {
0N/A }
0N/A try {
0N/A mailhost = "localhost";
0N/A openServer(mailhost);
0N/A } catch(Exception e) {
0N/A mailhost = "mailhost";
0N/A openServer(mailhost);
0N/A }
0N/A }
0N/A
0N/A /** Create an uninitialized SMTP client. */
0N/A public SmtpClient () throws IOException {
0N/A this(null);
0N/A }
0N/A
0N/A public SmtpClient(int to) throws IOException {
0N/A super();
0N/A setConnectTimeout(to);
0N/A try {
0N/A String s;
0N/A mailhost = java.security.AccessController.doPrivileged(
0N/A new sun.security.action.GetPropertyAction("mail.host"));
0N/A if (mailhost != null) {
0N/A openServer(mailhost);
0N/A return;
0N/A }
0N/A } catch(Exception e) {
0N/A }
0N/A try {
0N/A mailhost = "localhost";
0N/A openServer(mailhost);
0N/A } catch(Exception e) {
0N/A mailhost = "mailhost";
0N/A openServer(mailhost);
0N/A }
0N/A }
0N/A
0N/A public String getMailHost() {
0N/A return mailhost;
0N/A }
0N/A
0N/A String getEncoding () {
0N/A return encoding;
0N/A }
0N/A}
0N/A
0N/Aclass SmtpPrintStream extends java.io.PrintStream {
0N/A private SmtpClient target;
0N/A private int lastc = '\n';
0N/A
0N/A SmtpPrintStream (OutputStream fos, SmtpClient cl) throws UnsupportedEncodingException {
0N/A super(fos, false, cl.getEncoding());
0N/A target = cl;
0N/A }
0N/A
0N/A public void close() {
0N/A if (target == null)
0N/A return;
0N/A if (lastc != '\n') {
0N/A write('\n');
0N/A }
0N/A try {
0N/A target.issueCommand(".\r\n", 250);
0N/A target.message = null;
0N/A out = null;
0N/A target = null;
0N/A } catch (IOException e) {
0N/A }
0N/A }
0N/A
0N/A public void write(int b) {
0N/A try {
0N/A // quote a dot at the beginning of a line
0N/A if (lastc == '\n' && b == '.') {
0N/A out.write('.');
0N/A }
0N/A
0N/A // translate NL to CRLF
0N/A if (b == '\n' && lastc != '\r') {
0N/A out.write('\r');
0N/A }
0N/A out.write(b);
0N/A lastc = b;
0N/A } catch (IOException e) {
0N/A }
0N/A }
0N/A
0N/A public void write(byte b[], int off, int len) {
0N/A try {
0N/A int lc = lastc;
0N/A while (--len >= 0) {
0N/A int c = b[off++];
0N/A
0N/A // quote a dot at the beginning of a line
0N/A if (lc == '\n' && c == '.')
0N/A out.write('.');
0N/A
0N/A // translate NL to CRLF
0N/A if (c == '\n' && lc != '\r') {
0N/A out.write('\r');
0N/A }
0N/A out.write(c);
0N/A lc = c;
0N/A }
0N/A lastc = lc;
0N/A } catch (IOException e) {
0N/A }
0N/A }
0N/A public void print(String s) {
0N/A int len = s.length();
0N/A for (int i = 0; i < len; i++) {
0N/A write(s.charAt(i));
0N/A }
0N/A }
0N/A}