Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/net/smtp/SmtpClient.java
38830 views
/*1* Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.net.smtp;2627import java.util.StringTokenizer;28import java.io.*;29import java.net.*;30import sun.net.TransferProtocolClient;3132/**33* This class implements the SMTP client.34* You can send a piece of mail by creating a new SmtpClient, calling35* the "to" method to add destinations, calling "from" to name the36* sender, calling startMessage to return a stream to which you write37* the message (with RFC733 headers) and then you finally close the Smtp38* Client.39*40* @author James Gosling41*/4243public class SmtpClient extends TransferProtocolClient {4445private static int DEFAULT_SMTP_PORT = 25;46String mailhost;47SmtpPrintStream message;4849/**50* issue the QUIT command to the SMTP server and close the connection.51*/52public void closeServer() throws IOException {53if (serverIsOpen()) {54closeMessage();55issueCommand("QUIT\r\n", 221);56super.closeServer();57}58}5960void issueCommand(String cmd, int expect) throws IOException {61sendServer(cmd);62int reply;63while ((reply = readServerResponse()) != expect)64if (reply != 220) {65throw new SmtpProtocolException(getResponseString());66}67}6869private void toCanonical(String s) throws IOException {70if (s.startsWith("<"))71issueCommand("rcpt to: " + s + "\r\n", 250);72else73issueCommand("rcpt to: <" + s + ">\r\n", 250);74}7576public void to(String s) throws IOException {77if (s.indexOf('\n') != -1) {78throw new IOException("Illegal SMTP command",79new IllegalArgumentException("Illegal carriage return"));80}81int st = 0;82int limit = s.length();83int pos = 0;84int lastnonsp = 0;85int parendepth = 0;86boolean ignore = false;87while (pos < limit) {88int c = s.charAt(pos);89if (parendepth > 0) {90if (c == '(')91parendepth++;92else if (c == ')')93parendepth--;94if (parendepth == 0)95if (lastnonsp > st)96ignore = true;97else98st = pos + 1;99} else if (c == '(')100parendepth++;101else if (c == '<')102st = lastnonsp = pos + 1;103else if (c == '>')104ignore = true;105else if (c == ',') {106if (lastnonsp > st)107toCanonical(s.substring(st, lastnonsp));108st = pos + 1;109ignore = false;110} else {111if (c > ' ' && !ignore)112lastnonsp = pos + 1;113else if (st == pos)114st++;115}116pos++;117}118if (lastnonsp > st)119toCanonical(s.substring(st, lastnonsp));120}121122public void from(String s) throws IOException {123if (s.indexOf('\n') != -1) {124throw new IOException("Illegal SMTP command",125new IllegalArgumentException("Illegal carriage return"));126}127if (s.startsWith("<")) {128issueCommand("mail from: " + s + "\r\n", 250);129} else {130issueCommand("mail from: <" + s + ">\r\n", 250);131}132}133134/** open a SMTP connection to host <i>host</i>. */135private void openServer(String host) throws IOException {136mailhost = host;137openServer(mailhost, DEFAULT_SMTP_PORT);138issueCommand("helo "+InetAddress.getLocalHost().getHostName()+"\r\n", 250);139}140141public PrintStream startMessage() throws IOException {142issueCommand("data\r\n", 354);143try {144message = new SmtpPrintStream(serverOutput, this);145} catch (UnsupportedEncodingException e) {146throw new InternalError(encoding+" encoding not found", e);147}148return message;149}150151void closeMessage() throws IOException {152if (message != null)153message.close();154}155156/** New SMTP client connected to host <i>host</i>. */157public SmtpClient (String host) throws IOException {158super();159if (host != null) {160try {161openServer(host);162mailhost = host;163return;164} catch(Exception e) {165}166}167try {168String s;169mailhost = java.security.AccessController.doPrivileged(170new sun.security.action.GetPropertyAction("mail.host"));171if (mailhost != null) {172openServer(mailhost);173return;174}175} catch(Exception e) {176}177try {178mailhost = "localhost";179openServer(mailhost);180} catch(Exception e) {181mailhost = "mailhost";182openServer(mailhost);183}184}185186/** Create an uninitialized SMTP client. */187public SmtpClient () throws IOException {188this(null);189}190191public SmtpClient(int to) throws IOException {192super();193setConnectTimeout(to);194try {195String s;196mailhost = java.security.AccessController.doPrivileged(197new sun.security.action.GetPropertyAction("mail.host"));198if (mailhost != null) {199openServer(mailhost);200return;201}202} catch(Exception e) {203}204try {205mailhost = "localhost";206openServer(mailhost);207} catch(Exception e) {208mailhost = "mailhost";209openServer(mailhost);210}211}212213public String getMailHost() {214return mailhost;215}216217String getEncoding () {218return encoding;219}220}221222class SmtpPrintStream extends java.io.PrintStream {223private SmtpClient target;224private int lastc = '\n';225226SmtpPrintStream (OutputStream fos, SmtpClient cl) throws UnsupportedEncodingException {227super(fos, false, cl.getEncoding());228target = cl;229}230231public void close() {232if (target == null)233return;234if (lastc != '\n') {235write('\n');236}237try {238target.issueCommand(".\r\n", 250);239target.message = null;240out = null;241target = null;242} catch (IOException e) {243}244}245246public void write(int b) {247try {248// quote a dot at the beginning of a line249if (lastc == '\n' && b == '.') {250out.write('.');251}252253// translate NL to CRLF254if (b == '\n' && lastc != '\r') {255out.write('\r');256}257out.write(b);258lastc = b;259} catch (IOException e) {260}261}262263public void write(byte b[], int off, int len) {264try {265int lc = lastc;266while (--len >= 0) {267int c = b[off++];268269// quote a dot at the beginning of a line270if (lc == '\n' && c == '.')271out.write('.');272273// translate NL to CRLF274if (c == '\n' && lc != '\r') {275out.write('\r');276}277out.write(c);278lc = c;279}280lastc = lc;281} catch (IOException e) {282}283}284public void print(String s) {285int len = s.length();286for (int i = 0; i < len; i++) {287write(s.charAt(i));288}289}290}291292293